@songsid/agend 2.1.1-beta.16 → 2.1.1-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backend/claude-code.d.ts +37 -0
- package/dist/backend/claude-code.js +40 -1
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/kiro.d.ts +20 -0
- package/dist/backend/kiro.js +30 -0
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +27 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +15 -0
- package/dist/channel/adapters/discord.js +81 -1
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +21 -0
- package/dist/channel/adapters/telegram.js +82 -0
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/ipc-bridge.d.ts +9 -1
- package/dist/channel/ipc-bridge.js +12 -3
- package/dist/channel/ipc-bridge.js.map +1 -1
- package/dist/channel/ipc-timeouts.d.ts +40 -0
- package/dist/channel/ipc-timeouts.js +58 -0
- package/dist/channel/ipc-timeouts.js.map +1 -0
- package/dist/channel/mcp-server.js +5 -4
- package/dist/channel/mcp-server.js.map +1 -1
- package/dist/channel/types.d.ts +29 -0
- package/dist/daemon.d.ts +114 -5
- package/dist/daemon.js +336 -59
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +92 -1
- package/dist/fleet-manager.js +346 -20
- package/dist/fleet-manager.js.map +1 -1
- package/dist/hang-detector.d.ts +19 -13
- package/dist/hang-detector.js +19 -49
- package/dist/hang-detector.js.map +1 -1
- package/dist/instance-lifecycle.js +9 -0
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/outbound-handlers.d.ts +7 -0
- package/dist/outbound-handlers.js +62 -4
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/pane-write-lock.d.ts +48 -0
- package/dist/pane-write-lock.js +73 -0
- package/dist/pane-write-lock.js.map +1 -0
- package/dist/tmux-control.d.ts +48 -1
- package/dist/tmux-control.js +79 -6
- package/dist/tmux-control.js.map +1 -1
- package/package.json +1 -1
- package/dist/channel/tool-tracker.d.ts +0 -13
- package/dist/channel/tool-tracker.js +0 -58
- package/dist/channel/tool-tracker.js.map +0 -1
- package/dist/daemon-entry.d.ts +0 -1
- package/dist/daemon-entry.js +0 -30
- package/dist/daemon-entry.js.map +0 -1
package/dist/daemon.d.ts
CHANGED
|
@@ -11,8 +11,6 @@ export declare function buildInstructionReloadNotice(binaryName: string, instanc
|
|
|
11
11
|
export declare const DEFAULT_STUCK_TIMEOUT_MS: number;
|
|
12
12
|
export declare const DEFAULT_STATE_IDLE_DEBOUNCE_MS = 2000;
|
|
13
13
|
export declare const DEFAULT_STATE_SAFETY_SWEEP_MS = 60000;
|
|
14
|
-
/** @deprecated State detection is event-driven; this now aliases the safety sweep. */
|
|
15
|
-
export declare const DEFAULT_STATE_POLL_INTERVAL_MS = 60000;
|
|
16
14
|
/**
|
|
17
15
|
* Whether two working directories belong to the same project, so a fleet-scoped
|
|
18
16
|
* decision recorded in one reaches the other. Covers the worktree/checkout
|
|
@@ -82,16 +80,32 @@ export declare class AutoPauseController {
|
|
|
82
80
|
* Pane motion wins over a ready match because several backends keep their ready
|
|
83
81
|
* marker in a persistent header/footer while generating. A stable ready pane is
|
|
84
82
|
* idle; changing content is working; stable non-ready content eventually sticks.
|
|
83
|
+
*
|
|
84
|
+
* ## Why an optional busy pattern exists
|
|
85
|
+
*
|
|
86
|
+
* "Motion wins" degrades badly when a backend's ready marker is *always* on
|
|
87
|
+
* screen. `stuck` requires `!ready`, so for such a backend the state can only ever
|
|
88
|
+
* be idle or working — the stuck edge, and with it `handleStuckTransition` and the
|
|
89
|
+
* hang notification, is unreachable. A frozen CLI is then reported as idle, which
|
|
90
|
+
* also clears pending work: the message the user sent is quietly booked as done.
|
|
91
|
+
*
|
|
92
|
+
* claude-code was exactly this case (see ClaudeCodeBackend.getReadyPattern). A
|
|
93
|
+
* backend that can point at a marker meaning "generating right now" supplies
|
|
94
|
+
* `getBusyPattern()`, and that match vetoes ready regardless of what the ready
|
|
95
|
+
* pattern says.
|
|
85
96
|
*/
|
|
86
97
|
export declare class PaneStateMachine {
|
|
87
98
|
private readonly stuckTimeoutMs;
|
|
88
99
|
private readonly readyPattern;
|
|
100
|
+
private readonly busyPattern;
|
|
89
101
|
private lastPaneHash;
|
|
90
102
|
private lastPaneChangeAt;
|
|
91
103
|
private lastObservedAt;
|
|
92
104
|
private stateChangedAt;
|
|
93
105
|
private currentState;
|
|
94
|
-
constructor(readyPattern: RegExp, stuckTimeoutMs?: number, now?: number);
|
|
106
|
+
constructor(readyPattern: RegExp, stuckTimeoutMs?: number, now?: number, busyPattern?: RegExp | null);
|
|
107
|
+
/** Ready, unless the backend can positively see that it is still generating. */
|
|
108
|
+
private isReady;
|
|
95
109
|
observe(pane: string, now?: number): InstanceStateSnapshot;
|
|
96
110
|
/** Record pane motion from tmux control mode without capturing pane content. */
|
|
97
111
|
recordOutput(now?: number): InstanceStateSnapshot;
|
|
@@ -136,7 +150,6 @@ export declare class Daemon extends EventEmitter {
|
|
|
136
150
|
private ipcServer;
|
|
137
151
|
private messageBus;
|
|
138
152
|
private transcriptMonitor;
|
|
139
|
-
private toolTracker;
|
|
140
153
|
private guardian;
|
|
141
154
|
private adapter;
|
|
142
155
|
private pendingIpcRequests;
|
|
@@ -144,6 +157,8 @@ export declare class Daemon extends EventEmitter {
|
|
|
144
157
|
private lastThreadId;
|
|
145
158
|
private lastAdapterId;
|
|
146
159
|
private pendingAckMessage;
|
|
160
|
+
/** Last activity published to the fleet manager; null when nothing is running. */
|
|
161
|
+
private currentActivity;
|
|
147
162
|
private toolStatusMessageId;
|
|
148
163
|
private toolStatusLines;
|
|
149
164
|
private toolStatusDebounce;
|
|
@@ -161,6 +176,15 @@ export declare class Daemon extends EventEmitter {
|
|
|
161
176
|
/** CLI pane availability, independent from the daemon process and tri-state. */
|
|
162
177
|
private processStatus;
|
|
163
178
|
private spawning;
|
|
179
|
+
/**
|
|
180
|
+
* Resolves when the in-flight spawn finishes; null when none is running.
|
|
181
|
+
*
|
|
182
|
+
* `spawning` alone can only be polled. Delivery needs to *wait*, and a boolean
|
|
183
|
+
* poll would either busy-loop or race the flag being cleared.
|
|
184
|
+
*/
|
|
185
|
+
private spawnSettled;
|
|
186
|
+
private resolveSpawnSettled;
|
|
187
|
+
private spawnDepth;
|
|
164
188
|
private skipResume;
|
|
165
189
|
private backgroundSessionRecoveryAttempted;
|
|
166
190
|
/** Whether the last spawn started a fresh session (not resumed). */
|
|
@@ -182,6 +206,7 @@ export declare class Daemon extends EventEmitter {
|
|
|
182
206
|
private instanceStateIdleDebounceMs;
|
|
183
207
|
private instanceStateStuckTimeoutMs;
|
|
184
208
|
private instanceStateReadyPattern;
|
|
209
|
+
private instanceStateBusyPattern;
|
|
185
210
|
private instanceStateMonitorActive;
|
|
186
211
|
private statePollInFlight;
|
|
187
212
|
private autoPauseController;
|
|
@@ -200,7 +225,13 @@ export declare class Daemon extends EventEmitter {
|
|
|
200
225
|
private recentEvents;
|
|
201
226
|
private recentToolActivity;
|
|
202
227
|
private snapshotConsumed;
|
|
228
|
+
/** Orders inbound channel messages against each other (queue-depth accounting
|
|
229
|
+
* and ⏳/👀/✅ reactions live here). It does NOT cover the other writers that
|
|
230
|
+
* reach the pane — {@link paneWriteLock} does. */
|
|
203
231
|
private pasteLock;
|
|
232
|
+
/** Mutual exclusion for *every* write into the pane, whichever subsystem it
|
|
233
|
+
* comes from. See PaneWriteLock for why interleaving is destructive. */
|
|
234
|
+
private readonly paneWriteLock;
|
|
204
235
|
private pendingInstructionsUpdate;
|
|
205
236
|
private pendingInstructionsNotice;
|
|
206
237
|
private warmupNeeded;
|
|
@@ -259,6 +290,19 @@ export declare class Daemon extends EventEmitter {
|
|
|
259
290
|
* A dead remain-on-exit pane still contains the old ready prompt, so allowing
|
|
260
291
|
* the pane monitor to capture it would re-create a false idle state.
|
|
261
292
|
*/
|
|
293
|
+
/**
|
|
294
|
+
* Announce that this instance is no longer being supervised.
|
|
295
|
+
*
|
|
296
|
+
* Four health-check exits set `healthCheckPaused = true` and returned without
|
|
297
|
+
* telling anyone: a clean CLI exit, `max_retries <= 0`, crash retries exhausted,
|
|
298
|
+
* and the instance directory being deleted. Only the crash-LOOP case emitted an
|
|
299
|
+
* event, so a fleet could quietly contain a dead instance that still looked fine
|
|
300
|
+
* on the dashboard — while messages routed to it queued or failed with a bare ❌.
|
|
301
|
+
*
|
|
302
|
+
* `crash_loop` already had this treatment; this is the same bridge for the other
|
|
303
|
+
* four, carrying a human-readable cause and the operator's next step.
|
|
304
|
+
*/
|
|
305
|
+
private emitSupervisionEnded;
|
|
262
306
|
private setProcessStatus;
|
|
263
307
|
/**
|
|
264
308
|
* Periodically scan PTY output for backend-defined error patterns.
|
|
@@ -285,6 +329,12 @@ export declare class Daemon extends EventEmitter {
|
|
|
285
329
|
* Interrupt the CLI's current generation (cancel button / `/cancel`).
|
|
286
330
|
* Direct tmux key event (not a paste) so it registers as the interrupt key.
|
|
287
331
|
* kiro-cli interrupts on Ctrl+C; the others (claude-code, codex, …) on Escape.
|
|
332
|
+
*
|
|
333
|
+
* Deliberately NOT taken through `paneWriteLock`. Cancel is the user's way out
|
|
334
|
+
* of a pane that is busy or wedged — queueing it behind the very delivery chain
|
|
335
|
+
* it exists to unblock would make the button useless exactly when it is needed.
|
|
336
|
+
* The cost is accepted: an Escape landing between a paste and its Enter discards
|
|
337
|
+
* that message, which is what the user asked for anyway.
|
|
288
338
|
*/
|
|
289
339
|
sendEscape(): Promise<void>;
|
|
290
340
|
/** Send the backend-specific graceful quit command/key sequence. */
|
|
@@ -319,6 +369,18 @@ export declare class Daemon extends EventEmitter {
|
|
|
319
369
|
/** Restore the same monitor objects after wake without adding event listeners. */
|
|
320
370
|
private resumeRuntimeMonitors;
|
|
321
371
|
getMessageBus(): MessageBus;
|
|
372
|
+
/**
|
|
373
|
+
* Tell the fleet manager what this instance is doing right now, for the live
|
|
374
|
+
* progress line on the cancel button.
|
|
375
|
+
*
|
|
376
|
+
* Purely cosmetic — nothing decides anything from it, so it is fine that only
|
|
377
|
+
* backends with a transcript feed report at all (claude-code today). For the
|
|
378
|
+
* rest the progress line keeps showing just elapsed time.
|
|
379
|
+
*
|
|
380
|
+
* Repeats are dropped: the ticker only edits the channel message when the text
|
|
381
|
+
* changes, and a stream of identical broadcasts would defeat that.
|
|
382
|
+
*/
|
|
383
|
+
private publishActivity;
|
|
322
384
|
private summarizeTool;
|
|
323
385
|
private addToolStatus;
|
|
324
386
|
/** Debounce tool status updates to avoid channel rate limits */
|
|
@@ -349,6 +411,14 @@ export declare class Daemon extends EventEmitter {
|
|
|
349
411
|
* serial in both cases so separate PTY writes can never overlap.
|
|
350
412
|
*/
|
|
351
413
|
private deliverMessage;
|
|
414
|
+
/**
|
|
415
|
+
* The write half of a delivery: paste → Enter → confirm, with retries.
|
|
416
|
+
*
|
|
417
|
+
* Always called under {@link paneWriteLock}. Split out from `deliverMessage`
|
|
418
|
+
* precisely so the lock's scope is visible at the call site rather than being
|
|
419
|
+
* an invariant maintained by comments.
|
|
420
|
+
*/
|
|
421
|
+
private writeMessageToPane;
|
|
352
422
|
/**
|
|
353
423
|
* True when a busy native-queue paste appears to have landed: Codex shows a
|
|
354
424
|
* `↳` queue marker, or a distinctive slice of the pasted text is on screen.
|
|
@@ -357,7 +427,21 @@ export declare class Daemon extends EventEmitter {
|
|
|
357
427
|
private nativeQueuePasteVisible;
|
|
358
428
|
/** Re-resolve this instance's tmux window by name (stale id after crash/respawn). */
|
|
359
429
|
private recoverWindow;
|
|
360
|
-
/**
|
|
430
|
+
/**
|
|
431
|
+
* Poll up to ~2s (200ms × 10) for the pane to emit output after `since`.
|
|
432
|
+
*
|
|
433
|
+
* A `false` here is not "no output" — it is read as **"the message was pasted but
|
|
434
|
+
* never submitted"**, which re-sends Enter and then reports ❌ to the user. So a
|
|
435
|
+
* false negative costs a possible double submit and a failure notice for a
|
|
436
|
+
* message that actually arrived.
|
|
437
|
+
*
|
|
438
|
+
* That is exactly what a control-mode reconnect used to produce. `connect()`
|
|
439
|
+
* drops every output timestamp, so `hasOutputSince` answers `false` for a pane
|
|
440
|
+
* that did react — the evidence was thrown away, not absent. Blind time is
|
|
441
|
+
* therefore not counted against the budget: after a reset the poll restarts from
|
|
442
|
+
* the moment observation resumed. A hard wall-clock cap keeps a reconnect loop
|
|
443
|
+
* from extending this forever.
|
|
444
|
+
*/
|
|
361
445
|
private confirmBusyAfterEnter;
|
|
362
446
|
private getWindowId;
|
|
363
447
|
/** Find the IPC socket for a given sessionName */
|
|
@@ -375,6 +459,31 @@ export declare class Daemon extends EventEmitter {
|
|
|
375
459
|
* This replaces the old system-prompt injection approach.
|
|
376
460
|
*/
|
|
377
461
|
private injectSnapshotMessage;
|
|
462
|
+
/**
|
|
463
|
+
* Depth, not a flag: the wake path marks a spawn and then calls trySpawn, which
|
|
464
|
+
* marks another. With a plain boolean the inner one's completion would clear the
|
|
465
|
+
* latch while the outer spawn was still dismissing dialogs, releasing delivery
|
|
466
|
+
* into exactly the window this exists to close.
|
|
467
|
+
*/
|
|
468
|
+
private beginSpawn;
|
|
469
|
+
private endSpawn;
|
|
470
|
+
/**
|
|
471
|
+
* Hold until the CLI has finished starting up.
|
|
472
|
+
*
|
|
473
|
+
* Startup is not a quiet period: `dismissDialogsUntilReady` is clicking through
|
|
474
|
+
* trust prompts and session pickers. A pane showing a modal dialog produces no
|
|
475
|
+
* output, so `waitUntilIdle` reports it idle and a queued message gets pasted
|
|
476
|
+
* *into the dialog* — where the text is discarded and the Enter picks a menu
|
|
477
|
+
* item. The paste and the Enter both "succeed", so this loses the message
|
|
478
|
+
* without even a ❌.
|
|
479
|
+
*
|
|
480
|
+
* The pane write lock (#414) does not cover this: it serialises each key
|
|
481
|
+
* sequence, but it is released between one dialog and the next.
|
|
482
|
+
*
|
|
483
|
+
* Bounded, and called BEFORE the pane lock is taken — waiting on the spawn while
|
|
484
|
+
* holding the lock the spawn itself needs would deadlock.
|
|
485
|
+
*/
|
|
486
|
+
private waitForSpawnToSettle;
|
|
378
487
|
/** Spawn a CLI window. Returns true if --resume was used successfully. */
|
|
379
488
|
private spawnClaudeWindow;
|
|
380
489
|
/** Kill the entire process tree of the current tmux pane (CLI + MCP server). */
|