Merge pull request 'feat: statusbar 在送出第一個提示詞前就顯示額度、ctx 與系統資源' (#25) from feat/statusbar-prefetch into main
Reviewed-on: https://gitea.jsc.idv.tw/jiantw83/jsc-marketplace/pulls/25
This commit was merged in pull request #25.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jsc-statusbar",
|
||||
"version": "0.0.3",
|
||||
"version": "0.0.4",
|
||||
"description": "輸入框上方的單行狀態列:模型、目錄、分支、5h/7d 額度與重置、context、CPU/記憶體/磁碟",
|
||||
"license": "MIT",
|
||||
"types": "./types/index.d.ts",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { atom, read, update } from 'claude-code'
|
||||
import type { EngineInterface, Register, SessionContextUsage, SessionRateLimit } from 'claude-code'
|
||||
|
||||
import type { Mode, Sys, Usage } from '../types'
|
||||
import type { Mode, Sys, Usage, Window } from '../types'
|
||||
import { fit, cpuPercent, parseCpu, parseDf, parseGit, parseMem, parseOffset } from './format'
|
||||
import type { CpuSample } from './format'
|
||||
|
||||
@@ -19,6 +19,7 @@ const ALERT_AT = 90
|
||||
const GIT_TOOLS = new Set(['Bash', 'Edit', 'Write', 'NotebookEdit'])
|
||||
const LABEL: Record<string, string> = { five_hour: '5 小時', seven_day: '7 天' }
|
||||
|
||||
// 引擎要等第一次 API 回應才有額度與 ctx;先前的額度存在 $.store,開新對話時先顯示,ctx 先當作 0
|
||||
function toUsage(context: SessionContextUsage, rateLimits: SessionRateLimit[]): Usage {
|
||||
const win = (kind: string) => {
|
||||
const r = rateLimits.find(x => x.kind === kind)
|
||||
@@ -27,9 +28,25 @@ function toUsage(context: SessionContextUsage, rateLimits: SessionRateLimit[]):
|
||||
return {
|
||||
fiveHour: win('five_hour'),
|
||||
sevenDay: win('seven_day'),
|
||||
ctxTokens: context.tokens,
|
||||
ctxTokens: context.tokens ?? 0,
|
||||
ctxWindow: context.window,
|
||||
ctxPercent: context.percent,
|
||||
ctxPercent: context.percent ?? 0,
|
||||
}
|
||||
}
|
||||
|
||||
// 已過重置時間的視窗用量已歸零,不再沿用舊值
|
||||
const live = (w: Window | undefined, now: number) =>
|
||||
w && (!w.resetsAt || Date.parse(w.resetsAt) > now) ? w : undefined
|
||||
|
||||
async function restoreRates($: EngineInterface, usage: Usage): Promise<Usage> {
|
||||
const saved = (await $.store.get('rates')) as Pick<Usage, 'fiveHour' | 'sevenDay'> | undefined
|
||||
if (!saved) return usage
|
||||
const now = await $.clock.now()
|
||||
|
||||
return {
|
||||
...usage,
|
||||
fiveHour: usage.fiveHour ?? live(saved.fiveHour, now),
|
||||
sevenDay: usage.sevenDay ?? live(saved.sevenDay, now),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +121,11 @@ export const register: Register = on => {
|
||||
tzOffsetMin = parseOffset(r.stdout)
|
||||
} catch {}
|
||||
const u = await $.session.usage()
|
||||
await update($, usageAtom, () => toUsage(u.context, u.rateLimits))
|
||||
const usage = await restoreRates($, toUsage(u.context, u.rateLimits))
|
||||
await update($, usageAtom, () => usage)
|
||||
void refreshGit($)
|
||||
void refreshSys($)
|
||||
// CPU 要兩次取樣才算得出來,開場先隔 0.5 秒補一次,免得等到 3 秒後才出現
|
||||
void refreshSys($).then(() => $.clock.after(500, () => void refreshSys($)))
|
||||
$.clock.every(SYS_MS, () => void refreshSys($))
|
||||
$.clock.every(GIT_MS, () => void refreshGit($))
|
||||
|
||||
@@ -115,6 +134,11 @@ export const register: Register = on => {
|
||||
|
||||
on('session.measure', async ($, e, next) => {
|
||||
await update($, usageAtom, () => toUsage(e.context, e.rateLimits))
|
||||
if (e.rateLimits.length) {
|
||||
const w = (kind: string) => e.rateLimits.find(x => x.kind === kind)
|
||||
const pick = (r: SessionRateLimit | undefined) => r && { percent: r.percentUsed, resetsAt: r.resetsAt }
|
||||
await $.store.set('rates', { fiveHour: pick(w('five_hour')), sevenDay: pick(w('seven_day')) })
|
||||
}
|
||||
if (e.changed.includes('rateLimits')) await alert($, e.rateLimits)
|
||||
|
||||
return next(e)
|
||||
|
||||
Reference in New Issue
Block a user