@songsid/agend 2.1.5-beta.2 → 2.1.5-beta.20
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 +12 -0
- package/dist/backend/claude-code.js +14 -2
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex.d.ts +25 -1
- package/dist/backend/codex.js +76 -0
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/kiro.js +30 -2
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +70 -0
- package/dist/backend/types.js +23 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +17 -2
- package/dist/channel/adapters/discord.js +82 -8
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +2 -2
- package/dist/channel/adapters/telegram.js +8 -8
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/types.d.ts +22 -1
- package/dist/cli.js +37 -37
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +181 -21
- package/dist/daemon.js +1054 -225
- package/dist/daemon.js.map +1 -1
- package/dist/deadline.d.ts +23 -0
- package/dist/deadline.js +29 -0
- package/dist/deadline.js.map +1 -0
- package/dist/fleet-context.d.ts +17 -1
- package/dist/fleet-context.js.map +1 -1
- package/dist/fleet-manager.d.ts +189 -2
- package/dist/fleet-manager.js +808 -119
- package/dist/fleet-manager.js.map +1 -1
- package/dist/full-restart.d.ts +20 -0
- package/dist/full-restart.js +39 -0
- package/dist/full-restart.js.map +1 -0
- package/dist/instance-lifecycle.d.ts +8 -2
- package/dist/instance-lifecycle.js +47 -3
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instance-removal.d.ts +13 -0
- package/dist/instance-removal.js +14 -0
- package/dist/instance-removal.js.map +1 -0
- package/dist/instructions.js +2 -2
- package/dist/instructions.js.map +1 -1
- package/dist/locale.js +54 -4
- package/dist/locale.js.map +1 -1
- package/dist/login-controller.d.ts +31 -4
- package/dist/login-controller.js +52 -4
- package/dist/login-controller.js.map +1 -1
- package/dist/login-flows.d.ts +29 -0
- package/dist/login-flows.js +48 -1
- package/dist/login-flows.js.map +1 -1
- package/dist/outbound-handlers.d.ts +1 -0
- package/dist/outbound-handlers.js +118 -29
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +7 -0
- package/dist/outbound-schemas.js +3 -0
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/pane-input-residue.d.ts +25 -2
- package/dist/pane-input-residue.js +31 -2
- package/dist/pane-input-residue.js.map +1 -1
- package/dist/restart-progress.d.ts +35 -5
- package/dist/restart-progress.js +177 -34
- package/dist/restart-progress.js.map +1 -1
- package/dist/service-restart-selection.d.ts +27 -0
- package/dist/service-restart-selection.js +25 -0
- package/dist/service-restart-selection.js.map +1 -0
- package/dist/topic-commands.d.ts +27 -2
- package/dist/topic-commands.js +59 -13
- package/dist/topic-commands.js.map +1 -1
- package/dist/turn-reply-guard.d.ts +41 -0
- package/dist/turn-reply-guard.js +77 -0
- package/dist/turn-reply-guard.js.map +1 -0
- package/dist/ui/web-terminal/terminal.html +1 -0
- package/dist/update-marker.d.ts +11 -1
- package/dist/update-marker.js +19 -4
- package/dist/update-marker.js.map +1 -1
- package/dist/update-progress.d.ts +1 -1
- package/dist/update-progress.js +12 -0
- package/dist/update-progress.js.map +1 -1
- package/dist/usage/providers.d.ts +39 -0
- package/dist/usage/providers.js +69 -3
- package/dist/usage/providers.js.map +1 -1
- package/dist/web-api.d.ts +2 -1
- package/dist/web-api.js +2 -1
- package/dist/web-api.js.map +1 -1
- package/dist/web-terminal-http.d.ts +8 -0
- package/dist/web-terminal-http.js +29 -3
- package/dist/web-terminal-http.js.map +1 -1
- package/package.json +1 -1
package/dist/daemon.d.ts
CHANGED
|
@@ -11,6 +11,33 @@ import type { StormWindow } from "./storm-window.js";
|
|
|
11
11
|
import type { BackendOutageView } from "./backend-outage.js";
|
|
12
12
|
/** Point a resumed CLI at its one backend-native instruction source. */
|
|
13
13
|
export declare function buildInstructionReloadNotice(binaryName: string, instanceName: string, instanceDir: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Whether this backend has to be told in its pane that its instructions moved.
|
|
16
|
+
*
|
|
17
|
+
* A backend that re-reads them on resume already received the new ones from the
|
|
18
|
+
* resume itself, so the notice is pure interruption. Both places that can send
|
|
19
|
+
* it — the warmup paste and the deferred pendingInstructionsNotice — ask through
|
|
20
|
+
* here, so the two cannot drift apart again: the warmup path used to omit this
|
|
21
|
+
* check entirely and told claude-code to reload instructions it had just read.
|
|
22
|
+
*/
|
|
23
|
+
export declare function backendNeedsPaneReloadNotice(backend?: {
|
|
24
|
+
instructionsReloadedOnResume?: boolean;
|
|
25
|
+
}): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* What the warmup should do about changed instructions.
|
|
28
|
+
*
|
|
29
|
+
* `skip` — nothing to say, or this backend learns of the change by itself.
|
|
30
|
+
* `defer` — worth saying, but nobody is talking to the instance; say it when a
|
|
31
|
+
* real message next arrives rather than provoking an unsolicited reply.
|
|
32
|
+
* `paste` — say it now, into a pane that already has a delivery in flight.
|
|
33
|
+
*/
|
|
34
|
+
export declare function warmupNoticeAction(opts: {
|
|
35
|
+
warmupNeeded: boolean;
|
|
36
|
+
backend?: {
|
|
37
|
+
instructionsReloadedOnResume?: boolean;
|
|
38
|
+
};
|
|
39
|
+
pasteQueueDepth: number;
|
|
40
|
+
}): "skip" | "defer" | "paste";
|
|
14
41
|
export declare const DEFAULT_STUCK_TIMEOUT_MS: number;
|
|
15
42
|
export declare const DEFAULT_STATE_IDLE_DEBOUNCE_MS = 2000;
|
|
16
43
|
export declare const DEFAULT_STATE_SAFETY_SWEEP_MS = 60000;
|
|
@@ -172,7 +199,7 @@ export declare class PendingWorkTracker {
|
|
|
172
199
|
private lastIdleOrder;
|
|
173
200
|
constructor(now?: number);
|
|
174
201
|
recordInbound(now?: number): void;
|
|
175
|
-
recordIdle(now?: number):
|
|
202
|
+
recordIdle(now?: number): boolean;
|
|
176
203
|
hasPendingWork(): boolean;
|
|
177
204
|
}
|
|
178
205
|
/**
|
|
@@ -380,6 +407,14 @@ export declare class Daemon extends EventEmitter {
|
|
|
380
407
|
private spawnSettled;
|
|
381
408
|
private resolveSpawnSettled;
|
|
382
409
|
private spawnDepth;
|
|
410
|
+
/** Monotonic identity for nested beginSpawn/endSpawn lifecycles. */
|
|
411
|
+
private spawnGeneration;
|
|
412
|
+
/**
|
|
413
|
+
* Keeps passive startup-transient checks alive through the first positively
|
|
414
|
+
* submitted post-spawn message. Without this tail, a transient painted just
|
|
415
|
+
* after the startup scan can still swallow that message's Enter.
|
|
416
|
+
*/
|
|
417
|
+
private inputTransientGuardGeneration;
|
|
383
418
|
private skipResume;
|
|
384
419
|
private startupAborted;
|
|
385
420
|
/** First time the current on-screen blocking dialog was seen (0 = none); drives the parked report. */
|
|
@@ -412,15 +447,11 @@ export declare class Daemon extends EventEmitter {
|
|
|
412
447
|
private instanceStateMonitorActive;
|
|
413
448
|
private sessionCheckpointWarningEmitted;
|
|
414
449
|
private statePollInFlight;
|
|
415
|
-
private
|
|
416
|
-
private turnOutboundDelivered;
|
|
417
|
-
/** Successful `reply` specifically; cross-instance tools do not satisfy #648. */
|
|
418
|
-
private turnReplyDelivered;
|
|
419
|
-
private turnCorrelationId;
|
|
420
|
-
private turnInboundMarker;
|
|
450
|
+
private turnReplyGuard;
|
|
421
451
|
/** Prevent a visible stale XML fragment from being recovered on later turns. */
|
|
422
452
|
private lastMalformedToolCallSignature;
|
|
423
453
|
private proxyReplySeq;
|
|
454
|
+
private lastReplyDropWarningAt;
|
|
424
455
|
private autoPauseController;
|
|
425
456
|
private pauseRequested;
|
|
426
457
|
/**
|
|
@@ -573,6 +604,22 @@ export declare class Daemon extends EventEmitter {
|
|
|
573
604
|
private lastErrorCount;
|
|
574
605
|
private lastDetectedErrorType;
|
|
575
606
|
private static errorPatternKey;
|
|
607
|
+
/**
|
|
608
|
+
* Undo the auth suspicion a pattern match armed, once the backend's token-free
|
|
609
|
+
* probe has said the credentials are fine.
|
|
610
|
+
*
|
|
611
|
+
* emitErrorPattern arms these BEFORE the pty_error reaches the lifecycle, and
|
|
612
|
+
* the lifecycle's "valid" verdict used to just drop the incident — leaving the
|
|
613
|
+
* daemon permanently suspicious of an auth failure that never existed. That
|
|
614
|
+
* state is not inert: authFailureUnresolved suppresses the stuck/hang
|
|
615
|
+
* notification and holds MCP auto-restart (a later real MCP death is then read
|
|
616
|
+
* as already-confirmed auth trouble rather than re-verified), and the recovery
|
|
617
|
+
* gate suppresses further error detection until a ready pattern shows up.
|
|
618
|
+
*
|
|
619
|
+
* Only what an auth match armed is rolled back. If some other pattern has
|
|
620
|
+
* since armed the recovery gate, that one is still live and stays.
|
|
621
|
+
*/
|
|
622
|
+
clearSuspectedAuthFailure(): boolean;
|
|
576
623
|
private clearErrorRecoveryGate;
|
|
577
624
|
constructor(name: string, config: InstanceConfig, instanceDir: string, topicMode?: boolean, backend?: CliBackend | undefined, controlClient?: TmuxControlClient | undefined, rootLogger?: Logger, runtimeIdentity?: FleetInstructionsParams["runtimeIdentity"], spawnGate?: SpawnGate | undefined, stormWindow?: StormWindow | undefined,
|
|
578
625
|
/** Fleet-level "is this CLI's backend down?" memory — see backend-outage.ts. */
|
|
@@ -787,10 +834,14 @@ export declare class Daemon extends EventEmitter {
|
|
|
787
834
|
*/
|
|
788
835
|
private maybeProxyReplyOnTurnEnd;
|
|
789
836
|
private isClaudeCodeBackend;
|
|
837
|
+
private replyCompletionGuardEnabled;
|
|
838
|
+
private startReplyRecovery;
|
|
839
|
+
private reportReplyDropWithoutRetry;
|
|
840
|
+
private queueReplyRecoveryPrompt;
|
|
841
|
+
private queueMalformedReplyRecovery;
|
|
842
|
+
private reportUnrecoveredReplyDrop;
|
|
790
843
|
/** Relay the pane's final text to the channel, marked as a daemon proxy reply. */
|
|
791
844
|
private sendProxyReply;
|
|
792
|
-
/** Send a narrowly extracted #648 reply; operator notification is a separate event. */
|
|
793
|
-
private sendRecoveredMalformedReply;
|
|
794
845
|
/** Context-bound reply path shared by dead-MCP and malformed-call recovery. */
|
|
795
846
|
private deliverDaemonReply;
|
|
796
847
|
private clearInstanceStateIdleTimer;
|
|
@@ -937,6 +988,18 @@ export declare class Daemon extends EventEmitter {
|
|
|
937
988
|
* on purpose ("I trust", "Yes, continue") and would match ordinary prose.
|
|
938
989
|
*/
|
|
939
990
|
private deliveryBlockingDialogs;
|
|
991
|
+
/** Passive input-unavailable phases relevant to the current spawn only. */
|
|
992
|
+
private guardedInputTransients;
|
|
993
|
+
/** Match a passive transient against the current interactive screen. */
|
|
994
|
+
private inputTransientInPane;
|
|
995
|
+
/** Capture failure is unknown, never evidence that input is available. */
|
|
996
|
+
private probeInputTransient;
|
|
997
|
+
/**
|
|
998
|
+
* Wait under the pane lock for a passive transient to disappear. Unlike a
|
|
999
|
+
* dialog, this state clears by itself, so the wait cannot starve a keypress
|
|
1000
|
+
* dismisser. Stop or a replacement spawn invalidates the captured identity.
|
|
1001
|
+
*/
|
|
1002
|
+
private waitForInputTransientToClear;
|
|
940
1003
|
private static dialogKey;
|
|
941
1004
|
/** A dialog counts only when it is the CURRENT interactive region, if the backend can tell; else by pattern. */
|
|
942
1005
|
private static dialogMatches;
|
|
@@ -977,10 +1040,10 @@ export declare class Daemon extends EventEmitter {
|
|
|
977
1040
|
private isPaneReadyForDelivery;
|
|
978
1041
|
/**
|
|
979
1042
|
* Why a pane is not deliverable matters. "busy" may be handed to a native
|
|
980
|
-
* input queue or steered (after its own dialog probe); "dialog"
|
|
981
|
-
* must never be — a paste + Enter into a dialog answers it
|
|
982
|
-
*
|
|
983
|
-
*
|
|
1043
|
+
* input queue or steered (after its own dialog probe); "dialog", "transient"
|
|
1044
|
+
* and "unknown" must never be — a paste + Enter into a dialog answers it
|
|
1045
|
+
* with its default, while a startup transient swallows it and an unreadable
|
|
1046
|
+
* pane proves nothing. The silence gate comes first and costs no capture.
|
|
984
1047
|
*/
|
|
985
1048
|
private paneReadinessForDelivery;
|
|
986
1049
|
/**
|
|
@@ -1005,10 +1068,10 @@ export declare class Daemon extends EventEmitter {
|
|
|
1005
1068
|
*/
|
|
1006
1069
|
private submitStrandedInputIfAny;
|
|
1007
1070
|
/**
|
|
1008
|
-
* "stranded": an AgEnD message sits in the input row; "clear":
|
|
1009
|
-
*
|
|
1010
|
-
*
|
|
1011
|
-
* read. Only "clear"
|
|
1071
|
+
* "stranded": an AgEnD message sits in the input row; "clear": no strand is
|
|
1072
|
+
* visible under the backend's readiness policy; "busy": generating, or (for
|
|
1073
|
+
* a bottom-gated backend) the prompt is not at the bottom; "unknown": the
|
|
1074
|
+
* pane could not be read. Only "clear" permits the next paste.
|
|
1012
1075
|
*/
|
|
1013
1076
|
private strandedInputState;
|
|
1014
1077
|
/**
|
|
@@ -1054,11 +1117,71 @@ export declare class Daemon extends EventEmitter {
|
|
|
1054
1117
|
private sendDeliveryEnter;
|
|
1055
1118
|
private writeMessageToPane;
|
|
1056
1119
|
/**
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1059
|
-
*
|
|
1120
|
+
* The single place a pasted message is judged submitted, shared by the
|
|
1121
|
+
* native-queue handoff, the idle-gated redelivery and the system pastes.
|
|
1122
|
+
*
|
|
1123
|
+
* It replaces three divergent weak checks, the weakest of which accepted "the
|
|
1124
|
+
* pasted text is visible somewhere in the pane". That one was satisfied BY
|
|
1125
|
+
* the failure it was meant to catch: text stranded in the input row is on
|
|
1126
|
+
* screen, so a message nobody submitted was confirmed ✅ with no warning
|
|
1127
|
+
* anywhere. Evidence is weighed in order of what it can prove, and the
|
|
1128
|
+
* disqualifying evidence is checked first.
|
|
1129
|
+
*/
|
|
1130
|
+
/**
|
|
1131
|
+
* Whether this backend exposes an input row we can actually read, i.e. whether
|
|
1132
|
+
* confirmSubmitted can ever return a verdict stronger than a guess.
|
|
1133
|
+
*
|
|
1134
|
+
* This is a property of the BACKEND, not of one delivery's verdict. Keying the
|
|
1135
|
+
* output-signal fallback off the verdict instead let codex — which can be read
|
|
1136
|
+
* — fall back to "the pane printed something" whenever a paste left no trace,
|
|
1137
|
+
* which is the same false confirmation one layer down.
|
|
1138
|
+
*/
|
|
1139
|
+
private canProveSubmission;
|
|
1140
|
+
/** Positive submission retires the startup transient guard for this spawn. */
|
|
1141
|
+
private submittedProof;
|
|
1142
|
+
/**
|
|
1143
|
+
* Decide a submission after an Enter, with one bounded retry.
|
|
1144
|
+
*
|
|
1145
|
+
* Backends we can read must SHOW the text left the input row: neither a
|
|
1146
|
+
* strand nor a vanished paste may be upgraded to success by output, because
|
|
1147
|
+
* the output that would do the upgrading is usually the very redraw the Enter
|
|
1148
|
+
* was lost to. Backends we cannot read keep the legacy output signal — there
|
|
1149
|
+
* is nothing better available for them, and taking it away would fail every
|
|
1150
|
+
* one of their deliveries.
|
|
1151
|
+
*
|
|
1152
|
+
* One ladder, used by every post-Enter confirmation, so an escape hatch
|
|
1153
|
+
* cannot reappear in just one of them (it did: three copies, two of which
|
|
1154
|
+
* still confirmed on output alone).
|
|
1155
|
+
*/
|
|
1156
|
+
private confirmAfterEnter;
|
|
1157
|
+
private confirmSubmitted;
|
|
1158
|
+
/**
|
|
1159
|
+
* What the pane currently shows of a given message. Taken once before the
|
|
1160
|
+
* paste and once after, so confirmSubmitted can require a NEW marker or a NEW
|
|
1161
|
+
* echo rather than accepting whatever was already there.
|
|
1162
|
+
*/
|
|
1163
|
+
private capturePaneEvidence;
|
|
1164
|
+
private paneEvidence;
|
|
1165
|
+
/**
|
|
1166
|
+
* What identifies THIS message on screen. The routing envelope carries a
|
|
1167
|
+
* message_id that no earlier transcript entry can share, so prefer it: the
|
|
1168
|
+
* body alone is not distinctive enough — short repeated instructions ("carry
|
|
1169
|
+
* on", a status ping) recur verbatim, and an older copy would vouch for a
|
|
1170
|
+
* paste that never landed. System pastes carry no envelope and fall back to
|
|
1171
|
+
* the body signature, which the baseline comparison still ties to this paste.
|
|
1172
|
+
*/
|
|
1173
|
+
private submissionSignature;
|
|
1174
|
+
/**
|
|
1175
|
+
* Paste + submit + confirm for the SYSTEM messages that used to go out via
|
|
1176
|
+
* tmux.pasteText: one Enter (two for queue-less backends) and no verification
|
|
1177
|
+
* at all, so a swallowed Enter left the notice sitting in the input row where
|
|
1178
|
+
* the next delivery submitted both as one message. Shares confirmSubmitted
|
|
1179
|
+
* with the delivery path — having one primitive is the point.
|
|
1180
|
+
*
|
|
1181
|
+
* Best effort by design: these notices must never fail a delivery or throw.
|
|
1182
|
+
* The caller already holds paneWriteLock.
|
|
1060
1183
|
*/
|
|
1061
|
-
private
|
|
1184
|
+
private submitSystemPaste;
|
|
1062
1185
|
/** Re-resolve this instance's tmux window by name (stale id after crash/respawn). */
|
|
1063
1186
|
private recoverWindow;
|
|
1064
1187
|
/**
|
|
@@ -1119,6 +1242,32 @@ export declare class Daemon extends EventEmitter {
|
|
|
1119
1242
|
*/
|
|
1120
1243
|
private waitForSpawnToSettle;
|
|
1121
1244
|
/** Spawn a CLI window. Returns true if --resume was used successfully. */
|
|
1245
|
+
/**
|
|
1246
|
+
* Positive proof from the CLI that there is no conversation left to resume.
|
|
1247
|
+
*
|
|
1248
|
+
* Only this may justify abandoning a session. A startup that merely ran out of
|
|
1249
|
+
* budget proves nothing: a healthy cold start on a loaded host looks exactly
|
|
1250
|
+
* the same, which is how 9 instances silently lost their history.
|
|
1251
|
+
*
|
|
1252
|
+
* Deliberately does NOT match a bare "--continue": the pane text can mention
|
|
1253
|
+
* the flag (a usage error, an echoed invocation) without the CLI ever saying
|
|
1254
|
+
* the conversation is gone.
|
|
1255
|
+
*/
|
|
1256
|
+
private paneSaysNoConversation;
|
|
1257
|
+
/** How many consecutive startups have failed without proving the session is gone. */
|
|
1258
|
+
private unprovenResumeFailures;
|
|
1259
|
+
/** After this many, start fresh anyway — loudly — so a truly broken session still recovers. */
|
|
1260
|
+
private static readonly MAX_UNPROVEN_RESUME_FAILURES;
|
|
1261
|
+
/**
|
|
1262
|
+
* Set the session aside instead of deleting it.
|
|
1263
|
+
*
|
|
1264
|
+
* The whole defect being fixed here is silent, irreversible loss of a user's
|
|
1265
|
+
* conversation. Renaming costs nothing and turns a wrong call into something
|
|
1266
|
+
* recoverable: the id is still on disk under a dated name.
|
|
1267
|
+
*/
|
|
1268
|
+
private setSessionAside;
|
|
1269
|
+
/** Keep the newest few set-aside sessions; they are insurance, not an archive. */
|
|
1270
|
+
private pruneAbandonedSessions;
|
|
1122
1271
|
private spawnClaudeWindow;
|
|
1123
1272
|
/**
|
|
1124
1273
|
* Startup budget for this launch: the backend's override (resume-aware), never
|
|
@@ -1172,6 +1321,17 @@ export declare class Daemon extends EventEmitter {
|
|
|
1172
1321
|
* Returns true if CLI is ready, false if it failed or got stuck.
|
|
1173
1322
|
*/
|
|
1174
1323
|
private trySpawn;
|
|
1324
|
+
/**
|
|
1325
|
+
* Tell the agent its instructions moved, once the CLI is idle.
|
|
1326
|
+
*
|
|
1327
|
+
* A named method rather than an inline closure so the wiring itself is
|
|
1328
|
+
* testable: warmupNoticeAction's own tests pass even if this call site stops
|
|
1329
|
+
* consulting it, which is exactly the bug this path had — the decision was
|
|
1330
|
+
* made inline and never asked whether the backend needed telling at all.
|
|
1331
|
+
*
|
|
1332
|
+
* Never throws: a missed reload notice must not fail a spawn.
|
|
1333
|
+
*/
|
|
1334
|
+
private runWarmupInstructionNotice;
|
|
1175
1335
|
private trySpawnInsideGate;
|
|
1176
1336
|
/**
|
|
1177
1337
|
* The last leg of a spawn: confirm the pane is not positively dead, then run
|