@songsid/agend 2.1.0-beta.7 → 2.1.0-beta.9
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/antigravity.js +3 -2
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/context-guardian.d.ts +2 -0
- package/dist/context-guardian.js +10 -2
- package/dist/context-guardian.js.map +1 -1
- package/dist/daemon-entry.js +2 -1
- package/dist/daemon-entry.js.map +1 -1
- package/dist/daemon.d.ts +24 -1
- package/dist/daemon.js +127 -20
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-manager.d.ts +2 -1
- package/dist/fleet-manager.js +13 -2
- package/dist/fleet-manager.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +2 -1
- package/dist/instance-lifecycle.js +14 -4
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/logger.js +5 -2
- package/dist/logger.js.map +1 -1
- package/dist/statusline-watcher.d.ts +1 -1
- package/dist/statusline-watcher.js +3 -2
- package/dist/statusline-watcher.js.map +1 -1
- package/dist/transcript-monitor.js +2 -0
- package/dist/transcript-monitor.js.map +1 -1
- package/package.json +1 -1
|
@@ -122,8 +122,9 @@ node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{t
|
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
getReadyPattern() {
|
|
125
|
-
// Startup/header: Gemini shortcut text. Daily
|
|
126
|
-
|
|
125
|
+
// Startup/header: Gemini shortcut text. Daily prompts observed in the TUI
|
|
126
|
+
// are either "◔ 42%" or a standalone ">" line between separators.
|
|
127
|
+
return /\? for shortcuts|Gemini|◔\s*\d+%|^>\s*$/m;
|
|
127
128
|
}
|
|
128
129
|
getContextUsage() {
|
|
129
130
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../../src/backend/antigravity.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../../src/backend/antigravity.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,8 @@ export declare class ContextGuardian extends EventEmitter {
|
|
|
18
18
|
private logger;
|
|
19
19
|
private statusFilePath;
|
|
20
20
|
private consecutiveReadFailures;
|
|
21
|
+
private watching;
|
|
22
|
+
private readonly onStatusFileChange;
|
|
21
23
|
constructor(_config: GuardianConfig, logger: Logger, statusFilePath: string);
|
|
22
24
|
startWatching(): void;
|
|
23
25
|
private readAndCheck;
|
package/dist/context-guardian.js
CHANGED
|
@@ -16,6 +16,8 @@ export class ContextGuardian extends EventEmitter {
|
|
|
16
16
|
logger;
|
|
17
17
|
statusFilePath;
|
|
18
18
|
consecutiveReadFailures = 0;
|
|
19
|
+
watching = false;
|
|
20
|
+
onStatusFileChange = () => this.readAndCheck();
|
|
19
21
|
constructor(_config, logger, statusFilePath) {
|
|
20
22
|
super();
|
|
21
23
|
this._config = _config;
|
|
@@ -23,8 +25,11 @@ export class ContextGuardian extends EventEmitter {
|
|
|
23
25
|
this.statusFilePath = statusFilePath;
|
|
24
26
|
}
|
|
25
27
|
startWatching() {
|
|
28
|
+
if (this.watching)
|
|
29
|
+
return;
|
|
30
|
+
this.watching = true;
|
|
26
31
|
this.logger.debug({ path: this.statusFilePath }, "Watching status line file");
|
|
27
|
-
watchFile(this.statusFilePath, { interval: 2000 },
|
|
32
|
+
watchFile(this.statusFilePath, { interval: 2000 }, this.onStatusFileChange);
|
|
28
33
|
}
|
|
29
34
|
readAndCheck() {
|
|
30
35
|
try {
|
|
@@ -67,7 +72,10 @@ export class ContextGuardian extends EventEmitter {
|
|
|
67
72
|
}
|
|
68
73
|
}
|
|
69
74
|
stop() {
|
|
70
|
-
|
|
75
|
+
if (!this.watching)
|
|
76
|
+
return;
|
|
77
|
+
unwatchFile(this.statusFilePath, this.onStatusFileChange);
|
|
78
|
+
this.watching = false;
|
|
71
79
|
}
|
|
72
80
|
}
|
|
73
81
|
//# sourceMappingURL=context-guardian.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-guardian.js","sourceRoot":"","sources":["../src/context-guardian.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAM3E;;;;;;;;;;GAUG;AACH,MAAM,OAAO,eAAgB,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"context-guardian.js","sourceRoot":"","sources":["../src/context-guardian.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon-entry.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Daemon } from "./daemon.js";
|
|
2
|
+
import { createLogger } from "./logger.js";
|
|
2
3
|
const args = process.argv.slice(2);
|
|
3
4
|
function getArg(name) {
|
|
4
5
|
const idx = args.indexOf(name);
|
|
@@ -15,7 +16,7 @@ catch (err) {
|
|
|
15
16
|
process.exit(1);
|
|
16
17
|
}
|
|
17
18
|
const topicMode = args.includes("--topic-mode");
|
|
18
|
-
const daemon = new Daemon(name, config, instanceDir, topicMode);
|
|
19
|
+
const daemon = new Daemon(name, config, instanceDir, topicMode, undefined, undefined, createLogger(config.log_level));
|
|
19
20
|
daemon.start().catch((err) => {
|
|
20
21
|
console.error("Daemon failed:", err);
|
|
21
22
|
process.exit(1);
|
package/dist/daemon-entry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-entry.js","sourceRoot":"","sources":["../src/daemon-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"daemon-entry.js","sourceRoot":"","sources":["../src/daemon-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,SAAS,MAAM,CAAC,IAAY;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAClC,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAC7C,IAAI,MAAsB,CAAC;AAC3B,IAAI,CAAC;IACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAC1C,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,kCAAmC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;AAChD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAEtH,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC3B,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;IAC1B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;AACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC"}
|
package/dist/daemon.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
2
|
import type { InstanceConfig, RotationSnapshot } from "./types.js";
|
|
3
|
+
import type { Logger } from "./logger.js";
|
|
3
4
|
import { MessageBus } from "./channel/message-bus.js";
|
|
4
5
|
import type { CliBackend, InstanceState, InstanceStateSnapshot } from "./backend/types.js";
|
|
5
6
|
import { HangDetector } from "./hang-detector.js";
|
|
@@ -38,6 +39,20 @@ export declare class PaneStateMachine {
|
|
|
38
39
|
observe(pane: string, now?: number): InstanceStateSnapshot;
|
|
39
40
|
snapshot(now?: number): InstanceStateSnapshot;
|
|
40
41
|
}
|
|
42
|
+
/** Tracks whether an inbound arrived after the most recent confirmed idle prompt. */
|
|
43
|
+
export declare class PendingWorkTracker {
|
|
44
|
+
private lastInboundAt;
|
|
45
|
+
private lastIdleAt;
|
|
46
|
+
private sequence;
|
|
47
|
+
private lastInboundOrder;
|
|
48
|
+
private lastIdleOrder;
|
|
49
|
+
constructor(now?: number);
|
|
50
|
+
recordInbound(now?: number): void;
|
|
51
|
+
recordIdle(now?: number): void;
|
|
52
|
+
hasPendingWork(): boolean;
|
|
53
|
+
}
|
|
54
|
+
/** Redact likely credentials and control sequences before pane text reaches logs. */
|
|
55
|
+
export declare function sanitizePaneTail(pane: string, lineCount?: number): string[];
|
|
41
56
|
export declare class Daemon extends EventEmitter {
|
|
42
57
|
private name;
|
|
43
58
|
private config;
|
|
@@ -81,6 +96,7 @@ export declare class Daemon extends EventEmitter {
|
|
|
81
96
|
private hangDetector;
|
|
82
97
|
private instanceState;
|
|
83
98
|
private instanceStateMachine;
|
|
99
|
+
private pendingWork;
|
|
84
100
|
private instanceStateMonitorTimer;
|
|
85
101
|
private statePollInFlight;
|
|
86
102
|
private autoPauseController;
|
|
@@ -99,6 +115,8 @@ export declare class Daemon extends EventEmitter {
|
|
|
99
115
|
private lastBuiltInstructions;
|
|
100
116
|
private pasteQueueDepth;
|
|
101
117
|
private errorMonitorTimer;
|
|
118
|
+
/** Prevent in-flight monitor callbacks from re-arming after a pause. */
|
|
119
|
+
private runtimeMonitorsFrozen;
|
|
102
120
|
private errorWaitingForRecovery;
|
|
103
121
|
private errorDetectedAt;
|
|
104
122
|
/** Whether this instance is in an abnormal error state (auto-pause is normal). */
|
|
@@ -114,7 +132,7 @@ export declare class Daemon extends EventEmitter {
|
|
|
114
132
|
private static ERROR_COOLDOWN_MS;
|
|
115
133
|
private lastErrorCount;
|
|
116
134
|
private lastDetectedErrorType;
|
|
117
|
-
constructor(name: string, config: InstanceConfig, instanceDir: string, topicMode?: boolean, backend?: CliBackend | undefined, controlClient?: TmuxControlClient | undefined);
|
|
135
|
+
constructor(name: string, config: InstanceConfig, instanceDir: string, topicMode?: boolean, backend?: CliBackend | undefined, controlClient?: TmuxControlClient | undefined, rootLogger?: Logger);
|
|
118
136
|
start(): Promise<void>;
|
|
119
137
|
private startHealthCheck;
|
|
120
138
|
/**
|
|
@@ -142,6 +160,11 @@ export declare class Daemon extends EventEmitter {
|
|
|
142
160
|
/** Respawn the CLI in the preserved window and block until its prompt is ready. */
|
|
143
161
|
wake(timeoutMs?: number): Promise<void>;
|
|
144
162
|
private startInstanceStateMonitor;
|
|
163
|
+
private handleStuckTransition;
|
|
164
|
+
/** Stop every runtime poller/watcher while preserving IPC and daemon state. */
|
|
165
|
+
private freezeRuntimeMonitors;
|
|
166
|
+
/** Restore the same monitor objects after wake without adding event listeners. */
|
|
167
|
+
private resumeRuntimeMonitors;
|
|
145
168
|
getMessageBus(): MessageBus;
|
|
146
169
|
private summarizeTool;
|
|
147
170
|
private addToolStatus;
|
package/dist/daemon.js
CHANGED
|
@@ -3,7 +3,6 @@ import { mkdirSync, writeFileSync, readFileSync, existsSync, unlinkSync, rmSync,
|
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { createHash, randomBytes } from "node:crypto";
|
|
5
5
|
import { EventEmitter } from "node:events";
|
|
6
|
-
import { createLogger } from "./logger.js";
|
|
7
6
|
import { TmuxManager } from "./tmux-manager.js";
|
|
8
7
|
import { TranscriptMonitor } from "./transcript-monitor.js";
|
|
9
8
|
import { ContextGuardian } from "./context-guardian.js";
|
|
@@ -115,6 +114,55 @@ export class PaneStateMachine {
|
|
|
115
114
|
};
|
|
116
115
|
}
|
|
117
116
|
}
|
|
117
|
+
/** Tracks whether an inbound arrived after the most recent confirmed idle prompt. */
|
|
118
|
+
export class PendingWorkTracker {
|
|
119
|
+
lastInboundAt = 0;
|
|
120
|
+
lastIdleAt;
|
|
121
|
+
sequence = 0;
|
|
122
|
+
lastInboundOrder = 0;
|
|
123
|
+
lastIdleOrder = 0;
|
|
124
|
+
constructor(now = Date.now()) {
|
|
125
|
+
this.lastIdleAt = now;
|
|
126
|
+
}
|
|
127
|
+
recordInbound(now = Date.now()) {
|
|
128
|
+
this.lastInboundAt = now;
|
|
129
|
+
this.lastInboundOrder = ++this.sequence;
|
|
130
|
+
}
|
|
131
|
+
recordIdle(now = Date.now()) {
|
|
132
|
+
// An async pane poll can finish after a newer inbound. Do not let its stale
|
|
133
|
+
// observation clear work which had not arrived when the pane was captured.
|
|
134
|
+
if (now < this.lastInboundAt)
|
|
135
|
+
return;
|
|
136
|
+
this.lastIdleAt = now;
|
|
137
|
+
this.lastIdleOrder = ++this.sequence;
|
|
138
|
+
}
|
|
139
|
+
hasPendingWork() {
|
|
140
|
+
return this.lastInboundOrder > this.lastIdleOrder;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/** Redact likely credentials and control sequences before pane text reaches logs. */
|
|
144
|
+
export function sanitizePaneTail(pane, lineCount = 5) {
|
|
145
|
+
const secretAssignment = /\b(token|secret|password|passwd|api[_-]?key|authorization)\b\s*[:=]\s*\S+/gi;
|
|
146
|
+
const bearer = /\bBearer\s+\S+/gi;
|
|
147
|
+
const knownToken = /\b(?:sk-[A-Za-z0-9_-]+|ghp_[A-Za-z0-9]+|github_pat_[A-Za-z0-9_]+|AKIA[A-Z0-9]{16})\b/g;
|
|
148
|
+
const jwt = /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g;
|
|
149
|
+
const opaqueSecret = /\b[A-Za-z0-9_+/=-]{32,}\b/g;
|
|
150
|
+
const lines = pane
|
|
151
|
+
.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "")
|
|
152
|
+
.split(/\r?\n/);
|
|
153
|
+
while (lines.length > 0 && /^\s*$/.test(lines[lines.length - 1]))
|
|
154
|
+
lines.pop();
|
|
155
|
+
return lines
|
|
156
|
+
.slice(-lineCount)
|
|
157
|
+
.map(line => line
|
|
158
|
+
.replace(bearer, "Bearer [REDACTED]")
|
|
159
|
+
.replace(secretAssignment, "$1=[REDACTED]")
|
|
160
|
+
.replace(knownToken, "[REDACTED]")
|
|
161
|
+
.replace(jwt, "[REDACTED]")
|
|
162
|
+
.replace(opaqueSecret, "[REDACTED]")
|
|
163
|
+
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "")
|
|
164
|
+
.slice(0, 200));
|
|
165
|
+
}
|
|
118
166
|
export class Daemon extends EventEmitter {
|
|
119
167
|
name;
|
|
120
168
|
config;
|
|
@@ -164,6 +212,7 @@ export class Daemon extends EventEmitter {
|
|
|
164
212
|
hangDetector = null;
|
|
165
213
|
instanceState = "idle";
|
|
166
214
|
instanceStateMachine = null;
|
|
215
|
+
pendingWork = new PendingWorkTracker();
|
|
167
216
|
instanceStateMonitorTimer = null;
|
|
168
217
|
statePollInFlight = false;
|
|
169
218
|
autoPauseController;
|
|
@@ -189,6 +238,8 @@ export class Daemon extends EventEmitter {
|
|
|
189
238
|
pasteQueueDepth = 0;
|
|
190
239
|
// PTY error pattern monitoring
|
|
191
240
|
errorMonitorTimer = null;
|
|
241
|
+
/** Prevent in-flight monitor callbacks from re-arming after a pause. */
|
|
242
|
+
runtimeMonitorsFrozen = false;
|
|
192
243
|
errorWaitingForRecovery = false; // true = error detected, waiting for ready pattern
|
|
193
244
|
errorDetectedAt = 0;
|
|
194
245
|
/** Whether this instance is in an abnormal error state (auto-pause is normal). */
|
|
@@ -215,7 +266,7 @@ export class Daemon extends EventEmitter {
|
|
|
215
266
|
// still registers as new (prevents the old hash-dedup's permanent suppression).
|
|
216
267
|
lastErrorCount = new Map();
|
|
217
268
|
lastDetectedErrorType = null;
|
|
218
|
-
constructor(name, config, instanceDir, topicMode = false, backend, controlClient) {
|
|
269
|
+
constructor(name, config, instanceDir, topicMode = false, backend, controlClient, rootLogger) {
|
|
219
270
|
super();
|
|
220
271
|
this.name = name;
|
|
221
272
|
this.config = config;
|
|
@@ -223,7 +274,9 @@ export class Daemon extends EventEmitter {
|
|
|
223
274
|
this.topicMode = topicMode;
|
|
224
275
|
this.backend = backend;
|
|
225
276
|
this.controlClient = controlClient;
|
|
226
|
-
|
|
277
|
+
if (!rootLogger)
|
|
278
|
+
throw new Error("Daemon requires a shared root logger");
|
|
279
|
+
this.logger = rootLogger.child({ instance: name }, { level: config.log_level });
|
|
227
280
|
this.tmuxSessionName = getTmuxSession();
|
|
228
281
|
this.messageBus = new MessageBus();
|
|
229
282
|
this.messageBus.setLogger(this.logger);
|
|
@@ -521,11 +574,18 @@ export class Daemon extends EventEmitter {
|
|
|
521
574
|
this.logger.info(`${this.name} ready`);
|
|
522
575
|
}
|
|
523
576
|
startHealthCheck() {
|
|
577
|
+
if (this.runtimeMonitorsFrozen || this.healthCheckTimer)
|
|
578
|
+
return;
|
|
524
579
|
const { max_retries, backoff, reset_after } = this.config.restart_policy;
|
|
525
580
|
if (max_retries <= 0)
|
|
526
581
|
return; // restart disabled
|
|
527
582
|
const scheduleNext = () => {
|
|
583
|
+
if (this.runtimeMonitorsFrozen || this.healthCheckTimer)
|
|
584
|
+
return;
|
|
528
585
|
this.healthCheckTimer = setTimeout(async () => {
|
|
586
|
+
this.healthCheckTimer = null;
|
|
587
|
+
if (this.runtimeMonitorsFrozen)
|
|
588
|
+
return;
|
|
529
589
|
// Instance directory removed externally (e.g. `rm -rf ~/.agend/instances/<name>`).
|
|
530
590
|
// Stop the loop permanently — otherwise every tick triggers a respawn, whose
|
|
531
591
|
// writeRotationSnapshot fails with ENOENT and gets caught as "Failed to respawn",
|
|
@@ -776,6 +836,8 @@ export class Daemon extends EventEmitter {
|
|
|
776
836
|
* (ready pattern visible), it goes back to monitoring for new errors.
|
|
777
837
|
*/
|
|
778
838
|
startErrorMonitor() {
|
|
839
|
+
if (this.runtimeMonitorsFrozen || this.errorMonitorTimer)
|
|
840
|
+
return;
|
|
779
841
|
const patterns = this.backend?.getErrorPatterns?.() ?? [];
|
|
780
842
|
const dialogs = this.backend?.getRuntimeDialogs?.() ?? [];
|
|
781
843
|
if (!patterns.length && !dialogs.length)
|
|
@@ -895,26 +957,13 @@ export class Daemon extends EventEmitter {
|
|
|
895
957
|
}
|
|
896
958
|
async stop() {
|
|
897
959
|
this.logger.info("Stopping daemon instance");
|
|
898
|
-
|
|
899
|
-
clearTimeout(this.healthCheckTimer);
|
|
900
|
-
this.healthCheckTimer = null;
|
|
901
|
-
}
|
|
902
|
-
if (this.errorMonitorTimer) {
|
|
903
|
-
clearInterval(this.errorMonitorTimer);
|
|
904
|
-
this.errorMonitorTimer = null;
|
|
905
|
-
}
|
|
906
|
-
if (this.instanceStateMonitorTimer) {
|
|
907
|
-
clearInterval(this.instanceStateMonitorTimer);
|
|
908
|
-
this.instanceStateMonitorTimer = null;
|
|
909
|
-
}
|
|
960
|
+
this.freezeRuntimeMonitors();
|
|
910
961
|
if (this.toolStatusDebounce) {
|
|
911
962
|
clearTimeout(this.toolStatusDebounce);
|
|
912
963
|
this.toolStatusDebounce = null;
|
|
913
964
|
}
|
|
914
965
|
this.pendingIpcRequests.clear();
|
|
915
966
|
this.hangDetector?.stop();
|
|
916
|
-
this.transcriptMonitor?.stop();
|
|
917
|
-
this.guardian?.stop();
|
|
918
967
|
if (this.adapter)
|
|
919
968
|
await this.adapter.stop();
|
|
920
969
|
// Notify MCP servers of graceful shutdown (prevents reconnect attempts)
|
|
@@ -1007,6 +1056,7 @@ export class Daemon extends EventEmitter {
|
|
|
1007
1056
|
}
|
|
1008
1057
|
this.pauseWakeState = "pausing";
|
|
1009
1058
|
this.healthCheckPaused = true;
|
|
1059
|
+
this.freezeRuntimeMonitors();
|
|
1010
1060
|
const transition = (async () => {
|
|
1011
1061
|
try {
|
|
1012
1062
|
this.saveSessionId();
|
|
@@ -1053,6 +1103,7 @@ export class Daemon extends EventEmitter {
|
|
|
1053
1103
|
this.pauseWakeState = "active";
|
|
1054
1104
|
this.healthCheckPaused = false;
|
|
1055
1105
|
this.pauseRequested = false;
|
|
1106
|
+
this.resumeRuntimeMonitors();
|
|
1056
1107
|
throw err;
|
|
1057
1108
|
}
|
|
1058
1109
|
})();
|
|
@@ -1105,6 +1156,7 @@ export class Daemon extends EventEmitter {
|
|
|
1105
1156
|
}
|
|
1106
1157
|
catch { }
|
|
1107
1158
|
this.transcriptMonitor?.resetOffset();
|
|
1159
|
+
this.resumeRuntimeMonitors();
|
|
1108
1160
|
this.logger.info("Instance auto-woke");
|
|
1109
1161
|
this.ipcServer?.broadcast({
|
|
1110
1162
|
type: "instance_state", instanceName: this.name, state: this.instanceState, pausedAt: null,
|
|
@@ -1124,7 +1176,7 @@ export class Daemon extends EventEmitter {
|
|
|
1124
1176
|
}
|
|
1125
1177
|
}
|
|
1126
1178
|
startInstanceStateMonitor() {
|
|
1127
|
-
if (!this.tmux || !this.backend || this.instanceStateMonitorTimer)
|
|
1179
|
+
if (this.runtimeMonitorsFrozen || !this.tmux || !this.backend || this.instanceStateMonitorTimer)
|
|
1128
1180
|
return;
|
|
1129
1181
|
const rawConfig = this.config.hang_detector;
|
|
1130
1182
|
const timeoutMinutes = rawConfig?.timeout_minutes;
|
|
@@ -1134,7 +1186,8 @@ export class Daemon extends EventEmitter {
|
|
|
1134
1186
|
const pollIntervalMs = typeof rawConfig?.poll_interval_ms === "number" && rawConfig.poll_interval_ms > 0
|
|
1135
1187
|
? rawConfig.poll_interval_ms
|
|
1136
1188
|
: DEFAULT_STATE_POLL_INTERVAL_MS;
|
|
1137
|
-
|
|
1189
|
+
const readyPattern = this.backend.getReadyPattern();
|
|
1190
|
+
this.instanceStateMachine = new PaneStateMachine(readyPattern, stuckTimeoutMs);
|
|
1138
1191
|
const poll = async () => {
|
|
1139
1192
|
if (!this.tmux || this.spawning || this.statePollInFlight)
|
|
1140
1193
|
return;
|
|
@@ -1147,6 +1200,11 @@ export class Daemon extends EventEmitter {
|
|
|
1147
1200
|
const previous = this.instanceState;
|
|
1148
1201
|
const snapshot = this.instanceStateMachine.observe(pane);
|
|
1149
1202
|
this.instanceState = snapshot.state;
|
|
1203
|
+
// Only a transition back to idle completes pending work. Repeated idle
|
|
1204
|
+
// polls between enqueue and paste must not clear a newly-recorded inbound.
|
|
1205
|
+
if (snapshot.state === "idle" && previous !== "idle") {
|
|
1206
|
+
this.pendingWork.recordIdle(snapshot.observedAt);
|
|
1207
|
+
}
|
|
1150
1208
|
if (snapshot.state !== previous) {
|
|
1151
1209
|
this.logger.info({
|
|
1152
1210
|
previousState: previous,
|
|
@@ -1158,7 +1216,7 @@ export class Daemon extends EventEmitter {
|
|
|
1158
1216
|
// Emit exactly once per transition into stuck. Further notifications
|
|
1159
1217
|
// require observable progress (working) or a ready prompt (idle) first.
|
|
1160
1218
|
if (snapshot.state === "stuck") {
|
|
1161
|
-
this.
|
|
1219
|
+
this.handleStuckTransition(pane, snapshot, readyPattern);
|
|
1162
1220
|
}
|
|
1163
1221
|
}
|
|
1164
1222
|
if (snapshot.state !== "idle")
|
|
@@ -1180,6 +1238,54 @@ export class Daemon extends EventEmitter {
|
|
|
1180
1238
|
void poll();
|
|
1181
1239
|
this.instanceStateMonitorTimer = setInterval(() => { void poll(); }, pollIntervalMs);
|
|
1182
1240
|
}
|
|
1241
|
+
handleStuckTransition(pane, snapshot, readyPattern) {
|
|
1242
|
+
const deterministicReadyPattern = new RegExp(readyPattern.source, readyPattern.flags.replace(/[gy]/g, ""));
|
|
1243
|
+
const diagnostic = {
|
|
1244
|
+
backend: this.backend?.binaryName ?? this.config.backend ?? "unknown",
|
|
1245
|
+
paneTail: sanitizePaneTail(pane),
|
|
1246
|
+
readyPattern: readyPattern.toString(),
|
|
1247
|
+
readyMatched: deterministicReadyPattern.test(pane),
|
|
1248
|
+
unchangedForMs: snapshot.unchangedForMs,
|
|
1249
|
+
pendingWork: this.pendingWork.hasPendingWork(),
|
|
1250
|
+
};
|
|
1251
|
+
if (!diagnostic.pendingWork) {
|
|
1252
|
+
this.logger.debug(diagnostic, "Suppressing stuck notification without pending work");
|
|
1253
|
+
return;
|
|
1254
|
+
}
|
|
1255
|
+
this.logger.warn(diagnostic, "Instance pane stuck with pending work");
|
|
1256
|
+
this.hangDetector?.emit("hang", { unchangedForMs: snapshot.unchangedForMs });
|
|
1257
|
+
}
|
|
1258
|
+
/** Stop every runtime poller/watcher while preserving IPC and daemon state. */
|
|
1259
|
+
freezeRuntimeMonitors() {
|
|
1260
|
+
this.runtimeMonitorsFrozen = true;
|
|
1261
|
+
if (this.healthCheckTimer) {
|
|
1262
|
+
clearTimeout(this.healthCheckTimer);
|
|
1263
|
+
this.healthCheckTimer = null;
|
|
1264
|
+
}
|
|
1265
|
+
if (this.errorMonitorTimer) {
|
|
1266
|
+
clearInterval(this.errorMonitorTimer);
|
|
1267
|
+
this.errorMonitorTimer = null;
|
|
1268
|
+
}
|
|
1269
|
+
if (this.instanceStateMonitorTimer) {
|
|
1270
|
+
clearInterval(this.instanceStateMonitorTimer);
|
|
1271
|
+
this.instanceStateMonitorTimer = null;
|
|
1272
|
+
}
|
|
1273
|
+
this.transcriptMonitor?.stop();
|
|
1274
|
+
this.guardian?.stop();
|
|
1275
|
+
}
|
|
1276
|
+
/** Restore the same monitor objects after wake without adding event listeners. */
|
|
1277
|
+
resumeRuntimeMonitors() {
|
|
1278
|
+
if (!this.runtimeMonitorsFrozen)
|
|
1279
|
+
return;
|
|
1280
|
+
this.runtimeMonitorsFrozen = false;
|
|
1281
|
+
this.startHealthCheck();
|
|
1282
|
+
if (!this.config.lightweight) {
|
|
1283
|
+
this.transcriptMonitor?.startPolling();
|
|
1284
|
+
this.guardian?.startWatching();
|
|
1285
|
+
this.startErrorMonitor();
|
|
1286
|
+
}
|
|
1287
|
+
this.startInstanceStateMonitor();
|
|
1288
|
+
}
|
|
1183
1289
|
getMessageBus() {
|
|
1184
1290
|
return this.messageBus;
|
|
1185
1291
|
}
|
|
@@ -1264,6 +1370,7 @@ export class Daemon extends EventEmitter {
|
|
|
1264
1370
|
this.pendingInstructionsUpdate = undefined;
|
|
1265
1371
|
}
|
|
1266
1372
|
this.hangDetector?.recordInbound();
|
|
1373
|
+
this.pendingWork.recordInbound();
|
|
1267
1374
|
// v3: record user messages for rotation snapshot
|
|
1268
1375
|
this.recordRecentUserMessage(content, meta);
|
|
1269
1376
|
// Format message with metadata prefix for the agent
|