@songsid/agend 2.1.4-beta.6 → 2.1.4-beta.60

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 (185) hide show
  1. package/README.md +1 -1
  2. package/README.zh-TW.md +1 -1
  3. package/dist/agent-cli-instructions.md +2 -2
  4. package/dist/agent-endpoint.js +1 -1
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/backend/antigravity.d.ts +12 -8
  7. package/dist/backend/antigravity.js +189 -42
  8. package/dist/backend/antigravity.js.map +1 -1
  9. package/dist/backend/claude-code.d.ts +87 -23
  10. package/dist/backend/claude-code.js +361 -46
  11. package/dist/backend/claude-code.js.map +1 -1
  12. package/dist/backend/codex.d.ts +18 -0
  13. package/dist/backend/codex.js +143 -7
  14. package/dist/backend/codex.js.map +1 -1
  15. package/dist/backend/gemini-cli.js +2 -2
  16. package/dist/backend/gemini-cli.js.map +1 -1
  17. package/dist/backend/grok.js +2 -2
  18. package/dist/backend/grok.js.map +1 -1
  19. package/dist/backend/kiro.d.ts +52 -2
  20. package/dist/backend/kiro.js +267 -12
  21. package/dist/backend/kiro.js.map +1 -1
  22. package/dist/backend/opencode.js +17 -4
  23. package/dist/backend/opencode.js.map +1 -1
  24. package/dist/backend/types.d.ts +122 -3
  25. package/dist/backend/types.js +5 -1
  26. package/dist/backend/types.js.map +1 -1
  27. package/dist/backend-outage.d.ts +61 -0
  28. package/dist/backend-outage.js +71 -0
  29. package/dist/backend-outage.js.map +1 -0
  30. package/dist/channel/adapters/discord.d.ts +44 -2
  31. package/dist/channel/adapters/discord.js +529 -89
  32. package/dist/channel/adapters/discord.js.map +1 -1
  33. package/dist/channel/adapters/telegram.d.ts +30 -0
  34. package/dist/channel/adapters/telegram.js +221 -19
  35. package/dist/channel/adapters/telegram.js.map +1 -1
  36. package/dist/channel/agy-mcp-launcher.d.ts +2 -0
  37. package/dist/channel/agy-mcp-launcher.js +28 -0
  38. package/dist/channel/agy-mcp-launcher.js.map +1 -0
  39. package/dist/channel/ipc-bridge.d.ts +2 -1
  40. package/dist/channel/ipc-bridge.js +33 -4
  41. package/dist/channel/ipc-bridge.js.map +1 -1
  42. package/dist/channel/markdown-chunk.d.ts +42 -0
  43. package/dist/channel/markdown-chunk.js +205 -0
  44. package/dist/channel/markdown-chunk.js.map +1 -0
  45. package/dist/channel/mcp-server.js +28 -25
  46. package/dist/channel/mcp-server.js.map +1 -1
  47. package/dist/channel/mcp-tools.js +6 -4
  48. package/dist/channel/mcp-tools.js.map +1 -1
  49. package/dist/channel/message-queue.js +64 -8
  50. package/dist/channel/message-queue.js.map +1 -1
  51. package/dist/channel/types.d.ts +31 -1
  52. package/dist/classic-channel-manager.d.ts +65 -0
  53. package/dist/classic-channel-manager.js +172 -3
  54. package/dist/classic-channel-manager.js.map +1 -1
  55. package/dist/cli.js +124 -83
  56. package/dist/cli.js.map +1 -1
  57. package/dist/config-validator.js +16 -0
  58. package/dist/config-validator.js.map +1 -1
  59. package/dist/config.d.ts +4 -0
  60. package/dist/config.js +12 -1
  61. package/dist/config.js.map +1 -1
  62. package/dist/cross-instance-envelope.d.ts +6 -0
  63. package/dist/cross-instance-envelope.js +30 -0
  64. package/dist/cross-instance-envelope.js.map +1 -0
  65. package/dist/daemon.d.ts +506 -11
  66. package/dist/daemon.js +2162 -313
  67. package/dist/daemon.js.map +1 -1
  68. package/dist/doctor.d.ts +41 -0
  69. package/dist/doctor.js +267 -0
  70. package/dist/doctor.js.map +1 -0
  71. package/dist/fleet-context.d.ts +63 -0
  72. package/dist/fleet-context.js.map +1 -1
  73. package/dist/fleet-manager.d.ts +422 -12
  74. package/dist/fleet-manager.js +2961 -635
  75. package/dist/fleet-manager.js.map +1 -1
  76. package/dist/fleet-yaml-slim.d.ts +10 -0
  77. package/dist/fleet-yaml-slim.js +59 -0
  78. package/dist/fleet-yaml-slim.js.map +1 -0
  79. package/dist/general-knowledge/skills/backend-providers/SKILL.md +114 -0
  80. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +4 -1
  81. package/dist/general-knowledge/skills/delegation-playbook/SKILL.md +52 -0
  82. package/dist/general-knowledge/skills/development-workflow/SKILL.md +28 -0
  83. package/dist/general-knowledge/skills/fleet-config/SKILL.md +1 -0
  84. package/dist/general-knowledge/skills/fleet-health/SKILL.md +1 -0
  85. package/dist/general-knowledge/skills/fleet-restart/SKILL.md +1 -0
  86. package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +1 -0
  87. package/dist/general-knowledge/skills/model-discovery/SKILL.md +64 -16
  88. package/dist/general-knowledge/skills/multi-channel/SKILL.md +1 -0
  89. package/dist/general-knowledge/skills/scheduling/SKILL.md +1 -0
  90. package/dist/general-knowledge/skills/session-management/SKILL.md +172 -8
  91. package/dist/general-knowledge/skills/tui-effort/SKILL.md +1 -0
  92. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +30 -0
  93. package/dist/instance-lifecycle.d.ts +99 -0
  94. package/dist/instance-lifecycle.js +357 -11
  95. package/dist/instance-lifecycle.js.map +1 -1
  96. package/dist/instructions.d.ts +12 -0
  97. package/dist/instructions.js +74 -3
  98. package/dist/instructions.js.map +1 -1
  99. package/dist/locale.js +1022 -310
  100. package/dist/locale.js.map +1 -1
  101. package/dist/login-flows.d.ts +91 -0
  102. package/dist/login-flows.js +170 -0
  103. package/dist/login-flows.js.map +1 -0
  104. package/dist/login-manager.d.ts +63 -0
  105. package/dist/login-manager.js +134 -0
  106. package/dist/login-manager.js.map +1 -0
  107. package/dist/network-family.d.ts +18 -0
  108. package/dist/network-family.js +20 -0
  109. package/dist/network-family.js.map +1 -0
  110. package/dist/outbound-handlers.d.ts +16 -1
  111. package/dist/outbound-handlers.js +174 -40
  112. package/dist/outbound-handlers.js.map +1 -1
  113. package/dist/outbound-schemas.d.ts +11 -3
  114. package/dist/outbound-schemas.js +11 -0
  115. package/dist/outbound-schemas.js.map +1 -1
  116. package/dist/pane-input-residue.d.ts +52 -0
  117. package/dist/pane-input-residue.js +107 -0
  118. package/dist/pane-input-residue.js.map +1 -0
  119. package/dist/process-memory.d.ts +6 -0
  120. package/dist/process-memory.js +45 -0
  121. package/dist/process-memory.js.map +1 -1
  122. package/dist/reply-dedup.d.ts +7 -8
  123. package/dist/reply-dedup.js +0 -0
  124. package/dist/reply-dedup.js.map +1 -1
  125. package/dist/restart-progress.d.ts +2 -0
  126. package/dist/restart-progress.js +3 -0
  127. package/dist/restart-progress.js.map +1 -1
  128. package/dist/scheduler/db.d.ts +12 -0
  129. package/dist/scheduler/db.js +59 -0
  130. package/dist/scheduler/db.js.map +1 -1
  131. package/dist/service-installer.d.ts +11 -0
  132. package/dist/service-installer.js +84 -18
  133. package/dist/service-installer.js.map +1 -1
  134. package/dist/settings-api.js +1 -1
  135. package/dist/settings-api.js.map +1 -1
  136. package/dist/setup-wizard.js +2 -2
  137. package/dist/setup-wizard.js.map +1 -1
  138. package/dist/spawn-gate.d.ts +30 -0
  139. package/dist/spawn-gate.js +79 -0
  140. package/dist/spawn-gate.js.map +1 -0
  141. package/dist/steer-capability.d.ts +1 -0
  142. package/dist/steer-capability.js +6 -0
  143. package/dist/steer-capability.js.map +1 -0
  144. package/dist/storm-window.d.ts +83 -0
  145. package/dist/storm-window.js +251 -0
  146. package/dist/storm-window.js.map +1 -0
  147. package/dist/tips.d.ts +44 -0
  148. package/dist/tips.js +355 -0
  149. package/dist/tips.js.map +1 -0
  150. package/dist/tmux-manager.d.ts +16 -0
  151. package/dist/tmux-manager.js +110 -25
  152. package/dist/tmux-manager.js.map +1 -1
  153. package/dist/tool-progress.d.ts +40 -0
  154. package/dist/tool-progress.js +289 -0
  155. package/dist/tool-progress.js.map +1 -0
  156. package/dist/topic-commands.d.ts +45 -6
  157. package/dist/topic-commands.js +394 -66
  158. package/dist/topic-commands.js.map +1 -1
  159. package/dist/transcript-monitor.d.ts +15 -2
  160. package/dist/transcript-monitor.js +63 -17
  161. package/dist/transcript-monitor.js.map +1 -1
  162. package/dist/transcript-sources.d.ts +131 -0
  163. package/dist/transcript-sources.js +580 -0
  164. package/dist/transcript-sources.js.map +1 -0
  165. package/dist/types.d.ts +11 -0
  166. package/dist/ui/dashboard.html +55 -32
  167. package/dist/ui/settings.html +200 -60
  168. package/dist/ui/view.html +147 -30
  169. package/dist/usage/format-rich.d.ts +1 -1
  170. package/dist/usage/format-rich.js +28 -24
  171. package/dist/usage/format-rich.js.map +1 -1
  172. package/dist/usage/i18n-keys.d.ts +7 -0
  173. package/dist/usage/i18n-keys.js +34 -0
  174. package/dist/usage/i18n-keys.js.map +1 -0
  175. package/dist/usage/i18n.d.ts +5 -0
  176. package/dist/usage/i18n.js +27 -0
  177. package/dist/usage/i18n.js.map +1 -0
  178. package/dist/usage/providers.d.ts +21 -0
  179. package/dist/usage/providers.js +153 -75
  180. package/dist/usage/providers.js.map +1 -1
  181. package/dist/usage/usage-api.d.ts +11 -3
  182. package/dist/usage/usage-api.js +61 -24
  183. package/dist/usage/usage-api.js.map +1 -1
  184. package/dist/workflow-templates/default.md +2 -1
  185. package/package.json +2 -2
@@ -40,7 +40,7 @@ export interface CliBackendConfig {
40
40
  /** Action to take when an error pattern is detected in PTY output. */
41
41
  export type ErrorActionType = "notify" | "failover" | "restart" | "pause";
42
42
  /** Categorizes detected errors for logging and response. */
43
- export type ErrorType = "rate_limit" | "auth_error" | "crash" | "network" | "quota" | "timeout" | "model_error";
43
+ export type ErrorType = "rate_limit" | "auth_error" | "crash" | "network" | "quota" | "timeout" | "model_error" | "config_error";
44
44
  export interface ErrorPattern {
45
45
  pattern: RegExp;
46
46
  type: ErrorType;
@@ -60,6 +60,12 @@ export interface ErrorPattern {
60
60
  * immediately) whose backend ready-pattern only matches the startup banner,
61
61
  * so waiting would block ALL future error detection forever. */
62
62
  skipRecoveryWait?: boolean;
63
+ /** This error is a property of the BACKEND (its service is unreachable), not
64
+ * of one instance: every instance on that CLI fails at once. The lifecycle
65
+ * then records a fleet-level backend outage, notifies ONCE fleet-wide instead
66
+ * of per instance, and the daemon stops spending `--resume` attempts (and
67
+ * sessions) on it while it lasts. Only meaningful with type "network". */
68
+ fleetWide?: boolean;
63
69
  }
64
70
  /** A selectable model, surfaced by `/model` (id is what gets applied). */
65
71
  export interface ModelOption {
@@ -74,6 +80,12 @@ export interface CliEnv {
74
80
  authenticated?: boolean;
75
81
  currentModel?: string;
76
82
  models: ModelOption[];
83
+ /**
84
+ * Extended account catalog behind the "/model → more models" tier (claude:
85
+ * live `GET /v1/models` plus [1m] variants). Kept separate from `models` so
86
+ * the quick-pick tier stays short.
87
+ */
88
+ apiModels?: ModelOption[];
77
89
  /** Epoch ms the probe ran (drives the cache TTL). */
78
90
  probedAt: number;
79
91
  }
@@ -87,9 +99,52 @@ export interface RuntimeDialog {
87
99
  keys: string[];
88
100
  /** Human-readable description for logging. */
89
101
  description: string;
102
+ /**
103
+ * While this dialog is on screen the pane is NOT deliverable: no paste, no
104
+ * Enter, no native-queue or steer hand-off. Opt-in on purpose — the delivery
105
+ * gate runs on every ordinary message against the whole viewport, so only
106
+ * patterns that cannot match transcript prose belong here (require the
107
+ * dialog's structure: selector glyph, numbered options, exact wording).
108
+ * Absent means the runtime scanner may still auto-dismiss the dialog, but
109
+ * delivery is not held for it.
110
+ */
111
+ blocksDelivery?: boolean;
112
+ /**
113
+ * When present, decides whether the dialog is the CURRENT interactive region
114
+ * of the pane — typically bottom-anchored: the menu rows are the last thing
115
+ * on screen apart from the dialog's own footer, and no ready prompt follows
116
+ * them. Used instead of `pattern` wherever a match would block delivery or
117
+ * send keys; `pattern` stays the cheap identity/pre-filter. Without it a
118
+ * transcript that quotes the dialog verbatim (a pasted pane capture, this
119
+ * very bug being discussed) would count as a live dialog and receive keys.
120
+ */
121
+ isActive?(pane: string): boolean;
122
+ /**
123
+ * Recognise the dialog but NEVER answer it. Implies `blocksDelivery`. If it
124
+ * persists, the daemon reports it for a human. Use for dialogs whose default
125
+ * option is destructive when the exact shape is not the one we know how to
126
+ * navigate — e.g. a variant of Claude's session-resume prompt, where a blind
127
+ * Enter picks "Resume from summary" and drops the full context. `keys` is
128
+ * ignored.
129
+ */
130
+ holdOnly?: boolean;
90
131
  }
91
- /** A dialog that may appear during CLI startup (trust prompts, session pickers, etc.). */
92
- export type StartupDialog = RuntimeDialog;
132
+ /**
133
+ * A dialog that may appear during CLI startup (trust prompts, session pickers, etc.).
134
+ * With `fatal` set, the screen cannot be dismissed by keypresses (e.g. a corrupt
135
+ * claude.json modal whose only choices are "exit" and "reset config"): the daemon
136
+ * reports the error instead of sending keys — `keys` is ignored and should be [].
137
+ * This must be detected as a dialog, not left to the ready check: such modals
138
+ * often contain the `❯` selector that ready patterns match, so they would
139
+ * otherwise pass as ready and queued messages would be typed into the modal.
140
+ */
141
+ export type StartupDialog = RuntimeDialog & {
142
+ fatal?: {
143
+ type: ErrorType;
144
+ action: ErrorActionType;
145
+ message: string;
146
+ };
147
+ };
93
148
  export interface CliBackend {
94
149
  /** The CLI binary name (e.g. "claude", "gemini", "codex") */
95
150
  readonly binaryName: string;
@@ -109,6 +164,62 @@ export interface CliBackend {
109
164
  * at an empty prompt and during generation. Absent means false.
110
165
  */
111
166
  requiresDeliveryEnterRetry?(): boolean;
167
+ /**
168
+ * Whether the TUI DROPS an Enter that arrives while it is generating or
169
+ * running a tool, while still accepting the typed text as typeahead (Kiro's
170
+ * legacy UI, verified live on kiro-cli 2.21.0). For such a TUI, a quiet pane
171
+ * is not evidence of readiness: a shell/MCP tool can run for many seconds
172
+ * without painting anything, and a paste+Enter landing in that window leaves
173
+ * the text sitting unsubmitted in the prompt row until the next Enter — which
174
+ * then submits two messages as one. When true, the daemon requires the
175
+ * bottom-anchored ready marker (`getBottomReadyPattern`) before pasting and
176
+ * FAILS CLOSED without it (a non-blank pane whose bottom row is not the
177
+ * prompt is treated as busy — the prompt may simply have scrolled out of the
178
+ * viewport behind tool output), verifies SUBMISSION (not just "some output")
179
+ * after Enter, and submits any stranded text before pasting a new message.
180
+ * Return true only for a UI whose prompt row the pattern below recognises;
181
+ * other UI flavours of the same CLI should return false and keep the
182
+ * silence gate. Absent means false.
183
+ */
184
+ dropsEnterWhileBusy?(): boolean;
185
+ /**
186
+ * Ready marker tested against ONE pane row at a time (the LAST non-blank row
187
+ * for readiness), so `^` anchors the row start — anchor it: an unanchored
188
+ * marker matches ordinary tool output (`Progress 50% > /tmp/out`). Distinct
189
+ * from `getReadyPattern()`, which may match anywhere on screen (a prompt
190
+ * higher up is history). Required for `dropsEnterWhileBusy()` backends.
191
+ */
192
+ getBottomReadyPattern?(): RegExp | null;
193
+ /**
194
+ * Startup budget override, in ms, for reaching first output + ready state.
195
+ * `ctx.resume` is true when the CLI is launched with session resume. Return
196
+ * undefined to use `startup_timeout_ms` / the 25s default. Kiro's `--resume`
197
+ * needs a backend round trip before it paints anything (blank for >15s while
198
+ * the runtime host retried, live 2026-09-03) whereas a fresh prompt is local
199
+ * — so only the resume launch should get more time; a fresh start must stay
200
+ * tight. The daemon never lowers a user-configured `startup_timeout_ms`.
201
+ */
202
+ getStartupBudgetMs?(ctx: {
203
+ resume: boolean;
204
+ }): number | undefined;
205
+ /**
206
+ * Whether a failed resume launch should be retried ONCE with resume before
207
+ * the session is abandoned. For CLIs whose resume depends on a remote round
208
+ * trip, the first miss is usually the backend being slow, not the session
209
+ * being corrupt — and dropping to a fresh session loses the conversation.
210
+ * The daemon bounds this to one extra attempt. Absent means false.
211
+ */
212
+ retriesResumeOnStartupFailure?(): boolean;
213
+ /**
214
+ * Whether the TUI can emit terminal output while its visible pane is
215
+ * unchanged (for example, rerunning and repainting a status-line hook).
216
+ *
217
+ * The daemon normally treats every tmux control-mode output event as immediate
218
+ * evidence of work. Backends with periodic cosmetic redraws instead require a
219
+ * pane capture to confirm that visible content actually changed. Absent means
220
+ * false.
221
+ */
222
+ hasPeriodicPaneRedraw?(): boolean;
112
223
  /** Build the shell command string to launch the CLI in a tmux window. */
113
224
  buildCommand(config: CliBackendConfig): string;
114
225
  /** Write all config files the CLI needs before launch. */
@@ -193,6 +304,14 @@ export interface CliBackend {
193
304
  * verified equivalent. Used by the admin-only /clear fleet command.
194
305
  */
195
306
  getClearCommand(): string | null;
307
+ /**
308
+ * Optional confirmation shown after getClearCommand() is submitted. AgEnD
309
+ * already obtains an admin confirmation in the channel, so a backend that
310
+ * adds its own terminal prompt can be answered automatically. The daemon
311
+ * only consults this for /clear deliveries; ordinary runtime dialogs and
312
+ * manually typed commands are not affected.
313
+ */
314
+ getClearConfirmationDialog?(): RuntimeDialog | null;
196
315
  /**
197
316
  * The tmux key that interrupts the CLI's current generation WITHOUT quitting —
198
317
  * "Escape" for most, "C-c" (Ctrl+C) for kiro-cli. Used by the cancel button and
@@ -73,7 +73,11 @@ export function resolveBinary(name, fallbackDirs) {
73
73
  * Throws if `model` contains anything else, since `buildCommand` returns a
74
74
  * shell string consumed by tmux and we cannot rely on argv-style quoting.
75
75
  */
76
- const SAFE_MODEL_RE = /^[A-Za-z0-9._:/-]+$/;
76
+ // Brackets admit Claude Code's 1M-context suffix (opus[1m] — binary-verified
77
+ // "append [1m] to the model name for 1M"). They are shell GLOB characters,
78
+ // so every command-line embed of a model MUST go through shellQuote(): an
79
+ // unquoted opus[1m] can pathname-expand in bash and aborts zsh outright.
80
+ const SAFE_MODEL_RE = /^[A-Za-z0-9._:/[\]-]+$/;
77
81
  /**
78
82
  * Guard an effort level before it reaches a shell command line. Same reasoning
79
83
  * as validateModel: the value originates from a chat message, and the launch
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/backend/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/backend/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Fleet-level "is this CLI's backend reachable?" memory.
3
+ *
4
+ * Some failures are a property of the BACKEND, not of one instance: when
5
+ * runtime.us-east-1.kiro.dev stopped answering (2026-09-03, hours), every kiro
6
+ * instance printed the same `dispatch failure (timeout)` line every 10s, every
7
+ * `--resume` launch sat blank past its startup budget, and the daemon's
8
+ * "resume failed → clear the session and start fresh" fallback turned a
9
+ * transient outage into permanent conversation loss across the fleet.
10
+ *
11
+ * One tracker per fleet, keyed by backend name. Sightings come from the
12
+ * lifecycle's pty_error handler (running instances) and from the daemon's
13
+ * startup path (a failed launch whose pane shows the outage text). "Active"
14
+ * means seen within the last BACKEND_OUTAGE_ACTIVE_MS; nothing has to report
15
+ * recovery — the memory simply ages out once the CLI stops printing the error.
16
+ */
17
+ /**
18
+ * How long after the last sighting a backend is still considered down.
19
+ *
20
+ * Longer than the longest startup-retry backoff (15 min) plus a startup budget:
21
+ * in an all-down fleet nothing is running to refresh the memory, and a retry
22
+ * that begins after it expired would clear the session it was meant to keep.
23
+ * Recovery is also cleared POSITIVELY — a successful `--resume` launch on the
24
+ * backend proves it reachable (see Daemon.spawnClaudeWindow) — so the long TTL
25
+ * costs nothing once the service is back.
26
+ */
27
+ export declare const BACKEND_OUTAGE_ACTIVE_MS: number;
28
+ export interface BackendOutageSighting {
29
+ firstSeenAt: number;
30
+ lastSeenAt: number;
31
+ /** Last human-readable detail (the formatted error message), if any. */
32
+ detail?: string;
33
+ /** Instances that reported it during this outage. */
34
+ instances: Set<string>;
35
+ }
36
+ export declare class BackendOutageTracker {
37
+ private readonly now;
38
+ private readonly outages;
39
+ constructor(now?: () => number);
40
+ /**
41
+ * Record a sighting. Returns `isNew` when this opens an outage (first
42
+ * sighting, or the previous one had aged out) — the moment to notify.
43
+ */
44
+ record(backend: string, instance?: string, detail?: string): {
45
+ isNew: boolean;
46
+ sighting: BackendOutageSighting;
47
+ };
48
+ isActive(backend: string): boolean;
49
+ /** The active sighting, or null once it has aged out. */
50
+ active(backend: string): BackendOutageSighting | null;
51
+ /** Forget a backend (e.g. an operator-confirmed recovery). */
52
+ clear(backend: string): void;
53
+ }
54
+ /** The subset a Daemon needs; lets tests pass a plain object. */
55
+ export interface BackendOutageView {
56
+ isActive(backend: string): boolean;
57
+ record(backend: string, instance?: string, detail?: string): {
58
+ isNew: boolean;
59
+ };
60
+ clear(backend: string): void;
61
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Fleet-level "is this CLI's backend reachable?" memory.
3
+ *
4
+ * Some failures are a property of the BACKEND, not of one instance: when
5
+ * runtime.us-east-1.kiro.dev stopped answering (2026-09-03, hours), every kiro
6
+ * instance printed the same `dispatch failure (timeout)` line every 10s, every
7
+ * `--resume` launch sat blank past its startup budget, and the daemon's
8
+ * "resume failed → clear the session and start fresh" fallback turned a
9
+ * transient outage into permanent conversation loss across the fleet.
10
+ *
11
+ * One tracker per fleet, keyed by backend name. Sightings come from the
12
+ * lifecycle's pty_error handler (running instances) and from the daemon's
13
+ * startup path (a failed launch whose pane shows the outage text). "Active"
14
+ * means seen within the last BACKEND_OUTAGE_ACTIVE_MS; nothing has to report
15
+ * recovery — the memory simply ages out once the CLI stops printing the error.
16
+ */
17
+ /**
18
+ * How long after the last sighting a backend is still considered down.
19
+ *
20
+ * Longer than the longest startup-retry backoff (15 min) plus a startup budget:
21
+ * in an all-down fleet nothing is running to refresh the memory, and a retry
22
+ * that begins after it expired would clear the session it was meant to keep.
23
+ * Recovery is also cleared POSITIVELY — a successful `--resume` launch on the
24
+ * backend proves it reachable (see Daemon.spawnClaudeWindow) — so the long TTL
25
+ * costs nothing once the service is back.
26
+ */
27
+ export const BACKEND_OUTAGE_ACTIVE_MS = 20 * 60_000;
28
+ export class BackendOutageTracker {
29
+ now;
30
+ outages = new Map();
31
+ constructor(now = Date.now) {
32
+ this.now = now;
33
+ }
34
+ /**
35
+ * Record a sighting. Returns `isNew` when this opens an outage (first
36
+ * sighting, or the previous one had aged out) — the moment to notify.
37
+ */
38
+ record(backend, instance, detail) {
39
+ const now = this.now();
40
+ const existing = this.outages.get(backend);
41
+ if (existing && now - existing.lastSeenAt < BACKEND_OUTAGE_ACTIVE_MS) {
42
+ existing.lastSeenAt = now;
43
+ if (detail)
44
+ existing.detail = detail;
45
+ if (instance)
46
+ existing.instances.add(instance);
47
+ return { isNew: false, sighting: existing };
48
+ }
49
+ const sighting = {
50
+ firstSeenAt: now,
51
+ lastSeenAt: now,
52
+ detail,
53
+ instances: new Set(instance ? [instance] : []),
54
+ };
55
+ this.outages.set(backend, sighting);
56
+ return { isNew: true, sighting };
57
+ }
58
+ isActive(backend) {
59
+ const sighting = this.outages.get(backend);
60
+ return !!sighting && this.now() - sighting.lastSeenAt < BACKEND_OUTAGE_ACTIVE_MS;
61
+ }
62
+ /** The active sighting, or null once it has aged out. */
63
+ active(backend) {
64
+ return this.isActive(backend) ? this.outages.get(backend) : null;
65
+ }
66
+ /** Forget a backend (e.g. an operator-confirmed recovery). */
67
+ clear(backend) {
68
+ this.outages.delete(backend);
69
+ }
70
+ }
71
+ //# sourceMappingURL=backend-outage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-outage.js","sourceRoot":"","sources":["../src/backend-outage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,GAAG,MAAM,CAAC;AAWpD,MAAM,OAAO,oBAAoB;IAGF;IAFZ,OAAO,GAAG,IAAI,GAAG,EAAiC,CAAC;IAEpE,YAA6B,MAAoB,IAAI,CAAC,GAAG;QAA5B,QAAG,GAAH,GAAG,CAAyB;IAAG,CAAC;IAE7D;;;OAGG;IACH,MAAM,CAAC,OAAe,EAAE,QAAiB,EAAE,MAAe;QACxD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,QAAQ,IAAI,GAAG,GAAG,QAAQ,CAAC,UAAU,GAAG,wBAAwB,EAAE,CAAC;YACrE,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;YAC1B,IAAI,MAAM;gBAAE,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;YACrC,IAAI,QAAQ;gBAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC/C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAC9C,CAAC;QACD,MAAM,QAAQ,GAA0B;YACtC,WAAW,EAAE,GAAG;YAChB,UAAU,EAAE,GAAG;YACf,MAAM;YACN,SAAS,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/C,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACpC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IACnC,CAAC;IAED,QAAQ,CAAC,OAAe;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,UAAU,GAAG,wBAAwB,CAAC;IACnF,CAAC;IAED,yDAAyD;IACzD,MAAM,CAAC,OAAe;QACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,CAAC;IAED,8DAA8D;IAC9D,KAAK,CAAC,OAAe;QACnB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;CACF"}
@@ -1,5 +1,6 @@
1
1
  import { EventEmitter } from "node:events";
2
- import type { ChannelAdapter, ApprovalHandle, SendOpts, SentMessage, PermissionPrompt, Choice, AlertData } from "../types.js";
2
+ import { Client } from "discord.js";
3
+ import type { ChannelAdapter, ApprovalHandle, SendOpts, SentMessage, PermissionPrompt, Choice, AlertData, AdapterHealthSnapshot } from "../types.js";
3
4
  import type { AccessManager } from "../access-manager.js";
4
5
  /** Curated ClassicBot backends for Discord's native slash-option dropdown. */
5
6
  export declare const DISCORD_START_BACKEND_CHOICES: readonly [{
@@ -30,12 +31,39 @@ export interface DiscordAdapterOptions {
30
31
  categoryName?: string;
31
32
  generalChannelId?: string;
32
33
  registerCommands?: boolean;
34
+ /** Test seams; production callers leave these unset. */
35
+ clientFactory?: () => Client;
36
+ now?: () => number;
37
+ watchdogIntervalMs?: number;
38
+ staleThresholdMs?: number;
39
+ reconnectBaseDelayMs?: number;
33
40
  }
34
41
  export declare class DiscordAdapter extends EventEmitter implements ChannelAdapter {
35
42
  readonly type = "discord";
36
43
  readonly topology: "channels";
37
44
  readonly id: string;
38
45
  private client;
46
+ private readonly clientFactory;
47
+ private readonly now;
48
+ private readonly watchdogIntervalMs;
49
+ private readonly staleThresholdMs;
50
+ private readonly reconnectBaseDelayMs;
51
+ private desiredRunning;
52
+ private lifecycleEpoch;
53
+ private clientGeneration;
54
+ private reconnectPromise;
55
+ private watchdogTimer;
56
+ private lastWatchdogTickAt;
57
+ private generationReadyAt;
58
+ private generationNonReadySince;
59
+ private shardNonReadySince;
60
+ private previousHeartbeatAck;
61
+ private observedHeartbeatInterval;
62
+ private healthStatus;
63
+ private lastDispatchAt;
64
+ private lastReconnectAt;
65
+ private lastReconnectReason;
66
+ private reconnectCount;
39
67
  private botToken;
40
68
  private accessManager;
41
69
  private inboxDir;
@@ -49,10 +77,22 @@ export declare class DiscordAdapter extends EventEmitter implements ChannelAdapt
49
77
  private attachmentUrls;
50
78
  private categoryIdPromise?;
51
79
  constructor(opts: DiscordAdapterOptions);
80
+ private buildClient;
52
81
  private _fetchTextChannel;
53
- private _registerHandlers;
82
+ private registerClientHandlers;
54
83
  /** Mark channels as open (skip access control) — used for classic bot channels */
55
84
  setOpenChannels(channelIds: string[]): void;
85
+ private isCurrentClient;
86
+ private emitFromClient;
87
+ private emitHealthChanged;
88
+ private loginFreshClient;
89
+ /** Rebuild just this bot's gateway Client. Calls coalesce into one generation. */
90
+ reconnectGateway(reason: string): Promise<void>;
91
+ private readyClient;
92
+ private startGatewayWatchdog;
93
+ private checkGatewayLiveness;
94
+ getHealthSnapshot(): AdapterHealthSnapshot;
95
+ private handleClientReady;
56
96
  start(): Promise<void>;
57
97
  stop(): Promise<void>;
58
98
  /**
@@ -69,6 +109,8 @@ export declare class DiscordAdapter extends EventEmitter implements ChannelAdapt
69
109
  editMessage(chatId: string, messageId: string, text: string, threadId?: string): Promise<void>;
70
110
  /** Edit text and clear components (Discord keeps components on a plain edit,
71
111
  * so we must pass an empty array to drop the Cancel button). */
112
+ /** Keyboard-only removal — Discord keeps the original content untouched. */
113
+ removeMessageButtons(chatId: string, messageId: string, threadId?: string): Promise<void>;
72
114
  editMessageRemoveButtons(chatId: string, messageId: string, text: string, threadId?: string): Promise<void>;
73
115
  deleteMessage(chatId: string, messageId: string, threadId?: string): Promise<void>;
74
116
  react(chatId: string, messageId: string, emoji: string, threadId?: string): Promise<void>;