@agentmeshhq/agent 0.4.16 → 0.4.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/LICENSE +21 -0
- package/dist/__tests__/attach.test.d.ts +1 -0
- package/dist/__tests__/attach.test.js +200 -0
- package/dist/__tests__/attach.test.js.map +1 -0
- package/dist/__tests__/auth-guard.integration.test.js +1 -1
- package/dist/__tests__/auth-guard.integration.test.js.map +1 -1
- package/dist/__tests__/auth-guard.test.js +3 -3
- package/dist/__tests__/auth-guard.test.js.map +1 -1
- package/dist/__tests__/bootstrap.test.js +23 -0
- package/dist/__tests__/bootstrap.test.js.map +1 -1
- package/dist/__tests__/daemon-hub-resilience.test.js +2 -2
- package/dist/__tests__/daemon-hub-resilience.test.js.map +1 -1
- package/dist/__tests__/evicted-cleanup.test.js.map +1 -1
- package/dist/__tests__/injection-verify.test.d.ts +1 -0
- package/dist/__tests__/injection-verify.test.js +93 -0
- package/dist/__tests__/injection-verify.test.js.map +1 -0
- package/dist/__tests__/injector.test.js +124 -4
- package/dist/__tests__/injector.test.js.map +1 -1
- package/dist/__tests__/list.test.d.ts +1 -0
- package/dist/__tests__/list.test.js +62 -0
- package/dist/__tests__/list.test.js.map +1 -0
- package/dist/__tests__/opencode-serve.test.d.ts +1 -0
- package/dist/__tests__/opencode-serve.test.js +54 -0
- package/dist/__tests__/opencode-serve.test.js.map +1 -0
- package/dist/__tests__/opencode-session-policy.test.d.ts +1 -0
- package/dist/__tests__/opencode-session-policy.test.js +61 -0
- package/dist/__tests__/opencode-session-policy.test.js.map +1 -0
- package/dist/__tests__/opencode-session.test.d.ts +1 -0
- package/dist/__tests__/opencode-session.test.js +178 -0
- package/dist/__tests__/opencode-session.test.js.map +1 -0
- package/dist/__tests__/registry.register.test.js +16 -0
- package/dist/__tests__/registry.register.test.js.map +1 -1
- package/dist/__tests__/relay.test.d.ts +1 -0
- package/dist/__tests__/relay.test.js +136 -0
- package/dist/__tests__/relay.test.js.map +1 -0
- package/dist/__tests__/runner.test.js +17 -0
- package/dist/__tests__/runner.test.js.map +1 -1
- package/dist/__tests__/session-recovery.test.js +214 -11
- package/dist/__tests__/session-recovery.test.js.map +1 -1
- package/dist/__tests__/shared-resource-guards.test.js +1 -4
- package/dist/__tests__/shared-resource-guards.test.js.map +1 -1
- package/dist/__tests__/start-team-id.test.js +22 -0
- package/dist/__tests__/start-team-id.test.js.map +1 -1
- package/dist/__tests__/startup-diagnostics.test.d.ts +1 -0
- package/dist/__tests__/startup-diagnostics.test.js +250 -0
- package/dist/__tests__/startup-diagnostics.test.js.map +1 -0
- package/dist/__tests__/tmux-runtime.test.js +13 -0
- package/dist/__tests__/tmux-runtime.test.js.map +1 -1
- package/dist/__tests__/token-rejection-recovery.test.js +52 -0
- package/dist/__tests__/token-rejection-recovery.test.js.map +1 -1
- package/dist/__tests__/watcher-queue.test.d.ts +1 -0
- package/dist/__tests__/watcher-queue.test.js +90 -0
- package/dist/__tests__/watcher-queue.test.js.map +1 -0
- package/dist/__tests__/watcher-state.test.d.ts +1 -0
- package/dist/__tests__/watcher-state.test.js +159 -0
- package/dist/__tests__/watcher-state.test.js.map +1 -0
- package/dist/cli/attach.d.ts +1 -1
- package/dist/cli/attach.js +125 -2
- package/dist/cli/attach.js.map +1 -1
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/commands.d.ts +32 -0
- package/dist/cli/commands.js +165 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/index.js +97 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/list.js +26 -2
- package/dist/cli/list.js.map +1 -1
- package/dist/cli/relay.d.ts +4 -0
- package/dist/cli/relay.js +165 -3
- package/dist/cli/relay.js.map +1 -1
- package/dist/cli/start.d.ts +9 -1
- package/dist/cli/start.js +8 -0
- package/dist/cli/start.js.map +1 -1
- package/dist/cli/status.js +21 -8
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/test.js +12 -1
- package/dist/cli/test.js.map +1 -1
- package/dist/config/schema.d.ts +17 -1
- package/dist/core/auth-guard.js +2 -2
- package/dist/core/auth-guard.js.map +1 -1
- package/dist/core/chat-output-parser.d.ts +24 -0
- package/dist/core/chat-output-parser.js +150 -0
- package/dist/core/chat-output-parser.js.map +1 -0
- package/dist/core/chat-output-parser.test.d.ts +7 -0
- package/dist/core/chat-output-parser.test.js +151 -0
- package/dist/core/chat-output-parser.test.js.map +1 -0
- package/dist/core/daemon/bootstrap.d.ts +8 -0
- package/dist/core/daemon/bootstrap.js +6 -1
- package/dist/core/daemon/bootstrap.js.map +1 -1
- package/dist/core/daemon/crash-log.js +5 -0
- package/dist/core/daemon/crash-log.js.map +1 -1
- package/dist/core/daemon/injection-verify.d.ts +25 -0
- package/dist/core/daemon/injection-verify.js +94 -0
- package/dist/core/daemon/injection-verify.js.map +1 -0
- package/dist/core/daemon/roles.d.ts +2 -2
- package/dist/core/daemon/roles.js +3 -0
- package/dist/core/daemon/roles.js.map +1 -1
- package/dist/core/daemon/session-recovery.d.ts +18 -1
- package/dist/core/daemon/session-recovery.js +89 -5
- package/dist/core/daemon/session-recovery.js.map +1 -1
- package/dist/core/daemon/startup-diagnostics.d.ts +76 -0
- package/dist/core/daemon/startup-diagnostics.js +277 -0
- package/dist/core/daemon/startup-diagnostics.js.map +1 -0
- package/dist/core/daemon/state.d.ts +8 -0
- package/dist/core/daemon/state.js +8 -0
- package/dist/core/daemon/state.js.map +1 -1
- package/dist/core/daemon/tmux-session.d.ts +4 -0
- package/dist/core/daemon/tmux-session.js +9 -1
- package/dist/core/daemon/tmux-session.js.map +1 -1
- package/dist/core/daemon/watcher-loop.d.ts +27 -0
- package/dist/core/daemon/watcher-loop.js +134 -0
- package/dist/core/daemon/watcher-loop.js.map +1 -0
- package/dist/core/daemon/watcher-queue.d.ts +33 -0
- package/dist/core/daemon/watcher-queue.js +71 -0
- package/dist/core/daemon/watcher-queue.js.map +1 -0
- package/dist/core/daemon/watcher-state.d.ts +66 -0
- package/dist/core/daemon/watcher-state.js +151 -0
- package/dist/core/daemon/watcher-state.js.map +1 -0
- package/dist/core/daemon/workspace.js +10 -2
- package/dist/core/daemon/workspace.js.map +1 -1
- package/dist/core/daemon.d.ts +22 -1
- package/dist/core/daemon.js +289 -20
- package/dist/core/daemon.js.map +1 -1
- package/dist/core/handoff-sla.js +1 -1
- package/dist/core/handoff-sla.js.map +1 -1
- package/dist/core/injector.d.ts +2 -0
- package/dist/core/injector.js +227 -32
- package/dist/core/injector.js.map +1 -1
- package/dist/core/opencode-serve.d.ts +26 -0
- package/dist/core/opencode-serve.js +97 -0
- package/dist/core/opencode-serve.js.map +1 -0
- package/dist/core/opencode-session-policy.d.ts +10 -0
- package/dist/core/opencode-session-policy.js +10 -0
- package/dist/core/opencode-session-policy.js.map +1 -0
- package/dist/core/opencode-session.d.ts +12 -0
- package/dist/core/opencode-session.js +165 -0
- package/dist/core/opencode-session.js.map +1 -0
- package/dist/core/registry.d.ts +2 -1
- package/dist/core/registry.js +3 -2
- package/dist/core/registry.js.map +1 -1
- package/dist/core/runner/build.js +7 -31
- package/dist/core/runner/build.js.map +1 -1
- package/dist/core/runner/detect.js +2 -8
- package/dist/core/runner/detect.js.map +1 -1
- package/dist/core/runner/index.d.ts +3 -1
- package/dist/core/runner/index.js +2 -0
- package/dist/core/runner/index.js.map +1 -1
- package/dist/core/runner/kimi-models.d.ts +4 -0
- package/dist/core/runner/kimi-models.js +24 -0
- package/dist/core/runner/kimi-models.js.map +1 -0
- package/dist/core/runner/registry.d.ts +3 -0
- package/dist/core/runner/registry.js +75 -0
- package/dist/core/runner/registry.js.map +1 -0
- package/dist/core/runner/types.d.ts +17 -1
- package/dist/core/tmux-runtime.d.ts +2 -1
- package/dist/core/tmux-runtime.js +17 -1
- package/dist/core/tmux-runtime.js.map +1 -1
- package/dist/core/tmux.d.ts +4 -0
- package/dist/core/tmux.js +54 -11
- package/dist/core/tmux.js.map +1 -1
- package/dist/runtime/adapters/opencode.d.ts +63 -0
- package/dist/runtime/adapters/opencode.js +358 -0
- package/dist/runtime/adapters/opencode.js.map +1 -0
- package/dist/runtime/adapters/tmux-fallback.d.ts +23 -0
- package/dist/runtime/adapters/tmux-fallback.js +148 -0
- package/dist/runtime/adapters/tmux-fallback.js.map +1 -0
- package/dist/runtime/adapters/tmux-fallback.test.d.ts +4 -0
- package/dist/runtime/adapters/tmux-fallback.test.js +91 -0
- package/dist/runtime/adapters/tmux-fallback.test.js.map +1 -0
- package/dist/runtime/index.d.ts +146 -0
- package/dist/runtime/index.js +191 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/registry.d.ts +53 -0
- package/dist/runtime/registry.js +112 -0
- package/dist/runtime/registry.js.map +1 -0
- package/dist/runtime/registry.test.d.ts +4 -0
- package/dist/runtime/registry.test.js +69 -0
- package/dist/runtime/registry.test.js.map +1 -0
- package/dist/runtime/types.d.ts +158 -0
- package/dist/runtime/types.js +8 -0
- package/dist/runtime/types.js.map +1 -0
- package/package.json +11 -12
|
@@ -1,7 +1,91 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { readStartupDiagnostics } from "./startup-diagnostics.js";
|
|
2
|
+
/**
|
|
3
|
+
* Extended reasons that can indicate a recoverable session failure
|
|
4
|
+
*/
|
|
5
|
+
const RECOVERABLE_REASONS = [
|
|
6
|
+
"session_not_found",
|
|
7
|
+
"pane_dead",
|
|
8
|
+
"no_pid",
|
|
9
|
+
"pane_died",
|
|
10
|
+
"process_replaced",
|
|
11
|
+
"session_terminated",
|
|
12
|
+
];
|
|
13
|
+
/**
|
|
14
|
+
* Maximum age of an exit event to consider it relevant (60 seconds)
|
|
15
|
+
* Exit events older than this are considered stale and unrelated to current failures
|
|
16
|
+
*/
|
|
17
|
+
const MAX_EXIT_EVENT_AGE_MS = 60000;
|
|
18
|
+
/**
|
|
19
|
+
* Startup window - if process exits within this time of startup, it's recoverable
|
|
20
|
+
*/
|
|
21
|
+
const STARTUP_WINDOW_MS = 15000;
|
|
22
|
+
/**
|
|
23
|
+
* Check if a reason string matches recoverable patterns
|
|
24
|
+
*/
|
|
25
|
+
function matchesRecoverablePattern(reason) {
|
|
26
|
+
return (RECOVERABLE_REASONS.includes(reason) ||
|
|
27
|
+
reason.startsWith("check_failed") ||
|
|
28
|
+
reason.startsWith("session_creation_failed") ||
|
|
29
|
+
reason.startsWith("pane_dead"));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Gets the most recent process exit event from diagnostics
|
|
33
|
+
*/
|
|
34
|
+
export function getLastProcessExit(agentName) {
|
|
35
|
+
const entries = readStartupDiagnostics(agentName);
|
|
36
|
+
// Find the most recent exit entry
|
|
37
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
38
|
+
if (entries[i].type === "exit") {
|
|
39
|
+
return entries[i].data;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Determines if a session failure is recoverable based on the reason
|
|
46
|
+
* and startup diagnostics.
|
|
47
|
+
*
|
|
48
|
+
* A failure is considered recoverable if:
|
|
49
|
+
* 1. The reason matches known recoverable patterns
|
|
50
|
+
* 2. The process exited during startup (within 15s) AND the exit event is fresh
|
|
51
|
+
* (within 60s) - this suggests a transient issue that may resolve on retry
|
|
52
|
+
*
|
|
53
|
+
* The freshness guard prevents old exit events from misclassifying unrelated
|
|
54
|
+
* future failures as recoverable.
|
|
55
|
+
*/
|
|
56
|
+
export function isRecoverableSessionFailure(reason, agentName) {
|
|
57
|
+
// First check pattern match
|
|
58
|
+
if (matchesRecoverablePattern(reason)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
// If we have agent name, check startup diagnostics
|
|
62
|
+
if (agentName) {
|
|
63
|
+
const entries = readStartupDiagnostics(agentName);
|
|
64
|
+
let lastExit = null;
|
|
65
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
66
|
+
if (entries[i].type === "exit") {
|
|
67
|
+
lastExit = {
|
|
68
|
+
exit: entries[i].data,
|
|
69
|
+
timestamp: entries[i].timestamp,
|
|
70
|
+
};
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (lastExit) {
|
|
75
|
+
// Check freshness: exit event must be recent enough to be relevant
|
|
76
|
+
const exitTimestamp = new Date(lastExit.timestamp).getTime();
|
|
77
|
+
const now = Date.now();
|
|
78
|
+
const exitAgeMs = now - exitTimestamp;
|
|
79
|
+
// Only consider fresh exit events (within last 60 seconds)
|
|
80
|
+
if (exitAgeMs <= MAX_EXIT_EVENT_AGE_MS) {
|
|
81
|
+
// If process exited within 15 seconds of startup, consider it recoverable
|
|
82
|
+
// This catches cases where the runner crashed immediately
|
|
83
|
+
if (lastExit.exit.elapsedMs < STARTUP_WINDOW_MS) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
6
90
|
}
|
|
7
91
|
//# sourceMappingURL=session-recovery.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-recovery.js","sourceRoot":"","sources":["../../../src/core/daemon/session-recovery.ts"],"names":[],"mappings":"AAAA,MAAM,
|
|
1
|
+
{"version":3,"file":"session-recovery.js","sourceRoot":"","sources":["../../../src/core/daemon/session-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEzF;;GAEG;AACH,MAAM,mBAAmB,GAAG;IAC1B,mBAAmB;IACnB,WAAW;IACX,QAAQ;IACR,WAAW;IACX,kBAAkB;IAClB,oBAAoB;CACrB,CAAC;AAEF;;;GAGG;AACH,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAEpC;;GAEG;AACH,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAEhC;;GAEG;AACH,SAAS,yBAAyB,CAAC,MAAc;IAC/C,OAAO,CACL,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC;QACpC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC;QACjC,MAAM,CAAC,UAAU,CAAC,yBAAyB,CAAC;QAC5C,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAC/B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,MAAM,OAAO,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAClD,kCAAkC;IAClC,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,IAAwB,CAAC;QAC7C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAc,EAAE,SAAkB;IAC5E,4BAA4B;IAC5B,IAAI,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mDAAmD;IACnD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;QAOlD,IAAI,QAAQ,GAAqB,IAAI,CAAC;QAEtC,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC/B,QAAQ,GAAG;oBACT,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAwB;oBACzC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;iBAChC,CAAC;gBACF,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,mEAAmE;YACnE,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;YAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,GAAG,GAAG,aAAa,CAAC;YAEtC,2DAA2D;YAC3D,IAAI,SAAS,IAAI,qBAAqB,EAAE,CAAC;gBACvC,0EAA0E;gBAC1E,0DAA0D;gBAC1D,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,GAAG,iBAAiB,EAAE,CAAC;oBAChD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Startup Diagnostics for Agent Tmux Sessions
|
|
3
|
+
*
|
|
4
|
+
* Provides structured logging for runner startup to diagnose
|
|
5
|
+
* session creation failures and early exits.
|
|
6
|
+
*/
|
|
7
|
+
export interface StartupDiagnostics {
|
|
8
|
+
/** The final resolved command (with args) that was executed */
|
|
9
|
+
resolvedCommand: string;
|
|
10
|
+
/** Environment variables set (keys only, values redacted) */
|
|
11
|
+
envKeys: string[];
|
|
12
|
+
/** Session name used for tmux */
|
|
13
|
+
sessionName: string;
|
|
14
|
+
/** Working directory for the session */
|
|
15
|
+
workdir?: string;
|
|
16
|
+
/** Timestamp when session creation started */
|
|
17
|
+
startTime: string;
|
|
18
|
+
/** Runner type detected */
|
|
19
|
+
runnerKind: "opencode" | "claude" | "codex" | "other";
|
|
20
|
+
/** Whether autonomous mode was enabled */
|
|
21
|
+
autonomous?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface ProcessExitEvent {
|
|
24
|
+
/** Exit code (null if killed by signal) */
|
|
25
|
+
code: number | null;
|
|
26
|
+
/** Signal that killed the process (null if exited normally) */
|
|
27
|
+
signal: string | null;
|
|
28
|
+
/** Time elapsed since session creation (ms) */
|
|
29
|
+
elapsedMs: number;
|
|
30
|
+
/** Reason classification */
|
|
31
|
+
reason: string;
|
|
32
|
+
}
|
|
33
|
+
interface DiagnosticsEntry {
|
|
34
|
+
type: "startup" | "exit";
|
|
35
|
+
timestamp: string;
|
|
36
|
+
agentName: string;
|
|
37
|
+
data: StartupDiagnostics | ProcessExitEvent;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Redacts sensitive environment variable values, keeping only keys
|
|
41
|
+
*/
|
|
42
|
+
export declare function redactEnvKeys(env: Record<string, string | undefined>): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Detects the runner type from the command
|
|
45
|
+
*/
|
|
46
|
+
export declare function detectRunnerKind(command: string): "opencode" | "claude" | "codex" | "other";
|
|
47
|
+
/**
|
|
48
|
+
* Logs startup diagnostics for a new tmux session
|
|
49
|
+
*/
|
|
50
|
+
export declare function logSessionStartup(agentName: string, diagnostics: StartupDiagnostics): void;
|
|
51
|
+
/**
|
|
52
|
+
* Logs a process exit event
|
|
53
|
+
*/
|
|
54
|
+
export declare function logProcessExit(agentName: string, exitEvent: ProcessExitEvent): void;
|
|
55
|
+
/**
|
|
56
|
+
* Reads the recent diagnostics for an agent
|
|
57
|
+
*/
|
|
58
|
+
export declare function readStartupDiagnostics(agentName: string): DiagnosticsEntry[];
|
|
59
|
+
/**
|
|
60
|
+
* Clears old diagnostics for an agent (keeps last 100 entries)
|
|
61
|
+
*/
|
|
62
|
+
export declare function cleanupOldDiagnostics(agentName: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Captures the current pane PID for an agent's session
|
|
65
|
+
*/
|
|
66
|
+
export declare function capturePanePid(sessionName: string): number | null;
|
|
67
|
+
/**
|
|
68
|
+
* Monitors a tmux session for early process exit
|
|
69
|
+
* Returns a cleanup function to stop monitoring
|
|
70
|
+
*/
|
|
71
|
+
export declare function monitorSessionExit(agentName: string, sessionName: string, startTime: Date, onEarlyExit?: (event: ProcessExitEvent) => void): () => void;
|
|
72
|
+
/**
|
|
73
|
+
* Formats a diagnostic summary for display
|
|
74
|
+
*/
|
|
75
|
+
export declare function formatDiagnosticSummary(agentName: string): string;
|
|
76
|
+
export {};
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Startup Diagnostics for Agent Tmux Sessions
|
|
3
|
+
*
|
|
4
|
+
* Provides structured logging for runner startup to diagnose
|
|
5
|
+
* session creation failures and early exits.
|
|
6
|
+
*/
|
|
7
|
+
import { execSync } from "node:child_process";
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import os from "node:os";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
const DIAGNOSTICS_DIR = path.join(os.homedir(), ".agentmesh", "diagnostics");
|
|
12
|
+
const STARTUP_WINDOW_MS = 15000; // 15 second window for startup monitoring
|
|
13
|
+
/**
|
|
14
|
+
* Ensures the diagnostics directory exists
|
|
15
|
+
*/
|
|
16
|
+
function ensureDiagnosticsDir() {
|
|
17
|
+
if (!fs.existsSync(DIAGNOSTICS_DIR)) {
|
|
18
|
+
fs.mkdirSync(DIAGNOSTICS_DIR, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Gets the path to the diagnostics log file for an agent
|
|
23
|
+
*/
|
|
24
|
+
function getDiagnosticsPath(agentName) {
|
|
25
|
+
return path.join(DIAGNOSTICS_DIR, `${agentName}-startup.jsonl`);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Redacts sensitive environment variable values, keeping only keys
|
|
29
|
+
*/
|
|
30
|
+
export function redactEnvKeys(env) {
|
|
31
|
+
const sensitiveKeys = new Set([
|
|
32
|
+
"token",
|
|
33
|
+
"key",
|
|
34
|
+
"secret",
|
|
35
|
+
"password",
|
|
36
|
+
"auth",
|
|
37
|
+
"credential",
|
|
38
|
+
"api_key",
|
|
39
|
+
"apikey",
|
|
40
|
+
]);
|
|
41
|
+
return Object.entries(env)
|
|
42
|
+
.filter(([, value]) => value !== undefined && value !== "")
|
|
43
|
+
.map(([key]) => {
|
|
44
|
+
const lowerKey = key.toLowerCase();
|
|
45
|
+
// Mark sensitive keys with [REDACTED] suffix
|
|
46
|
+
const isSensitive = sensitiveKeys.has(lowerKey) || [...sensitiveKeys].some((sk) => lowerKey.includes(sk));
|
|
47
|
+
return isSensitive ? `${key}=[REDACTED]` : key;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Detects the runner type from the command
|
|
52
|
+
*/
|
|
53
|
+
export function detectRunnerKind(command) {
|
|
54
|
+
const cmd = command.trim().toLowerCase();
|
|
55
|
+
if (cmd.startsWith("opencode"))
|
|
56
|
+
return "opencode";
|
|
57
|
+
if (cmd.startsWith("claude"))
|
|
58
|
+
return "claude";
|
|
59
|
+
if (cmd.startsWith("codex"))
|
|
60
|
+
return "codex";
|
|
61
|
+
return "other";
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Logs startup diagnostics for a new tmux session
|
|
65
|
+
*/
|
|
66
|
+
export function logSessionStartup(agentName, diagnostics) {
|
|
67
|
+
ensureDiagnosticsDir();
|
|
68
|
+
const entry = {
|
|
69
|
+
type: "startup",
|
|
70
|
+
timestamp: new Date().toISOString(),
|
|
71
|
+
agentName,
|
|
72
|
+
data: diagnostics,
|
|
73
|
+
};
|
|
74
|
+
const logPath = getDiagnosticsPath(agentName);
|
|
75
|
+
fs.appendFileSync(logPath, `${JSON.stringify(entry)}\n`);
|
|
76
|
+
// Also log to console for immediate visibility
|
|
77
|
+
console.log(`[STARTUP] ${agentName}: ${diagnostics.resolvedCommand}`);
|
|
78
|
+
console.log(`[STARTUP] Runner: ${diagnostics.runnerKind}, Autonomous: ${diagnostics.autonomous ?? false}`);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Logs a process exit event
|
|
82
|
+
*/
|
|
83
|
+
export function logProcessExit(agentName, exitEvent) {
|
|
84
|
+
ensureDiagnosticsDir();
|
|
85
|
+
const entry = {
|
|
86
|
+
type: "exit",
|
|
87
|
+
timestamp: new Date().toISOString(),
|
|
88
|
+
agentName,
|
|
89
|
+
data: exitEvent,
|
|
90
|
+
};
|
|
91
|
+
const logPath = getDiagnosticsPath(agentName);
|
|
92
|
+
fs.appendFileSync(logPath, `${JSON.stringify(entry)}\n`);
|
|
93
|
+
// Log with appropriate severity
|
|
94
|
+
const severity = exitEvent.elapsedMs < STARTUP_WINDOW_MS ? "ERROR" : "WARN";
|
|
95
|
+
console.log(`[${severity}] ${agentName}: Process exited (code=${exitEvent.code}, signal=${exitEvent.signal}, elapsed=${exitEvent.elapsedMs}ms) - ${exitEvent.reason}`);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Reads the recent diagnostics for an agent
|
|
99
|
+
*/
|
|
100
|
+
export function readStartupDiagnostics(agentName) {
|
|
101
|
+
try {
|
|
102
|
+
const logPath = getDiagnosticsPath(agentName);
|
|
103
|
+
if (!fs.existsSync(logPath)) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
const content = fs.readFileSync(logPath, "utf-8");
|
|
107
|
+
return content
|
|
108
|
+
.trim()
|
|
109
|
+
.split("\n")
|
|
110
|
+
.filter(Boolean)
|
|
111
|
+
.map((line) => JSON.parse(line));
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Clears old diagnostics for an agent (keeps last 100 entries)
|
|
119
|
+
*/
|
|
120
|
+
export function cleanupOldDiagnostics(agentName) {
|
|
121
|
+
try {
|
|
122
|
+
const entries = readStartupDiagnostics(agentName);
|
|
123
|
+
if (entries.length <= 100)
|
|
124
|
+
return;
|
|
125
|
+
const logPath = getDiagnosticsPath(agentName);
|
|
126
|
+
const recent = entries.slice(-100);
|
|
127
|
+
fs.writeFileSync(logPath, `${recent.map((e) => JSON.stringify(e)).join("\n")}\n`);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// Non-fatal: cleanup failure should not break anything
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Captures the current pane PID for an agent's session
|
|
135
|
+
*/
|
|
136
|
+
export function capturePanePid(sessionName) {
|
|
137
|
+
try {
|
|
138
|
+
const output = execSync(`tmux list-panes -t "${sessionName}" -F "#{pane_pid}"`, {
|
|
139
|
+
encoding: "utf-8",
|
|
140
|
+
timeout: 5000,
|
|
141
|
+
}).trim();
|
|
142
|
+
const pid = parseInt(output, 10);
|
|
143
|
+
return Number.isNaN(pid) ? null : pid;
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Monitors a tmux session for early process exit
|
|
151
|
+
* Returns a cleanup function to stop monitoring
|
|
152
|
+
*/
|
|
153
|
+
export function monitorSessionExit(agentName, sessionName, startTime, onEarlyExit) {
|
|
154
|
+
const initialPid = capturePanePid(sessionName);
|
|
155
|
+
let checkInterval = null;
|
|
156
|
+
let hasExited = false;
|
|
157
|
+
// Stop monitoring after startup window + grace period
|
|
158
|
+
const stopMonitoringAt = startTime.getTime() + STARTUP_WINDOW_MS + 5000;
|
|
159
|
+
checkInterval = setInterval(() => {
|
|
160
|
+
if (hasExited)
|
|
161
|
+
return;
|
|
162
|
+
const now = Date.now();
|
|
163
|
+
if (now > stopMonitoringAt) {
|
|
164
|
+
// Startup window passed, stop monitoring
|
|
165
|
+
if (checkInterval) {
|
|
166
|
+
clearInterval(checkInterval);
|
|
167
|
+
checkInterval = null;
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
// Check if session still exists
|
|
173
|
+
execSync(`tmux has-session -t "${sessionName}" 2>/dev/null`, { timeout: 1000 });
|
|
174
|
+
// Check if pane is dead
|
|
175
|
+
const paneInfo = execSync(`tmux list-panes -t "${sessionName}" -F "#{pane_pid}:#{pane_dead}" 2>/dev/null`, { encoding: "utf-8", timeout: 1000 }).trim();
|
|
176
|
+
const [currentPidStr, dead] = paneInfo.split(":");
|
|
177
|
+
const currentPid = parseInt(currentPidStr, 10);
|
|
178
|
+
if (dead === "1") {
|
|
179
|
+
hasExited = true;
|
|
180
|
+
const elapsedMs = now - startTime.getTime();
|
|
181
|
+
const event = {
|
|
182
|
+
code: null,
|
|
183
|
+
signal: null,
|
|
184
|
+
elapsedMs,
|
|
185
|
+
reason: "pane_died",
|
|
186
|
+
};
|
|
187
|
+
logProcessExit(agentName, event);
|
|
188
|
+
onEarlyExit?.(event);
|
|
189
|
+
if (checkInterval) {
|
|
190
|
+
clearInterval(checkInterval);
|
|
191
|
+
checkInterval = null;
|
|
192
|
+
}
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
// Check if PID changed (process restarted/exited)
|
|
196
|
+
if (initialPid && !Number.isNaN(currentPid) && currentPid !== initialPid && initialPid > 0) {
|
|
197
|
+
hasExited = true;
|
|
198
|
+
const elapsedMs = now - startTime.getTime();
|
|
199
|
+
const event = {
|
|
200
|
+
code: null,
|
|
201
|
+
signal: null,
|
|
202
|
+
elapsedMs,
|
|
203
|
+
reason: "process_replaced",
|
|
204
|
+
};
|
|
205
|
+
logProcessExit(agentName, event);
|
|
206
|
+
onEarlyExit?.(event);
|
|
207
|
+
if (checkInterval) {
|
|
208
|
+
clearInterval(checkInterval);
|
|
209
|
+
checkInterval = null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// Session no longer exists - process exited
|
|
215
|
+
if (!hasExited) {
|
|
216
|
+
hasExited = true;
|
|
217
|
+
const elapsedMs = now - startTime.getTime();
|
|
218
|
+
const event = {
|
|
219
|
+
code: null,
|
|
220
|
+
signal: null,
|
|
221
|
+
elapsedMs,
|
|
222
|
+
reason: "session_terminated",
|
|
223
|
+
};
|
|
224
|
+
logProcessExit(agentName, event);
|
|
225
|
+
onEarlyExit?.(event);
|
|
226
|
+
if (checkInterval) {
|
|
227
|
+
clearInterval(checkInterval);
|
|
228
|
+
checkInterval = null;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}, 1000); // Check every second
|
|
233
|
+
// Return cleanup function
|
|
234
|
+
return () => {
|
|
235
|
+
if (checkInterval) {
|
|
236
|
+
clearInterval(checkInterval);
|
|
237
|
+
checkInterval = null;
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Formats a diagnostic summary for display
|
|
243
|
+
*/
|
|
244
|
+
export function formatDiagnosticSummary(agentName) {
|
|
245
|
+
const entries = readStartupDiagnostics(agentName);
|
|
246
|
+
if (entries.length === 0) {
|
|
247
|
+
return `No startup diagnostics found for ${agentName}`;
|
|
248
|
+
}
|
|
249
|
+
const recent = entries.slice(-5); // Last 5 entries
|
|
250
|
+
const lines = [
|
|
251
|
+
`\n=== Startup Diagnostics for ${agentName} ===`,
|
|
252
|
+
`Total entries: ${entries.length}`,
|
|
253
|
+
"",
|
|
254
|
+
];
|
|
255
|
+
for (const entry of recent) {
|
|
256
|
+
if (entry.type === "startup") {
|
|
257
|
+
const data = entry.data;
|
|
258
|
+
lines.push(`[${entry.timestamp}] STARTUP`);
|
|
259
|
+
lines.push(` Command: ${data.resolvedCommand}`);
|
|
260
|
+
lines.push(` Runner: ${data.runnerKind}`);
|
|
261
|
+
lines.push(` Session: ${data.sessionName}`);
|
|
262
|
+
lines.push(` Workdir: ${data.workdir ?? "(not set)"}`);
|
|
263
|
+
lines.push(` Autonomous: ${data.autonomous ?? false}`);
|
|
264
|
+
lines.push(` Env vars: ${data.envKeys.join(", ")}`);
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const data = entry.data;
|
|
268
|
+
lines.push(`[${entry.timestamp}] EXIT`);
|
|
269
|
+
lines.push(` Code: ${data.code ?? "N/A"}, Signal: ${data.signal ?? "N/A"}`);
|
|
270
|
+
lines.push(` Elapsed: ${data.elapsedMs}ms`);
|
|
271
|
+
lines.push(` Reason: ${data.reason}`);
|
|
272
|
+
}
|
|
273
|
+
lines.push("");
|
|
274
|
+
}
|
|
275
|
+
return lines.join("\n");
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=startup-diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup-diagnostics.js","sourceRoot":"","sources":["../../../src/core/daemon/startup-diagnostics.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,14 @@ export interface PersistRunningStateInput {
|
|
|
11
11
|
sandboxContainer?: string;
|
|
12
12
|
serveMode: boolean;
|
|
13
13
|
servePort: number;
|
|
14
|
+
serveHostname?: string;
|
|
15
|
+
serveUrl?: string;
|
|
16
|
+
servePublicUrl?: string;
|
|
17
|
+
serveAuthType?: "none" | "basic";
|
|
18
|
+
serveUsername?: string;
|
|
19
|
+
servePasswordEnv?: string;
|
|
20
|
+
serveHealthy?: boolean;
|
|
21
|
+
serveVersion?: string;
|
|
14
22
|
}
|
|
15
23
|
/**
|
|
16
24
|
* Get the PID of the foreground process running in a tmux pane.
|
|
@@ -73,6 +73,14 @@ export function persistRunningState(input) {
|
|
|
73
73
|
runnerType: input.runnerType,
|
|
74
74
|
sandboxContainer: input.sandboxContainer,
|
|
75
75
|
servePort: input.serveMode ? input.servePort : undefined,
|
|
76
|
+
serveHostname: input.serveMode ? input.serveHostname : undefined,
|
|
77
|
+
serveUrl: input.serveMode ? input.serveUrl : undefined,
|
|
78
|
+
servePublicUrl: input.serveMode ? input.servePublicUrl : undefined,
|
|
79
|
+
serveAuthType: input.serveMode ? input.serveAuthType : undefined,
|
|
80
|
+
serveUsername: input.serveMode ? input.serveUsername : undefined,
|
|
81
|
+
servePasswordEnv: input.serveMode ? input.servePasswordEnv : undefined,
|
|
82
|
+
serveHealthy: input.serveMode ? input.serveHealthy : undefined,
|
|
83
|
+
serveVersion: input.serveMode ? input.serveVersion : undefined,
|
|
76
84
|
});
|
|
77
85
|
}
|
|
78
86
|
//# sourceMappingURL=state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/core/daemon/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/core/daemon/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RunnerType } from "../runner/types.js";
|
|
1
2
|
import { type SessionEnv } from "../tmux.js";
|
|
2
3
|
export interface StartTmuxSessionInput {
|
|
3
4
|
agentName: string;
|
|
@@ -5,7 +6,10 @@ export interface StartTmuxSessionInput {
|
|
|
5
6
|
command: string;
|
|
6
7
|
workdir?: string;
|
|
7
8
|
runnerEnv: SessionEnv;
|
|
9
|
+
runnerType: RunnerType;
|
|
8
10
|
shouldRestoreContext: boolean;
|
|
11
|
+
serveMode: boolean;
|
|
12
|
+
sandboxMode: boolean;
|
|
9
13
|
autonomous?: boolean;
|
|
10
14
|
}
|
|
11
15
|
export interface StartTmuxSessionResult {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { loadContext } from "../../context/index.js";
|
|
2
|
+
import { shouldRestoreOpenCodeSession } from "../opencode-session-policy.js";
|
|
2
3
|
import { snapshotSessionId } from "../session-id.js";
|
|
3
4
|
import { createSession, getSessionName, sessionExists, updateSessionEnvironment, } from "../tmux.js";
|
|
4
5
|
/**
|
|
@@ -9,7 +10,14 @@ export function startTmuxRuntimeSession(input) {
|
|
|
9
10
|
const alreadyExists = sessionExists(sessionName);
|
|
10
11
|
if (!alreadyExists) {
|
|
11
12
|
let savedSessionId;
|
|
12
|
-
if (input.shouldRestoreContext &&
|
|
13
|
+
if (input.shouldRestoreContext &&
|
|
14
|
+
input.agentId &&
|
|
15
|
+
shouldRestoreOpenCodeSession({
|
|
16
|
+
runnerType: input.runnerType,
|
|
17
|
+
autonomous: input.autonomous ?? false,
|
|
18
|
+
serveMode: input.serveMode,
|
|
19
|
+
sandboxMode: input.sandboxMode,
|
|
20
|
+
})) {
|
|
13
21
|
const savedContext = loadContext(input.agentId);
|
|
14
22
|
savedSessionId = savedContext?.custom?.opencodeSessionId;
|
|
15
23
|
if (savedSessionId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux-session.js","sourceRoot":"","sources":["../../../src/core/daemon/tmux-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,aAAa,EACb,cAAc,EAEd,aAAa,EACb,wBAAwB,GACzB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"tmux-session.js","sourceRoot":"","sources":["../../../src/core/daemon/tmux-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAE7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,aAAa,EACb,cAAc,EAEd,aAAa,EACb,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAoBpB;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAA4B;IAClE,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAEjD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,IAAI,cAAkC,CAAC;QAEvC,IACE,KAAK,CAAC,oBAAoB;YAC1B,KAAK,CAAC,OAAO;YACb,4BAA4B,CAAC;gBAC3B,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,KAAK;gBACrC,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC,EACF,CAAC;YACD,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAChD,cAAc,GAAG,YAAY,EAAE,MAAM,EAAE,iBAAuC,CAAC;YAC/E,IAAI,cAAc,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,8CAA8C,cAAc,EAAE,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;QAED,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAE7D,OAAO,CAAC,GAAG,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAC;QAErD,MAAM,OAAO,GAAG,aAAa,CAC3B,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,SAAS,EACf,cAAc,EACd,KAAK,CAAC,UAAU,CACjB,CAAC;QAEF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,OAAO;YACL,iBAAiB;YACjB,wBAAwB,EAAE,cAAc;SACzC,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,qCAAqC,WAAW,EAAE,CAAC,CAAC;IAChE,wBAAwB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3D,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM-powered watcher loop.
|
|
3
|
+
*
|
|
4
|
+
* Two event sources feed the tick queue:
|
|
5
|
+
* 1. Scheduled ticker — every 2 min, full state fetch
|
|
6
|
+
* 2. WebSocket events — immediate reactive ticks (coalesced while LLM is busy)
|
|
7
|
+
*
|
|
8
|
+
* A consumer loop polls every 5s:
|
|
9
|
+
* - If LLM is processing → check tmux for completion
|
|
10
|
+
* - If idle and queue has items → dequeue, fetch state, inject into tmux
|
|
11
|
+
*
|
|
12
|
+
* Epic #883
|
|
13
|
+
*/
|
|
14
|
+
import type { WatcherTickQueue } from "./watcher-queue.js";
|
|
15
|
+
import { type WatcherContext } from "./watcher-state.js";
|
|
16
|
+
export interface WatcherLoopHandle {
|
|
17
|
+
stop: () => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function startWatcherLoop(ctx: WatcherContext, queue: WatcherTickQueue): WatcherLoopHandle;
|
|
20
|
+
/**
|
|
21
|
+
* Intercept WebSocket events relevant to the watcher and enqueue reactive ticks.
|
|
22
|
+
* Returns true if the event was consumed (watcher-relevant), false otherwise.
|
|
23
|
+
*/
|
|
24
|
+
export declare function handleWatcherWebSocketEvent(event: {
|
|
25
|
+
type: string;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}, queue: WatcherTickQueue): boolean;
|