@songsid/agend 2.1.2-beta.8 → 2.1.2

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.
Files changed (174) hide show
  1. package/dist/access-path.js +15 -6
  2. package/dist/access-path.js.map +1 -1
  3. package/dist/agent-cli-instructions.md +1 -0
  4. package/dist/agent-cli.js +14 -0
  5. package/dist/agent-cli.js.map +1 -1
  6. package/dist/agent-endpoint.d.ts +2 -0
  7. package/dist/agent-endpoint.js +25 -1
  8. package/dist/agent-endpoint.js.map +1 -1
  9. package/dist/backend/antigravity.d.ts +20 -0
  10. package/dist/backend/antigravity.js +51 -4
  11. package/dist/backend/antigravity.js.map +1 -1
  12. package/dist/backend/claude-code.d.ts +59 -0
  13. package/dist/backend/claude-code.js +67 -1
  14. package/dist/backend/claude-code.js.map +1 -1
  15. package/dist/backend/codex.d.ts +26 -0
  16. package/dist/backend/codex.js +100 -0
  17. package/dist/backend/codex.js.map +1 -1
  18. package/dist/backend/grok.d.ts +25 -0
  19. package/dist/backend/grok.js +51 -0
  20. package/dist/backend/grok.js.map +1 -1
  21. package/dist/backend/kiro.d.ts +23 -0
  22. package/dist/backend/kiro.js +120 -2
  23. package/dist/backend/kiro.js.map +1 -1
  24. package/dist/backend/types.d.ts +58 -0
  25. package/dist/backend/types.js +13 -1
  26. package/dist/backend/types.js.map +1 -1
  27. package/dist/channel/adapters/discord.d.ts +15 -0
  28. package/dist/channel/adapters/discord.js +120 -8
  29. package/dist/channel/adapters/discord.js.map +1 -1
  30. package/dist/channel/adapters/telegram.d.ts +21 -0
  31. package/dist/channel/adapters/telegram.js +86 -0
  32. package/dist/channel/adapters/telegram.js.map +1 -1
  33. package/dist/channel/ipc-bridge.d.ts +9 -1
  34. package/dist/channel/ipc-bridge.js +12 -3
  35. package/dist/channel/ipc-bridge.js.map +1 -1
  36. package/dist/channel/ipc-timeouts.d.ts +46 -0
  37. package/dist/channel/ipc-timeouts.js +65 -0
  38. package/dist/channel/ipc-timeouts.js.map +1 -0
  39. package/dist/channel/mcp-server.js +25 -14
  40. package/dist/channel/mcp-server.js.map +1 -1
  41. package/dist/channel/mcp-tools.js +30 -1
  42. package/dist/channel/mcp-tools.js.map +1 -1
  43. package/dist/channel/reconnect-backoff.d.ts +17 -0
  44. package/dist/channel/reconnect-backoff.js +21 -0
  45. package/dist/channel/reconnect-backoff.js.map +1 -0
  46. package/dist/channel/types.d.ts +29 -0
  47. package/dist/classic-channel-manager.js +1 -5
  48. package/dist/classic-channel-manager.js.map +1 -1
  49. package/dist/cli.js +242 -91
  50. package/dist/cli.js.map +1 -1
  51. package/dist/completion.d.ts +27 -0
  52. package/dist/completion.js +121 -0
  53. package/dist/completion.js.map +1 -0
  54. package/dist/config-validator.js +21 -0
  55. package/dist/config-validator.js.map +1 -1
  56. package/dist/config.js +2 -0
  57. package/dist/config.js.map +1 -1
  58. package/dist/cost-guard.d.ts +3 -1
  59. package/dist/cost-guard.js +3 -1
  60. package/dist/cost-guard.js.map +1 -1
  61. package/dist/daemon.d.ts +299 -7
  62. package/dist/daemon.js +1152 -311
  63. package/dist/daemon.js.map +1 -1
  64. package/dist/event-log.d.ts +31 -0
  65. package/dist/event-log.js +96 -0
  66. package/dist/event-log.js.map +1 -1
  67. package/dist/fleet-context.d.ts +14 -0
  68. package/dist/fleet-lock.d.ts +28 -0
  69. package/dist/fleet-lock.js +130 -0
  70. package/dist/fleet-lock.js.map +1 -0
  71. package/dist/fleet-manager.d.ts +348 -6
  72. package/dist/fleet-manager.js +1860 -262
  73. package/dist/fleet-manager.js.map +1 -1
  74. package/dist/general-instance.d.ts +9 -0
  75. package/dist/general-instance.js +11 -0
  76. package/dist/general-instance.js.map +1 -0
  77. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +22 -0
  78. package/dist/general-knowledge/skills/model-discovery/SKILL.md +14 -23
  79. package/dist/general-knowledge/skills/session-management/SKILL.md +15 -34
  80. package/dist/hang-detector.d.ts +19 -13
  81. package/dist/hang-detector.js +19 -49
  82. package/dist/hang-detector.js.map +1 -1
  83. package/dist/instance-lifecycle.d.ts +58 -2
  84. package/dist/instance-lifecycle.js +231 -46
  85. package/dist/instance-lifecycle.js.map +1 -1
  86. package/dist/locale.js +7 -1
  87. package/dist/locale.js.map +1 -1
  88. package/dist/logger.js +14 -0
  89. package/dist/logger.js.map +1 -1
  90. package/dist/mcp-liveness.d.ts +21 -0
  91. package/dist/mcp-liveness.js +27 -0
  92. package/dist/mcp-liveness.js.map +1 -0
  93. package/dist/outbound-handlers.d.ts +9 -0
  94. package/dist/outbound-handlers.js +194 -31
  95. package/dist/outbound-handlers.js.map +1 -1
  96. package/dist/outbound-schemas.d.ts +11 -3
  97. package/dist/outbound-schemas.js +16 -2
  98. package/dist/outbound-schemas.js.map +1 -1
  99. package/dist/pane-write-lock.d.ts +48 -0
  100. package/dist/pane-write-lock.js +73 -0
  101. package/dist/pane-write-lock.js.map +1 -0
  102. package/dist/process-memory.d.ts +31 -0
  103. package/dist/process-memory.js +79 -0
  104. package/dist/process-memory.js.map +1 -0
  105. package/dist/quickstart.js +17 -16
  106. package/dist/quickstart.js.map +1 -1
  107. package/dist/reply-dedup.d.ts +41 -0
  108. package/dist/reply-dedup.js +0 -0
  109. package/dist/reply-dedup.js.map +1 -0
  110. package/dist/restart-progress.d.ts +41 -0
  111. package/dist/restart-progress.js +97 -0
  112. package/dist/restart-progress.js.map +1 -0
  113. package/dist/scheduler/db.js +3 -0
  114. package/dist/scheduler/db.js.map +1 -1
  115. package/dist/sd-notify.d.ts +27 -0
  116. package/dist/sd-notify.js +33 -1
  117. package/dist/sd-notify.js.map +1 -1
  118. package/dist/secret-file.d.ts +33 -0
  119. package/dist/secret-file.js +36 -0
  120. package/dist/secret-file.js.map +1 -0
  121. package/dist/service-installer.d.ts +28 -0
  122. package/dist/service-installer.js +72 -1
  123. package/dist/service-installer.js.map +1 -1
  124. package/dist/settings-api.js +5 -3
  125. package/dist/settings-api.js.map +1 -1
  126. package/dist/setup-wizard.js +9 -7
  127. package/dist/setup-wizard.js.map +1 -1
  128. package/dist/tmux-control.d.ts +58 -5
  129. package/dist/tmux-control.js +102 -14
  130. package/dist/tmux-control.js.map +1 -1
  131. package/dist/tmux-manager.d.ts +31 -1
  132. package/dist/tmux-manager.js +40 -11
  133. package/dist/tmux-manager.js.map +1 -1
  134. package/dist/topic-commands.d.ts +49 -9
  135. package/dist/topic-commands.js +270 -109
  136. package/dist/topic-commands.js.map +1 -1
  137. package/dist/tui-glyphs.d.ts +5 -1
  138. package/dist/tui-glyphs.js +6 -2
  139. package/dist/tui-glyphs.js.map +1 -1
  140. package/dist/types.d.ts +19 -2
  141. package/dist/ui/settings.html +1 -1
  142. package/dist/ui/view.html +123 -2
  143. package/dist/update-marker.d.ts +15 -0
  144. package/dist/update-marker.js +69 -0
  145. package/dist/update-marker.js.map +1 -0
  146. package/dist/usage/format-rich.d.ts +11 -0
  147. package/dist/usage/format-rich.js +121 -0
  148. package/dist/usage/format-rich.js.map +1 -0
  149. package/dist/usage/provider-alerts.d.ts +33 -0
  150. package/dist/usage/provider-alerts.js +57 -0
  151. package/dist/usage/provider-alerts.js.map +1 -0
  152. package/dist/usage/providers.d.ts +130 -0
  153. package/dist/usage/providers.js +1063 -0
  154. package/dist/usage/providers.js.map +1 -0
  155. package/dist/usage/statusline-usage.d.ts +20 -0
  156. package/dist/usage/statusline-usage.js +120 -0
  157. package/dist/usage/statusline-usage.js.map +1 -0
  158. package/dist/usage/usage-api.d.ts +50 -0
  159. package/dist/usage/usage-api.js +197 -0
  160. package/dist/usage/usage-api.js.map +1 -0
  161. package/dist/view-api.js +8 -3
  162. package/dist/view-api.js.map +1 -1
  163. package/dist/web-api.js +7 -3
  164. package/dist/web-api.js.map +1 -1
  165. package/dist/web-auth.d.ts +6 -0
  166. package/dist/web-auth.js +54 -0
  167. package/dist/web-auth.js.map +1 -0
  168. package/package.json +4 -1
  169. package/dist/channel/tool-tracker.d.ts +0 -13
  170. package/dist/channel/tool-tracker.js +0 -58
  171. package/dist/channel/tool-tracker.js.map +0 -1
  172. package/dist/daemon-entry.d.ts +0 -1
  173. package/dist/daemon-entry.js +0 -30
  174. package/dist/daemon-entry.js.map +0 -1
@@ -0,0 +1,121 @@
1
+ const BAR_WIDTH = 10;
2
+ /** `████░░░░░░` for 40%. Clamped — a vendor "105% used" must not overflow. */
3
+ export function usageBar(percent) {
4
+ const filled = Math.round(Math.min(100, Math.max(0, percent)) / 100 * BAR_WIDTH);
5
+ return "█".repeat(filled) + "░".repeat(BAR_WIDTH - filled);
6
+ }
7
+ function statusDot(p) {
8
+ if (p.status === "error")
9
+ return "🔴";
10
+ if (p.status === "no-credentials")
11
+ return "⚪";
12
+ // Highest metric drives the colour: the reader scans for "which one is hot".
13
+ const hottest = Math.max(0, ...p.metrics.map(metricPercent).filter((v) => v !== null));
14
+ return hottest >= 90 ? "🔴" : hottest >= 70 ? "🟡" : "🟢";
15
+ }
16
+ /** A metric's fill percentage, when one can honestly be computed. */
17
+ function metricPercent(m) {
18
+ if (m.type === "percent" && typeof m.used === "number")
19
+ return m.used;
20
+ if (m.type === "dollars" && typeof m.used === "number" && m.limit)
21
+ return (m.used / m.limit) * 100;
22
+ return null;
23
+ }
24
+ function resetSuffix(resetsAt) {
25
+ if (!resetsAt)
26
+ return "";
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`;
34
+ }
35
+ function metricLine(m) {
36
+ const pct = metricPercent(m);
37
+ switch (m.type) {
38
+ case "percent":
39
+ return {
40
+ bar: usageBar(pct ?? 0),
41
+ // note explains WHICH number this is (e.g. "busiest of 8 models"); it is
42
+ // what stops a legitimate 0% from reading as a broken meter.
43
+ text: `${Math.round(m.used ?? 0)}% ${m.label}${m.note ? ` (${m.note})` : ""}${resetSuffix(m.resetsAt)}`,
44
+ };
45
+ case "dollars": {
46
+ const used = `$${(m.used ?? 0).toFixed(2)}`;
47
+ return m.limit
48
+ ? { bar: usageBar(pct ?? 0), text: `${used}/$${m.limit.toFixed(2)} ${m.label}` }
49
+ : { bar: null, text: `${used} ${m.label}` };
50
+ }
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
+ }
56
+ }
57
+ function toBlocks(payload) {
58
+ return payload.providers.map(p => ({
59
+ dot: statusDot(p),
60
+ name: p.name,
61
+ plan: p.plan ?? null,
62
+ // An ok row can carry a hint too — e.g. "cached 3m ago — live query is rate
63
+ // limited" from the stale fallback. Shown under the metrics, not instead of
64
+ // them, so old numbers still read as numbers.
65
+ note: p.status === "no-credentials" ? "not logged in"
66
+ : p.status === "error" ? `⚠️ ${p.error ?? "error"}`
67
+ : null,
68
+ okHint: p.status === "ok" && p.hint ? p.hint : null,
69
+ lines: p.status === "ok" ? p.metrics.map(metricLine).filter((l) => l !== null) : [],
70
+ }));
71
+ }
72
+ /** Discord: native Markdown in plain message content. */
73
+ export function renderUsageMarkdown(payload) {
74
+ const out = ["📊 **AI Subscription Usage**"];
75
+ for (const b of toBlocks(payload)) {
76
+ out.push("", `${b.dot} **${b.name}**${b.plan ? ` (${b.plan})` : ""}`);
77
+ if (b.note) {
78
+ out.push(`> ${b.note}`);
79
+ continue;
80
+ }
81
+ if (b.lines.length === 0) {
82
+ out.push(b.okHint ? `> ${b.okHint}` : "> no data");
83
+ continue;
84
+ }
85
+ for (const l of b.lines) {
86
+ out.push(l.bar ? `\`${l.bar}\` ${l.text}` : l.text);
87
+ }
88
+ if (b.okHint)
89
+ out.push(`> ${b.okHint}`);
90
+ }
91
+ return out.join("\n");
92
+ }
93
+ function escapeHtml(s) {
94
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
95
+ }
96
+ /**
97
+ * Telegram: HTML parse mode. Every payload-derived string is entity-escaped —
98
+ * provider errors and metric labels come from vendor responses, and one stray
99
+ * `<` would make Telegram reject the whole message.
100
+ */
101
+ export function renderUsageHtml(payload) {
102
+ const out = ["📊 <b>AI Subscription Usage</b>"];
103
+ for (const b of toBlocks(payload)) {
104
+ out.push("", `${b.dot} <b>${escapeHtml(b.name)}</b>${b.plan ? ` (${escapeHtml(b.plan)})` : ""}`);
105
+ if (b.note) {
106
+ out.push(escapeHtml(b.note));
107
+ continue;
108
+ }
109
+ if (b.lines.length === 0) {
110
+ out.push(b.okHint ? escapeHtml(b.okHint) : "no data");
111
+ continue;
112
+ }
113
+ for (const l of b.lines) {
114
+ out.push(l.bar ? `<code>${l.bar}</code> ${escapeHtml(l.text)}` : escapeHtml(l.text));
115
+ }
116
+ if (b.okHint)
117
+ out.push(escapeHtml(b.okHint));
118
+ }
119
+ return out.join("\n");
120
+ }
121
+ //# sourceMappingURL=format-rich.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-rich.js","sourceRoot":"","sources":["../../src/usage/format-rich.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Rate-limit state that only the CLI can see, remembered for the usage panel.
3
+ *
4
+ * Antigravity's quota summary API reports per-model bucket pools — and those
5
+ * can read "0% used" while the account-level individual cap is exhausted.
6
+ * Verified live (2026-08-02, same minute): `agy -p` returned "Individual quota
7
+ * reached … Resets in 139h12m12s" while `retrieveUserQuotaSummary` reported
8
+ * every bucket at remainingFraction 1.0. No Google API exposes the individual
9
+ * cap; the generation error relayed through a running instance's pane is the
10
+ * only place it surfaces. So the daemon's error monitor reports it here, and
11
+ * the usage provider overlays it on the row that would otherwise say 🟢 0%.
12
+ *
13
+ * In-memory on purpose: the fleet process hosts both the error monitor and the
14
+ * usage provider, and a restart just means the alert reappears the next time an
15
+ * instance hits the cap.
16
+ */
17
+ /**
18
+ * `Resets in 139h12m12s` → milliseconds. Null when the text carries no such
19
+ * phrase — the caller falls back to a default TTL rather than guessing.
20
+ */
21
+ export declare function parseResetsIn(text: string): number | null;
22
+ /**
23
+ * Record a CLI-observed rate limit for a usage provider. The alert expires by
24
+ * itself at the reset time the message names (or after an hour when it names
25
+ * none), which is what makes "reset 後警示消失" true without a cleanup job.
26
+ */
27
+ export declare function reportProviderRateLimit(providerId: string, message: string, now?: number): void;
28
+ /** The live alert for a provider, or null once its reset time has passed. */
29
+ export declare function getProviderRateLimit(providerId: string, now?: number): {
30
+ message: string;
31
+ resetsAtMs: number;
32
+ } | null;
33
+ export declare function clearProviderRateLimitsForTests(): void;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Rate-limit state that only the CLI can see, remembered for the usage panel.
3
+ *
4
+ * Antigravity's quota summary API reports per-model bucket pools — and those
5
+ * can read "0% used" while the account-level individual cap is exhausted.
6
+ * Verified live (2026-08-02, same minute): `agy -p` returned "Individual quota
7
+ * reached … Resets in 139h12m12s" while `retrieveUserQuotaSummary` reported
8
+ * every bucket at remainingFraction 1.0. No Google API exposes the individual
9
+ * cap; the generation error relayed through a running instance's pane is the
10
+ * only place it surfaces. So the daemon's error monitor reports it here, and
11
+ * the usage provider overlays it on the row that would otherwise say 🟢 0%.
12
+ *
13
+ * In-memory on purpose: the fleet process hosts both the error monitor and the
14
+ * usage provider, and a restart just means the alert reappears the next time an
15
+ * instance hits the cap.
16
+ */
17
+ const alerts = new Map();
18
+ /**
19
+ * `Resets in 139h12m12s` → milliseconds. Null when the text carries no such
20
+ * phrase — the caller falls back to a default TTL rather than guessing.
21
+ */
22
+ export function parseResetsIn(text) {
23
+ const m = text.match(/Resets? in (?:(\d+)h)?(?:(\d+)m)?(?:(\d+(?:\.\d+)?)s)?/i);
24
+ if (!m || (!m[1] && !m[2] && !m[3]))
25
+ return null;
26
+ return (Number(m[1] ?? 0) * 3600 + Number(m[2] ?? 0) * 60 + Number(m[3] ?? 0)) * 1000;
27
+ }
28
+ /** A cap with no parseable reset still should not alarm forever. */
29
+ const DEFAULT_ALERT_TTL_MS = 60 * 60_000;
30
+ /**
31
+ * Record a CLI-observed rate limit for a usage provider. The alert expires by
32
+ * itself at the reset time the message names (or after an hour when it names
33
+ * none), which is what makes "reset 後警示消失" true without a cleanup job.
34
+ */
35
+ export function reportProviderRateLimit(providerId, message, now = Date.now()) {
36
+ const resetInMs = parseResetsIn(message);
37
+ alerts.set(providerId, {
38
+ message,
39
+ resetsAtMs: now + (resetInMs ?? DEFAULT_ALERT_TTL_MS),
40
+ reportedAtMs: now,
41
+ });
42
+ }
43
+ /** The live alert for a provider, or null once its reset time has passed. */
44
+ export function getProviderRateLimit(providerId, now = Date.now()) {
45
+ const alert = alerts.get(providerId);
46
+ if (!alert)
47
+ return null;
48
+ if (now >= alert.resetsAtMs) {
49
+ alerts.delete(providerId);
50
+ return null;
51
+ }
52
+ return { message: alert.message, resetsAtMs: alert.resetsAtMs };
53
+ }
54
+ export function clearProviderRateLimitsForTests() {
55
+ alerts.clear();
56
+ }
57
+ //# sourceMappingURL=provider-alerts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-alerts.js","sourceRoot":"","sources":["../../src/usage/provider-alerts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;AAEhD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAChF,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AACxF,CAAC;AAED,oEAAoE;AACpE,MAAM,oBAAoB,GAAG,EAAE,GAAG,MAAM,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,UAAkB,EAAE,OAAe,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC3F,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE;QACrB,OAAO;QACP,UAAU,EAAE,GAAG,GAAG,CAAC,SAAS,IAAI,oBAAoB,CAAC;QACrD,YAAY,EAAE,GAAG;KAClB,CAAC,CAAC;AACL,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,oBAAoB,CAAC,UAAkB,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAEvE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QAC5B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,+BAA+B;IAC7C,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC"}
@@ -0,0 +1,130 @@
1
+ import { type StatuslineRateLimits } from "./statusline-usage.js";
2
+ export interface UsageMetric {
3
+ label: string;
4
+ type: "percent" | "dollars" | "count" | "text";
5
+ used?: number;
6
+ limit?: number;
7
+ value?: number | string;
8
+ unit?: string;
9
+ note?: string;
10
+ resetsAt?: string | null;
11
+ windowMs?: number | null;
12
+ }
13
+ export interface ProviderUsage {
14
+ id: string;
15
+ name: string;
16
+ status: "ok" | "error" | "no-credentials";
17
+ plan?: string | null;
18
+ error?: string;
19
+ hint?: string;
20
+ metrics: UsageMetric[];
21
+ }
22
+ /** `CLAUDE_CODE_OAUTH_TOKEN` as exported in a shell rc file, or null. */
23
+ export declare function tokenFromShellRc(read: (path: string) => string, home?: string, files?: readonly string[]): string | null;
24
+ /**
25
+ * Where the Claude OAuth bearer comes from, in preference order:
26
+ *
27
+ * 1. `~/.claude/.credentials.json` (`claudeAiOauth.accessToken`) when present and
28
+ * unexpired — the interactive `/login` flow. Carries plan metadata.
29
+ * 2. `CLAUDE_CODE_OAUTH_TOKEN` — the long-lived (annual) token minted by
30
+ * `claude setup-token`. Users on this flow often have NO credentials file at
31
+ * all (or a stale one from an old login), which is why /usage showed them
32
+ * "not logged in" / "token expired" while their CLI worked fine. Same token
33
+ * family (`sk-ant-oat…`), same usage endpoint; it just carries no plan
34
+ * metadata, so plan shows unknown.
35
+ * 3. The same variable as exported in a shell rc file. A systemd-launched daemon
36
+ * inherits none of the user's interactive shell, so a `setup-token` login was
37
+ * invisible to /usage unless the user duplicated it into ~/.agend/.env.
38
+ * 4. An expired file token with no other source stays an explicit error.
39
+ * 5. `ANTHROPIC_API_KEY` alone is named in the hint but NOT used: console API
40
+ * keys are pay-per-token and have no subscription usage to query — the OAuth
41
+ * endpoint rejects them, and pretending otherwise would render a misleading
42
+ * error instead of an accurate "log in" hint.
43
+ */
44
+ export declare function resolveClaudeAuth(file: {
45
+ accessToken?: string;
46
+ expiresAt?: number;
47
+ subscriptionType?: string;
48
+ rateLimitTier?: string;
49
+ } | null, env?: NodeJS.ProcessEnv, rcLookup?: () => string | null): {
50
+ token: string;
51
+ plan: string | null;
52
+ } | {
53
+ error: string;
54
+ plan: string | null;
55
+ } | null;
56
+ /**
57
+ * Render a statusline reading as provider metrics.
58
+ *
59
+ * Kept deliberately close to the API path's shape so the panel looks the same
60
+ * wherever the numbers came from — the hint is what tells the difference, and
61
+ * it names the source because a number with no provenance invites "is this
62
+ * even live?".
63
+ */
64
+ export declare function statuslineUsage(reading: StatuslineRateLimits, plan: string | null, now?: number): Omit<ProviderUsage, "id" | "name">;
65
+ /** Exported for tests — the statusline/API preference order is the subject. */
66
+ export declare function fetchClaudeUsage(): Promise<Omit<ProviderUsage, "id" | "name">>;
67
+ interface AgyBucket {
68
+ bucketId?: string;
69
+ displayName?: string;
70
+ remainingFraction?: number;
71
+ resetTime?: string;
72
+ }
73
+ /**
74
+ * Pool the summary's buckets into at most four metrics.
75
+ *
76
+ * Two payload shapes exist. Older accounts report pooled ids (`gemini-5h`,
77
+ * `gemini-weekly`, `3p-5h`, `3p-weekly`), which map 1:1. This machine's live
78
+ * response instead lists PER-MODEL buckets (`gemini-3.6-flash-high`,
79
+ * `claude-sonnet-4-6`, `gpt-oss-120b-medium`, …) — those aggregate into a
80
+ * Gemini pool and an everything-else pool, keeping each pool's WORST remaining
81
+ * fraction, because eleven per-model meters is noise and the binding constraint
82
+ * is the one that runs out first.
83
+ */
84
+ export declare function agyPoolMetrics(buckets: AgyBucket[]): UsageMetric[];
85
+ interface AgyStoredToken {
86
+ access_token?: string;
87
+ refresh_token?: string;
88
+ expiry?: string;
89
+ expiry_date?: number;
90
+ }
91
+ /**
92
+ * agy's token file, in either shape.
93
+ *
94
+ * This machine writes it nested (`{ token: {...}, id_token, auth_method }`),
95
+ * which is what the provider was built against. Flat (`{ access_token, ... }`)
96
+ * is accepted too — it costs one `??` and other installs or future agy versions
97
+ * may differ. `expiry_date` (epoch ms, the shape ~/.gemini/oauth_creds.json
98
+ * uses) is read alongside `expiry` (RFC3339) for the same reason.
99
+ */
100
+ export declare function readAgyToken(file: unknown): AgyStoredToken;
101
+ interface KiroToken {
102
+ access_token?: string;
103
+ expires_at?: string;
104
+ region?: string;
105
+ profile_arn?: string;
106
+ /** IAM Identity Center portal URL — present only for Q Developer Pro logins. */
107
+ start_url?: string;
108
+ /** Social login provider (google/github/…) — present only for free-tier logins. */
109
+ provider?: string;
110
+ }
111
+ /**
112
+ * Which Kiro login is in use. Verified against a real kiro-cli auth store:
113
+ * - IAM Identity Center (Amazon Q Developer Pro) tokens carry `start_url`
114
+ * (e.g. `https://d-xxxx.awsapps.com/start/`) and no social `provider`.
115
+ * - Free-tier social logins (Builder ID / Google / GitHub) carry `provider`
116
+ * and a `profile_arn`.
117
+ * Q Developer Pro is a seat-licensed subscription, so the credit/usage endpoint
118
+ * that Builder ID reports against does not describe it.
119
+ */
120
+ export type KiroAuthKind = "q-developer-pro" | "builder-id";
121
+ export declare function kiroAuthKind(token: KiroToken): KiroAuthKind;
122
+ /** Exported for tests: the Q-Pro and expired paths return without any network call. */
123
+ export declare function fetchKiroUsage(): Promise<Omit<ProviderUsage, "id" | "name">>;
124
+ /** Fetch every provider in parallel. Providers without local credentials are
125
+ * skipped (per the panel's contract: absent CLIs simply don't show). */
126
+ export declare function fetchAllUsage(): Promise<{
127
+ fetchedAt: string;
128
+ providers: ProviderUsage[];
129
+ }>;
130
+ export {};