pi-ark-usage 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/extensions/index.ts +14 -1
- package/extensions/lib/widget.ts +52 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,8 @@ Volc Usage: sess 30%(reset after 4h18m) / wk 37%(reset after 4d) / mo 19%(reset
|
|
|
10
10
|
|
|
11
11
|
- **AK/SK 直连 OpenAPI**:不走子进程、不依赖 SSO 登录态;凭据只从环境变量或配置文件读取,本扩展不保存、不上传任何 Key
|
|
12
12
|
- **三个周期同屏**:session(会话)/ weekly(周)/ monthly(月),并显示各周期重置倒计时
|
|
13
|
-
-
|
|
13
|
+
- **Powerline 状态段**:通过 `ctx.ui.setStatus("ark-usage", …)` 发布单行摘要(`1% 4h38m | 15% 5d4h | 54% 23d4h`,固定按 session/weekly/monthly 顺序),可直接显示在 [pi-powerline-footer](https://www.npmjs.com/package/pi-powerline-footer) 的 `extension_statuses` / customItems 上;百分比按阈值绿/黄/红着色,时间部分紫色,分隔符跟随主题 `thinkingHigh`(编辑器边框色)
|
|
14
|
+
- **阈值着色**:低用量绿色(<50%)、接近上限黄色(50–79%)、超过红线红色(≥80%,默认值,可用 `/arkset` 调整)
|
|
14
15
|
- **单轮消耗**:以每轮对话开始前的快照为基线,结算时标注各周期增量(如 `(+2)`)
|
|
15
16
|
- **产品切换感知**:在个人版/团队版、Coding Plan/Agent Plan 之间切换时标注 `(变更)`;套餐周期重置时标注 `(已重置)`
|
|
16
17
|
- **持久化缓存**:重启 pi 后立即显示上次快照(`~/.pi/agent/pi-ark-usage/cache.json`,0600 权限,临时文件原子写入)
|
package/extensions/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
ArkUsageComponent,
|
|
27
27
|
AUTO_REFRESH_MAX_MINUTES,
|
|
28
28
|
LOCALES,
|
|
29
|
+
buildCompactStatus,
|
|
29
30
|
buildItems,
|
|
30
31
|
formatRemaining,
|
|
31
32
|
getSettings,
|
|
@@ -48,6 +49,8 @@ import type {
|
|
|
48
49
|
} from "./lib/types.js";
|
|
49
50
|
|
|
50
51
|
const WIDGET_KEY = "pi-ark-usage";
|
|
52
|
+
/** Extension-status key consumed by pi-powerline-footer (powerline slot). */
|
|
53
|
+
const STATUS_KEY = "ark-usage";
|
|
51
54
|
const TICK_MS = 60_000;
|
|
52
55
|
const AGENT_START_TIMEOUT_MS = 3_000;
|
|
53
56
|
const BASELINE_FRESH_MS = 60 * 60_000;
|
|
@@ -128,14 +131,24 @@ function activeSnapshot(): PlanSnapshot | null {
|
|
|
128
131
|
function renderWidget(ctx: ExtensionContext): void {
|
|
129
132
|
lastCtx = ctx;
|
|
130
133
|
const snap = activeSnapshot();
|
|
134
|
+
const widgetStatus = status === "ok" && !snap ? "none" : status;
|
|
131
135
|
const items: RenderItem[] = buildItems(
|
|
132
136
|
snap,
|
|
133
137
|
language,
|
|
134
|
-
|
|
138
|
+
widgetStatus,
|
|
135
139
|
ctx.isIdle(),
|
|
136
140
|
deltas,
|
|
137
141
|
note,
|
|
138
142
|
);
|
|
143
|
+
// Publish the one-line summary to the extension-status slot (powerline).
|
|
144
|
+
// The ticker calls renderWidget every minute while idle, keeping the
|
|
145
|
+
// reset countdown fresh without refetching.
|
|
146
|
+
const compact = buildCompactStatus(snap, widgetStatus, ctx.ui.theme);
|
|
147
|
+
if (compact) {
|
|
148
|
+
ctx.ui.setStatus(STATUS_KEY, compact);
|
|
149
|
+
} else {
|
|
150
|
+
ctx.ui.setStatus(STATUS_KEY, undefined);
|
|
151
|
+
}
|
|
139
152
|
if (activeWidget) {
|
|
140
153
|
activeWidget.update(items);
|
|
141
154
|
return;
|
package/extensions/lib/widget.ts
CHANGED
|
@@ -122,7 +122,7 @@ export const LOCALES: Record<Language, Locale> = { zh: ZH, en: EN };
|
|
|
122
122
|
export const AUTO_REFRESH_MAX_MINUTES = 30;
|
|
123
123
|
|
|
124
124
|
export const DEFAULT_SETTINGS: ArkSettings = {
|
|
125
|
-
pctYellow:
|
|
125
|
+
pctYellow: 50,
|
|
126
126
|
pctRed: 80,
|
|
127
127
|
autoRefreshMinutes: 5,
|
|
128
128
|
product: "auto",
|
|
@@ -209,6 +209,57 @@ export function formatAge(fetchedAt: number, lang: Language): string {
|
|
|
209
209
|
return LOCALES[lang].ageMinutesAgo(m);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
/* ---------------------- compact status (powerline slot) -------------------- */
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Compact reset countdown for the powerline status: `38m`, `4h38m`, `5d4h`.
|
|
216
|
+
* Lower-precision units are dropped to keep the line short and stable.
|
|
217
|
+
*/
|
|
218
|
+
export function formatCompactRemaining(ms: number): string {
|
|
219
|
+
if (!Number.isFinite(ms) || ms <= 0) return "";
|
|
220
|
+
const totalMin = Math.floor(ms / 60_000);
|
|
221
|
+
const d = Math.floor(totalMin / 1440);
|
|
222
|
+
const h = Math.floor((totalMin % 1440) / 60);
|
|
223
|
+
const m = totalMin % 60;
|
|
224
|
+
if (d > 0) return `${d}d${h}h`;
|
|
225
|
+
if (h > 0) return `${h}h${m}m`;
|
|
226
|
+
return `${m}m`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* One-line colored summary for the powerline extension-status slot:
|
|
231
|
+
* `1% 4h38m | 15% 5d4h | 54% 23d4h`
|
|
232
|
+
*
|
|
233
|
+
* Periods are shown in API order (session / weekly / monthly) without
|
|
234
|
+
* labels — the order itself is the convention. Percent follows the
|
|
235
|
+
* yellow/red thresholds (green below yellow, yellow below red, red at/above
|
|
236
|
+
* red); the time part is always purple; the ` | ` separator uses the
|
|
237
|
+
* editor border color (`thinkingHigh`, pink in the dark theme).
|
|
238
|
+
*
|
|
239
|
+
* Returns null when nothing should be shown (the powerline item hides).
|
|
240
|
+
*/
|
|
241
|
+
export function buildCompactStatus(
|
|
242
|
+
snapshot: PlanSnapshot | null,
|
|
243
|
+
status: WidgetStatus,
|
|
244
|
+
theme: Theme,
|
|
245
|
+
): string | null {
|
|
246
|
+
if (snapshot && snapshot.periods.length > 0) {
|
|
247
|
+
const sep = theme.fg("thinkingHigh", " | ");
|
|
248
|
+
return snapshot.periods
|
|
249
|
+
.map((p) => {
|
|
250
|
+
const pct = coloredPct(clampPct(p.percent));
|
|
251
|
+
const reset = p.reset_at
|
|
252
|
+
? formatCompactRemaining(new Date(p.reset_at).getTime() - Date.now())
|
|
253
|
+
: "";
|
|
254
|
+
return reset ? `${pct} ${hexFg(HEX_COLORS.purple, reset)}` : pct;
|
|
255
|
+
})
|
|
256
|
+
.join(sep);
|
|
257
|
+
}
|
|
258
|
+
if (status === "fetching") return hexFg(HEX_COLORS.purple, "…");
|
|
259
|
+
if (status === "failed") return hexFg(HEX_COLORS.red, "failed");
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
|
|
212
263
|
/* ----------------------------- snapshot -> items --------------------------- */
|
|
213
264
|
|
|
214
265
|
export type WidgetStatus = "ok" | "fetching" | "failed" | "no-binary" | "none";
|