@songsid/agend 2.1.1-beta.11 → 2.1.1-beta.13
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/dist/backend/antigravity.js +5 -2
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.js +3 -0
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex.d.ts +16 -0
- package/dist/backend/codex.js +248 -56
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/grok.js +20 -0
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro.js +18 -2
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +7 -0
- package/dist/backend/types.js +1 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.js +4 -5
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.js +50 -15
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/ipc-bridge.d.ts +8 -0
- package/dist/channel/ipc-bridge.js +41 -14
- package/dist/channel/ipc-bridge.js.map +1 -1
- package/dist/channel/mcp-server.js +25 -10
- package/dist/channel/mcp-server.js.map +1 -1
- package/dist/channel/mcp-tools.js +25 -0
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/message-queue.d.ts +1 -0
- package/dist/channel/message-queue.js +49 -17
- package/dist/channel/message-queue.js.map +1 -1
- package/dist/channel/reconnect-backoff.d.ts +17 -0
- package/dist/channel/reconnect-backoff.js +21 -0
- package/dist/channel/reconnect-backoff.js.map +1 -0
- package/dist/cli.js +71 -26
- package/dist/cli.js.map +1 -1
- package/dist/completion.d.ts +27 -0
- package/dist/completion.js +121 -0
- package/dist/completion.js.map +1 -0
- package/dist/config-validator.js +9 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +74 -8
- package/dist/daemon.js +254 -18
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +7 -1
- package/dist/fleet-manager.js +89 -16
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +22 -0
- package/dist/general-knowledge/skills/model-discovery/SKILL.md +14 -23
- package/dist/general-knowledge/skills/session-management/SKILL.md +15 -34
- package/dist/instance-lifecycle.d.ts +13 -1
- package/dist/instance-lifecycle.js +70 -3
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +5 -0
- package/dist/instructions.js +9 -11
- package/dist/instructions.js.map +1 -1
- package/dist/logger.js +14 -0
- package/dist/logger.js.map +1 -1
- package/dist/mcp-liveness.d.ts +21 -0
- package/dist/mcp-liveness.js +27 -0
- package/dist/mcp-liveness.js.map +1 -0
- package/dist/outbound-handlers.d.ts +9 -0
- package/dist/outbound-handlers.js +46 -26
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.js +1 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/tmux-control.js +4 -2
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.d.ts +14 -0
- package/dist/tmux-manager.js +20 -6
- package/dist/tmux-manager.js.map +1 -1
- package/dist/topic-commands.d.ts +22 -1
- package/dist/topic-commands.js +95 -57
- package/dist/topic-commands.js.map +1 -1
- package/dist/tui-glyphs.d.ts +25 -0
- package/dist/tui-glyphs.js +26 -0
- package/dist/tui-glyphs.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/ui/view.html +114 -2
- package/dist/usage/providers.d.ts +26 -0
- package/dist/usage/providers.js +577 -0
- package/dist/usage/providers.js.map +1 -0
- package/dist/usage/usage-api.d.ts +35 -0
- package/dist/usage/usage-api.js +52 -0
- package/dist/usage/usage-api.js.map +1 -0
- package/dist/view-api.d.ts +3 -0
- package/dist/view-api.js +10 -2
- package/dist/view-api.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/view.html
CHANGED
|
@@ -83,6 +83,27 @@
|
|
|
83
83
|
.help-panel li { font-size: 13px; margin: 6px 0; color: var(--fg); }
|
|
84
84
|
.help-panel .close { position: absolute; top: 14px; right: 16px; cursor: pointer; color: var(--dim); font-size: 22px; line-height: 1; background: none; border: none; }
|
|
85
85
|
|
|
86
|
+
/* AI usage panel (shares .help-panel chrome) */
|
|
87
|
+
.u-provider { margin: 14px 0 4px; padding-top: 10px; border-top: 1px solid var(--border); }
|
|
88
|
+
.u-provider:first-of-type { border-top: none; padding-top: 0; }
|
|
89
|
+
.u-head { display: flex; align-items: baseline; gap: 8px; }
|
|
90
|
+
.u-head .u-name { font-size: 14px; font-weight: 600; }
|
|
91
|
+
.u-head .u-plan { color: var(--dim); font-size: 11px; }
|
|
92
|
+
.u-metric { margin: 8px 0; }
|
|
93
|
+
.u-row { display: flex; align-items: baseline; gap: 6px; font-size: 12px; }
|
|
94
|
+
.u-row .u-label { color: var(--dim); flex: 1; min-width: 0; }
|
|
95
|
+
.u-row .u-val { font-variant-numeric: tabular-nums; }
|
|
96
|
+
.u-row .u-status { font-size: 11px; font-weight: 600; }
|
|
97
|
+
.u-status.warn { color: #d29922; } .u-status.crit { color: #f85149; }
|
|
98
|
+
.u-meter { height: 6px; background: var(--border); border-radius: 3px; overflow: hidden; margin-top: 4px; }
|
|
99
|
+
.u-fill { height: 100%; border-radius: 3px; background: var(--accent); min-width: 2px; }
|
|
100
|
+
.u-fill.warn { background: #d29922; } .u-fill.crit { background: #f85149; }
|
|
101
|
+
.u-sub { color: var(--dim); font-size: 11px; margin-top: 2px; font-variant-numeric: tabular-nums; }
|
|
102
|
+
.u-err { color: #d29922; font-size: 12px; margin: 6px 0; }
|
|
103
|
+
.u-foot { color: var(--dim); font-size: 11px; margin-top: 14px; display: flex; gap: 8px; align-items: baseline; }
|
|
104
|
+
.u-foot button { background: none; border: 1px solid var(--border); border-radius: 5px; color: var(--dim); cursor: pointer; font-size: 11px; padding: 2px 8px; }
|
|
105
|
+
.u-foot button:hover { color: var(--fg); border-color: var(--accent); }
|
|
106
|
+
|
|
86
107
|
#densityBtn { font-size: 14px; font-weight: 600; letter-spacing: -.5px; }
|
|
87
108
|
@media (max-width: 700px) {
|
|
88
109
|
#sidebar { width: 180px; flex-basis: 180px; }
|
|
@@ -93,6 +114,7 @@
|
|
|
93
114
|
</style>
|
|
94
115
|
</head>
|
|
95
116
|
<body>
|
|
117
|
+
<button class="help-btn" id="usageBtn" title="AI usage" style="right:140px; display:none">📊</button>
|
|
96
118
|
<button class="help-btn" id="densityBtn" title="Font density" style="right:98px">⤢</button>
|
|
97
119
|
<button class="help-btn" id="langBtn" title="Language" style="right:56px">🌐</button>
|
|
98
120
|
<button class="help-btn" id="helpBtn" title="Help">ℹ️</button>
|
|
@@ -101,6 +123,10 @@
|
|
|
101
123
|
<button class="close" id="helpClose" title="Close">×</button>
|
|
102
124
|
<div id="helpContent"></div>
|
|
103
125
|
</aside>
|
|
126
|
+
<aside class="help-panel" id="usagePanel">
|
|
127
|
+
<button class="close" id="usageClose" title="Close">×</button>
|
|
128
|
+
<div id="usageContent"></div>
|
|
129
|
+
</aside>
|
|
104
130
|
<div id="sidebar"><h1 data-i18n="viewTitle">AgEnD · View</h1><div id="list"></div></div>
|
|
105
131
|
<div id="main">
|
|
106
132
|
<div id="term"><pre id="pre"></pre></div>
|
|
@@ -147,7 +173,10 @@
|
|
|
147
173
|
help2: "Click a group header ▼/▶ to collapse/expand", help3: "✏️ Edit changes display name, role, description",
|
|
148
174
|
help4: "Drag to reorder (needs web.token permission)",
|
|
149
175
|
help5: "Click ⤢ to cycle font density: Fit → Comfortable → Compact",
|
|
150
|
-
densityFit: "Fit", densityComfortable: "Comfortable", densityCompact: "Compact", densityLabel: "Font density"
|
|
176
|
+
densityFit: "Fit", densityComfortable: "Comfortable", densityCompact: "Compact", densityLabel: "Font density",
|
|
177
|
+
usageTitle: "📊 AI Usage", usageEmpty: "No AI CLI logins found on this machine.",
|
|
178
|
+
usageUpdated: "updated", usageRefresh: "Refresh", usageHigh: "high", usageNear: "near limit",
|
|
179
|
+
usageResets: "resets in {t}", usageSoon: "resets soon", usageFail: "Could not load usage data." },
|
|
151
180
|
"zh-TW": { viewTitle: "AgEnD · 檢視", editProfile: "✏️ 編輯", save: "儲存", cancel: "取消",
|
|
152
181
|
displayName: "顯示名稱", role: "角色", description: "描述", tokenPh: "web.token(儲存時需要)",
|
|
153
182
|
saveHint: "檢視為公開(唯讀)。儲存需要 web.token(~/.agend/web.token)。", helpTitle: "📖 使用說明",
|
|
@@ -155,7 +184,10 @@
|
|
|
155
184
|
help2: "點 group header ▼/▶ 收合/展開", help3: "✏️ Edit 可修改顯示名稱、角色、描述",
|
|
156
185
|
help4: "拖曳可調整順序(需 web.token 權限)",
|
|
157
186
|
help5: "點 ⤢ 循環切換字級密度:剛好填滿 → 舒適 → 精簡",
|
|
158
|
-
densityFit: "剛好填滿", densityComfortable: "舒適", densityCompact: "精簡", densityLabel: "字級密度"
|
|
187
|
+
densityFit: "剛好填滿", densityComfortable: "舒適", densityCompact: "精簡", densityLabel: "字級密度",
|
|
188
|
+
usageTitle: "📊 AI 訂閱用量", usageEmpty: "本機沒有偵測到已登入的 AI CLI。",
|
|
189
|
+
usageUpdated: "更新於", usageRefresh: "重新整理", usageHigh: "偏高", usageNear: "接近上限",
|
|
190
|
+
usageResets: "{t} 後重置", usageSoon: "即將重置", usageFail: "無法載入用量資料。" },
|
|
159
191
|
};
|
|
160
192
|
let lang = localStorage.getItem("agend_lang") || (navigator.language && navigator.language.toLowerCase().startsWith("zh") ? "zh-TW" : "en");
|
|
161
193
|
if (!I18N[lang]) lang = "en";
|
|
@@ -667,6 +699,86 @@
|
|
|
667
699
|
q("densityBtn").onclick = cycleDensity;
|
|
668
700
|
window.addEventListener("keydown", (e) => { if (e.key === "Escape") setHelp(false); });
|
|
669
701
|
|
|
702
|
+
// ── AI usage panel ────────────────────────────────────
|
|
703
|
+
let usageData = null;
|
|
704
|
+
let usageTimer = null;
|
|
705
|
+
|
|
706
|
+
function usageResetText(iso) {
|
|
707
|
+
if (!iso) return "";
|
|
708
|
+
const ms = new Date(iso).getTime() - Date.now();
|
|
709
|
+
if (isNaN(ms)) return "";
|
|
710
|
+
if (ms <= 0) return T("usageSoon");
|
|
711
|
+
const h = Math.floor(ms / 3600000), m = Math.floor((ms % 3600000) / 60000);
|
|
712
|
+
const t = h >= 48 ? `${Math.floor(h / 24)}d ${h % 24}h` : h > 0 ? `${h}h ${m}m` : `${m}m`;
|
|
713
|
+
return T("usageResets").replace("{t}", t);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
function usageMetricHtml(m) {
|
|
717
|
+
if (m.type === "percent") {
|
|
718
|
+
const pct = Math.min(100, Math.max(0, m.used ?? 0));
|
|
719
|
+
const cls = pct >= 90 ? "crit" : pct >= 70 ? "warn" : "";
|
|
720
|
+
const word = pct >= 90 ? T("usageNear") : pct >= 70 ? T("usageHigh") : "";
|
|
721
|
+
const sub = [m.note, usageResetText(m.resetsAt)].filter(Boolean).join(" · ");
|
|
722
|
+
return `<div class="u-metric"><div class="u-row"><span class="u-label">${esc(m.label)}</span>` +
|
|
723
|
+
(word ? `<span class="u-status ${cls}">${esc(word)}</span>` : "") +
|
|
724
|
+
`<span class="u-val">${pct.toFixed(0)}%</span></div>` +
|
|
725
|
+
`<div class="u-meter"><div class="u-fill ${cls}" style="width:${pct}%"></div></div>` +
|
|
726
|
+
(sub ? `<div class="u-sub">${esc(sub)}</div>` : "") + `</div>`;
|
|
727
|
+
}
|
|
728
|
+
if (m.type === "dollars") {
|
|
729
|
+
const val = m.limit ? `$${(m.used ?? 0).toFixed(2)} / $${m.limit.toFixed(2)}` : `$${(m.used ?? 0).toFixed(2)}`;
|
|
730
|
+
return `<div class="u-metric"><div class="u-row"><span class="u-label">${esc(m.label)}</span><span class="u-val">${esc(val)}</span></div></div>`;
|
|
731
|
+
}
|
|
732
|
+
const val = `${m.value ?? ""} ${m.unit ?? ""}`.trim();
|
|
733
|
+
return `<div class="u-metric"><div class="u-row"><span class="u-label">${esc(m.label)}</span><span class="u-val">${esc(val)}</span></div>` +
|
|
734
|
+
(m.note ? `<div class="u-sub">${esc(m.note)}</div>` : "") + `</div>`;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
function renderUsage() {
|
|
738
|
+
const box = q("usageContent");
|
|
739
|
+
if (!usageData || !Array.isArray(usageData.providers)) { box.innerHTML = `<h3>${T("usageTitle")}</h3><div class="u-err">${T("usageFail")}</div>`; return; }
|
|
740
|
+
let html = `<h3>${T("usageTitle")}</h3>`;
|
|
741
|
+
if (!usageData.providers.length) html += `<div class="u-err">${T("usageEmpty")}</div>`;
|
|
742
|
+
for (const p of usageData.providers) {
|
|
743
|
+
html += `<div class="u-provider"><div class="u-head"><span class="u-name">${esc(p.name)}</span>` +
|
|
744
|
+
(p.plan ? `<span class="u-plan">${esc(p.plan)}</span>` : "") + `</div>`;
|
|
745
|
+
if (p.status === "error") html += `<div class="u-err">${esc(p.error || "error")}</div>`;
|
|
746
|
+
else html += (p.metrics || []).map(usageMetricHtml).join("");
|
|
747
|
+
html += `</div>`;
|
|
748
|
+
}
|
|
749
|
+
const at = new Date(usageData.fetchedAt).toLocaleTimeString();
|
|
750
|
+
html += `<div class="u-foot"><span>${T("usageUpdated")} ${esc(at)}</span><button id="usageRefresh">${T("usageRefresh")}</button></div>`;
|
|
751
|
+
box.innerHTML = html;
|
|
752
|
+
const rb = q("usageRefresh");
|
|
753
|
+
if (rb) rb.onclick = () => loadUsage(true);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
async function loadUsage(force) {
|
|
757
|
+
try {
|
|
758
|
+
const r = await fetch(`/api/ai-usage${force ? "?force=1" : ""}`);
|
|
759
|
+
if (r.status === 404) { q("usageBtn").style.display = "none"; return false; }
|
|
760
|
+
usageData = await r.json();
|
|
761
|
+
} catch { usageData = null; }
|
|
762
|
+
renderUsage();
|
|
763
|
+
return true;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const setUsage = (open) => {
|
|
767
|
+
q("usagePanel").classList.toggle("open", open);
|
|
768
|
+
q("helpBackdrop").classList.toggle("open", open);
|
|
769
|
+
if (open) { setHelp(false); loadUsage(false); if (!usageTimer) usageTimer = setInterval(() => loadUsage(false), 60_000); }
|
|
770
|
+
else if (usageTimer) { clearInterval(usageTimer); usageTimer = null; }
|
|
771
|
+
};
|
|
772
|
+
q("usageBtn").onclick = () => setUsage(!q("usagePanel").classList.contains("open"));
|
|
773
|
+
q("usageClose").onclick = () => setUsage(false);
|
|
774
|
+
q("helpBackdrop").addEventListener("click", () => setUsage(false));
|
|
775
|
+
q("helpBtn").addEventListener("click", () => setUsage(false));
|
|
776
|
+
window.addEventListener("keydown", (e) => { if (e.key === "Escape") setUsage(false); });
|
|
777
|
+
q("langBtn").addEventListener("click", () => { if (usageData) renderUsage(); });
|
|
778
|
+
// Probe once at boot: shows the 📊 button only when the endpoint is enabled,
|
|
779
|
+
// and warms the server-side 5-minute cache so the first open is instant.
|
|
780
|
+
loadUsage(false).then(ok => { if (ok !== false) q("usageBtn").style.display = ""; });
|
|
781
|
+
|
|
670
782
|
window.addEventListener("resize", scheduleFit);
|
|
671
783
|
// Catches container changes the window resize event doesn't see — chiefly the
|
|
672
784
|
// profile card expanding or collapsing.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface UsageMetric {
|
|
2
|
+
label: string;
|
|
3
|
+
type: "percent" | "dollars" | "count" | "text";
|
|
4
|
+
used?: number;
|
|
5
|
+
limit?: number;
|
|
6
|
+
value?: number | string;
|
|
7
|
+
unit?: string;
|
|
8
|
+
note?: string;
|
|
9
|
+
resetsAt?: string | null;
|
|
10
|
+
windowMs?: number | null;
|
|
11
|
+
}
|
|
12
|
+
export interface ProviderUsage {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
status: "ok" | "error" | "no-credentials";
|
|
16
|
+
plan?: string | null;
|
|
17
|
+
error?: string;
|
|
18
|
+
hint?: string;
|
|
19
|
+
metrics: UsageMetric[];
|
|
20
|
+
}
|
|
21
|
+
/** Fetch every provider in parallel. Providers without local credentials are
|
|
22
|
+
* skipped (per the panel's contract: absent CLIs simply don't show). */
|
|
23
|
+
export declare function fetchAllUsage(): Promise<{
|
|
24
|
+
fetchedAt: string;
|
|
25
|
+
providers: ProviderUsage[];
|
|
26
|
+
}>;
|