@songsid/agend 2.1.12-beta.2 → 2.1.12-beta.4
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 +54 -8
- package/README.zh-TW.md +104 -11
- package/dist/agent-endpoint.d.ts +2 -0
- package/dist/agent-endpoint.js +38 -29
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/backend/claude-code.d.ts +20 -0
- package/dist/backend/claude-code.js +84 -25
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex.d.ts +20 -0
- package/dist/backend/codex.js +55 -5
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/factory.js +5 -5
- package/dist/backend/factory.js.map +1 -1
- package/dist/backend/index.d.ts +0 -1
- package/dist/backend/index.js +0 -1
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/kiro.d.ts +10 -1
- package/dist/backend/kiro.js +13 -0
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/mock.d.ts +1 -1
- package/dist/backend/mock.js +1 -1
- package/dist/backend/muse.d.ts +20 -0
- package/dist/backend/muse.js +68 -11
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/removed.d.ts +12 -0
- package/dist/backend/removed.js +18 -0
- package/dist/backend/removed.js.map +1 -0
- package/dist/backend/session-signals.js +5 -10
- package/dist/backend/session-signals.js.map +1 -1
- package/dist/backend/types.d.ts +15 -1
- package/dist/backend/types.js +0 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.js +9 -0
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +14 -8
- package/dist/channel/adapters/telegram.js +80 -26
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +2 -2
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/classic-channel-manager.js +2 -2
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +27 -53
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +1 -1
- package/dist/command-table.js +4 -2
- package/dist/command-table.js.map +1 -1
- package/dist/config-validator.js +48 -10
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +7 -5
- package/dist/config.js.map +1 -1
- package/dist/context-guardian.d.ts +1 -1
- package/dist/context-guardian.js +1 -1
- package/dist/cross-instance-notice.d.ts +39 -0
- package/dist/cross-instance-notice.js +84 -0
- package/dist/cross-instance-notice.js.map +1 -0
- package/dist/daemon.d.ts +73 -2
- package/dist/daemon.js +333 -31
- package/dist/daemon.js.map +1 -1
- package/dist/daily-summary.js +0 -3
- package/dist/daily-summary.js.map +1 -1
- package/dist/fleet-manager.d.ts +16 -3
- package/dist/fleet-manager.js +110 -53
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +1 -1
- package/dist/instance-config-impact.js +3 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +9 -1
- package/dist/instance-lifecycle.js +62 -7
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +30 -6
- package/dist/locale.js.map +1 -1
- package/dist/memory-pressure.d.ts +8 -2
- package/dist/memory-pressure.js +10 -4
- package/dist/memory-pressure.js.map +1 -1
- package/dist/outbound-handlers.js +47 -25
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +0 -1
- package/dist/outbound-schemas.js +3 -3
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/reply-dedup.d.ts +5 -0
- package/dist/reply-dedup.js +9 -0
- package/dist/reply-dedup.js.map +1 -1
- package/dist/settings-api.js +5 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/setup-wizard.js +0 -4
- package/dist/setup-wizard.js.map +1 -1
- package/dist/spawn-gate.js +4 -3
- package/dist/spawn-gate.js.map +1 -1
- package/dist/target-queue-worker.d.ts +1 -1
- package/dist/topic-commands.d.ts +64 -5
- package/dist/topic-commands.js +172 -14
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-jsonl.d.ts +20 -0
- package/dist/transcript-jsonl.js +64 -0
- package/dist/transcript-jsonl.js.map +1 -0
- package/dist/transcript-monitor.js +21 -29
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +1 -1
- package/dist/transcript-sources.js +29 -26
- package/dist/transcript-sources.js.map +1 -1
- package/dist/turn-reply-guard.d.ts +25 -1
- package/dist/turn-reply-guard.js +36 -1
- package/dist/turn-reply-guard.js.map +1 -1
- package/dist/types.d.ts +13 -4
- package/dist/ui/dashboard.html +3 -3
- package/dist/ui/settings.html +58 -16
- package/dist/ui/view.html +17 -10
- package/dist/ui/web-terminal/terminal.css +1 -1
- package/dist/ui/web-terminal/terminal.js +5 -1
- package/dist/update-check.d.ts +15 -6
- package/dist/update-check.js +20 -7
- package/dist/update-check.js.map +1 -1
- package/dist/usage/format-rich.js +3 -7
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +1 -1
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/i18n.d.ts +5 -2
- package/dist/usage/i18n.js +9 -5
- package/dist/usage/i18n.js.map +1 -1
- package/dist/usage/providers.d.ts +11 -5
- package/dist/usage/providers.js +55 -1
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/usage-api.d.ts +0 -9
- package/dist/usage/usage-api.js +7 -32
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/wake-coordinator.js +1 -1
- package/dist/web-api.js +1 -2
- package/dist/web-api.js.map +1 -1
- package/package.json +1 -1
- package/dist/backend/gemini-cli.d.ts +0 -20
- package/dist/backend/gemini-cli.js +0 -169
- package/dist/backend/gemini-cli.js.map +0 -1
package/dist/ui/settings.html
CHANGED
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
const $ = (id) => document.getElementById(id);
|
|
251
251
|
const el = (tag, attrs = {}, ...kids) => { const e = document.createElement(tag); for (const k in attrs) { if (k === "class") e.className = attrs[k]; else if (k === "html") e.innerHTML = attrs[k]; else if (k.startsWith("on")) e.addEventListener(k.slice(2), attrs[k]); else e.setAttribute(k, attrs[k]); } for (const c of kids) if (c != null) e.append(c); return e; };
|
|
252
252
|
const esc = (s) => String(s).replace(/[&<>]/g, c => ({ "&":"&","<":"<",">":">" }[c]));
|
|
253
|
-
const BACKENDS = ["claude-code", "kiro-cli", "codex", "opencode", "
|
|
253
|
+
const BACKENDS = ["claude-code", "kiro-cli", "codex", "opencode", "antigravity", "grok", "muse"];
|
|
254
254
|
|
|
255
255
|
// ── i18n ──
|
|
256
256
|
const I18N = {
|
|
@@ -267,8 +267,8 @@
|
|
|
267
267
|
se_src_instance: "agent", se_src_platform: "connection", se_src_builtin: "default", se_pick: "Pick…", se_useDefault: "Use the default", se_fallback: "the default is used instead",
|
|
268
268
|
se_unicode: "Emoji", se_telegramOnly: "Telegram allows only these reactions", se_serverEmojis: "Server emojis", se_noServerEmojis: "No custom emojis on this server.", se_primaryServer: "primary", se_externalEmojiHint: "Another server's emoji needs the bot's Use External Emojis permission in the channel it reacts in.", se_unavailable: "unavailable",
|
|
269
269
|
se_hint: "Empty keeps the default. The preview is resolved by AgEnD exactly as the bot will react.",
|
|
270
|
-
detection: "Detection", startup: "Startup", backendSection: "Backend", advancedSection: "Advanced & Access", hangEnabled: "Hang detector enabled", hangTimeout: "Stuck timeout", agentMode: "Agent mode", toolSet: "Tool set", toolProgress: "Tool progress", replyCompletionGuard: "Require a delivered reply", replyGuardSupported: "Available for Claude Code and Kiro legacy/TUI in MCP mode.", replyGuardUnsupported: "Stored but inactive: {0} in {1} mode does not support reply-drop recovery.", logLevel: "Log level", concurrency: "Startup concurrency", staggerDelay: "Stagger delay", lightweight: "Lightweight mode", modelFailover: "Fallback model", displayName: "Display name", pause: "Pause", wake: "Wake", accessMode: "Access mode", affected: "Affected instances",
|
|
271
|
-
language: "Language (bot replies)", defaultBackend: "Default backend", defaultModel: "Default model", allowedUsers: "Allowed users (primary bot)",
|
|
270
|
+
detection: "Detection", startup: "Startup", backendSection: "Backend", advancedSection: "Advanced & Access", hangEnabled: "Hang detector enabled", hangTimeout: "Stuck timeout", agentMode: "Agent mode", toolSet: "Tool set", toolProgress: "Tool progress", crossInstanceVisibility: "Bot-to-bot messages in topics", crossInstanceVisibilityHint: "full: the whole message · summary: one line · hidden: nothing. Messages are always delivered; the Mirror Topic still shows them.", replyCompletionGuard: "Require a delivered reply", replyGuardSupported: "Available for Claude Code and Kiro legacy/TUI in MCP mode.", replyGuardUnsupported: "Stored but inactive: {0} in {1} mode does not support reply-drop recovery.", logLevel: "Log level", concurrency: "Startup concurrency", staggerDelay: "Stagger delay", lightweight: "Lightweight mode", modelFailover: "Fallback model", displayName: "Display name", pause: "Pause", wake: "Wake", accessMode: "Access mode", affected: "Affected instances",
|
|
271
|
+
language: "Language (bot replies)", defaultBackend: "Default backend", defaultModel: "Default model", allowedUsers: "Allowed users (primary bot)", localeAuto: "Auto (follow system)",
|
|
272
272
|
classicAdmins: "ClassicBot admins", allowedGuilds: "Allowed guilds", type: "Type", adapterId: "Adapter id",
|
|
273
273
|
tokenEnv: "Bot token env var", groupId: "Group / guild id", nameField: "Name",
|
|
274
274
|
envHint: "Put the actual token in ~/.agend/.env under this env var, then Reload Fleet.",
|
|
@@ -309,7 +309,7 @@
|
|
|
309
309
|
signatureMismatch: "fleet.yaml and the running configuration disagree on: {0}. Restarting will not clear this — check daemon.log first.",
|
|
310
310
|
applyStillWorking: "Still restarting ({0}s) — AgEnD is still working; this page keeps checking.",
|
|
311
311
|
applyLostJob: "Lost track of this apply (the fleet may have restarted). Reload the page to see the current state.",
|
|
312
|
-
changesPending: "{0} change(s) not applied", impactNow: "⚡ Immediately", impactAgent: "🔄 Restart this Agent", impactFleet: "🔄🔄 Restart AgEnD", queued: "Queued: {0}", applyFailed: "Apply failed", changesApplied: "✓ Changes applied. AgEnD is reconciling affected Agents.", reviewChanges: "Review changes", readyApply: "Ready to apply", copied: "Copied", expectedMapping: "expected a mapping", configLoadFailed: "Failed to load config — open the Settings link again.",
|
|
312
|
+
changesPending: "{0} change(s) not applied", impactNow: "⚡ Immediately", impactAgent: "🔄 Restart this Agent", impactFleet: "🔄🔄 Restart AgEnD", queued: "Queued: {0}", applyFailed: "Apply failed", changesApplied: "✓ Changes applied. AgEnD is reconciling affected Agents.", reviewChanges: "Review changes", backendUnavailable: "{0} (removed — choose another backend)", readyApply: "Ready to apply", copied: "Copied", expectedMapping: "expected a mapping", configLoadFailed: "Failed to load config — open the Settings link again.",
|
|
313
313
|
confirmOpenAccess: "Open access allows anyone in this channel to operate the bot. Continue?", confirmLockedEmpty: "Locked access has no allowed users. This may leave nobody able to administer the bot. Continue?", accessLockedEmpty: "Locked mode has no allowed users; add at least one administrator to avoid lockout.", accessChangeCancelled: "Access mode change cancelled",
|
|
314
314
|
mustNonNegative: "Must be 0 or greater", mustPositive: "Must be greater than 0", nonnegativeInteger: "Must be a non-negative integer", failoverEmpty: "Empty list disables failover", concurrencyRange: "Must be an integer from 1 to 20", concurrencyWarning: "May exceed CPU capacity on smaller hosts", staggerRange: "Must be between 0 and 30000", staggerWarning: "Very low values can cause startup spikes",
|
|
315
315
|
},
|
|
@@ -326,8 +326,8 @@
|
|
|
326
326
|
backend: "後端", model: "模型", workingDir: "工作目錄", channelBinding: "頻道綁定",
|
|
327
327
|
description: "描述", systemPrompt: "System prompt", tags: "標籤", generalTopicField: "General topic(fleet 分派器)",
|
|
328
328
|
runtimeResources: "執行環境與資源", autoPause: "閒置後自動暫停", minutes: "分鐘", inheritDefault: "沿用全域預設值",
|
|
329
|
-
detection: "偵測", startup: "啟動", backendSection: "後端", advancedSection: "進階與存取", hangEnabled: "啟用卡住偵測", hangTimeout: "卡住逾時", agentMode: "Agent 模式", toolSet: "工具集", toolProgress: "工具進度", replyCompletionGuard: "要求送出回覆", replyGuardSupported: "Claude Code 與 Kiro legacy/TUI 的 MCP 模式可用。", replyGuardUnsupported: "設定會保留,但不會生效:{0} 的 {1} 模式不支援回覆遺失補救。", logLevel: "Log 等級", concurrency: "啟動併發數", staggerDelay: "錯開延遲", lightweight: "輕量模式", modelFailover: "備援模型", displayName: "顯示名稱", pause: "暫停", wake: "喚醒", accessMode: "存取模式", affected: "受影響 instances",
|
|
330
|
-
language: "語言(bot 回覆)", defaultBackend: "預設後端", defaultModel: "預設模型", allowedUsers: "允許使用者(主 bot)",
|
|
329
|
+
detection: "偵測", startup: "啟動", backendSection: "後端", advancedSection: "進階與存取", hangEnabled: "啟用卡住偵測", hangTimeout: "卡住逾時", agentMode: "Agent 模式", toolSet: "工具集", toolProgress: "工具進度", crossInstanceVisibility: "Agent 之間的訊息在主題中", crossInstanceVisibilityHint: "full:完整訊息 · summary:一行摘要 · hidden:不顯示。訊息一律照常送達,Mirror Topic 也照常顯示。", replyCompletionGuard: "要求送出回覆", replyGuardSupported: "Claude Code 與 Kiro legacy/TUI 的 MCP 模式可用。", replyGuardUnsupported: "設定會保留,但不會生效:{0} 的 {1} 模式不支援回覆遺失補救。", logLevel: "Log 等級", concurrency: "啟動併發數", staggerDelay: "錯開延遲", lightweight: "輕量模式", modelFailover: "備援模型", displayName: "顯示名稱", pause: "暫停", wake: "喚醒", accessMode: "存取模式", affected: "受影響 instances",
|
|
330
|
+
language: "語言(bot 回覆)", defaultBackend: "預設後端", defaultModel: "預設模型", allowedUsers: "允許使用者(主 bot)", localeAuto: "自動(跟隨系統)",
|
|
331
331
|
classicAdmins: "ClassicBot 管理員", allowedGuilds: "允許的伺服器", type: "類型", adapterId: "Adapter id",
|
|
332
332
|
tokenEnv: "Bot token 環境變數", groupId: "群組 / guild id", nameField: "名稱",
|
|
333
333
|
envHint: "把實際 token 放到 ~/.agend/.env 的這個環境變數下,然後點重新載入。",
|
|
@@ -368,7 +368,7 @@
|
|
|
368
368
|
signatureMismatch: "fleet.yaml 與執行中的設定在這些項目上不一致:{0}。重新啟動無法解決,請先查看 daemon.log。",
|
|
369
369
|
applyStillWorking: "仍在重啟中({0} 秒)—— AgEnD 還在處理,此頁面會持續確認。",
|
|
370
370
|
applyLostJob: "已追蹤不到這次套用(AgEnD 可能重啟過)。請重新整理頁面查看目前狀態。",
|
|
371
|
-
changesPending: "有 {0} 項變更尚未套用", impactNow: "⚡ 立即生效", impactAgent: "🔄 重新啟動此 Agent", impactFleet: "🔄🔄 重新啟動 AgEnD", queued: "已加入待套用:{0}", applyFailed: "套用失敗", changesApplied: "✓ 變更已套用,AgEnD 正在協調受影響的 Agent。", reviewChanges: "檢查變更", readyApply: "可套用變更", copied: "已複製", expectedMapping: "預期為 mapping", configLoadFailed: "載入設定失敗 — 請重新開啟 Settings 連結。",
|
|
371
|
+
changesPending: "有 {0} 項變更尚未套用", impactNow: "⚡ 立即生效", impactAgent: "🔄 重新啟動此 Agent", impactFleet: "🔄🔄 重新啟動 AgEnD", queued: "已加入待套用:{0}", applyFailed: "套用失敗", changesApplied: "✓ 變更已套用,AgEnD 正在協調受影響的 Agent。", reviewChanges: "檢查變更", backendUnavailable: "{0}(已移除,請選擇其他 backend)", readyApply: "可套用變更", copied: "已複製", expectedMapping: "預期為 mapping", configLoadFailed: "載入設定失敗 — 請重新開啟 Settings 連結。",
|
|
372
372
|
confirmOpenAccess: "Open 模式會允許此頻道中的所有人操作 bot,確定要繼續嗎?", confirmLockedEmpty: "Locked 模式目前沒有允許的使用者,可能導致沒有人能管理 bot,確定要繼續嗎?", accessLockedEmpty: "Locked 模式沒有允許的使用者;建議至少加入一位管理員,避免無法操作。", accessChangeCancelled: "已取消 Access Mode 變更",
|
|
373
373
|
mustNonNegative: "必須為 0 或更大的數值", mustPositive: "必須大於 0", nonnegativeInteger: "必須是非負整數", failoverEmpty: "空白清單會停用模型備援", concurrencyRange: "必須是 1 到 20 的整數", concurrencyWarning: "在較小的主機上可能超出 CPU 負荷", staggerRange: "必須介於 0 到 30000", staggerWarning: "數值太低可能造成啟動尖峰",
|
|
374
374
|
},
|
|
@@ -473,6 +473,35 @@
|
|
|
473
473
|
box.append(chips, el("div", { class: "chip-add" }, inp, el("button", { class: "sm", onclick: add }, "+ Add")));
|
|
474
474
|
redraw(); return box;
|
|
475
475
|
}
|
|
476
|
+
/**
|
|
477
|
+
* The backend picker keeps a current value it does not offer, such as the removed gemini-cli (#1280 review):
|
|
478
|
+
* otherwise the select falls to its first option and an unrelated edit would switch the instance's CLI and
|
|
479
|
+
* account to claude-code without anyone choosing it. The value stays until the user picks another.
|
|
480
|
+
*/
|
|
481
|
+
function backendSelect(value) {
|
|
482
|
+
return select(value, BACKENDS.includes(value) ? BACKENDS : [{ value, label: tf("backendUnavailable", value) }, ...BACKENDS]);
|
|
483
|
+
}
|
|
484
|
+
const LOCALES = [["en", "English"], ["zh-TW", "繁體中文 (zh-TW)"]];
|
|
485
|
+
/**
|
|
486
|
+
* The locale picker adds an explicit "Auto (follow system)" option for unset (#1310):
|
|
487
|
+
* without it the select falls to its first option (en) and any unrelated defaults
|
|
488
|
+
* save writes locale: en, pinning the language and disabling timezone auto-detect.
|
|
489
|
+
* Like backendSelect, it also keeps a value it does not offer until the user picks another.
|
|
490
|
+
*/
|
|
491
|
+
function localeSelect(value) {
|
|
492
|
+
const s = el("select");
|
|
493
|
+
const auto = el("option", {}, t("localeAuto")); auto.value = "";
|
|
494
|
+
if (!value) auto.selected = true;
|
|
495
|
+
s.append(auto);
|
|
496
|
+
if (value && !LOCALES.some(([v]) => v === value)) {
|
|
497
|
+
const unknown = el("option", {}, value); unknown.value = value; unknown.selected = true;
|
|
498
|
+
s.append(unknown);
|
|
499
|
+
}
|
|
500
|
+
for (const [v, lbl] of LOCALES) {
|
|
501
|
+
const o = el("option", {}, lbl); o.value = v; if (v === value) o.selected = true; s.append(o);
|
|
502
|
+
}
|
|
503
|
+
return s;
|
|
504
|
+
}
|
|
476
505
|
function select(value, options) { const s = el("select"); for (const o of options) { const val = typeof o === "string" ? o : o.value; const label = typeof o === "string" ? o : o.label; const opt = el("option", {}, label); opt.value = val; if (val === value) opt.selected = true; s.append(opt); } return s; }
|
|
477
506
|
const impactText = (kind) => t(kind === "now" ? "impactNow" : kind === "fleet" ? "impactFleet" : "impactAgent");
|
|
478
507
|
// The server derives every field's impact from HOT_INSTANCE_CONFIG_KEYS and
|
|
@@ -1035,6 +1064,9 @@
|
|
|
1035
1064
|
function changedFields(next, baseline) {
|
|
1036
1065
|
return Object.fromEntries(Object.entries(next).filter(([key, value]) => !sameValue(value, baseline[key])));
|
|
1037
1066
|
}
|
|
1067
|
+
// #1302: cross-instance (bot-to-bot) notices. Unset, or a value the fleet does not know, means full.
|
|
1068
|
+
const VISIBILITY_MODES = ["full", "summary", "hidden"];
|
|
1069
|
+
const visibilityDefault = (defaults) => VISIBILITY_MODES.includes(defaults?.cross_instance_visibility) ? defaults.cross_instance_visibility : "full";
|
|
1038
1070
|
function overrideControl(inst, key, input, inheritedValue, impactField = `instance.${key}`) {
|
|
1039
1071
|
const inherited = !hasOwn(inst, key);
|
|
1040
1072
|
const toggle = el("input", { type: "checkbox" }); toggle.checked = inherited;
|
|
@@ -1151,7 +1183,7 @@
|
|
|
1151
1183
|
function agentEditForm(name, inst) {
|
|
1152
1184
|
const box = el("div", { class: "edit" });
|
|
1153
1185
|
const defaults = state.fleet.defaults || {};
|
|
1154
|
-
const fBackend =
|
|
1186
|
+
const fBackend = backendSelect(inst.backend || state.fleet.defaults?.backend || "claude-code");
|
|
1155
1187
|
const fModel = el("input", { type: "text", value: inst.model || "", placeholder: "(inherit default)" });
|
|
1156
1188
|
const fWd = el("input", { type: "text", value: inst.working_directory || "" });
|
|
1157
1189
|
const fChan = select(inst.channel_id || "", ["", ...channelIds()]);
|
|
@@ -1166,6 +1198,10 @@
|
|
|
1166
1198
|
const agentMode = overrideControl(inst, "agent_mode", select(inst.agent_mode || defaults.agent_mode || "mcp", ["mcp", "cli"]), defaults.agent_mode || "mcp");
|
|
1167
1199
|
const toolSet = overrideControl(inst, "tool_set", select(inst.tool_set || defaults.tool_set || "full", ["full", "standard", "minimal"]), defaults.tool_set || "full");
|
|
1168
1200
|
const toolProgress = overrideControl(inst, "tool_progress", select(inst.tool_progress ?? defaults.tool_progress ?? "off", ["off", "standard", "verbose"]), defaults.tool_progress ?? "off");
|
|
1201
|
+
// #1302. The baseline is what the picker shows before anyone touches it, so a value it cannot show (a typo in
|
|
1202
|
+
// fleet.yaml, which the fleet reads as unset) is never rewritten by an unrelated edit.
|
|
1203
|
+
const visibility = overrideControl(inst, "cross_instance_visibility", select(inst.cross_instance_visibility ?? visibilityDefault(defaults), VISIBILITY_MODES), visibilityDefault(defaults));
|
|
1204
|
+
const visibilityBaseline = hasOwn(inst, "cross_instance_visibility") ? visibility.input.value : null;
|
|
1169
1205
|
const fReplyGuard = el("input", { type: "checkbox" });
|
|
1170
1206
|
fReplyGuard.checked = inst.reply_completion_guard ?? defaults.reply_completion_guard ?? true;
|
|
1171
1207
|
const replyGuard = overrideControl(inst, "reply_completion_guard", fReplyGuard, defaults.reply_completion_guard ?? true);
|
|
@@ -1223,6 +1259,7 @@
|
|
|
1223
1259
|
agent_mode: agentMode.toggle.checked ? null : agentMode.input.value,
|
|
1224
1260
|
tool_set: toolSet.toggle.checked ? null : toolSet.input.value,
|
|
1225
1261
|
tool_progress: toolProgress.toggle.checked ? null : toolProgress.input.value,
|
|
1262
|
+
cross_instance_visibility: visibility.toggle.checked ? null : visibility.input.value,
|
|
1226
1263
|
reply_completion_guard: replyGuard.toggle.checked ? null : replyGuard.input.checked,
|
|
1227
1264
|
log_level: logLevel.toggle.checked ? null : logLevel.input.value,
|
|
1228
1265
|
lightweight: lightweight.toggle.checked ? null : lightweight.input.checked,
|
|
@@ -1244,6 +1281,7 @@
|
|
|
1244
1281
|
agent_mode: hasOwn(inst, "agent_mode") ? inst.agent_mode : null,
|
|
1245
1282
|
tool_set: hasOwn(inst, "tool_set") ? inst.tool_set : null,
|
|
1246
1283
|
tool_progress: hasOwn(inst, "tool_progress") ? inst.tool_progress : null,
|
|
1284
|
+
cross_instance_visibility: visibilityBaseline,
|
|
1247
1285
|
reply_completion_guard: hasOwn(inst, "reply_completion_guard") ? inst.reply_completion_guard : null,
|
|
1248
1286
|
log_level: hasOwn(inst, "log_level") ? inst.log_level : null,
|
|
1249
1287
|
lightweight: hasOwn(inst, "lightweight") ? inst.lightweight : null,
|
|
@@ -1281,6 +1319,7 @@
|
|
|
1281
1319
|
el("div", {}, el("label", {}, t("agentMode"), impact("instance.agent_mode")), agentMode.row),
|
|
1282
1320
|
el("div", {}, el("label", {}, t("toolSet"), impact("instance.tool_set")), toolSet.row),
|
|
1283
1321
|
el("div", {}, el("label", {}, t("toolProgress"), impact("instance.tool_progress")), toolProgress.row),
|
|
1322
|
+
el("div", {}, el("label", {}, t("crossInstanceVisibility"), impact("instance.cross_instance_visibility")), visibility.row, el("div", { class: "hint" }, t("crossInstanceVisibilityHint"))),
|
|
1284
1323
|
el("div", {}, el("label", {}, t("replyCompletionGuard"), impact("instance.reply_completion_guard")), replyGuard.row, replyHint),
|
|
1285
1324
|
el("div", {}, el("label", {}, t("logLevel"), impact("instance.log_level")), logLevel.row),
|
|
1286
1325
|
el("div", {}, el("label", {}, t("lightweight"), impact("instance.lightweight")), lightweight.row),
|
|
@@ -1306,7 +1345,7 @@
|
|
|
1306
1345
|
"instance.display_name", "instance.description", "instance.backend",
|
|
1307
1346
|
"instance.model", "instance.working_directory", "instance.auto_pause_after",
|
|
1308
1347
|
"instance.topic_id", "instance.hang_detector", "instance.agent_mode",
|
|
1309
|
-
"instance.tool_set", "instance.tool_progress",
|
|
1348
|
+
"instance.tool_set", "instance.tool_progress", "instance.cross_instance_visibility",
|
|
1310
1349
|
"instance.reply_completion_guard", "instance.log_level",
|
|
1311
1350
|
"instance.lightweight", "instance.model_failover", "instance.systemPrompt",
|
|
1312
1351
|
"instance.tags", "instance.general_topic", "instance.status_emojis",
|
|
@@ -1650,7 +1689,7 @@
|
|
|
1650
1689
|
const inheritedToolProgress = classicDefaults.tool_progress ?? fleetDefaults.tool_progress ?? "off";
|
|
1651
1690
|
const inheritedReplyGuard = classicDefaults.reply_completion_guard ?? fleetDefaults.reply_completion_guard ?? true;
|
|
1652
1691
|
const runtime = classicRuntime(c.instanceName);
|
|
1653
|
-
const fBackend =
|
|
1692
|
+
const fBackend = backendSelect(c.backend || inheritedBackend);
|
|
1654
1693
|
const fModel = el("input", { type: "text", value: c.model || "", placeholder: inheritedModel || "(inherit default)" });
|
|
1655
1694
|
const auto = overrideControl(c, "auto_pause_after", el("input", { type: "number", min: "0", step: "1", value: c.auto_pause_after ?? inheritedAutoPause, placeholder: "0 = disabled" }), inheritedAutoPause, "classic.auto_pause_after");
|
|
1656
1695
|
const toolProgress = overrideControl(c, "tool_progress", select(c.tool_progress ?? inheritedToolProgress, ["off", "standard", "verbose"]), inheritedToolProgress, "classic.tool_progress");
|
|
@@ -1836,25 +1875,25 @@
|
|
|
1836
1875
|
const allowedUsers = [...(originalPrimaryAccess.allowed_users || [])];
|
|
1837
1876
|
c.admin_users = c.admin_users || []; c.allowed_guilds = c.allowed_guilds || [];
|
|
1838
1877
|
|
|
1839
|
-
const fBackend =
|
|
1840
|
-
const fClassicBackend =
|
|
1878
|
+
const fBackend = backendSelect(d.backend || "claude-code");
|
|
1879
|
+
const fClassicBackend = backendSelect(c.backend || d.backend || "claude-code");
|
|
1841
1880
|
const fModel = el("input", { type: "text", value: d.model || "", placeholder: "e.g. claude-opus-4-8" });
|
|
1842
1881
|
const fAgentMode = select(d.agent_mode || "mcp", ["mcp", "cli"]);
|
|
1843
1882
|
const fToolSet = select(d.tool_set || "full", ["full", "standard", "minimal"]);
|
|
1844
1883
|
const fToolProgress = select(d.tool_progress ?? "off", ["off", "standard", "verbose"]);
|
|
1884
|
+
const fVisibility = select(visibilityDefault(d), VISIBILITY_MODES);
|
|
1845
1885
|
const fReplyGuard = el("input", { type: "checkbox" }); fReplyGuard.checked = d.reply_completion_guard ?? true;
|
|
1846
1886
|
const fClassicToolProgress = overrideControl(c, "tool_progress", select(c.tool_progress ?? d.tool_progress ?? "off", ["off", "standard", "verbose"]), d.tool_progress ?? "off", "classic_defaults.tool_progress");
|
|
1847
1887
|
const fClassicReplyInput = el("input", { type: "checkbox" }); fClassicReplyInput.checked = c.reply_completion_guard ?? d.reply_completion_guard ?? true;
|
|
1848
1888
|
const fClassicReplyGuard = overrideControl(c, "reply_completion_guard", fClassicReplyInput, d.reply_completion_guard ?? true, "classic_defaults.reply_completion_guard");
|
|
1849
1889
|
const fAccessMode = select(originalPrimaryAccess.mode || "locked", ["locked", "open", "pairing"]);
|
|
1850
1890
|
const fLogLevel = select(d.log_level || "info", ["trace", "debug", "info", "warn", "error"]);
|
|
1851
|
-
const fLocale =
|
|
1891
|
+
const fLocale = localeSelect(d.locale || "");
|
|
1852
1892
|
const fAutoPause = el("input", { type: "number", min: "0", step: "1", value: d.auto_pause_after ?? 0, placeholder: "0 = disabled" });
|
|
1853
1893
|
const fHangEnabled = el("input", { type: "checkbox" }); fHangEnabled.checked = hang.enabled !== false;
|
|
1854
1894
|
const fHangTimeout = el("input", { type: "number", min: "0.1", step: "0.5", value: hang.timeout_minutes ?? 15 });
|
|
1855
1895
|
const fConcurrency = el("input", { type: "number", min: "1", max: "20", step: "1", value: startup.concurrency ?? 10 });
|
|
1856
1896
|
const fStagger = el("input", { type: "number", min: "0", max: "30000", step: "100", value: startup.stagger_delay_ms ?? 500 });
|
|
1857
|
-
[["en", "English"], ["zh-TW", "繁體中文 (zh-TW)"]].forEach(([v, lbl]) => { const o = el("option", {}, lbl); o.value = v; if ((d.locale || "") === v) o.selected = true; fLocale.append(o); });
|
|
1858
1897
|
const msg = el("span", { class: "msg" });
|
|
1859
1898
|
const autoFeedback = el("div", { class: "feedback" });
|
|
1860
1899
|
const hangFeedback = el("div", { class: "feedback" });
|
|
@@ -1894,11 +1933,12 @@
|
|
|
1894
1933
|
const nextDefaults = {
|
|
1895
1934
|
backend: fBackend.value,
|
|
1896
1935
|
model: fModel.value || undefined,
|
|
1897
|
-
locale: fLocale.value,
|
|
1936
|
+
locale: fLocale.value || null,
|
|
1898
1937
|
auto_pause_after: Number(fAutoPause.value),
|
|
1899
1938
|
agent_mode: fAgentMode.value,
|
|
1900
1939
|
tool_set: fToolSet.value,
|
|
1901
1940
|
tool_progress: fToolProgress.value,
|
|
1941
|
+
cross_instance_visibility: fVisibility.value,
|
|
1902
1942
|
reply_completion_guard: fReplyGuard.checked,
|
|
1903
1943
|
log_level: fLogLevel.value,
|
|
1904
1944
|
hang_detector: { enabled: fHangEnabled.checked, timeout_minutes: Number(fHangTimeout.value) },
|
|
@@ -1907,11 +1947,12 @@
|
|
|
1907
1947
|
const defaultsPatch = changedFields(nextDefaults, {
|
|
1908
1948
|
backend: d.backend || "claude-code",
|
|
1909
1949
|
model: d.model || undefined,
|
|
1910
|
-
locale: d.locale ||
|
|
1950
|
+
locale: d.locale || null,
|
|
1911
1951
|
auto_pause_after: d.auto_pause_after ?? 0,
|
|
1912
1952
|
agent_mode: d.agent_mode || "mcp",
|
|
1913
1953
|
tool_set: d.tool_set || "full",
|
|
1914
1954
|
tool_progress: d.tool_progress ?? "off",
|
|
1955
|
+
cross_instance_visibility: visibilityDefault(d),
|
|
1915
1956
|
reply_completion_guard: d.reply_completion_guard ?? true,
|
|
1916
1957
|
log_level: d.log_level || "info",
|
|
1917
1958
|
hang_detector: { enabled: hang.enabled !== false, timeout_minutes: hang.timeout_minutes ?? 15 },
|
|
@@ -1959,6 +2000,7 @@
|
|
|
1959
2000
|
el("div", { class: "field" }, el("label", {}, t("defaultModel"), impact("defaults.model")), fModel),
|
|
1960
2001
|
el("div", { class: "field" }, el("label", {}, `${t("autoPause")} (${t("minutes")})`, impact("defaults.auto_pause_after")), fAutoPause, autoFeedback),
|
|
1961
2002
|
el("div", { class: "field" }, el("label", {}, t("toolProgress"), impact("defaults.tool_progress")), fToolProgress),
|
|
2003
|
+
el("div", { class: "field" }, el("label", {}, t("crossInstanceVisibility"), impact("defaults.cross_instance_visibility")), fVisibility, el("div", { class: "hint" }, t("crossInstanceVisibilityHint"))),
|
|
1962
2004
|
el("div", { class: "field" }, el("label", { style: "display:flex;align-items:center;gap:8px" }, fReplyGuard, el("span", {}, t("replyCompletionGuard")), impact("defaults.reply_completion_guard")), defaultReplyHint))),
|
|
1963
2005
|
section("ClassicBot", true,
|
|
1964
2006
|
el("div", { class: "grid2" },
|
package/dist/ui/view.html
CHANGED
|
@@ -159,7 +159,6 @@
|
|
|
159
159
|
/* Neutral note (subscription plan, or "sign-in needed") — deliberately not the
|
|
160
160
|
amber error colour, since neither state is a failure. */
|
|
161
161
|
.u-note { color: var(--dim); font-size: 13px; margin: 8px 0; }
|
|
162
|
-
.u-next { font-size: 13px; font-weight: 600; margin: 4px 0 10px; line-height: 1.5; }
|
|
163
162
|
.u-foot { color: var(--dim); font-size: 11px; margin-top: 14px; display: flex; gap: 8px; align-items: baseline; }
|
|
164
163
|
.u-foot button { background: none; border: 1px solid var(--border); border-radius: 5px; color: var(--dim); cursor: pointer; font-size: 11px; padding: 2px 8px; }
|
|
165
164
|
.u-foot button:hover { color: var(--fg); border-color: var(--accent); }
|
|
@@ -252,7 +251,7 @@
|
|
|
252
251
|
usageResets: "resets in {t}", usageSoon: "resets soon", usageFail: "Could not load usage data.",
|
|
253
252
|
"usage.title": "AI Subscription Usage", "usage.title_plain": "AI subscription usage", "usage.empty_active": "No active backends with usage tracking",
|
|
254
253
|
"usage.not_logged_in": "not logged in", "usage.error_fallback": "error", "usage.no_data": "no data",
|
|
255
|
-
"usage.reset.in": "resets in {0}", "usage.reset.soon": "resets soon", "usage.
|
|
254
|
+
"usage.reset.in": "resets in {0}", "usage.reset.soon": "resets soon", "usage.ticket_expiry": "🎫 Nearest expiry: {0} (in {1})",
|
|
256
255
|
"usage.duration.days_hours": "{0}d {1}h", "usage.duration.hours_minutes": "{0}h {1}m", "usage.duration.minutes": "{0}m",
|
|
257
256
|
"usage.metric.session": "Session", "usage.metric.weekly": "Weekly", "usage.metric.monthly": "Monthly",
|
|
258
257
|
"usage.metric.days_window": "{0}-day window", "usage.metric.named": "{0}",
|
|
@@ -316,7 +315,7 @@
|
|
|
316
315
|
usageResets: "{t}後重置", usageSoon: "即將重置", usageFail: "無法載入用量資料。",
|
|
317
316
|
"usage.title": "AI 訂閱用量", "usage.title_plain": "AI 訂閱用量", "usage.empty_active": "沒有使用中且支援用量追蹤的 Backend",
|
|
318
317
|
"usage.not_logged_in": "未登入", "usage.error_fallback": "錯誤", "usage.no_data": "無資料",
|
|
319
|
-
"usage.reset.in": "{0} 後重置", "usage.reset.soon": "即將重置", "usage.
|
|
318
|
+
"usage.reset.in": "{0} 後重置", "usage.reset.soon": "即將重置", "usage.ticket_expiry": "🎫 最近過期:{0}({1} 後)",
|
|
320
319
|
"usage.duration.days_hours": "{0}d{1}h", "usage.duration.hours_minutes": "{0}h{1}m", "usage.duration.minutes": "{0}m",
|
|
321
320
|
"usage.metric.session": "Session", "usage.metric.weekly": "每週", "usage.metric.monthly": "每月",
|
|
322
321
|
"usage.metric.days_window": "{0} 天視窗", "usage.metric.named": "{0}",
|
|
@@ -1002,6 +1001,18 @@
|
|
|
1002
1001
|
const ms = new Date(iso).getTime() - Date.now();
|
|
1003
1002
|
if (isNaN(ms)) return "";
|
|
1004
1003
|
if (ms <= 0) return T("usage.reset.soon");
|
|
1004
|
+
return usageLocalized("", { key: "usage.reset.in", args: [usageDuration(ms)] });
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// #1244: "🎫 Nearest expiry: 10/22 (in 15d 4h)" — when the soonest reset ticket expires. An expiry, not a reset.
|
|
1008
|
+
function usageExpiryText(iso) {
|
|
1009
|
+
if (!iso) return "";
|
|
1010
|
+
const at = new Date(iso), ms = at.getTime() - Date.now();
|
|
1011
|
+
if (!(ms > 0)) return "";
|
|
1012
|
+
return usageLocalized("", { key: "usage.ticket_expiry", args: [`${at.getMonth() + 1}/${at.getDate()}`, usageDuration(ms)] });
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
function usageDuration(ms) {
|
|
1005
1016
|
const totalMinutes = Math.max(1, Math.ceil(ms / 60000));
|
|
1006
1017
|
const d = Math.floor(totalMinutes / 1440), h = Math.floor((totalMinutes % 1440) / 60), m = totalMinutes % 60;
|
|
1007
1018
|
const duration = totalMinutes >= 2880
|
|
@@ -1009,7 +1020,7 @@
|
|
|
1009
1020
|
: totalMinutes >= 60
|
|
1010
1021
|
? usageLocalized("", { key: "usage.duration.hours_minutes", args: [Math.floor(totalMinutes / 60), m] })
|
|
1011
1022
|
: usageLocalized("", { key: "usage.duration.minutes", args: [totalMinutes] });
|
|
1012
|
-
return
|
|
1023
|
+
return duration;
|
|
1013
1024
|
}
|
|
1014
1025
|
|
|
1015
1026
|
function usageLocalized(fallback, ref) {
|
|
@@ -1040,8 +1051,9 @@
|
|
|
1040
1051
|
const value = usageLocalized(m.value ?? "", m.valueI18n);
|
|
1041
1052
|
const unit = usageLocalized(m.unit ?? "", m.unitI18n);
|
|
1042
1053
|
const val = `${value} ${unit}`.trim();
|
|
1054
|
+
const sub = [note, usageExpiryText(m.expiresAt)].filter(Boolean).join(" · ");
|
|
1043
1055
|
return `<div class="u-metric"><div class="u-row"><span class="u-label">${esc(label)}</span><span class="u-val">${esc(val)}</span></div>` +
|
|
1044
|
-
(
|
|
1056
|
+
(sub ? `<div class="u-sub">${esc(sub)}</div>` : "") + `</div>`;
|
|
1045
1057
|
}
|
|
1046
1058
|
|
|
1047
1059
|
const USAGE_ICON = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M2.5 13.5h11"/><path d="M4.5 11V8"/><path d="M8 11V4.5"/><path d="M11.5 11V6.5"/></svg>';
|
|
@@ -1051,11 +1063,6 @@
|
|
|
1051
1063
|
let html = `<h3>${USAGE_ICON}${T("usage.title")}</h3>`;
|
|
1052
1064
|
const providers = orderedUsageProviders(usageData.providers);
|
|
1053
1065
|
if (!providers.length) html += `<div class="u-err">${T("usage.empty_active")}</div>`;
|
|
1054
|
-
// #1232: each backend's soonest reset, in one line at the top — "⏳ Next reset · Claude resets in 5h 12m · Codex …".
|
|
1055
|
-
const nextResets = providers
|
|
1056
|
-
.filter(p => p.status === "ok" && p.nextResetAt && new Date(p.nextResetAt).getTime() > Date.now())
|
|
1057
|
-
.map(p => `${esc(p.name)} ${esc(usageResetText(p.nextResetAt))}`);
|
|
1058
|
-
if (nextResets.length) html += `<div class="u-next">${esc(T("usage.next_resets"))} · ${nextResets.join(" · ")}</div>`;
|
|
1059
1066
|
for (let index = 0; index < providers.length; index++) {
|
|
1060
1067
|
const p = providers[index];
|
|
1061
1068
|
const key = providerKey(p);
|
|
@@ -9,7 +9,7 @@ body { display: flex; flex-direction: column; }
|
|
|
9
9
|
#gate input { flex: 1; font: 16px ui-monospace, monospace; letter-spacing: 1px; padding: 8px; background: #000; color: #fff; border: 1px solid #555; border-radius: 4px; }
|
|
10
10
|
#gate button { padding: 8px 16px; background: #246; color: #fff; border: 0; border-radius: 4px; cursor: pointer; }
|
|
11
11
|
#gate-msg { color: #f88; min-height: 1.5em; }
|
|
12
|
-
#term { flex: 1; min-height: 0; padding: 4px; }
|
|
12
|
+
#term { flex: 1; min-height: 0; padding: 4px; overflow: hidden; } /* never drawn over the rows below it (#1242) */
|
|
13
13
|
#code-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 10px; background: #1c1c1c; border-top: 1px solid #333; }
|
|
14
14
|
#code-row[hidden] { display: none; }
|
|
15
15
|
#code-row input { flex: 1; min-width: 12em; font: 16px ui-monospace, monospace; padding: 8px; background: #000; color: #fff; border: 1px solid #555; border-radius: 4px; }
|
|
@@ -87,7 +87,11 @@
|
|
|
87
87
|
term.onData(function (s) { send(new TextEncoder().encode(s)); });
|
|
88
88
|
term.onBinary(function (s) { var b = new Uint8Array(s.length); for (var i = 0; i < s.length; i++) b[i] = s.charCodeAt(i) & 255; send(b); });
|
|
89
89
|
term.onResize(function (size) { if (ws && ws.readyState === 1) ws.send(JSON.stringify({ t: "resize", cols: size.cols, rows: size.rows })); });
|
|
90
|
-
|
|
90
|
+
// Re-fit whenever the terminal's box changes, not only when the window does (#1242): the sign-in code row
|
|
91
|
+
// appears after the first fit (on "hello"), and a terminal fitted to the taller box ran under that row and
|
|
92
|
+
// covered it — the code box was not on screen until a zoom change (a window resize) re-fitted it.
|
|
93
|
+
if (typeof ResizeObserver === "function") new ResizeObserver(function () { if (fit) fit.fit(); }).observe(termEl);
|
|
94
|
+
else window.addEventListener("resize", function () { if (fit) fit.fit(); });
|
|
91
95
|
} else {
|
|
92
96
|
term.reset(); // the server replays its buffer on (re)connect
|
|
93
97
|
}
|
package/dist/update-check.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ import { execFileSync } from "node:child_process";
|
|
|
7
7
|
export declare const UPDATE_COMMAND = "agend update";
|
|
8
8
|
export interface UpdateVersionOptions {
|
|
9
9
|
version?: string;
|
|
10
|
+
/** The alpha channel (`@alpha`, the next minor's previews, #1259). */
|
|
11
|
+
alpha?: boolean;
|
|
10
12
|
beta?: boolean;
|
|
11
13
|
/** Back to the stable line (`@latest`), even from a beta install — may go back a version. */
|
|
12
14
|
stable?: boolean;
|
|
@@ -23,19 +25,26 @@ export declare function isPrereleaseVersion(version: string): boolean;
|
|
|
23
25
|
* below alphanumeric ones, which compare in ASCII order.
|
|
24
26
|
*/
|
|
25
27
|
export declare function compareSemver(a: string, b: string): number | null;
|
|
28
|
+
export type UpdateChannel = "latest" | "beta" | "alpha";
|
|
29
|
+
/**
|
|
30
|
+
* The npm dist-tag an install follows (#1259): an alpha (`x.y.z-alpha.N`) is on
|
|
31
|
+
* `@alpha`, any other prerelease (beta, rc…) on `@beta`, a release on `@latest`.
|
|
32
|
+
* Mirrors what publish.yml publishes each tag to (scripts/npm-dist-tag.mjs).
|
|
33
|
+
*/
|
|
34
|
+
export declare function installedChannel(version: string): UpdateChannel;
|
|
26
35
|
/**
|
|
27
36
|
* The npm selector `agend update` installs from. An explicit choice wins
|
|
28
|
-
* (`--version`, then `--beta`,
|
|
29
|
-
* installed version is on —
|
|
30
|
-
*
|
|
37
|
+
* (`--version`, then `--alpha`, `--beta`, `--stable`); with none, the line the
|
|
38
|
+
* installed version is on — an alpha stays on `@alpha`, a beta on `@beta`, so
|
|
39
|
+
* nobody is moved to another channel without asking. `installedVersion` is the
|
|
31
40
|
* version of the package being replaced (the CLI's own package.json), never
|
|
32
41
|
* the version of whatever code happened to call it.
|
|
33
42
|
*/
|
|
34
43
|
export declare function getUpdateSelector(opts: UpdateVersionOptions, installedVersion: string): string;
|
|
35
44
|
/**
|
|
36
|
-
* Which "update available" line to post. A beta install's `/update`
|
|
37
|
-
*
|
|
38
|
-
* than "Run: /update", which would not move it there.
|
|
45
|
+
* Which "update available" line to post. A beta or alpha install's `/update`
|
|
46
|
+
* stays on its channel, so a newer STABLE release needs `--stable` — say so
|
|
47
|
+
* rather than "Run: /update", which would not move it there.
|
|
39
48
|
*/
|
|
40
49
|
export declare function updateNoticeKey(currentVersion: string, targetVersion: string): "update.available_stable" | "update.available_current";
|
|
41
50
|
/**
|
package/dist/update-check.js
CHANGED
|
@@ -65,27 +65,40 @@ export function compareSemver(a, b) {
|
|
|
65
65
|
}
|
|
66
66
|
return Math.sign(pa.pre.length - pb.pre.length);
|
|
67
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* The npm dist-tag an install follows (#1259): an alpha (`x.y.z-alpha.N`) is on
|
|
70
|
+
* `@alpha`, any other prerelease (beta, rc…) on `@beta`, a release on `@latest`.
|
|
71
|
+
* Mirrors what publish.yml publishes each tag to (scripts/npm-dist-tag.mjs).
|
|
72
|
+
*/
|
|
73
|
+
export function installedChannel(version) {
|
|
74
|
+
const pre = parseSemver(version)?.pre ?? [];
|
|
75
|
+
if (pre.length === 0)
|
|
76
|
+
return "latest";
|
|
77
|
+
return pre[0] === "alpha" ? "alpha" : "beta";
|
|
78
|
+
}
|
|
68
79
|
/**
|
|
69
80
|
* The npm selector `agend update` installs from. An explicit choice wins
|
|
70
|
-
* (`--version`, then `--beta`,
|
|
71
|
-
* installed version is on —
|
|
72
|
-
*
|
|
81
|
+
* (`--version`, then `--alpha`, `--beta`, `--stable`); with none, the line the
|
|
82
|
+
* installed version is on — an alpha stays on `@alpha`, a beta on `@beta`, so
|
|
83
|
+
* nobody is moved to another channel without asking. `installedVersion` is the
|
|
73
84
|
* version of the package being replaced (the CLI's own package.json), never
|
|
74
85
|
* the version of whatever code happened to call it.
|
|
75
86
|
*/
|
|
76
87
|
export function getUpdateSelector(opts, installedVersion) {
|
|
77
88
|
if (opts.version)
|
|
78
89
|
return opts.version;
|
|
90
|
+
if (opts.alpha)
|
|
91
|
+
return "alpha";
|
|
79
92
|
if (opts.beta)
|
|
80
93
|
return "beta";
|
|
81
94
|
if (opts.stable)
|
|
82
95
|
return "latest";
|
|
83
|
-
return
|
|
96
|
+
return installedChannel(installedVersion);
|
|
84
97
|
}
|
|
85
98
|
/**
|
|
86
|
-
* Which "update available" line to post. A beta install's `/update`
|
|
87
|
-
*
|
|
88
|
-
* than "Run: /update", which would not move it there.
|
|
99
|
+
* Which "update available" line to post. A beta or alpha install's `/update`
|
|
100
|
+
* stays on its channel, so a newer STABLE release needs `--stable` — say so
|
|
101
|
+
* rather than "Run: /update", which would not move it there.
|
|
89
102
|
*/
|
|
90
103
|
export function updateNoticeKey(currentVersion, targetVersion) {
|
|
91
104
|
return isPrereleaseVersion(currentVersion) && !isPrereleaseVersion(targetVersion) ? "update.available_stable" : "update.available_current";
|
package/dist/update-check.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAY7C;;;;;GAKG;AACH,MAAM,GAAG,GAAG,iBAAiB,CAAC;AAC9B,MAAM,MAAM,GAAG,MAAM,GAAG,8BAA8B,CAAC;AACvD,MAAM,QAAQ,GAAG,eAAe,CAAC;AACjC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,MAAM,SAAS,MAAM,cAAc,QAAQ,SAAS,QAAQ,OAAO,CAAC,CAAC;AAIxI,SAAS,WAAW,CAAC,OAAe;IAClC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACxE,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;AACvC,CAAC;AAED,oHAAoH;AACpH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,mGAAmG;AACnG,SAAS,cAAc,CAAC,CAAS,EAAE,CAAS;IAC1C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,CAAS;IAChD,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IAChC,CAAC;IACD,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAChG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAChE,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC;YAAE,SAAS;QACtB,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjD,IAAI,EAAE,IAAI,EAAE;YAAE,OAAO,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1C,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAClD,CAAC;AAID;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;IAC5C,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACtC,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA0B,EAAE,gBAAwB;IACpF,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC;IACtC,IAAI,IAAI,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC;IAC/B,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IAC7B,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IACjC,OAAO,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,cAAsB,EAAE,aAAqB;IAC3E,OAAO,mBAAmB,CAAC,cAAc,CAAC,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,0BAA0B,CAAC;AAC7I,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,gBAAwB,EAAE,aAA4B,EAAE,IAA0B;IACvH,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACtF,MAAM,KAAK,GAAG,aAAa,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;IAC7D,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,MAA2B,YAAY;IAEvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,GAAG,CAChB,KAAK,EACL,CAAC,MAAM,EAAE,kBAAkB,QAAQ,EAAE,EAAE,SAAS,CAAC,EACjD;YACE,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;YACnC,OAAO,EAAE,MAAM;SAChB,CACF,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,OAAO,OAAO,IAAI,IAAI,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,cAAsB,EACtB,aAA4B,EAC5B,KAAK,GAAG,KAAK;IAEb,OAAO,CAAC,KAAK;WACR,aAAa,KAAK,IAAI;WACtB,gBAAgB,CAAC,cAAc,CAAC,KAAK,gBAAgB,CAAC,aAAa,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAW3C;IACC,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5E,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,OAAO,GAAG,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC;AACjE,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,MAAkC,IAAI,CAAC,EAAE,CACnF,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAE5J,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9D,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAOD,gFAAgF;AAChF,MAAM,UAAU,mBAAmB,CACjC,MAAqB,EACrB,SAAuB,OAAO;IAE9B,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACjE,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACnC,MAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACjD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isVisibleUsageMetric } from "./usage-api.js";
|
|
2
2
|
import { t } from "../locale.js";
|
|
3
|
-
import {
|
|
3
|
+
import { usageExpiryText, usageResetText, usageText } from "./i18n.js";
|
|
4
4
|
const BAR_WIDTH = 10;
|
|
5
5
|
/** `████░░░░░░` for 40%. Clamped — a vendor "105% used" must not overflow. */
|
|
6
6
|
export function usageBar(percent) {
|
|
@@ -48,7 +48,8 @@ function metricLine(m) {
|
|
|
48
48
|
}
|
|
49
49
|
case "count": {
|
|
50
50
|
const unit = m.unit ? usageText(m.unit, m.unitI18n) : "";
|
|
51
|
-
|
|
51
|
+
const expiry = usageExpiryText(m.expiresAt);
|
|
52
|
+
return { bar: null, text: `${label}: ${m.value ?? "?"}${unit ? ` ${unit}` : ""}${note ? ` (${note})` : ""}${expiry ? ` · ${expiry}` : ""}` };
|
|
52
53
|
}
|
|
53
54
|
case "text": {
|
|
54
55
|
const value = m.value != null ? usageText(String(m.value), m.valueI18n) : null;
|
|
@@ -68,7 +69,6 @@ function toBlocks(payload) {
|
|
|
68
69
|
: p.status === "error" ? `⚠️ ${usageText(p.error ?? t("usage.error_fallback"), p.errorI18n)}`
|
|
69
70
|
: null,
|
|
70
71
|
okHint: p.status === "ok" && p.hint ? usageText(p.hint, p.hintI18n) : null,
|
|
71
|
-
nextReset: p.status === "ok" ? usageNextResetText(p.nextResetAt) || null : null,
|
|
72
72
|
lines: p.status === "ok"
|
|
73
73
|
? p.metrics.filter(isVisibleUsageMetric).map(metricLine).filter((l) => l !== null)
|
|
74
74
|
: [],
|
|
@@ -83,8 +83,6 @@ export function renderUsageMarkdown(payload) {
|
|
|
83
83
|
out.push(`> ${b.note}`);
|
|
84
84
|
continue;
|
|
85
85
|
}
|
|
86
|
-
if (b.nextReset)
|
|
87
|
-
out.push(b.nextReset);
|
|
88
86
|
if (b.lines.length === 0) {
|
|
89
87
|
out.push(b.okHint ? `> ${b.okHint}` : `> ${t("usage.no_data")}`);
|
|
90
88
|
continue;
|
|
@@ -113,8 +111,6 @@ export function renderUsageHtml(payload) {
|
|
|
113
111
|
out.push(escapeHtml(b.note));
|
|
114
112
|
continue;
|
|
115
113
|
}
|
|
116
|
-
if (b.nextReset)
|
|
117
|
-
out.push(escapeHtml(b.nextReset));
|
|
118
114
|
if (b.lines.length === 0) {
|
|
119
115
|
out.push(b.okHint ? escapeHtml(b.okHint) : escapeHtml(t("usage.no_data")));
|
|
120
116
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-rich.js","sourceRoot":"","sources":["../../src/usage/format-rich.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,oBAAoB,EAAqB,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACjC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"format-rich.js","sourceRoot":"","sources":["../../src/usage/format-rich.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* Keep this list explicit: the parity test rejects a key missing from either
|
|
4
4
|
* locale surface before a mixed-language release can ship.
|
|
5
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.value.unlimited", "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"];
|
|
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.ticket_expiry", "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.value.unlimited", "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
7
|
export type UsageI18nKey = typeof USAGE_I18N_KEYS[number];
|
package/dist/usage/i18n-keys.js
CHANGED
|
@@ -10,7 +10,7 @@ export const USAGE_I18N_KEYS = [
|
|
|
10
10
|
"usage.metric.session", "usage.metric.weekly", "usage.metric.monthly", "usage.metric.days_window",
|
|
11
11
|
"usage.metric.named", "usage.metric.named_session", "usage.metric.named_weekly",
|
|
12
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",
|
|
13
|
+
"usage.metric.rate_limit_resets", "usage.ticket_expiry", "usage.metric.credits", "usage.metric.weekly_limit",
|
|
14
14
|
"usage.metric.pay_as_you_go", "usage.metric.bonus_credits", "usage.metric.overage_charges",
|
|
15
15
|
"usage.metric.pay_per_use", "usage.unit.available", "usage.unit.credits",
|
|
16
16
|
"usage.metric.usage_monthly", "usage.note.used_limit_unit", "usage.note.bonus_codes",
|
|
@@ -1 +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;
|
|
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,qBAAqB,EAAE,sBAAsB,EAAE,2BAA2B;IAC5G,4BAA4B,EAAE,4BAA4B,EAAE,8BAA8B;IAC1F,0BAA0B,EAAE,sBAAsB,EAAE,oBAAoB;IACxE,4BAA4B,EAAE,4BAA4B,EAAE,wBAAwB;IACpF,sBAAsB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,oBAAoB;IACxF,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"}
|
package/dist/usage/i18n.d.ts
CHANGED
|
@@ -3,5 +3,8 @@ import type { UsageI18nRef } from "./providers.js";
|
|
|
3
3
|
export declare function usageText(fallback: string, ref?: UsageI18nRef): string;
|
|
4
4
|
/** Minute-precision duration shared by the chat and MCP usage renderers. */
|
|
5
5
|
export declare function usageResetText(resetsAt?: string | null): string;
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* "🎫 Nearest expiry: 10/22 (in 15d 4h)" — when the soonest of a metric's tickets expires (#1244); "" when none is
|
|
8
|
+
* still ahead. An expiry, never a reset: the ticket is gone, nothing refills.
|
|
9
|
+
*/
|
|
10
|
+
export declare function usageExpiryText(expiresAt?: string | null): string;
|