@songsid/agend 2.2.0-beta.4 → 2.2.0-beta.6

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 (116) hide show
  1. package/dist/backend/claude-carry.d.ts +22 -0
  2. package/dist/backend/claude-carry.js +170 -0
  3. package/dist/backend/claude-carry.js.map +1 -0
  4. package/dist/backend/claude-code.d.ts +23 -0
  5. package/dist/backend/claude-code.js +102 -2
  6. package/dist/backend/claude-code.js.map +1 -1
  7. package/dist/backend/credential-profile.d.ts +7 -0
  8. package/dist/backend/credential-profile.js +7 -1
  9. package/dist/backend/credential-profile.js.map +1 -1
  10. package/dist/backend/kiro.js +5 -2
  11. package/dist/backend/kiro.js.map +1 -1
  12. package/dist/backend/muse.d.ts +41 -0
  13. package/dist/backend/muse.js +239 -44
  14. package/dist/backend/muse.js.map +1 -1
  15. package/dist/backend/types.d.ts +7 -0
  16. package/dist/backend/types.js.map +1 -1
  17. package/dist/background-work-ended.d.ts +18 -0
  18. package/dist/background-work-ended.js +30 -0
  19. package/dist/background-work-ended.js.map +1 -0
  20. package/dist/channel/adapters/telegram.d.ts +4 -5
  21. package/dist/channel/adapters/telegram.js +33 -17
  22. package/dist/channel/adapters/telegram.js.map +1 -1
  23. package/dist/channel/message-edit-errors.d.ts +5 -0
  24. package/dist/channel/message-edit-errors.js +24 -0
  25. package/dist/channel/message-edit-errors.js.map +1 -0
  26. package/dist/cli.js +60 -10
  27. package/dist/cli.js.map +1 -1
  28. package/dist/config-validator.js +3 -0
  29. package/dist/config-validator.js.map +1 -1
  30. package/dist/daemon.js +41 -0
  31. package/dist/daemon.js.map +1 -1
  32. package/dist/fleet-context.d.ts +4 -1
  33. package/dist/fleet-manager.d.ts +112 -5
  34. package/dist/fleet-manager.js +516 -52
  35. package/dist/fleet-manager.js.map +1 -1
  36. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +44 -9
  37. package/dist/locale.js +18 -2
  38. package/dist/locale.js.map +1 -1
  39. package/dist/needs-you-hub.js +2 -0
  40. package/dist/needs-you-hub.js.map +1 -1
  41. package/dist/needs-you-live.d.ts +6 -0
  42. package/dist/needs-you-live.js +23 -3
  43. package/dist/needs-you-live.js.map +1 -1
  44. package/dist/outbound-handlers.d.ts +7 -0
  45. package/dist/outbound-handlers.js +19 -10
  46. package/dist/outbound-handlers.js.map +1 -1
  47. package/dist/public-preview.d.ts +100 -0
  48. package/dist/public-preview.js +233 -0
  49. package/dist/public-preview.js.map +1 -0
  50. package/dist/public-web-gateway.js +4 -3
  51. package/dist/public-web-gateway.js.map +1 -1
  52. package/dist/public-web-link.d.ts +20 -0
  53. package/dist/public-web-link.js +26 -1
  54. package/dist/public-web-link.js.map +1 -1
  55. package/dist/restart-progress.d.ts +33 -0
  56. package/dist/restart-progress.js +30 -0
  57. package/dist/restart-progress.js.map +1 -1
  58. package/dist/service-installer.d.ts +31 -0
  59. package/dist/service-installer.js +41 -2
  60. package/dist/service-installer.js.map +1 -1
  61. package/dist/topic-commands.js +3 -1
  62. package/dist/topic-commands.js.map +1 -1
  63. package/dist/tunnel/purpose-lane.d.ts +5 -1
  64. package/dist/tunnel/purpose-lane.js +14 -7
  65. package/dist/tunnel/purpose-lane.js.map +1 -1
  66. package/dist/types.d.ts +6 -0
  67. package/dist/ui/chat-strings.js +14 -2
  68. package/dist/ui/chat-thread.js +2 -2
  69. package/dist/ui/panel-chat.js +9 -2
  70. package/dist/ui/panel-fleet.js +148 -35
  71. package/dist/ui/panel-needs.js +4 -3
  72. package/dist/ui/panel-settings.js +1 -1
  73. package/dist/ui/preview-status.js +28 -0
  74. package/dist/ui/preview.js +35 -2
  75. package/dist/ui/shared/app-i18n.js +4 -0
  76. package/dist/ui/shared/app-prefs.js +1 -0
  77. package/dist/ui/shared/app-shell.js +146 -2
  78. package/dist/ui/shared/app-stream.js +21 -4
  79. package/dist/ui/shared/app.css +41 -15
  80. package/dist/ui/shared/instance-nav.js +47 -16
  81. package/dist/ui/shared/usage-dialog.js +10 -1
  82. package/dist/ui/shared/view-strings.js +4 -0
  83. package/dist/update-install.d.ts +13 -1
  84. package/dist/update-install.js +16 -4
  85. package/dist/update-install.js.map +1 -1
  86. package/dist/update-marker.d.ts +51 -0
  87. package/dist/update-marker.js +61 -0
  88. package/dist/update-marker.js.map +1 -1
  89. package/dist/usage/i18n-keys.d.ts +1 -1
  90. package/dist/usage/i18n-keys.js +1 -1
  91. package/dist/usage/i18n-keys.js.map +1 -1
  92. package/dist/usage/providers.d.ts +34 -5
  93. package/dist/usage/providers.js +160 -27
  94. package/dist/usage/providers.js.map +1 -1
  95. package/dist/usage/statusline-usage.d.ts +6 -2
  96. package/dist/usage/statusline-usage.js +10 -4
  97. package/dist/usage/statusline-usage.js.map +1 -1
  98. package/dist/web-api.d.ts +20 -1
  99. package/dist/web-api.js +101 -13
  100. package/dist/web-api.js.map +1 -1
  101. package/dist/web-auth.js +2 -1
  102. package/dist/web-auth.js.map +1 -1
  103. package/dist/web-prefs.js +2 -0
  104. package/dist/web-prefs.js.map +1 -1
  105. package/dist/web-preview.d.ts +14 -1
  106. package/dist/web-preview.js +35 -13
  107. package/dist/web-preview.js.map +1 -1
  108. package/dist/web-schedules.d.ts +12 -0
  109. package/dist/web-schedules.js +34 -0
  110. package/dist/web-schedules.js.map +1 -0
  111. package/dist/web-server-drain.d.ts +10 -0
  112. package/dist/web-server-drain.js +50 -0
  113. package/dist/web-server-drain.js.map +1 -0
  114. package/package.json +1 -1
  115. package/templates/launchd.plist.ejs +3 -1
  116. package/templates/systemd.service.ejs +2 -1
@@ -23,6 +23,64 @@ import { atomicWriteFileSync } from "./atomic-write.js";
23
23
  */
24
24
  export const UPDATE_MARKER_MAX_AGE_MS = 15 * 60_000;
25
25
  const FILE = "update-in-progress.json";
26
+ export function updateReceiptOf(marker) {
27
+ if (!marker?.progress?.target?.messageId)
28
+ return null;
29
+ return { startedAt: marker.startedAt, messageId: marker.progress.target.messageId, operation: updateProgressOperation(marker.progress) };
30
+ }
31
+ function sameReceipt(a, b) {
32
+ return !!a && !!b && a.startedAt === b.startedAt && a.messageId === b.messageId && a.operation === b.operation;
33
+ }
34
+ export function updateMarkerIdentity(dataDir) {
35
+ const marker = readMarker(dataDir);
36
+ if (!marker)
37
+ return null;
38
+ return { startedAt: marker.startedAt, receipt: marker.progress ? updateReceiptOf(marker) : null };
39
+ }
40
+ /** The same marker: started at the same time, with the same receipt (or none on both). */
41
+ export function sameUpdateMarker(a, b) {
42
+ if (!a || !b || a.startedAt !== b.startedAt)
43
+ return false;
44
+ return a.receipt === null ? b.receipt === null : sameReceipt(a.receipt, b.receipt);
45
+ }
46
+ /**
47
+ * Mark the current update as owing its retire outcome, before the restart
48
+ * that may let a new fleet consume this receipt. Returns the receipt the
49
+ * later write must still match.
50
+ */
51
+ export function markCleanupPending(dataDir) {
52
+ const marker = readUpdateProgress(dataDir);
53
+ const receipt = updateReceiptOf(marker);
54
+ if (!receipt || !marker)
55
+ return null;
56
+ marker.pid = process.pid;
57
+ marker.progress = { ...marker.progress, cleanup: "pending" };
58
+ return writeMarker(dataDir, marker) ? receipt : null;
59
+ }
60
+ /**
61
+ * Record a retire outcome against the receipt captured before the restart.
62
+ * Refuses when the marker is gone (the new fleet already consumed it) or
63
+ * belongs to another operation (e.g. a later full-restart adopted it) — the
64
+ * warning was already printed to the updater's own output, so refusing here
65
+ * loses nothing the operator saw.
66
+ */
67
+ export function writeCleanupOutcome(dataDir, receipt, outcome) {
68
+ if (!receipt)
69
+ return false;
70
+ const marker = readUpdateProgress(dataDir);
71
+ if (!marker || !sameReceipt(updateReceiptOf(marker), receipt))
72
+ return false;
73
+ marker.pid = process.pid;
74
+ marker.progress = {
75
+ ...marker.progress,
76
+ // Prose follows the same rule as setUpdateProgressStage; the command is
77
+ // verbatim so quoted paths survive byte-exact.
78
+ ...(outcome?.warning !== undefined ? { warning: outcome.warning.replace(/\s+/g, " ").trim().slice(0, 300) } : {}),
79
+ ...(outcome?.cleanupCommand !== undefined ? { cleanupCommand: outcome.cleanupCommand } : {}),
80
+ cleanup: "done",
81
+ };
82
+ return writeMarker(dataDir, marker);
83
+ }
26
84
  function markerPath(dataDir) {
27
85
  return join(dataDir, FILE);
28
86
  }
@@ -91,6 +149,9 @@ export function setUpdateProgressStage(dataDir, stage, details = {}) {
91
149
  stage,
92
150
  ...(details.version !== undefined ? { version: details.version } : {}),
93
151
  ...(details.error !== undefined ? { error: details.error.replace(/\s+/g, " ").trim().slice(0, 300) } : {}),
152
+ ...(details.warning !== undefined ? { warning: details.warning.replace(/\s+/g, " ").trim().slice(0, 300) } : {}),
153
+ ...(details.cleanupCommand !== undefined ? { cleanupCommand: details.cleanupCommand } : {}),
154
+ ...(details.cleanup !== undefined ? { cleanup: details.cleanup } : {}),
94
155
  ...(stage === "failed" ? { failedStage: previousStage } : {}),
95
156
  };
96
157
  return writeMarker(dataDir, marker);
@@ -1 +1 @@
1
- {"version":3,"file":"update-marker.js","sourceRoot":"","sources":["../src/update-marker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update-marker.js","sourceRoot":"","sources":["../src/update-marker.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.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.rate_limited_transient", "usage.stale_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.claude_profile_signed_out", "usage.hint.claude_profile_signed_out_chat", "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.rate_limited_transient", "usage.stale_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];
@@ -20,7 +20,7 @@ export const USAGE_I18N_KEYS = [
20
20
  "usage.hint.statusline_now", "usage.hint.statusline_minutes", "usage.hint.claude_api_key",
21
21
  "usage.hint.login_claude", "usage.hint.login_agy", "usage.hint.no_quota",
22
22
  "usage.hint.login_codex", "usage.hint.codex_no_oauth", "usage.hint.login_grok",
23
- "usage.hint.grok_no_login", "usage.hint.login_kiro", "usage.hint.kiro_signed_out",
23
+ "usage.hint.grok_no_login", "usage.hint.login_kiro", "usage.hint.kiro_signed_out", "usage.hint.claude_profile_signed_out", "usage.hint.claude_profile_signed_out_chat",
24
24
  "usage.hint.token_refreshing", "usage.hint.subscription_no_credit", "usage.hint.no_quota_account",
25
25
  "usage.error.unreachable", "usage.error.token_rejected", "usage.error.rate_limited", "usage.error.rate_limited_transient", "usage.stale_rate_limited",
26
26
  "usage.error.http", "usage.error.billing_http", "usage.error.invalid_response",
@@ -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,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,EAAE,oCAAoC,EAAE,0BAA0B;IACrJ,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"}
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,EAAE,sCAAsC,EAAE,2CAA2C;IACtK,6BAA6B,EAAE,mCAAmC,EAAE,6BAA6B;IACjG,yBAAyB,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,oCAAoC,EAAE,0BAA0B;IACrJ,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"}
@@ -106,14 +106,43 @@ export declare function resolveClaudeAuth(file: {
106
106
  * even live?".
107
107
  */
108
108
  export declare function statuslineUsage(reading: StatuslineRateLimits, plan: string | null, now?: number): Omit<ProviderUsage, "id" | "name">;
109
+ /** `security find-generic-password -w`: the item's secret, or null (no such item, locked, not macOS). */
110
+ type KeychainRead = (service: string, account: string) => Promise<string | null>;
111
+ declare let claudeKeychain: {
112
+ platform: NodeJS.Platform;
113
+ read: KeychainRead;
114
+ username: () => string;
115
+ };
116
+ /** Test seam (#1699): the platform, the Keychain read and the OS user name; null restores all three. */
117
+ export declare function setClaudeKeychainForTests(seam: Partial<typeof claudeKeychain> | null): void;
118
+ /**
119
+ * Whether a shell rc sets `CLAUDE_CODE_OAUTH_TOKEN` at all — any assignment, export or declaration that is not a
120
+ * comment, whatever its value: `"$OTHER"` or `${OTHER}` is a token once the pane's shell expands it, so unlike
121
+ * tokenFromShellRc (which must hand the API a literal bearer) this never discounts one it cannot read (#1713 review).
122
+ * Files those rcs `source` are not followed.
123
+ */
124
+ export declare function shellRcSetsClaudeToken(read: (path: string) => string, home?: string, files?: readonly string[]): boolean;
109
125
  /**
110
126
  * Best-effort OAuth access token for direct Anthropic API calls (the /model
111
127
  * catalog probe). Same resolution order as the usage panel: credentials file →
112
- * CLAUDE_CODE_OAUTH_TOKEN → shell rc. Null when nothing usable exists.
128
+ * CLAUDE_CODE_OAUTH_TOKEN → shell rc. Null when nothing usable exists. With
129
+ * `storeHome` (a credential profile's config dir, #1699): that profile's login only.
130
+ */
131
+ export declare function getClaudeOAuthToken(storeHome?: string): Promise<string | null>;
132
+ /** Which subscription a Claude row is (#1699): a profile's (with its name), or the shared one beside profiles. */
133
+ export interface ClaudeUsageScope {
134
+ profile?: string;
135
+ besideProfiles?: boolean;
136
+ }
137
+ /**
138
+ * Exported for tests — the statusline/API preference order is the subject.
139
+ *
140
+ * `storeHome` (#1699): a credential profile's config dir — the row reads that profile's login and only the rate
141
+ * limits its own instances wrote (their conversations are under its `projects/`); a profile with no login says so,
142
+ * with the line that signs it in, and never shows the shared account's numbers. Without it: the shared login as
143
+ * always; beside profiles (`besideProfiles`), its statusline fallback leaves the profiles' instances out.
113
144
  */
114
- export declare function getClaudeOAuthToken(): Promise<string | null>;
115
- /** Exported for tests — the statusline/API preference order is the subject. */
116
- export declare function fetchClaudeUsage(): Promise<Omit<ProviderUsage, "id" | "name">>;
145
+ export declare function fetchClaudeUsage(storeHome?: string, scope?: ClaudeUsageScope): Promise<Omit<ProviderUsage, "id" | "name">>;
117
146
  interface AgyBucket {
118
147
  bucketId?: string;
119
148
  displayName?: string;
@@ -172,7 +201,7 @@ export declare function fetchKiroUsage(storeHome?: string): Promise<Omit<Provide
172
201
  type UsageProvider = {
173
202
  id: string;
174
203
  name: string;
175
- fetch: (storeHome?: string) => Promise<Omit<ProviderUsage, "id" | "name">>;
204
+ fetch: (storeHome?: string, scope?: ClaudeUsageScope) => Promise<Omit<ProviderUsage, "id" | "name">>;
176
205
  };
177
206
  type UsageFleetConfig = Parameters<typeof listConfiguredProfiles>[0];
178
207
  /** Read the daemon-written, token-free Muse relay snapshot for active Muse instances. */
@@ -20,13 +20,15 @@
20
20
  */
21
21
  import { readFile, writeFile, access, constants } from "node:fs/promises";
22
22
  import { readFileSync, readdirSync } from "node:fs";
23
- import { join } from "node:path";
23
+ import { join, resolve, sep } from "node:path";
24
+ import { execFile } from "node:child_process";
24
25
  import { getAgendHome } from "../paths.js";
25
26
  import { loadFleetConfig } from "../config.js";
26
27
  import { classicProfile, profileName, readClassicBindings } from "../classic-bindings.js";
27
- import { credentialHomeSpec, credentialProfileStoreHome, instanceCredentialProfile, } from "../backend/credential-profile.js";
28
+ import { CHAT_PROFILE_LOGIN_BACKENDS, credentialHomeSpec, credentialProfileLoginCommand, credentialProfileStoreHome, instanceCredentialProfile, } from "../backend/credential-profile.js";
29
+ import { claudeKeychainService } from "../backend/claude-code.js";
28
30
  import { readKiroAuthTokens } from "../backend/kiro-auth-store.js";
29
- import { homedir } from "node:os";
31
+ import { homedir, userInfo } from "node:os";
30
32
  import { getProviderRateLimit } from "./provider-alerts.js";
31
33
  import { MUSE_USAGE_STALE_MS, readMuseUsageSnapshot } from "../muse-usage-relay.js";
32
34
  import { readStatuslineRateLimits, } from "./statusline-usage.js";
@@ -216,43 +218,163 @@ export function statuslineUsage(reading, plan, now = Date.now()) {
216
218
  metrics,
217
219
  };
218
220
  }
221
+ /** `claudeAiOauth` of a credentials document (the `.credentials.json` file, or the same JSON in a Keychain item). */
222
+ function claudeOAuthOf(json) {
223
+ try {
224
+ const value = JSON.parse(json)?.claudeAiOauth;
225
+ return value && typeof value === "object" ? value : null;
226
+ }
227
+ catch {
228
+ return null;
229
+ }
230
+ }
231
+ async function readClaudeCredentialsFile(dir) {
232
+ try {
233
+ return claudeOAuthOf(await readFile(join(dir, ".credentials.json"), "utf8"));
234
+ }
235
+ catch {
236
+ return null;
237
+ }
238
+ }
239
+ const readKeychainItem = (service, account) => new Promise(done => {
240
+ execFile("security", ["find-generic-password", "-a", account, "-w", "-s", service], { timeout: 5_000 }, (err, stdout) => {
241
+ done(err ? null : String(stdout).trim() || null);
242
+ });
243
+ });
244
+ const defaultKeychain = () => ({ platform: process.platform, read: readKeychainItem, username: () => userInfo().username });
245
+ let claudeKeychain = defaultKeychain();
246
+ /** Test seam (#1699): the platform, the Keychain read and the OS user name; null restores all three. */
247
+ export function setClaudeKeychainForTests(seam) {
248
+ claudeKeychain = seam ? { ...claudeKeychain, ...seam } : defaultKeychain();
249
+ }
219
250
  /**
220
- * Best-effort OAuth access token for direct Anthropic API calls (the /model
221
- * catalog probe). Same resolution order as the usage panel: credentials file →
222
- * CLAUDE_CODE_OAUTH_TOKEN → shell rc. Null when nothing usable exists.
251
+ * The account claude files its Keychain item under (2.1.296, as Prism read it from the official darwin bundle, #1713
252
+ * review): `$USER`, else the OS user name; one that cannot be read or is not `[a-zA-Z0-9._-]+` is "claude-code-user".
223
253
  */
224
- export async function getClaudeOAuthToken() {
225
- const home = process.env.CLAUDE_HOME || join(homedir(), ".claude");
226
- let file;
254
+ function claudeKeychainAccount() {
255
+ let name;
227
256
  try {
228
- file = JSON.parse(await readFile(join(home, ".credentials.json"), "utf8")).claudeAiOauth ?? null;
257
+ name = process.env.USER || claudeKeychain.username();
229
258
  }
230
259
  catch {
231
- file = null;
260
+ name = undefined;
232
261
  }
233
- const auth = resolveClaudeAuth(file);
234
- return auth && "token" in auth ? auth.token : null;
262
+ return name && /^[a-zA-Z0-9._-]+$/.test(name) ? name : "claude-code-user";
235
263
  }
236
- /** Exported for tests — the statusline/API preference order is the subject. */
237
- export async function fetchClaudeUsage() {
238
- const home = process.env.CLAUDE_HOME || join(homedir(), ".claude");
239
- let file;
264
+ /**
265
+ * A credential profile's own Claude login (#1699) — and nothing else: on macOS the Keychain item claude keeps for
266
+ * exactly this config dir (claudeKeychainService; the account is $USER, as claude names it), else — or when that has
267
+ * none — the dir's `.credentials.json`. Never the shared login, `CLAUDE_CODE_OAUTH_TOKEN` or a shell rc: those are
268
+ * another account's, and their numbers on this row would be a lie about this subscription.
269
+ */
270
+ async function readClaudeProfileLogin(configDir) {
271
+ if (claudeKeychain.platform === "darwin") {
272
+ // As claude: a credentials document in the Keychain is THE login — one with no OAuth in it (say only MCP
273
+ // logins) means no OAuth login, and an older `.credentials.json` beside it is not consulted (#1713 review).
274
+ const secret = await claudeKeychain.read(claudeKeychainService(configDir), claudeKeychainAccount());
275
+ const document = secret ? credentialsDocument(secret) : null;
276
+ if (document)
277
+ return claudeOAuthOf(secret);
278
+ }
279
+ return readClaudeCredentialsFile(configDir);
280
+ }
281
+ /** A credentials document (any JSON object), or null — unparseable is no document, as claude reads its storage. */
282
+ function credentialsDocument(json) {
240
283
  try {
241
- file = JSON.parse(await readFile(join(home, ".credentials.json"), "utf8")).claudeAiOauth ?? null;
284
+ const v = JSON.parse(json);
285
+ return v && typeof v === "object" ? v : null;
242
286
  }
243
287
  catch {
244
- file = null;
288
+ return null;
245
289
  }
290
+ }
291
+ /**
292
+ * Whether a token the profile's own login does not control can reach claude in a profile's pane: AgEnD sets only
293
+ * `CLAUDE_CONFIG_DIR` for a profile, so `CLAUDE_CODE_OAUTH_TOKEN` from the fleet's environment, or set in a shell rc
294
+ * the pane's shell reads, still signs it in — and outranks the stored login (#1713 review).
295
+ */
296
+ function envTokenReachesClaude() {
297
+ return !!process.env.CLAUDE_CODE_OAUTH_TOKEN?.trim() || shellRcSetsClaudeToken((path) => readFileSync(path, "utf-8"));
298
+ }
299
+ /**
300
+ * Whether a shell rc sets `CLAUDE_CODE_OAUTH_TOKEN` at all — any assignment, export or declaration that is not a
301
+ * comment, whatever its value: `"$OTHER"` or `${OTHER}` is a token once the pane's shell expands it, so unlike
302
+ * tokenFromShellRc (which must hand the API a literal bearer) this never discounts one it cannot read (#1713 review).
303
+ * Files those rcs `source` are not followed.
304
+ */
305
+ export function shellRcSetsClaudeToken(read, home = homedir(), files = SHELL_RC_FILES) {
306
+ const sets = [
307
+ /^[ \t]*(?:(?:export|readonly|local|declare|typeset)(?:[ \t]+-[a-zA-Z]+)*[ \t]+(?:[^#\n]*[ \t])?)?CLAUDE_CODE_OAUTH_TOKEN[ \t]*=/m,
308
+ /^[ \t]*(?:export|declare[ \t]+-[a-zA-Z]*x[a-zA-Z]*|typeset[ \t]+-[a-zA-Z]*x[a-zA-Z]*)[ \t]+(?:[^#\n]*[ \t])?CLAUDE_CODE_OAUTH_TOKEN\b/m,
309
+ /^[ \t]*setenv[ \t]+CLAUDE_CODE_OAUTH_TOKEN\b/m,
310
+ ];
311
+ for (const file of files) {
312
+ let content;
313
+ try {
314
+ content = read(join(home, file));
315
+ }
316
+ catch {
317
+ continue;
318
+ }
319
+ if (sets.some((re) => re.test(content)))
320
+ return true;
321
+ }
322
+ return false;
323
+ }
324
+ /** `path` is `dir` or inside it. */
325
+ const isWithin = (path, dir) => { const p = resolve(path); return p === dir || p.startsWith(dir + sep); };
326
+ /**
327
+ * Best-effort OAuth access token for direct Anthropic API calls (the /model
328
+ * catalog probe). Same resolution order as the usage panel: credentials file →
329
+ * CLAUDE_CODE_OAUTH_TOKEN → shell rc. Null when nothing usable exists. With
330
+ * `storeHome` (a credential profile's config dir, #1699): that profile's login only.
331
+ */
332
+ export async function getClaudeOAuthToken(storeHome) {
333
+ const auth = storeHome !== undefined
334
+ ? resolveClaudeAuth(await readClaudeProfileLogin(storeHome), {}, () => null)
335
+ : resolveClaudeAuth(await readClaudeCredentialsFile(process.env.CLAUDE_HOME || join(homedir(), ".claude")));
336
+ return auth && "token" in auth ? auth.token : null;
337
+ }
338
+ /**
339
+ * Exported for tests — the statusline/API preference order is the subject.
340
+ *
341
+ * `storeHome` (#1699): a credential profile's config dir — the row reads that profile's login and only the rate
342
+ * limits its own instances wrote (their conversations are under its `projects/`); a profile with no login says so,
343
+ * with the line that signs it in, and never shows the shared account's numbers. Without it: the shared login as
344
+ * always; beside profiles (`besideProfiles`), its statusline fallback leaves the profiles' instances out.
345
+ */
346
+ export async function fetchClaudeUsage(storeHome, scope = {}) {
347
+ const profileHome = storeHome !== undefined ? resolve(storeHome) : null;
348
+ const file = profileHome !== null
349
+ ? await readClaudeProfileLogin(profileHome)
350
+ : await readClaudeCredentialsFile(process.env.CLAUDE_HOME || join(homedir(), ".claude"));
246
351
  // Read before anything else: it costs one stat per instance, needs no token,
247
352
  // and it is what keeps the panel useful when the API path cannot run at all.
248
- const statusline = readStatuslineRateLimits();
249
- const auth = resolveClaudeAuth(file);
353
+ // A profile's: only readings written under its own `projects/` — and only when nothing but its own login can
354
+ // have signed those instances in. Where the conversation is says which config dir, not whose subscription: with
355
+ // a token in the environment the readings may be another account's, so none is this row's (#1713 review).
356
+ const profilesRoot = resolve(getAgendHome(), "credential-profiles", "claude-code");
357
+ const statusline = profileHome !== null
358
+ ? (envTokenReachesClaude() ? null : readStatuslineRateLimits(undefined, undefined, (path) => path !== null && isWithin(path, join(profileHome, "projects"))))
359
+ : readStatuslineRateLimits(undefined, undefined, scope.besideProfiles ? (path) => path === null || !isWithin(path, profilesRoot) : undefined);
360
+ const auth = profileHome !== null ? resolveClaudeAuth(file, {}, () => null) : resolveClaudeAuth(file);
250
361
  if (auth === null) {
251
362
  // No token anywhere — but the CLI itself is logged in somehow (including an
252
363
  // API key, which the usage endpoint rejects outright), and it wrote its
253
364
  // limits down. This is the case the whole statusline source exists for.
254
365
  if (statusline)
255
366
  return statuslineUsage(statusline, null);
367
+ if (profileHome !== null) {
368
+ // On screen (`ok`, as kiro's signed-out row), with what signs this profile in — never a fallback: from chat
369
+ // (`/login claude-code <profile>`, #1699 part 2), or the exact line on the host — the same words as the auth alert.
370
+ const host = (scope.profile && credentialProfileLoginCommand(getAgendHome(), "claude-code", scope.profile))
371
+ || `CLAUDE_CONFIG_DIR=${JSON.stringify(profileHome)} claude auth login`;
372
+ if (scope.profile && CHAT_PROFILE_LOGIN_BACKENDS.has("claude-code")) {
373
+ const chat = `/login claude-code ${scope.profile}`;
374
+ return { status: "ok", hint: `Not logged in — sign in with \`${chat}\` (or run \`${host}\` on the host).`, hintI18n: i18n("usage.hint.claude_profile_signed_out_chat", chat, host), metrics: [] };
375
+ }
376
+ return { status: "ok", hint: `Not logged in — sign in with: ${host}`, hintI18n: i18n("usage.hint.claude_profile_signed_out", host), metrics: [] };
377
+ }
256
378
  const hint = process.env.ANTHROPIC_API_KEY
257
379
  ? "API-key login has no subscription usage. Use `claude /login` or set CLAUDE_CODE_OAUTH_TOKEN (from `claude setup-token`)."
258
380
  : "Log in with the Claude Code CLI (`claude`).";
@@ -1274,13 +1396,14 @@ export function providersForConfig(config, base = DEFAULT_PROVIDERS) {
1274
1396
  rows.push({
1275
1397
  id: provider.id,
1276
1398
  name: provider.id === "codex" ? `${provider.name} (default)` : provider.name,
1277
- fetch: () => provider.fetch(),
1399
+ // Claude's shared row keeps its statusline fallback to the shared instances (#1699); others ignore the scope.
1400
+ fetch: () => provider.fetch(undefined, { besideProfiles: true }),
1278
1401
  });
1279
1402
  }
1280
1403
  rows.push(...profiles.map(profile => ({
1281
1404
  id: `${provider.id}:${profile}`,
1282
1405
  name: `${provider.name} (${profile})`,
1283
- fetch: () => provider.fetch(credentialProfileStoreHome(getAgendHome(), backendName, profile)),
1406
+ fetch: () => provider.fetch(credentialProfileStoreHome(getAgendHome(), backendName, profile), { profile }),
1284
1407
  })));
1285
1408
  return rows;
1286
1409
  });
@@ -1302,7 +1425,7 @@ function hasEffectiveSharedBinding(config, backendName) {
1302
1425
  const instances = config.instances ?? {};
1303
1426
  let sawEffectiveBinding = false;
1304
1427
  for (const instance of Object.values(instances)) {
1305
- const backend = instance.backend ?? defaults?.backend;
1428
+ const backend = instance.backend ?? defaultBackend(defaults);
1306
1429
  if (backend !== backendName)
1307
1430
  continue;
1308
1431
  sawEffectiveBinding = true;
@@ -1313,12 +1436,20 @@ function hasEffectiveSharedBinding(config, backendName) {
1313
1436
  // backend is this provider and no profile was configured. With no known
1314
1437
  // binding at all, preserve the pre-profile shared-provider behaviour.
1315
1438
  if (!sawEffectiveBinding) {
1316
- if (defaults?.backend === backendName && !instanceCredentialProfile(undefined, defaults, backendName))
1439
+ if (defaultBackend(defaults) === backendName && !instanceCredentialProfile(undefined, defaults, backendName))
1317
1440
  return true;
1318
1441
  return Object.keys(instances).length === 0;
1319
1442
  }
1320
1443
  return false;
1321
1444
  }
1445
+ /**
1446
+ * The backend an instance without one runs: the fleet default, else Claude Code — as the fleet launches it
1447
+ * (fleet-manager's bindings). Claude Code is the backend instances most often leave unnamed, so without this a
1448
+ * Claude profile on such an instance had no row of its own (#1699).
1449
+ */
1450
+ function defaultBackend(defaults) {
1451
+ return defaults?.backend ?? "claude-code";
1452
+ }
1322
1453
  /** Profiles on effective bindings only (not dormant backend_options on another backend). */
1323
1454
  function effectiveCredentialProfiles(config, backendName) {
1324
1455
  if (!config)
@@ -1326,14 +1457,14 @@ function effectiveCredentialProfiles(config, backendName) {
1326
1457
  const found = new Set();
1327
1458
  const defaults = config.defaults;
1328
1459
  for (const instance of Object.values(config.instances ?? {})) {
1329
- const backend = instance.backend ?? defaults?.backend;
1460
+ const backend = instance.backend ?? defaultBackend(defaults);
1330
1461
  if (backend !== backendName)
1331
1462
  continue;
1332
1463
  const profile = bindingProfile(instance, defaults, backendName);
1333
1464
  if (profile)
1334
1465
  found.add(profile);
1335
1466
  }
1336
- if (Object.keys(config.instances ?? {}).length === 0 && defaults?.backend === backendName) {
1467
+ if (Object.keys(config.instances ?? {}).length === 0 && defaultBackend(defaults) === backendName) {
1337
1468
  const profile = instanceCredentialProfile(undefined, defaults, backendName);
1338
1469
  if (profile)
1339
1470
  found.add(profile);
@@ -1387,6 +1518,8 @@ function usageBackendForProviderId(id) {
1387
1518
  return "kiro-cli";
1388
1519
  if (id === "codex")
1389
1520
  return "codex";
1521
+ if (id === "claude")
1522
+ return "claude-code";
1390
1523
  return null;
1391
1524
  }
1392
1525
  let PROVIDERS = DEFAULT_PROVIDERS;