@songsid/agend 2.1.4-beta.6 → 2.1.4-beta.61
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 +1 -1
- package/README.zh-TW.md +1 -1
- package/dist/agent-cli-instructions.md +2 -2
- package/dist/agent-endpoint.js +1 -1
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/backend/antigravity.d.ts +12 -8
- package/dist/backend/antigravity.js +189 -42
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +87 -23
- package/dist/backend/claude-code.js +361 -46
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex.d.ts +18 -0
- package/dist/backend/codex.js +143 -7
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/gemini-cli.js +2 -2
- package/dist/backend/gemini-cli.js.map +1 -1
- package/dist/backend/grok.js +2 -2
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro.d.ts +52 -2
- package/dist/backend/kiro.js +267 -12
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/opencode.js +17 -4
- package/dist/backend/opencode.js.map +1 -1
- package/dist/backend/types.d.ts +122 -3
- package/dist/backend/types.js +5 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-outage.d.ts +61 -0
- package/dist/backend-outage.js +71 -0
- package/dist/backend-outage.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +44 -2
- package/dist/channel/adapters/discord.js +529 -89
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +30 -0
- package/dist/channel/adapters/telegram.js +221 -19
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/agy-mcp-launcher.d.ts +2 -0
- package/dist/channel/agy-mcp-launcher.js +28 -0
- package/dist/channel/agy-mcp-launcher.js.map +1 -0
- package/dist/channel/ipc-bridge.d.ts +2 -1
- package/dist/channel/ipc-bridge.js +33 -4
- package/dist/channel/ipc-bridge.js.map +1 -1
- package/dist/channel/markdown-chunk.d.ts +42 -0
- package/dist/channel/markdown-chunk.js +205 -0
- package/dist/channel/markdown-chunk.js.map +1 -0
- package/dist/channel/mcp-server.js +28 -25
- package/dist/channel/mcp-server.js.map +1 -1
- package/dist/channel/mcp-tools.js +6 -4
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/message-queue.js +64 -8
- package/dist/channel/message-queue.js.map +1 -1
- package/dist/channel/types.d.ts +31 -1
- package/dist/classic-channel-manager.d.ts +65 -0
- package/dist/classic-channel-manager.js +172 -3
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +124 -83
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.js +16 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js +12 -1
- package/dist/config.js.map +1 -1
- package/dist/cross-instance-envelope.d.ts +6 -0
- package/dist/cross-instance-envelope.js +30 -0
- package/dist/cross-instance-envelope.js.map +1 -0
- package/dist/daemon.d.ts +506 -11
- package/dist/daemon.js +2162 -313
- package/dist/daemon.js.map +1 -1
- package/dist/doctor.d.ts +41 -0
- package/dist/doctor.js +267 -0
- package/dist/doctor.js.map +1 -0
- package/dist/fleet-context.d.ts +63 -0
- package/dist/fleet-context.js.map +1 -1
- package/dist/fleet-manager.d.ts +462 -12
- package/dist/fleet-manager.js +3027 -634
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-yaml-slim.d.ts +10 -0
- package/dist/fleet-yaml-slim.js +59 -0
- package/dist/fleet-yaml-slim.js.map +1 -0
- package/dist/general-knowledge/skills/backend-providers/SKILL.md +114 -0
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +4 -1
- package/dist/general-knowledge/skills/delegation-playbook/SKILL.md +52 -0
- package/dist/general-knowledge/skills/development-workflow/SKILL.md +28 -0
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +1 -0
- package/dist/general-knowledge/skills/fleet-health/SKILL.md +1 -0
- package/dist/general-knowledge/skills/fleet-restart/SKILL.md +1 -0
- package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +1 -0
- package/dist/general-knowledge/skills/model-discovery/SKILL.md +64 -16
- package/dist/general-knowledge/skills/multi-channel/SKILL.md +1 -0
- package/dist/general-knowledge/skills/scheduling/SKILL.md +1 -0
- package/dist/general-knowledge/skills/session-management/SKILL.md +172 -8
- package/dist/general-knowledge/skills/tui-effort/SKILL.md +1 -0
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +30 -0
- package/dist/instance-lifecycle.d.ts +99 -0
- package/dist/instance-lifecycle.js +357 -11
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +12 -0
- package/dist/instructions.js +74 -3
- package/dist/instructions.js.map +1 -1
- package/dist/locale.js +1022 -310
- package/dist/locale.js.map +1 -1
- package/dist/login-flows.d.ts +91 -0
- package/dist/login-flows.js +170 -0
- package/dist/login-flows.js.map +1 -0
- package/dist/login-manager.d.ts +63 -0
- package/dist/login-manager.js +134 -0
- package/dist/login-manager.js.map +1 -0
- package/dist/network-family.d.ts +18 -0
- package/dist/network-family.js +20 -0
- package/dist/network-family.js.map +1 -0
- package/dist/outbound-handlers.d.ts +16 -1
- package/dist/outbound-handlers.js +174 -40
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +11 -3
- package/dist/outbound-schemas.js +11 -0
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/pane-input-residue.d.ts +52 -0
- package/dist/pane-input-residue.js +107 -0
- package/dist/pane-input-residue.js.map +1 -0
- package/dist/process-memory.d.ts +6 -0
- package/dist/process-memory.js +45 -0
- package/dist/process-memory.js.map +1 -1
- package/dist/reply-dedup.d.ts +7 -8
- package/dist/reply-dedup.js +0 -0
- package/dist/reply-dedup.js.map +1 -1
- package/dist/restart-progress.d.ts +2 -0
- package/dist/restart-progress.js +3 -0
- package/dist/restart-progress.js.map +1 -1
- package/dist/scheduler/db.d.ts +12 -0
- package/dist/scheduler/db.js +59 -0
- package/dist/scheduler/db.js.map +1 -1
- package/dist/service-installer.d.ts +11 -0
- package/dist/service-installer.js +84 -18
- package/dist/service-installer.js.map +1 -1
- package/dist/settings-api.js +1 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/setup-wizard.js +2 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/spawn-gate.d.ts +30 -0
- package/dist/spawn-gate.js +79 -0
- package/dist/spawn-gate.js.map +1 -0
- package/dist/steer-capability.d.ts +1 -0
- package/dist/steer-capability.js +6 -0
- package/dist/steer-capability.js.map +1 -0
- package/dist/storm-window.d.ts +83 -0
- package/dist/storm-window.js +251 -0
- package/dist/storm-window.js.map +1 -0
- package/dist/tips.d.ts +44 -0
- package/dist/tips.js +355 -0
- package/dist/tips.js.map +1 -0
- package/dist/tmux-manager.d.ts +16 -0
- package/dist/tmux-manager.js +110 -25
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-progress.d.ts +40 -0
- package/dist/tool-progress.js +289 -0
- package/dist/tool-progress.js.map +1 -0
- package/dist/topic-commands.d.ts +45 -6
- package/dist/topic-commands.js +394 -66
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-monitor.d.ts +15 -2
- package/dist/transcript-monitor.js +63 -17
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +131 -0
- package/dist/transcript-sources.js +580 -0
- package/dist/transcript-sources.js.map +1 -0
- package/dist/types.d.ts +11 -0
- package/dist/ui/dashboard.html +55 -32
- package/dist/ui/settings.html +200 -60
- package/dist/ui/view.html +147 -30
- package/dist/usage/format-rich.d.ts +1 -1
- package/dist/usage/format-rich.js +28 -24
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/i18n-keys.d.ts +7 -0
- package/dist/usage/i18n-keys.js +34 -0
- package/dist/usage/i18n-keys.js.map +1 -0
- package/dist/usage/i18n.d.ts +5 -0
- package/dist/usage/i18n.js +27 -0
- package/dist/usage/i18n.js.map +1 -0
- package/dist/usage/providers.d.ts +21 -0
- package/dist/usage/providers.js +153 -75
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/usage-api.d.ts +11 -3
- package/dist/usage/usage-api.js +61 -24
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/workflow-templates/default.md +2 -1
- package/package.json +2 -2
package/dist/ui/view.html
CHANGED
|
@@ -129,17 +129,17 @@
|
|
|
129
129
|
</style>
|
|
130
130
|
</head>
|
|
131
131
|
<body>
|
|
132
|
-
<button class="help-btn" id="usageBtn" title="AI usage" style="right:140px; display:none">📊</button>
|
|
133
|
-
<button class="help-btn" id="densityBtn" title="Font density" style="right:98px">⤢</button>
|
|
134
|
-
<button class="help-btn" id="langBtn" title="Language" style="right:56px">🌐</button>
|
|
135
|
-
<button class="help-btn" id="helpBtn" title="Help">ℹ️</button>
|
|
132
|
+
<button class="help-btn" id="usageBtn" data-i18n-title="usageButton" title="AI usage" style="right:140px; display:none">📊</button>
|
|
133
|
+
<button class="help-btn" id="densityBtn" data-i18n-title="densityLabel" title="Font density" style="right:98px">⤢</button>
|
|
134
|
+
<button class="help-btn" id="langBtn" data-i18n-title="languageButton" title="Language" style="right:56px">🌐</button>
|
|
135
|
+
<button class="help-btn" id="helpBtn" data-i18n-title="helpButton" title="Help">ℹ️</button>
|
|
136
136
|
<div class="help-backdrop" id="helpBackdrop"></div>
|
|
137
137
|
<aside class="help-panel" id="helpPanel">
|
|
138
|
-
<button class="close" id="helpClose" title="Close">×</button>
|
|
138
|
+
<button class="close" id="helpClose" data-i18n-title="close" title="Close">×</button>
|
|
139
139
|
<div id="helpContent"></div>
|
|
140
140
|
</aside>
|
|
141
141
|
<aside class="help-panel" id="usagePanel">
|
|
142
|
-
<button class="close" id="usageClose" title="Close">×</button>
|
|
142
|
+
<button class="close" id="usageClose" data-i18n-title="close" title="Close">×</button>
|
|
143
143
|
<div id="usageContent"></div>
|
|
144
144
|
</aside>
|
|
145
145
|
<div id="sidebar"><h1 data-i18n="viewTitle">AgEnD · View</h1><div id="list"></div></div>
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
<div class="meta" id="meta"></div>
|
|
153
153
|
<div class="desc" id="desc"></div>
|
|
154
154
|
</div>
|
|
155
|
-
<button id="cardToggle" title="Expand profile" aria-expanded="false">▲</button>
|
|
155
|
+
<button id="cardToggle" data-i18n-title="expandProfile" title="Expand profile" aria-expanded="false">▲</button>
|
|
156
156
|
<button id="editBtn" data-i18n="editProfile">✏️ Edit</button>
|
|
157
157
|
<div id="edit">
|
|
158
158
|
<input id="fDisplay" data-i18n-ph="displayName" placeholder="Display name">
|
|
@@ -193,7 +193,54 @@
|
|
|
193
193
|
tooltipBackend: "Backend: {value}", tooltipStatus: "Status: {value}", tooltipContext: "Context: {value}",
|
|
194
194
|
tooltipUnavailable: "Unavailable", statusRunning: "Running", statusPaused: "Paused",
|
|
195
195
|
statusStopped: "Stopped", statusCrashed: "Crashed", statusUnknown: "Unknown",
|
|
196
|
-
usageResets: "resets in {t}", usageSoon: "resets soon", usageFail: "Could not load usage data."
|
|
196
|
+
usageResets: "resets in {t}", usageSoon: "resets soon", usageFail: "Could not load usage data.",
|
|
197
|
+
"usage.title": "AI Subscription Usage", "usage.title_plain": "AI subscription usage", "usage.empty_active": "No active backends with usage tracking",
|
|
198
|
+
"usage.not_logged_in": "not logged in", "usage.error_fallback": "error", "usage.no_data": "no data",
|
|
199
|
+
"usage.reset.in": "resets in {0}", "usage.reset.soon": "resets soon",
|
|
200
|
+
"usage.duration.days_hours": "{0}d {1}h", "usage.duration.hours_minutes": "{0}h {1}m", "usage.duration.minutes": "{0}m",
|
|
201
|
+
"usage.metric.session": "Session", "usage.metric.weekly": "Weekly", "usage.metric.monthly": "Monthly",
|
|
202
|
+
"usage.metric.days_window": "{0}-day window", "usage.metric.named": "{0}",
|
|
203
|
+
"usage.metric.named_session": "{0} (session)", "usage.metric.named_weekly": "{0} (weekly)",
|
|
204
|
+
"usage.metric.named_monthly": "{0} (monthly)", "usage.metric.named_days": "{0} ({1}d)",
|
|
205
|
+
"usage.metric.extra_usage": "Extra usage", "usage.metric.rate_limit_resets": "Rate limit resets",
|
|
206
|
+
"usage.metric.credits": "Credits", "usage.metric.weekly_limit": "Weekly limit",
|
|
207
|
+
"usage.metric.pay_as_you_go": "Pay as you go", "usage.metric.bonus_credits": "Bonus credits",
|
|
208
|
+
"usage.metric.overage_charges": "Overage charges", "usage.metric.pay_per_use": "Pay-per-use",
|
|
209
|
+
"usage.metric.usage_monthly": "Usage (monthly)",
|
|
210
|
+
"usage.unit.available": "available", "usage.unit.credits": "credits",
|
|
211
|
+
"usage.value.disabled": "Disabled", "usage.value.cap": "{0} cap",
|
|
212
|
+
"usage.note.binding": "binding", "usage.note.binding_severity": "binding · {0}",
|
|
213
|
+
"usage.note.busiest_model": "busiest of {0} model", "usage.note.busiest_models": "busiest of {0} models",
|
|
214
|
+
"usage.note.used_limit_unit": "{0} / {1} {2}", "usage.note.bonus_codes": "{0} / {1} {2} · {3} codes",
|
|
215
|
+
"usage.metric.agy_claude_others": "Claude & others", "usage.metric.agy_claude_others_session": "Claude & others (session)",
|
|
216
|
+
"usage.metric.agy_claude_others_weekly": "Claude & others (weekly)",
|
|
217
|
+
"usage.hint.statusline_now": "from {0}'s statusline, just now — no API call; plan and per-model limits need a CLI login",
|
|
218
|
+
"usage.hint.statusline_minutes": "from {0}'s statusline, {1}m ago — no API call; plan and per-model limits need a CLI login",
|
|
219
|
+
"usage.hint.claude_api_key": "API-key login has no subscription usage. Use `claude /login` or set CLAUDE_CODE_OAUTH_TOKEN (from `claude setup-token`).",
|
|
220
|
+
"usage.hint.login_claude": "Log in with the Claude Code CLI (`claude`).",
|
|
221
|
+
"usage.hint.login_agy": "Log in with the Antigravity CLI (`agy`).", "usage.hint.no_quota": "No quota information reported for this account.",
|
|
222
|
+
"usage.hint.login_codex": "Log in with the Codex CLI (`codex`).", "usage.hint.codex_no_oauth": "auth.json has no OAuth login (API-key-only auth cannot read usage).",
|
|
223
|
+
"usage.hint.login_grok": "Log in with the Grok CLI (`grok login`).", "usage.hint.grok_no_login": "auth.json has no usable login. Run `grok login`.",
|
|
224
|
+
"usage.hint.login_kiro": "Log in with the Kiro CLI (`kiro-cli`).", "usage.hint.kiro_signed_out": "Signed out — run `kiro-cli` to log in.",
|
|
225
|
+
"usage.hint.token_refreshing": "Token refreshing — try again in a moment.", "usage.hint.subscription_no_credit": "Subscription — no credit usage to report.",
|
|
226
|
+
"usage.hint.no_quota_account": "No quota information available for this account type.",
|
|
227
|
+
"usage.error.unreachable": "Could not reach {0}.", "usage.error.token_rejected": "Token rejected. Run `{0}` once to refresh the login.",
|
|
228
|
+
"usage.error.rate_limited": "Rate limited by {0} — try again later.", "usage.error.http": "Usage request failed (HTTP {0}).",
|
|
229
|
+
"usage.error.billing_http": "Billing request failed (HTTP {0}).", "usage.error.invalid_response": "Invalid response from usage endpoint.",
|
|
230
|
+
"usage.error.invalid_billing_response": "Invalid response from billing endpoint.", "usage.error.invalid_kiro_response": "Invalid response from GetUsageLimits.",
|
|
231
|
+
"usage.error.claude_token_expired": "Access token expired — it refreshes the next time any Claude instance runs.",
|
|
232
|
+
"usage.error.codex_token_expired": "Access token expired. Run `codex` once to refresh it.",
|
|
233
|
+
"usage.error.grok_expired": "Grok session expired. Run `grok login` again.", "usage.error.grok_response_changed": "Grok billing response changed.",
|
|
234
|
+
"usage.error.agy_cap": "Individual cap reached — CLI is rate limited (resets in ~{0}). The per-model pool quotas are separate and may still read 0% used.",
|
|
235
|
+
"usage.error.agy_no_refresh": "Access token expired and no refresh token is stored. Run `agy` once.",
|
|
236
|
+
"usage.error.agy_token_expired": "Access token expired. Run `agy` once to refresh it (or set AGY_OAUTH_CLIENT_ID/SECRET to refresh automatically).",
|
|
237
|
+
"usage.error.agy_login_expired": "Google sign-in expired. Run `agy` once to log in again.", "usage.error.agy_refresh_empty": "Google token refresh returned no token.",
|
|
238
|
+
"usage.error.grok_auth_readonly": "Token expired and auth.json is read-only. Run `grok` once to refresh it.", "usage.error.grok_no_refresh": "Token expired and no refresh token was found. Run `grok login`.",
|
|
239
|
+
"usage.error.grok_refresh_unreachable": "Could not reach auth.x.ai to refresh the token.", "usage.error.grok_invalid_refresh": "Invalid refresh response from auth.x.ai.",
|
|
240
|
+
"usage.error.grok_persist": "Refreshed but could not write auth.json. Run `grok` once instead.",
|
|
241
|
+
usageButton: "AI usage", languageButton: "Language", helpButton: "Help", close: "Close", expandProfile: "Expand profile",
|
|
242
|
+
rosterFailed: "Failed to load roster: {error}\n(Is the fleet running?)", paneFailed: "⚠ Could not load pane for {name} (HTTP {status}).",
|
|
243
|
+
tokenRequired: "web.token required", avatarFailed: "Avatar upload failed: {error}", saved: "Saved", saveFailed: "Save failed: {error}" },
|
|
197
244
|
"zh-TW": { viewTitle: "AgEnD · 檢視", editProfile: "✏️ 編輯", save: "儲存", cancel: "取消",
|
|
198
245
|
displayName: "顯示名稱", role: "角色", description: "描述", tokenPh: "web.token(儲存時需要)",
|
|
199
246
|
saveHint: "檢視為公開(唯讀)。儲存需要 web.token(~/.agend/web.token)。", helpTitle: "📖 使用說明",
|
|
@@ -208,14 +255,63 @@
|
|
|
208
255
|
tooltipBackend: "後端:{value}", tooltipStatus: "狀態:{value}", tooltipContext: "上下文:{value}",
|
|
209
256
|
tooltipUnavailable: "無資料", statusRunning: "運行中", statusPaused: "已暫停",
|
|
210
257
|
statusStopped: "已停止", statusCrashed: "已崩潰", statusUnknown: "未知",
|
|
211
|
-
usageResets: "{t}
|
|
258
|
+
usageResets: "{t}後重置", usageSoon: "即將重置", usageFail: "無法載入用量資料。",
|
|
259
|
+
"usage.title": "AI 訂閱用量", "usage.title_plain": "AI 訂閱用量", "usage.empty_active": "沒有使用中且支援用量追蹤的 Backend",
|
|
260
|
+
"usage.not_logged_in": "未登入", "usage.error_fallback": "錯誤", "usage.no_data": "無資料",
|
|
261
|
+
"usage.reset.in": "{0} 後重置", "usage.reset.soon": "即將重置",
|
|
262
|
+
"usage.duration.days_hours": "{0}d{1}h", "usage.duration.hours_minutes": "{0}h{1}m", "usage.duration.minutes": "{0}m",
|
|
263
|
+
"usage.metric.session": "Session", "usage.metric.weekly": "每週", "usage.metric.monthly": "每月",
|
|
264
|
+
"usage.metric.days_window": "{0} 天視窗", "usage.metric.named": "{0}",
|
|
265
|
+
"usage.metric.named_session": "{0}(Session)", "usage.metric.named_weekly": "{0}(週)",
|
|
266
|
+
"usage.metric.named_monthly": "{0}(每月)", "usage.metric.named_days": "{0}({1} 天)",
|
|
267
|
+
"usage.metric.extra_usage": "額外用量", "usage.metric.rate_limit_resets": "額度重置券",
|
|
268
|
+
"usage.metric.credits": "額度", "usage.metric.weekly_limit": "每週上限",
|
|
269
|
+
"usage.metric.pay_as_you_go": "隨用隨付", "usage.metric.bonus_credits": "贈送額度",
|
|
270
|
+
"usage.metric.overage_charges": "超額費用", "usage.metric.pay_per_use": "隨用隨付",
|
|
271
|
+
"usage.metric.usage_monthly": "用量(每月)",
|
|
272
|
+
"usage.unit.available": "可用", "usage.unit.credits": "額度",
|
|
273
|
+
"usage.value.disabled": "已停用", "usage.value.cap": "上限 {0}",
|
|
274
|
+
"usage.note.binding": "生效", "usage.note.binding_severity": "生效 · {0}",
|
|
275
|
+
"usage.note.busiest_model": "{0} 個模型中用量最高者", "usage.note.busiest_models": "{0} 個模型中用量最高者",
|
|
276
|
+
"usage.note.used_limit_unit": "{0} / {1} {2}", "usage.note.bonus_codes": "{0} / {1} {2} · {3} 組代碼",
|
|
277
|
+
"usage.metric.agy_claude_others": "Claude 與其他模型", "usage.metric.agy_claude_others_session": "Claude 與其他模型(Session)",
|
|
278
|
+
"usage.metric.agy_claude_others_weekly": "Claude 與其他模型(每週)",
|
|
279
|
+
"usage.hint.statusline_now": "來自 {0} 的 statusline(剛剛);未呼叫 API,方案與各模型上限需要 CLI 登入資料",
|
|
280
|
+
"usage.hint.statusline_minutes": "來自 {0} 的 statusline({1} 分鐘前);未呼叫 API,方案與各模型上限需要 CLI 登入資料",
|
|
281
|
+
"usage.hint.claude_api_key": "API key 登入沒有訂閱用量資料。請使用 `claude /login`,或設定 CLAUDE_CODE_OAUTH_TOKEN(由 `claude setup-token` 取得)。",
|
|
282
|
+
"usage.hint.login_claude": "請使用 Claude Code CLI(`claude`)登入。",
|
|
283
|
+
"usage.hint.login_agy": "請使用 Antigravity CLI(`agy`)登入。", "usage.hint.no_quota": "此帳號未回報額度資訊。",
|
|
284
|
+
"usage.hint.login_codex": "請使用 Codex CLI(`codex`)登入。", "usage.hint.codex_no_oauth": "auth.json 沒有 OAuth 登入資料;只有 API key 時無法讀取用量。",
|
|
285
|
+
"usage.hint.login_grok": "請使用 Grok CLI(`grok login`)登入。", "usage.hint.grok_no_login": "auth.json 沒有可用的登入資料。請執行 `grok login`。",
|
|
286
|
+
"usage.hint.login_kiro": "請使用 Kiro CLI(`kiro-cli`)登入。", "usage.hint.kiro_signed_out": "目前已登出;請執行 `kiro-cli` 登入。",
|
|
287
|
+
"usage.hint.token_refreshing": "Token 更新中 — 請稍候再試。", "usage.hint.subscription_no_credit": "訂閱方案沒有可回報的額度用量。",
|
|
288
|
+
"usage.hint.no_quota_account": "此帳號類型沒有可用的額度資訊。",
|
|
289
|
+
"usage.error.unreachable": "無法連線至 {0}。", "usage.error.token_rejected": "Token 已被拒絕。請執行一次 `{0}` 以更新登入。",
|
|
290
|
+
"usage.error.rate_limited": "{0} 暫時限制請求速率,請稍後再試。", "usage.error.http": "用量請求失敗(HTTP {0})。",
|
|
291
|
+
"usage.error.billing_http": "計費請求失敗(HTTP {0})。", "usage.error.invalid_response": "用量端點回傳了無效資料。",
|
|
292
|
+
"usage.error.invalid_billing_response": "計費端點回傳了無效資料。", "usage.error.invalid_kiro_response": "GetUsageLimits 回傳了無效資料。",
|
|
293
|
+
"usage.error.claude_token_expired": "Access token 已過期;下次啟動任一 Claude instance 時會重新整理。",
|
|
294
|
+
"usage.error.codex_token_expired": "Access token 已過期。請執行一次 `codex` 以重新整理。",
|
|
295
|
+
"usage.error.grok_expired": "Grok session 已過期。請再次執行 `grok login`。", "usage.error.grok_response_changed": "Grok 計費回應格式已變更。",
|
|
296
|
+
"usage.error.agy_cap": "個人上限已用完,CLI 正受到速率限制(約 {0} 後重置)。各模型的額度池是另一組計數,因此仍可能顯示 0% 已使用。",
|
|
297
|
+
"usage.error.agy_no_refresh": "Access token 已過期,且未儲存 refresh token。請執行一次 `agy`。",
|
|
298
|
+
"usage.error.agy_token_expired": "Access token 已過期。請執行一次 `agy` 重新整理,或設定 AGY_OAUTH_CLIENT_ID/SECRET 以自動更新。",
|
|
299
|
+
"usage.error.agy_login_expired": "Google 登入已過期。請執行一次 `agy` 重新登入。", "usage.error.agy_refresh_empty": "Google token 更新回應沒有 access token。",
|
|
300
|
+
"usage.error.grok_auth_readonly": "Token 已過期且 auth.json 為唯讀。請執行一次 `grok` 重新整理。", "usage.error.grok_no_refresh": "Token 已過期且找不到 refresh token。請執行 `grok login`。",
|
|
301
|
+
"usage.error.grok_refresh_unreachable": "無法連線至 auth.x.ai 以更新 token。", "usage.error.grok_invalid_refresh": "auth.x.ai 回傳了無效的 token 更新資料。",
|
|
302
|
+
"usage.error.grok_persist": "Token 已更新但無法寫入 auth.json。請改為執行一次 `grok`。",
|
|
303
|
+
usageButton: "AI 訂閱用量", languageButton: "語言", helpButton: "使用說明", close: "關閉", expandProfile: "展開個人資料",
|
|
304
|
+
rosterFailed: "載入 instance 清單失敗:{error}\n(Fleet 是否正在執行?)", paneFailed: "⚠ 無法載入 {name} 的 pane(HTTP {status})。",
|
|
305
|
+
tokenRequired: "需要 web.token", avatarFailed: "上傳頭像失敗:{error}", saved: "已儲存", saveFailed: "儲存失敗:{error}" },
|
|
212
306
|
};
|
|
213
307
|
let lang = localStorage.getItem("agend_lang") || (navigator.language && navigator.language.toLowerCase().startsWith("zh") ? "zh-TW" : "en");
|
|
214
308
|
if (!I18N[lang]) lang = "en";
|
|
215
309
|
const T = (k) => (I18N[lang] && I18N[lang][k]) || I18N.en[k] || k;
|
|
310
|
+
const TF = (k, values = {}) => Object.entries(values).reduce((s, [name, value]) => s.replaceAll(`{${name}}`, String(value)), T(k));
|
|
216
311
|
function applyI18n() {
|
|
217
312
|
document.querySelectorAll("[data-i18n]").forEach(e => { e.textContent = T(e.getAttribute("data-i18n")); });
|
|
218
313
|
document.querySelectorAll("[data-i18n-ph]").forEach(e => { e.setAttribute("placeholder", T(e.getAttribute("data-i18n-ph"))); });
|
|
314
|
+
document.querySelectorAll("[data-i18n-title]").forEach(e => { e.setAttribute("title", T(e.getAttribute("data-i18n-title"))); });
|
|
219
315
|
const hc = q("helpContent");
|
|
220
316
|
if (hc) { hc.innerHTML = ""; const h3 = document.createElement("h3"); h3.textContent = T("helpTitle"); hc.append(h3);
|
|
221
317
|
const ul = document.createElement("ul"); for (const k of ["help1","help2","help3","help4","help5"]) { const li = document.createElement("li"); li.textContent = T(k); ul.append(li); } hc.append(ul); }
|
|
@@ -557,7 +653,7 @@
|
|
|
557
653
|
if (!current && roster.length) current = roster[0].instance_name;
|
|
558
654
|
computeOrder();
|
|
559
655
|
renderList(); renderCard();
|
|
560
|
-
} catch (e) { q("pre").textContent = "
|
|
656
|
+
} catch (e) { q("pre").textContent = TF("rosterFailed", { error: e.message }); }
|
|
561
657
|
}
|
|
562
658
|
|
|
563
659
|
// ── Terminal ──────────────────────────────────────────
|
|
@@ -575,7 +671,7 @@
|
|
|
575
671
|
if (!r.ok) {
|
|
576
672
|
// Surface the failure instead of leaving the previous instance's output
|
|
577
673
|
// on screen (which reads as "switching did nothing").
|
|
578
|
-
q("pre").textContent =
|
|
674
|
+
q("pre").textContent = TF("paneFailed", { name: target, status: r.status });
|
|
579
675
|
return;
|
|
580
676
|
}
|
|
581
677
|
const text = await r.text();
|
|
@@ -714,7 +810,7 @@
|
|
|
714
810
|
const it = roster.find(r => r.instance_name === current);
|
|
715
811
|
if (!it) return;
|
|
716
812
|
const wt = q("fToken").value.trim();
|
|
717
|
-
if (!wt) { q("msg").className = "err"; q("msg").textContent = "
|
|
813
|
+
if (!wt) { q("msg").className = "err"; q("msg").textContent = T("tokenRequired"); return; }
|
|
718
814
|
localStorage.setItem("agend_web_token", wt);
|
|
719
815
|
const name = encodeURIComponent(current);
|
|
720
816
|
try {
|
|
@@ -727,12 +823,12 @@
|
|
|
727
823
|
const file = q("fAvatar").files[0];
|
|
728
824
|
if (file) {
|
|
729
825
|
const ar = await fetch(`/api/avatar/${name}`, { method: "POST", headers: { "Content-Type": file.type, "X-Agend-Token": wt }, body: file });
|
|
730
|
-
if (!ar.ok) { const e = await ar.json().catch(() => ({})); throw new Error("
|
|
826
|
+
if (!ar.ok) { const e = await ar.json().catch(() => ({})); throw new Error(TF("avatarFailed", { error: e.error || ar.status })); }
|
|
731
827
|
}
|
|
732
|
-
q("msg").className = "ok"; q("msg").textContent = "
|
|
828
|
+
q("msg").className = "ok"; q("msg").textContent = T("saved");
|
|
733
829
|
await loadRoster();
|
|
734
830
|
setTimeout(exitEdit, 500);
|
|
735
|
-
} catch (e) { q("msg").className = "err"; q("msg").textContent = e.message; }
|
|
831
|
+
} catch (e) { q("msg").className = "err"; q("msg").textContent = e.message.startsWith(T("avatarFailed").split("{")[0]) ? e.message : TF("saveFailed", { error: e.message }); }
|
|
736
832
|
}
|
|
737
833
|
|
|
738
834
|
q("editBtn").onclick = enterEdit;
|
|
@@ -783,19 +879,32 @@
|
|
|
783
879
|
if (!iso) return "";
|
|
784
880
|
const ms = new Date(iso).getTime() - Date.now();
|
|
785
881
|
if (isNaN(ms)) return "";
|
|
786
|
-
if (ms <= 0) return T("
|
|
787
|
-
const
|
|
788
|
-
const
|
|
789
|
-
|
|
882
|
+
if (ms <= 0) return T("usage.reset.soon");
|
|
883
|
+
const totalMinutes = Math.max(1, Math.ceil(ms / 60000));
|
|
884
|
+
const d = Math.floor(totalMinutes / 1440), h = Math.floor((totalMinutes % 1440) / 60), m = totalMinutes % 60;
|
|
885
|
+
const duration = totalMinutes >= 2880
|
|
886
|
+
? usageLocalized("", { key: "usage.duration.days_hours", args: [d, h] })
|
|
887
|
+
: totalMinutes >= 60
|
|
888
|
+
? usageLocalized("", { key: "usage.duration.hours_minutes", args: [Math.floor(totalMinutes / 60), m] })
|
|
889
|
+
: usageLocalized("", { key: "usage.duration.minutes", args: [totalMinutes] });
|
|
890
|
+
return usageLocalized("", { key: "usage.reset.in", args: [duration] });
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
function usageLocalized(fallback, ref) {
|
|
894
|
+
if (!ref || typeof ref.key !== "string") return fallback == null ? "" : String(fallback);
|
|
895
|
+
const args = Array.isArray(ref.args) ? ref.args : [];
|
|
896
|
+
return args.reduce((text, value, index) => text.replaceAll(`{${index}}`, String(value)), T(ref.key));
|
|
790
897
|
}
|
|
791
898
|
|
|
792
899
|
function usageMetricHtml(m) {
|
|
900
|
+
const label = usageLocalized(m.label, m.labelI18n);
|
|
901
|
+
const note = m.note ? usageLocalized(m.note, m.noteI18n) : "";
|
|
793
902
|
if (m.type === "percent") {
|
|
794
903
|
const pct = Math.min(100, Math.max(0, m.used ?? 0));
|
|
795
904
|
const cls = pct >= 90 ? "crit" : pct >= 70 ? "warn" : "";
|
|
796
905
|
const word = pct >= 90 ? T("usageNear") : pct >= 70 ? T("usageHigh") : "";
|
|
797
|
-
const sub = [
|
|
798
|
-
return `<div class="u-metric"><div class="u-row"><span class="u-label">${esc(
|
|
906
|
+
const sub = [note, usageResetText(m.resetsAt)].filter(Boolean).join(" · ");
|
|
907
|
+
return `<div class="u-metric"><div class="u-row"><span class="u-label">${esc(label)}</span>` +
|
|
799
908
|
(word ? `<span class="u-status ${cls}">${esc(word)}</span>` : "") +
|
|
800
909
|
`<span class="u-val">${pct.toFixed(0)}%</span></div>` +
|
|
801
910
|
`<div class="u-meter"><div class="u-fill ${cls}" style="width:${pct}%"></div></div>` +
|
|
@@ -803,19 +912,22 @@
|
|
|
803
912
|
}
|
|
804
913
|
if (m.type === "dollars") {
|
|
805
914
|
const val = m.limit ? `$${(m.used ?? 0).toFixed(2)} / $${m.limit.toFixed(2)}` : `$${(m.used ?? 0).toFixed(2)}`;
|
|
806
|
-
return `<div class="u-metric"><div class="u-row"><span class="u-label">${esc(
|
|
915
|
+
return `<div class="u-metric"><div class="u-row"><span class="u-label">${esc(label)}</span><span class="u-val">${esc(val)}</span></div>` +
|
|
916
|
+
(note ? `<div class="u-sub">${esc(note)}</div>` : "") + `</div>`;
|
|
807
917
|
}
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
|
|
918
|
+
const value = usageLocalized(m.value ?? "", m.valueI18n);
|
|
919
|
+
const unit = usageLocalized(m.unit ?? "", m.unitI18n);
|
|
920
|
+
const val = `${value} ${unit}`.trim();
|
|
921
|
+
return `<div class="u-metric"><div class="u-row"><span class="u-label">${esc(label)}</span><span class="u-val">${esc(val)}</span></div>` +
|
|
922
|
+
(note ? `<div class="u-sub">${esc(note)}</div>` : "") + `</div>`;
|
|
811
923
|
}
|
|
812
924
|
|
|
813
925
|
function renderUsage() {
|
|
814
926
|
const box = q("usageContent");
|
|
815
|
-
if (!usageData || !Array.isArray(usageData.providers)) { box.innerHTML = `<h3
|
|
816
|
-
let html = `<h3
|
|
927
|
+
if (!usageData || !Array.isArray(usageData.providers)) { box.innerHTML = `<h3>📊 ${T("usage.title")}</h3><div class="u-err">${T("usageFail")}</div>`; return; }
|
|
928
|
+
let html = `<h3>📊 ${T("usage.title")}</h3>`;
|
|
817
929
|
const providers = orderedUsageProviders(usageData.providers);
|
|
818
|
-
if (!providers.length) html += `<div class="u-err">${T("
|
|
930
|
+
if (!providers.length) html += `<div class="u-err">${T("usage.empty_active")}</div>`;
|
|
819
931
|
for (let index = 0; index < providers.length; index++) {
|
|
820
932
|
const p = providers[index];
|
|
821
933
|
const key = providerKey(p);
|
|
@@ -823,13 +935,18 @@
|
|
|
823
935
|
(p.plan ? `<span class="u-plan">${esc(p.plan)}</span>` : "") +
|
|
824
936
|
`<span class="u-order"><button class="u-move" data-provider="${esc(key)}" data-delta="-1" title="${T("usageMoveUp")}" aria-label="${T("usageMoveUp")}"${index === 0 ? " disabled" : ""}>↑</button>` +
|
|
825
937
|
`<button class="u-move" data-provider="${esc(key)}" data-delta="1" title="${T("usageMoveDown")}" aria-label="${T("usageMoveDown")}"${index === providers.length - 1 ? " disabled" : ""}>↓</button></span></div>`;
|
|
826
|
-
if (p.status === "error") html += `<div class="u-err">${esc(p.error || "
|
|
938
|
+
if (p.status === "error") html += `<div class="u-err">${esc(usageLocalized(p.error || T("usage.error_fallback"), p.errorI18n))}</div>`;
|
|
939
|
+
else if (p.status === "no-credentials") {
|
|
940
|
+
html += `<div class="u-note">${esc(T("usage.not_logged_in"))}</div>`;
|
|
941
|
+
if (p.hint) html += `<div class="u-note">${esc(usageLocalized(p.hint, p.hintI18n))}</div>`;
|
|
942
|
+
}
|
|
827
943
|
else {
|
|
828
944
|
html += (p.metrics || []).map(usageMetricHtml).join("");
|
|
829
945
|
// A provider with nothing to meter (subscription plan) or one awaiting
|
|
830
946
|
// sign-in carries a hint instead of metrics. Without this the panel
|
|
831
947
|
// rendered an empty box, so those states looked broken.
|
|
832
|
-
if (p.hint) html += `<div class="u-note">${esc(p.hint)}</div>`;
|
|
948
|
+
if (p.hint) html += `<div class="u-note">${esc(usageLocalized(p.hint, p.hintI18n))}</div>`;
|
|
949
|
+
else if (!(p.metrics || []).length) html += `<div class="u-note">${esc(T("usage.no_data"))}</div>`;
|
|
833
950
|
}
|
|
834
951
|
html += `</div>`;
|
|
835
952
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type UsagePayload } from "./usage-api.js";
|
|
2
2
|
/** `████░░░░░░` for 40%. Clamped — a vendor "105% used" must not overflow. */
|
|
3
3
|
export declare function usageBar(percent: number): string;
|
|
4
4
|
/** Discord: native Markdown in plain message content. */
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { isVisibleUsageMetric } from "./usage-api.js";
|
|
2
|
+
import { t } from "../locale.js";
|
|
3
|
+
import { usageResetText, usageText } from "./i18n.js";
|
|
1
4
|
const BAR_WIDTH = 10;
|
|
2
5
|
/** `████░░░░░░` for 40%. Clamped — a vendor "105% used" must not overflow. */
|
|
3
6
|
export function usageBar(percent) {
|
|
@@ -22,36 +25,35 @@ function metricPercent(m) {
|
|
|
22
25
|
return null;
|
|
23
26
|
}
|
|
24
27
|
function resetSuffix(resetsAt) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const at = new Date(resetsAt);
|
|
28
|
-
if (Number.isNaN(at.getTime()))
|
|
29
|
-
return "";
|
|
30
|
-
const hours = Math.round((at.getTime() - Date.now()) / 3_600_000);
|
|
31
|
-
if (hours <= 0)
|
|
32
|
-
return "";
|
|
33
|
-
return hours >= 48 ? ` · resets in ${Math.round(hours / 24)}d` : ` · resets in ${hours}h`;
|
|
28
|
+
const text = usageResetText(resetsAt);
|
|
29
|
+
return text ? ` · ${text}` : "";
|
|
34
30
|
}
|
|
35
31
|
function metricLine(m) {
|
|
36
32
|
const pct = metricPercent(m);
|
|
33
|
+
const label = usageText(m.label, m.labelI18n);
|
|
34
|
+
const note = m.note ? usageText(m.note, m.noteI18n) : "";
|
|
37
35
|
switch (m.type) {
|
|
38
36
|
case "percent":
|
|
39
37
|
return {
|
|
40
38
|
bar: usageBar(pct ?? 0),
|
|
41
39
|
// note explains WHICH number this is (e.g. "busiest of 8 models"); it is
|
|
42
40
|
// what stops a legitimate 0% from reading as a broken meter.
|
|
43
|
-
text: `${Math.round(m.used ?? 0)}% ${
|
|
41
|
+
text: `${Math.round(m.used ?? 0)}% ${label}${note ? ` (${note})` : ""}${resetSuffix(m.resetsAt)}`,
|
|
44
42
|
};
|
|
45
43
|
case "dollars": {
|
|
46
44
|
const used = `$${(m.used ?? 0).toFixed(2)}`;
|
|
47
45
|
return m.limit
|
|
48
|
-
? { bar: usageBar(pct ?? 0), text: `${used}/$${m.limit.toFixed(2)} ${
|
|
49
|
-
: { bar: null, text: `${used} ${
|
|
46
|
+
? { bar: usageBar(pct ?? 0), text: `${used}/$${m.limit.toFixed(2)} ${label}` }
|
|
47
|
+
: { bar: null, text: `${used} ${label}` };
|
|
48
|
+
}
|
|
49
|
+
case "count": {
|
|
50
|
+
const unit = m.unit ? usageText(m.unit, m.unitI18n) : "";
|
|
51
|
+
return { bar: null, text: `${label}: ${m.value ?? "?"}${unit ? ` ${unit}` : ""}${note ? ` (${note})` : ""}` };
|
|
52
|
+
}
|
|
53
|
+
case "text": {
|
|
54
|
+
const value = m.value != null ? usageText(String(m.value), m.valueI18n) : null;
|
|
55
|
+
return value != null ? { bar: null, text: `${label}: ${value}${note ? ` (${note})` : ""}` } : null;
|
|
50
56
|
}
|
|
51
|
-
case "count":
|
|
52
|
-
return { bar: null, text: `${m.label}: ${m.value ?? "?"}${m.unit ? ` ${m.unit}` : ""}` };
|
|
53
|
-
case "text":
|
|
54
|
-
return m.value != null ? { bar: null, text: `${m.label}: ${m.value}` } : null;
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
function toBlocks(payload) {
|
|
@@ -62,16 +64,18 @@ function toBlocks(payload) {
|
|
|
62
64
|
// An ok row can carry a hint too — e.g. "cached 3m ago — live query is rate
|
|
63
65
|
// limited" from the stale fallback. Shown under the metrics, not instead of
|
|
64
66
|
// them, so old numbers still read as numbers.
|
|
65
|
-
note: p.status === "no-credentials" ? "
|
|
66
|
-
: p.status === "error" ? `⚠️ ${p.error ?? "
|
|
67
|
+
note: p.status === "no-credentials" ? t("usage.not_logged_in")
|
|
68
|
+
: p.status === "error" ? `⚠️ ${usageText(p.error ?? t("usage.error_fallback"), p.errorI18n)}`
|
|
67
69
|
: null,
|
|
68
|
-
okHint: p.status === "ok" && p.hint ? p.hint : null,
|
|
69
|
-
lines: p.status === "ok"
|
|
70
|
+
okHint: p.status === "ok" && p.hint ? usageText(p.hint, p.hintI18n) : null,
|
|
71
|
+
lines: p.status === "ok"
|
|
72
|
+
? p.metrics.filter(isVisibleUsageMetric).map(metricLine).filter((l) => l !== null)
|
|
73
|
+
: [],
|
|
70
74
|
}));
|
|
71
75
|
}
|
|
72
76
|
/** Discord: native Markdown in plain message content. */
|
|
73
77
|
export function renderUsageMarkdown(payload) {
|
|
74
|
-
const out = [
|
|
78
|
+
const out = [`📊 **${t("usage.title")}**`];
|
|
75
79
|
for (const b of toBlocks(payload)) {
|
|
76
80
|
out.push("", `${b.dot} **${b.name}**${b.plan ? ` (${b.plan})` : ""}`);
|
|
77
81
|
if (b.note) {
|
|
@@ -79,7 +83,7 @@ export function renderUsageMarkdown(payload) {
|
|
|
79
83
|
continue;
|
|
80
84
|
}
|
|
81
85
|
if (b.lines.length === 0) {
|
|
82
|
-
out.push(b.okHint ? `> ${b.okHint}` :
|
|
86
|
+
out.push(b.okHint ? `> ${b.okHint}` : `> ${t("usage.no_data")}`);
|
|
83
87
|
continue;
|
|
84
88
|
}
|
|
85
89
|
for (const l of b.lines) {
|
|
@@ -99,7 +103,7 @@ function escapeHtml(s) {
|
|
|
99
103
|
* `<` would make Telegram reject the whole message.
|
|
100
104
|
*/
|
|
101
105
|
export function renderUsageHtml(payload) {
|
|
102
|
-
const out = [
|
|
106
|
+
const out = [`📊 <b>${escapeHtml(t("usage.title"))}</b>`];
|
|
103
107
|
for (const b of toBlocks(payload)) {
|
|
104
108
|
out.push("", `${b.dot} <b>${escapeHtml(b.name)}</b>${b.plan ? ` (${escapeHtml(b.plan)})` : ""}`);
|
|
105
109
|
if (b.note) {
|
|
@@ -107,7 +111,7 @@ export function renderUsageHtml(payload) {
|
|
|
107
111
|
continue;
|
|
108
112
|
}
|
|
109
113
|
if (b.lines.length === 0) {
|
|
110
|
-
out.push(b.okHint ? escapeHtml(b.okHint) : "
|
|
114
|
+
out.push(b.okHint ? escapeHtml(b.okHint) : escapeHtml(t("usage.no_data")));
|
|
111
115
|
continue;
|
|
112
116
|
}
|
|
113
117
|
for (const l of b.lines) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-rich.js","sourceRoot":"","sources":["../../src/usage/format-rich.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"format-rich.js","sourceRoot":"","sources":["../../src/usage/format-rich.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage copy shared by the server renderers and the browser-only View renderer.
|
|
3
|
+
* Keep this list explicit: the parity test rejects a key missing from either
|
|
4
|
+
* locale surface before a mixed-language release can ship.
|
|
5
|
+
*/
|
|
6
|
+
export declare const USAGE_I18N_KEYS: readonly ["usage.title", "usage.title_plain", "usage.empty_active", "usage.not_logged_in", "usage.error_fallback", "usage.no_data", "usage.reset.in", "usage.reset.soon", "usage.duration.days_hours", "usage.duration.hours_minutes", "usage.duration.minutes", "usage.metric.session", "usage.metric.weekly", "usage.metric.monthly", "usage.metric.days_window", "usage.metric.named", "usage.metric.named_session", "usage.metric.named_weekly", "usage.metric.named_monthly", "usage.metric.named_days", "usage.metric.extra_usage", "usage.metric.rate_limit_resets", "usage.metric.credits", "usage.metric.weekly_limit", "usage.metric.pay_as_you_go", "usage.metric.bonus_credits", "usage.metric.overage_charges", "usage.metric.pay_per_use", "usage.unit.available", "usage.unit.credits", "usage.metric.usage_monthly", "usage.note.used_limit_unit", "usage.note.bonus_codes", "usage.value.disabled", "usage.value.cap", "usage.note.binding", "usage.note.binding_severity", "usage.note.busiest_model", "usage.note.busiest_models", "usage.metric.agy_claude_others", "usage.metric.agy_claude_others_session", "usage.metric.agy_claude_others_weekly", "usage.hint.statusline_now", "usage.hint.statusline_minutes", "usage.hint.claude_api_key", "usage.hint.login_claude", "usage.hint.login_agy", "usage.hint.no_quota", "usage.hint.login_codex", "usage.hint.codex_no_oauth", "usage.hint.login_grok", "usage.hint.grok_no_login", "usage.hint.login_kiro", "usage.hint.kiro_signed_out", "usage.hint.token_refreshing", "usage.hint.subscription_no_credit", "usage.hint.no_quota_account", "usage.error.unreachable", "usage.error.token_rejected", "usage.error.rate_limited", "usage.error.http", "usage.error.billing_http", "usage.error.invalid_response", "usage.error.invalid_billing_response", "usage.error.invalid_kiro_response", "usage.error.claude_token_expired", "usage.error.codex_token_expired", "usage.error.grok_expired", "usage.error.grok_response_changed", "usage.error.agy_cap", "usage.error.agy_no_refresh", "usage.error.agy_token_expired", "usage.error.agy_login_expired", "usage.error.agy_refresh_empty", "usage.error.grok_auth_readonly", "usage.error.grok_no_refresh", "usage.error.grok_refresh_unreachable", "usage.error.grok_invalid_refresh", "usage.error.grok_persist"];
|
|
7
|
+
export type UsageI18nKey = typeof USAGE_I18N_KEYS[number];
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Usage copy shared by the server renderers and the browser-only View renderer.
|
|
3
|
+
* Keep this list explicit: the parity test rejects a key missing from either
|
|
4
|
+
* locale surface before a mixed-language release can ship.
|
|
5
|
+
*/
|
|
6
|
+
export const USAGE_I18N_KEYS = [
|
|
7
|
+
"usage.title", "usage.title_plain", "usage.empty_active", "usage.not_logged_in",
|
|
8
|
+
"usage.error_fallback", "usage.no_data", "usage.reset.in", "usage.reset.soon",
|
|
9
|
+
"usage.duration.days_hours", "usage.duration.hours_minutes", "usage.duration.minutes",
|
|
10
|
+
"usage.metric.session", "usage.metric.weekly", "usage.metric.monthly", "usage.metric.days_window",
|
|
11
|
+
"usage.metric.named", "usage.metric.named_session", "usage.metric.named_weekly",
|
|
12
|
+
"usage.metric.named_monthly", "usage.metric.named_days", "usage.metric.extra_usage",
|
|
13
|
+
"usage.metric.rate_limit_resets", "usage.metric.credits", "usage.metric.weekly_limit",
|
|
14
|
+
"usage.metric.pay_as_you_go", "usage.metric.bonus_credits", "usage.metric.overage_charges",
|
|
15
|
+
"usage.metric.pay_per_use", "usage.unit.available", "usage.unit.credits",
|
|
16
|
+
"usage.metric.usage_monthly", "usage.note.used_limit_unit", "usage.note.bonus_codes",
|
|
17
|
+
"usage.value.disabled", "usage.value.cap", "usage.note.binding",
|
|
18
|
+
"usage.note.binding_severity", "usage.note.busiest_model", "usage.note.busiest_models",
|
|
19
|
+
"usage.metric.agy_claude_others", "usage.metric.agy_claude_others_session", "usage.metric.agy_claude_others_weekly",
|
|
20
|
+
"usage.hint.statusline_now", "usage.hint.statusline_minutes", "usage.hint.claude_api_key",
|
|
21
|
+
"usage.hint.login_claude", "usage.hint.login_agy", "usage.hint.no_quota",
|
|
22
|
+
"usage.hint.login_codex", "usage.hint.codex_no_oauth", "usage.hint.login_grok",
|
|
23
|
+
"usage.hint.grok_no_login", "usage.hint.login_kiro", "usage.hint.kiro_signed_out",
|
|
24
|
+
"usage.hint.token_refreshing", "usage.hint.subscription_no_credit", "usage.hint.no_quota_account",
|
|
25
|
+
"usage.error.unreachable", "usage.error.token_rejected", "usage.error.rate_limited",
|
|
26
|
+
"usage.error.http", "usage.error.billing_http", "usage.error.invalid_response",
|
|
27
|
+
"usage.error.invalid_billing_response", "usage.error.invalid_kiro_response",
|
|
28
|
+
"usage.error.claude_token_expired", "usage.error.codex_token_expired",
|
|
29
|
+
"usage.error.grok_expired", "usage.error.grok_response_changed", "usage.error.agy_cap",
|
|
30
|
+
"usage.error.agy_no_refresh", "usage.error.agy_token_expired", "usage.error.agy_login_expired",
|
|
31
|
+
"usage.error.agy_refresh_empty", "usage.error.grok_auth_readonly", "usage.error.grok_no_refresh",
|
|
32
|
+
"usage.error.grok_refresh_unreachable", "usage.error.grok_invalid_refresh", "usage.error.grok_persist",
|
|
33
|
+
];
|
|
34
|
+
//# sourceMappingURL=i18n-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n-keys.js","sourceRoot":"","sources":["../../src/usage/i18n-keys.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,aAAa,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,qBAAqB;IAC/E,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB;IAC7E,2BAA2B,EAAE,8BAA8B,EAAE,wBAAwB;IACrF,sBAAsB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,0BAA0B;IACjG,oBAAoB,EAAE,4BAA4B,EAAE,2BAA2B;IAC/E,4BAA4B,EAAE,yBAAyB,EAAE,0BAA0B;IACnF,gCAAgC,EAAE,sBAAsB,EAAE,2BAA2B;IACrF,4BAA4B,EAAE,4BAA4B,EAAE,8BAA8B;IAC1F,0BAA0B,EAAE,sBAAsB,EAAE,oBAAoB;IACxE,4BAA4B,EAAE,4BAA4B,EAAE,wBAAwB;IACpF,sBAAsB,EAAE,iBAAiB,EAAE,oBAAoB;IAC/D,6BAA6B,EAAE,0BAA0B,EAAE,2BAA2B;IACtF,gCAAgC,EAAE,wCAAwC,EAAE,uCAAuC;IACnH,2BAA2B,EAAE,+BAA+B,EAAE,2BAA2B;IACzF,yBAAyB,EAAE,sBAAsB,EAAE,qBAAqB;IACxE,wBAAwB,EAAE,2BAA2B,EAAE,uBAAuB;IAC9E,0BAA0B,EAAE,uBAAuB,EAAE,4BAA4B;IACjF,6BAA6B,EAAE,mCAAmC,EAAE,6BAA6B;IACjG,yBAAyB,EAAE,4BAA4B,EAAE,0BAA0B;IACnF,kBAAkB,EAAE,0BAA0B,EAAE,8BAA8B;IAC9E,sCAAsC,EAAE,mCAAmC;IAC3E,kCAAkC,EAAE,iCAAiC;IACrE,0BAA0B,EAAE,mCAAmC,EAAE,qBAAqB;IACtF,4BAA4B,EAAE,+BAA+B,EAAE,+BAA+B;IAC9F,+BAA+B,EAAE,gCAAgC,EAAE,6BAA6B;IAChG,sCAAsC,EAAE,kCAAkC,EAAE,0BAA0B;CAC9F,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { UsageI18nRef } from "./providers.js";
|
|
2
|
+
/** Resolve AgEnD-owned usage copy while preserving raw vendor text as fallback. */
|
|
3
|
+
export declare function usageText(fallback: string, ref?: UsageI18nRef): string;
|
|
4
|
+
/** Minute-precision duration shared by the chat and MCP usage renderers. */
|
|
5
|
+
export declare function usageResetText(resetsAt?: string | null): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { t } from "../locale.js";
|
|
2
|
+
/** Resolve AgEnD-owned usage copy while preserving raw vendor text as fallback. */
|
|
3
|
+
export function usageText(fallback, ref) {
|
|
4
|
+
return ref ? t(ref.key, ...(ref.args ?? [])) : fallback;
|
|
5
|
+
}
|
|
6
|
+
/** Minute-precision duration shared by the chat and MCP usage renderers. */
|
|
7
|
+
export function usageResetText(resetsAt) {
|
|
8
|
+
if (!resetsAt)
|
|
9
|
+
return "";
|
|
10
|
+
const at = new Date(resetsAt);
|
|
11
|
+
if (Number.isNaN(at.getTime()))
|
|
12
|
+
return "";
|
|
13
|
+
const remainingMs = at.getTime() - Date.now();
|
|
14
|
+
if (remainingMs <= 0)
|
|
15
|
+
return t("usage.reset.soon");
|
|
16
|
+
const totalMinutes = Math.max(1, Math.ceil(remainingMs / 60_000));
|
|
17
|
+
const days = Math.floor(totalMinutes / 1_440);
|
|
18
|
+
const hours = Math.floor((totalMinutes % 1_440) / 60);
|
|
19
|
+
const minutes = totalMinutes % 60;
|
|
20
|
+
const duration = totalMinutes >= 2_880
|
|
21
|
+
? t("usage.duration.days_hours", days, hours)
|
|
22
|
+
: totalMinutes >= 60
|
|
23
|
+
? t("usage.duration.hours_minutes", Math.floor(totalMinutes / 60), minutes)
|
|
24
|
+
: t("usage.duration.minutes", totalMinutes);
|
|
25
|
+
return t("usage.reset.in", duration);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=i18n.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["../../src/usage/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAGjC,mFAAmF;AACnF,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,GAAkB;IAC5D,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC1D,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,cAAc,CAAC,QAAwB;IACrD,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzB,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9C,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAEnD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,YAAY,IAAI,KAAK;QACpC,CAAC,CAAC,CAAC,CAAC,2BAA2B,EAAE,IAAI,EAAE,KAAK,CAAC;QAC7C,CAAC,CAAC,YAAY,IAAI,EAAE;YAClB,CAAC,CAAC,CAAC,CAAC,8BAA8B,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC;YAC3E,CAAC,CAAC,CAAC,CAAC,wBAAwB,EAAE,YAAY,CAAC,CAAC;IAChD,OAAO,CAAC,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { type StatuslineRateLimits } from "./statusline-usage.js";
|
|
2
|
+
import type { UsageI18nKey } from "./i18n-keys.js";
|
|
2
3
|
export interface UsageMetric {
|
|
3
4
|
label: string;
|
|
5
|
+
/** Locale-neutral semantic text. Renderers translate this and keep `label` as a fallback. */
|
|
6
|
+
labelI18n?: UsageI18nRef;
|
|
7
|
+
/** Vendor-reported per-model quota, rather than an account's primary window. */
|
|
8
|
+
scope?: "model";
|
|
4
9
|
type: "percent" | "dollars" | "count" | "text";
|
|
5
10
|
used?: number;
|
|
6
11
|
limit?: number;
|
|
7
12
|
value?: number | string;
|
|
13
|
+
valueI18n?: UsageI18nRef;
|
|
8
14
|
unit?: string;
|
|
15
|
+
unitI18n?: UsageI18nRef;
|
|
9
16
|
note?: string;
|
|
17
|
+
noteI18n?: UsageI18nRef;
|
|
10
18
|
resetsAt?: string | null;
|
|
11
19
|
windowMs?: number | null;
|
|
12
20
|
}
|
|
@@ -16,9 +24,15 @@ export interface ProviderUsage {
|
|
|
16
24
|
status: "ok" | "error" | "no-credentials";
|
|
17
25
|
plan?: string | null;
|
|
18
26
|
error?: string;
|
|
27
|
+
errorI18n?: UsageI18nRef;
|
|
19
28
|
hint?: string;
|
|
29
|
+
hintI18n?: UsageI18nRef;
|
|
20
30
|
metrics: UsageMetric[];
|
|
21
31
|
}
|
|
32
|
+
export interface UsageI18nRef {
|
|
33
|
+
key: UsageI18nKey;
|
|
34
|
+
args?: Array<string | number>;
|
|
35
|
+
}
|
|
22
36
|
/** `CLAUDE_CODE_OAUTH_TOKEN` as exported in a shell rc file, or null. */
|
|
23
37
|
export declare function tokenFromShellRc(read: (path: string) => string, home?: string, files?: readonly string[]): string | null;
|
|
24
38
|
/**
|
|
@@ -62,6 +76,12 @@ export declare function resolveClaudeAuth(file: {
|
|
|
62
76
|
* even live?".
|
|
63
77
|
*/
|
|
64
78
|
export declare function statuslineUsage(reading: StatuslineRateLimits, plan: string | null, now?: number): Omit<ProviderUsage, "id" | "name">;
|
|
79
|
+
/**
|
|
80
|
+
* Best-effort OAuth access token for direct Anthropic API calls (the /model
|
|
81
|
+
* catalog probe). Same resolution order as the usage panel: credentials file →
|
|
82
|
+
* CLAUDE_CODE_OAUTH_TOKEN → shell rc. Null when nothing usable exists.
|
|
83
|
+
*/
|
|
84
|
+
export declare function getClaudeOAuthToken(): Promise<string | null>;
|
|
65
85
|
/** Exported for tests — the statusline/API preference order is the subject. */
|
|
66
86
|
export declare function fetchClaudeUsage(): Promise<Omit<ProviderUsage, "id" | "name">>;
|
|
67
87
|
interface AgyBucket {
|
|
@@ -98,6 +118,7 @@ interface AgyStoredToken {
|
|
|
98
118
|
* uses) is read alongside `expiry` (RFC3339) for the same reason.
|
|
99
119
|
*/
|
|
100
120
|
export declare function readAgyToken(file: unknown): AgyStoredToken;
|
|
121
|
+
export declare function fetchCodexUsage(): Promise<Omit<ProviderUsage, "id" | "name">>;
|
|
101
122
|
interface KiroToken {
|
|
102
123
|
access_token?: string;
|
|
103
124
|
expires_at?: string;
|