sensorium-mcp 3.1.0-refactor.8 → 3.1.0
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/config/agent-settings.d.ts +6 -0
- package/dist/config/agent-settings.d.ts.map +1 -1
- package/dist/config/agent-settings.js +22 -0
- package/dist/config/agent-settings.js.map +1 -1
- package/dist/config/detail-grant.d.ts +39 -0
- package/dist/config/detail-grant.d.ts.map +1 -0
- package/dist/config/detail-grant.js +61 -0
- package/dist/config/detail-grant.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +5 -3
- package/dist/config/index.js.map +1 -1
- package/dist/config/misc-settings.d.ts +2 -0
- package/dist/config/misc-settings.d.ts.map +1 -1
- package/dist/config/misc-settings.js +22 -0
- package/dist/config/misc-settings.js.map +1 -1
- package/dist/config/settings-store.d.ts +41 -2
- package/dist/config/settings-store.d.ts.map +1 -1
- package/dist/config/settings-store.js +151 -14
- package/dist/config/settings-store.js.map +1 -1
- package/dist/dashboard/routes/copilot.d.ts.map +1 -1
- package/dist/dashboard/routes/copilot.js +17 -1
- package/dist/dashboard/routes/copilot.js.map +1 -1
- package/dist/dashboard/routes/settings.d.ts +2 -0
- package/dist/dashboard/routes/settings.d.ts.map +1 -1
- package/dist/dashboard/routes/settings.js +25 -1
- package/dist/dashboard/routes/settings.js.map +1 -1
- package/dist/dashboard/routes/threads-read.d.ts.map +1 -1
- package/dist/dashboard/routes/threads-read.js +15 -3
- package/dist/dashboard/routes/threads-read.js.map +1 -1
- package/dist/dashboard/routes/threads.d.ts.map +1 -1
- package/dist/dashboard/routes/threads.js +13 -4
- package/dist/dashboard/routes/threads.js.map +1 -1
- package/dist/dashboard/routes.d.ts.map +1 -1
- package/dist/dashboard/routes.js +14 -5
- package/dist/dashboard/routes.js.map +1 -1
- package/dist/dashboard/spa.html +11 -11
- package/dist/data/daily-marker.js +3 -3
- package/dist/data/daily-marker.js.map +1 -1
- package/dist/data/file-storage.d.ts.map +1 -1
- package/dist/data/file-storage.js +3 -3
- package/dist/data/file-storage.js.map +1 -1
- package/dist/data/memory/bootstrap.d.ts.map +1 -1
- package/dist/data/memory/bootstrap.js +2 -3
- package/dist/data/memory/bootstrap.js.map +1 -1
- package/dist/data/memory/migration-runner.d.ts.map +1 -1
- package/dist/data/memory/migration-runner.js +4 -7
- package/dist/data/memory/migration-runner.js.map +1 -1
- package/dist/data/memory/schema-ddl.d.ts +1 -1
- package/dist/data/memory/schema-ddl.d.ts.map +1 -1
- package/dist/data/memory/schema-ddl.js +7 -1
- package/dist/data/memory/schema-ddl.js.map +1 -1
- package/dist/data/memory/schema.js +2 -2
- package/dist/data/memory/schema.js.map +1 -1
- package/dist/index.js +67 -21
- package/dist/index.js.map +1 -1
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +21 -2
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/paths.d.ts +29 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +36 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/types.d.ts +1 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/server/factory.js +16 -6
- package/dist/server/factory.js.map +1 -1
- package/dist/server/http-server.d.ts.map +1 -1
- package/dist/server/http-server.js +52 -20
- package/dist/server/http-server.js.map +1 -1
- package/dist/services/agent-spawn.service.d.ts +3 -3
- package/dist/services/agent-spawn.service.d.ts.map +1 -1
- package/dist/services/agent-spawn.service.js +30 -9
- package/dist/services/agent-spawn.service.js.map +1 -1
- package/dist/services/background-runner.d.ts.map +1 -1
- package/dist/services/background-runner.js +22 -12
- package/dist/services/background-runner.js.map +1 -1
- package/dist/services/broker-client.d.ts +209 -0
- package/dist/services/broker-client.d.ts.map +1 -0
- package/dist/services/broker-client.js +359 -0
- package/dist/services/broker-client.js.map +1 -0
- package/dist/services/claude-spawn.service.d.ts +1 -1
- package/dist/services/claude-spawn.service.d.ts.map +1 -1
- package/dist/services/claude-spawn.service.js +25 -25
- package/dist/services/claude-spawn.service.js.map +1 -1
- package/dist/services/codex-spawn.service.d.ts +1 -1
- package/dist/services/codex-spawn.service.d.ts.map +1 -1
- package/dist/services/codex-spawn.service.js +19 -24
- package/dist/services/codex-spawn.service.js.map +1 -1
- package/dist/services/copilot-spawn.service.d.ts +1 -1
- package/dist/services/copilot-spawn.service.d.ts.map +1 -1
- package/dist/services/copilot-spawn.service.js +86 -37
- package/dist/services/copilot-spawn.service.js.map +1 -1
- package/dist/services/dispatcher/broker.d.ts +4 -3
- package/dist/services/dispatcher/broker.d.ts.map +1 -1
- package/dist/services/dispatcher/broker.js +23 -11
- package/dist/services/dispatcher/broker.js.map +1 -1
- package/dist/services/dispatcher/lock.js +2 -2
- package/dist/services/dispatcher/lock.js.map +1 -1
- package/dist/services/dispatcher/poller.d.ts.map +1 -1
- package/dist/services/dispatcher/poller.js +24 -5
- package/dist/services/dispatcher/poller.js.map +1 -1
- package/dist/services/flight-recorder.service.d.ts +37 -0
- package/dist/services/flight-recorder.service.d.ts.map +1 -0
- package/dist/services/flight-recorder.service.js +210 -0
- package/dist/services/flight-recorder.service.js.map +1 -0
- package/dist/services/keeper.service.d.ts +9 -0
- package/dist/services/keeper.service.d.ts.map +1 -1
- package/dist/services/keeper.service.js +198 -39
- package/dist/services/keeper.service.js.map +1 -1
- package/dist/services/maintenance-signal.d.ts.map +1 -1
- package/dist/services/maintenance-signal.js +2 -3
- package/dist/services/maintenance-signal.js.map +1 -1
- package/dist/services/process.service.d.ts +76 -61
- package/dist/services/process.service.d.ts.map +1 -1
- package/dist/services/process.service.js +224 -608
- package/dist/services/process.service.js.map +1 -1
- package/dist/services/reconnect-snapshot.service.js +2 -2
- package/dist/services/reconnect-snapshot.service.js.map +1 -1
- package/dist/services/scheduler.d.ts +1 -0
- package/dist/services/scheduler.d.ts.map +1 -1
- package/dist/services/scheduler.js +69 -14
- package/dist/services/scheduler.js.map +1 -1
- package/dist/services/self-update.service.d.ts +113 -15
- package/dist/services/self-update.service.d.ts.map +1 -1
- package/dist/services/self-update.service.js +382 -109
- package/dist/services/self-update.service.js.map +1 -1
- package/dist/services/spawn-common.d.ts +49 -23
- package/dist/services/spawn-common.d.ts.map +1 -1
- package/dist/services/spawn-common.js +262 -47
- package/dist/services/spawn-common.js.map +1 -1
- package/dist/services/spawn-exit-watcher.d.ts +43 -0
- package/dist/services/spawn-exit-watcher.d.ts.map +1 -0
- package/dist/services/spawn-exit-watcher.js +127 -0
- package/dist/services/spawn-exit-watcher.js.map +1 -0
- package/dist/services/telegram.d.ts +3 -2
- package/dist/services/telegram.d.ts.map +1 -1
- package/dist/services/telegram.js +8 -5
- package/dist/services/telegram.js.map +1 -1
- package/dist/services/thread-health.service.d.ts +1 -1
- package/dist/services/thread-health.service.d.ts.map +1 -1
- package/dist/services/thread-health.service.js +11 -7
- package/dist/services/thread-health.service.js.map +1 -1
- package/dist/services/thread-lifecycle.service.js +2 -2
- package/dist/services/thread-lifecycle.service.js.map +1 -1
- package/dist/services/topic.service.d.ts +1 -1
- package/dist/services/topic.service.d.ts.map +1 -1
- package/dist/services/topic.service.js +3 -2
- package/dist/services/topic.service.js.map +1 -1
- package/dist/services/worker-cleanup.service.d.ts.map +1 -1
- package/dist/services/worker-cleanup.service.js +25 -99
- package/dist/services/worker-cleanup.service.js.map +1 -1
- package/dist/test-bootstrap.d.ts +39 -0
- package/dist/test-bootstrap.d.ts.map +1 -0
- package/dist/test-bootstrap.js +78 -0
- package/dist/test-bootstrap.js.map +1 -0
- package/dist/tools/defs/session-defs.js +1 -1
- package/dist/tools/defs/session-defs.js.map +1 -1
- package/dist/tools/defs/utility-defs.d.ts.map +1 -1
- package/dist/tools/defs/utility-defs.js +4 -3
- package/dist/tools/defs/utility-defs.js.map +1 -1
- package/dist/tools/delegate-tool.d.ts +1 -1
- package/dist/tools/delegate-tool.d.ts.map +1 -1
- package/dist/tools/delegate-tool.js +37 -6
- package/dist/tools/delegate-tool.js.map +1 -1
- package/dist/tools/session-tools.d.ts.map +1 -1
- package/dist/tools/session-tools.js +34 -20
- package/dist/tools/session-tools.js.map +1 -1
- package/dist/tools/utility-tools.js +1 -1
- package/dist/tools/utility-tools.js.map +1 -1
- package/dist/tools/wait/context.d.ts +13 -0
- package/dist/tools/wait/context.d.ts.map +1 -1
- package/dist/tools/wait/message-delivery.d.ts.map +1 -1
- package/dist/tools/wait/message-delivery.js +2 -3
- package/dist/tools/wait/message-delivery.js.map +1 -1
- package/dist/tools/wait/poll-loop.d.ts.map +1 -1
- package/dist/tools/wait/poll-loop.js +8 -1
- package/dist/tools/wait/poll-loop.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin HTTP client for the supervisor's process broker (plan §4.1, Phase 2).
|
|
3
|
+
*
|
|
4
|
+
* Liveness, identity and kill move OFF the Node event loop and OUT of child
|
|
5
|
+
* processes: the supervisor answers from one native NtQuerySystemInformation
|
|
6
|
+
* snapshot and kills via native TerminateProcess/TerminateJobObject. Nothing
|
|
7
|
+
* here ever spawns a process — the EDR-gated tasklist/powershell/taskkill
|
|
8
|
+
* machinery this replaces was itself the leading event-loop stall generator.
|
|
9
|
+
*
|
|
10
|
+
* Degradation contract (the audited-safe direction, same as the old breakers):
|
|
11
|
+
* every function returns `null` when the broker cannot answer (unreachable,
|
|
12
|
+
* auth-rejected, timeout) and the caller MUST treat null as "cannot confirm
|
|
13
|
+
* → assume alive / kill not performed". Communication is strictly one-way
|
|
14
|
+
* MCP → supervisor.
|
|
15
|
+
*/
|
|
16
|
+
import { log } from "../lib/logger.js";
|
|
17
|
+
import { errorMessage } from "../lib/utils.js";
|
|
18
|
+
const REQUEST_TIMEOUT_MS = 3000;
|
|
19
|
+
// Timeouts here are pure LIVENESS backstops — correctness never depends on
|
|
20
|
+
// their values. A spawn whose request outlives the client timeout is resolved
|
|
21
|
+
// through the reconcile path (query the broker registry, adopt or retry the
|
|
22
|
+
// idempotent spawn — see launchAgent), never by a blind local spawn, so no
|
|
23
|
+
// timeout value can cause a duplicate agent. Spawns are sub-second on this
|
|
24
|
+
// machine; the generous budgets only keep a pathologically slow call from
|
|
25
|
+
// tying up its caller forever. Kill's TerminateJobObject settle loop alone can
|
|
26
|
+
// take ~2.2s server-side, hence the longer mutate budget. Reads keep 3s.
|
|
27
|
+
const SPAWN_TIMEOUT_MS = 30_000;
|
|
28
|
+
const MUTATE_TIMEOUT_MS = 10_000;
|
|
29
|
+
// After a failed broker call, skip further calls for a short window instead of
|
|
30
|
+
// re-paying a connect timeout for every pid in a sweep (the keeper checks many
|
|
31
|
+
// pids per cycle). Connection-refused fails in ~1 ms so this is only load-bearing
|
|
32
|
+
// when the supervisor itself is wedged.
|
|
33
|
+
const UNREACHABLE_COOLDOWN_MS = 5000;
|
|
34
|
+
let unreachableUntil = 0;
|
|
35
|
+
let unreachableLogged = false;
|
|
36
|
+
let lastFailureKind = "uncertain";
|
|
37
|
+
function classifyFetchError(err) {
|
|
38
|
+
const e = err;
|
|
39
|
+
// AbortSignal.timeout → the request was sent and the response never arrived.
|
|
40
|
+
if (e?.name === "TimeoutError" || e?.name === "AbortError")
|
|
41
|
+
return "uncertain";
|
|
42
|
+
const code = e?.cause?.code ?? e?.cause?.errors?.find((x) => x?.code)?.code ?? e?.code ?? undefined;
|
|
43
|
+
switch (code) {
|
|
44
|
+
case "ECONNREFUSED":
|
|
45
|
+
case "ENOTFOUND":
|
|
46
|
+
case "EAI_AGAIN":
|
|
47
|
+
case "EADDRNOTAVAIL":
|
|
48
|
+
case "EHOSTUNREACH":
|
|
49
|
+
case "ENETUNREACH":
|
|
50
|
+
case "UND_ERR_CONNECT_TIMEOUT":
|
|
51
|
+
return "no-connection";
|
|
52
|
+
}
|
|
53
|
+
// Some undici versions wrap the socket error in a bare Error with only a
|
|
54
|
+
// message ("connect ECONNREFUSED …", "bad port"). Fall back to the text for
|
|
55
|
+
// the same connection-never-established classes; anything unrecognized stays
|
|
56
|
+
// "uncertain" — the safe direction.
|
|
57
|
+
const msg = e?.cause?.message ?? "";
|
|
58
|
+
if (/ECONNREFUSED|ENOTFOUND|EHOSTUNREACH|ENETUNREACH|bad port|invalid url/i.test(msg))
|
|
59
|
+
return "no-connection";
|
|
60
|
+
return "uncertain";
|
|
61
|
+
}
|
|
62
|
+
function brokerBaseUrl() {
|
|
63
|
+
const port = Number.parseInt(process.env.SUPERVISOR_HTTP_PORT ?? "", 10) || 8848;
|
|
64
|
+
return `http://127.0.0.1:${port}`;
|
|
65
|
+
}
|
|
66
|
+
function authHeaders() {
|
|
67
|
+
const secret = process.env.MCP_HTTP_SECRET;
|
|
68
|
+
return secret ? { Authorization: `Bearer ${secret}` } : {};
|
|
69
|
+
}
|
|
70
|
+
async function brokerFetchClassified(path, init, timeoutMs = REQUEST_TIMEOUT_MS, opts) {
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
// During the cooldown we answer from the LAST observed failure kind: the
|
|
73
|
+
// spawn contract needs "could the broker have received a request" and a
|
|
74
|
+
// skipped call inherits the evidence that started the cooldown. The cooldown
|
|
75
|
+
// exists to protect the keeper's many-pids-per-cycle sweeps from paying a
|
|
76
|
+
// full timeout each; spawn/reconcile calls are rare and correctness-critical,
|
|
77
|
+
// so they bypass it — a reconcile probe must never be answered from stale
|
|
78
|
+
// evidence created by the very spawn it is reconciling.
|
|
79
|
+
if (!opts?.bypassCooldown && now < unreachableUntil)
|
|
80
|
+
return { res: null, failure: lastFailureKind };
|
|
81
|
+
try {
|
|
82
|
+
const res = await fetch(`${brokerBaseUrl()}${path}`, {
|
|
83
|
+
...init,
|
|
84
|
+
headers: { ...authHeaders(), ...init?.headers },
|
|
85
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
86
|
+
});
|
|
87
|
+
unreachableLogged = false;
|
|
88
|
+
return { res };
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
const failure = classifyFetchError(err);
|
|
92
|
+
unreachableUntil = Date.now() + UNREACHABLE_COOLDOWN_MS;
|
|
93
|
+
lastFailureKind = failure;
|
|
94
|
+
if (!unreachableLogged) {
|
|
95
|
+
// WARN, deliberately: every liveness answer during this outage degrades to
|
|
96
|
+
// "cannot confirm → treat alive" and every kill falls back to best-effort —
|
|
97
|
+
// a silent fallback must never look like a healthy answer. Logged once per
|
|
98
|
+
// outage episode (reset on the first successful call) to avoid a warn storm
|
|
99
|
+
// when the keeper sweeps many pids per cycle.
|
|
100
|
+
log.warn(`[broker] unreachable (${errorMessage(err)}, ${failure}) — degrading to "cannot confirm": liveness treated as alive, kills fall back to native root-only`);
|
|
101
|
+
unreachableLogged = true;
|
|
102
|
+
}
|
|
103
|
+
return { res: null, failure };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function brokerFetch(path, init, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
107
|
+
return (await brokerFetchClassified(path, init, timeoutMs)).res;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Ask the broker whether `pid` is alive AND (when `startedAtMs` is given) still
|
|
111
|
+
* the same process we spawned (creation-time identity, ±60s tolerance — the
|
|
112
|
+
* same rule the deleted tasklist/Get-Process snapshots enforced).
|
|
113
|
+
* `startTimeTicks` (native creation FILETIME from a broker spawn) upgrades the
|
|
114
|
+
* check to exact identity. Returns null when the broker cannot answer.
|
|
115
|
+
*/
|
|
116
|
+
export async function brokerCheckAlive(pid, startedAtMs, startTimeTicks) {
|
|
117
|
+
const params = new URLSearchParams({ pid: String(pid) });
|
|
118
|
+
if (startTimeTicks !== undefined && startTimeTicks !== 0)
|
|
119
|
+
params.set("startTicks", String(startTimeTicks));
|
|
120
|
+
else if (startedAtMs !== undefined)
|
|
121
|
+
params.set("startMs", String(Math.round(startedAtMs)));
|
|
122
|
+
const res = await brokerFetch(`/proc/alive?${params}`);
|
|
123
|
+
if (!res || !res.ok)
|
|
124
|
+
return null;
|
|
125
|
+
try {
|
|
126
|
+
return (await res.json());
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Job-based thread liveness — the single source of truth for a broker-spawned
|
|
134
|
+
* worker. A launcher CLI (claude.exe/copilot.exe forks the real agent then exits)
|
|
135
|
+
* makes the originally-spawned pid a lie; the thread's JOB is not. Returns
|
|
136
|
+
* `known:false` when the broker has no record of the thread, and null when the
|
|
137
|
+
* broker cannot answer (unreachable → "cannot confirm → treat alive").
|
|
138
|
+
*/
|
|
139
|
+
export async function brokerCheckAliveByThread(threadId) {
|
|
140
|
+
const res = await brokerFetch(`/proc/alive?threadId=${threadId}`);
|
|
141
|
+
if (!res)
|
|
142
|
+
return null; // unreachable → cannot confirm
|
|
143
|
+
if (res.status === 404)
|
|
144
|
+
return { known: false, alive: false };
|
|
145
|
+
if (!res.ok)
|
|
146
|
+
return null;
|
|
147
|
+
try {
|
|
148
|
+
const b = (await res.json());
|
|
149
|
+
return {
|
|
150
|
+
known: true,
|
|
151
|
+
alive: b.alive,
|
|
152
|
+
source: b.source,
|
|
153
|
+
exitCode: b.exitCode,
|
|
154
|
+
registryState: b.registryState,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Ask the broker to kill the process tree rooted at `pid` (native, identity-
|
|
163
|
+
* checked when `startedAtMs` is given; the broker records the outcome in its
|
|
164
|
+
* on-disk registry). Returns null when the broker cannot answer — the caller
|
|
165
|
+
* must then fall back / re-verify, never assume the kill happened.
|
|
166
|
+
*
|
|
167
|
+
* Pass `pid` as undefined to route the kill by THREAD instead: the broker then
|
|
168
|
+
* takes the KillByThread path (job kill of every live member, or the registry-
|
|
169
|
+
* identity survivor when the job assign failed) rather than KillByPid. This is
|
|
170
|
+
* the correct call for a launcher-forked worker whose recorded pid is the
|
|
171
|
+
* already-exited launcher — KillByPid(launcher) hits the broker's AlreadyDead
|
|
172
|
+
* fast-path and never touches the live forked child.
|
|
173
|
+
*/
|
|
174
|
+
export async function brokerKillTree(pid, opts = {}) {
|
|
175
|
+
const res = await brokerFetch(`/proc/kill`, {
|
|
176
|
+
method: "POST",
|
|
177
|
+
headers: { "Content-Type": "application/json" },
|
|
178
|
+
body: JSON.stringify({
|
|
179
|
+
pid,
|
|
180
|
+
threadId: opts.threadId,
|
|
181
|
+
startMs: opts.startedAtMs !== undefined ? Math.round(opts.startedAtMs) : undefined,
|
|
182
|
+
killedBy: opts.killedBy ?? "mcp",
|
|
183
|
+
reason: opts.reason,
|
|
184
|
+
}),
|
|
185
|
+
}, MUTATE_TIMEOUT_MS);
|
|
186
|
+
if (!res)
|
|
187
|
+
return null;
|
|
188
|
+
// 403 = the broker REFUSED (self/server protection). That is an answer, not an
|
|
189
|
+
// outage: report it as not-killed-still-alive so callers never retry-storm.
|
|
190
|
+
if (!res.ok && res.status !== 403)
|
|
191
|
+
return null;
|
|
192
|
+
try {
|
|
193
|
+
return (await res.json());
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Ask the supervisor to spawn an agent process: CreateProcess(CREATE_SUSPENDED)
|
|
201
|
+
* → assign to the thread's named job → resume. The supervisor is the process
|
|
202
|
+
* owner; children (hooks, grandchildren) land in the job automatically.
|
|
203
|
+
* Spawn is idempotent by threadId server-side (create-or-return), which is what
|
|
204
|
+
* makes retrying after an uncertain outcome safe.
|
|
205
|
+
*/
|
|
206
|
+
export async function brokerSpawn(spec) {
|
|
207
|
+
const { res, failure } = await brokerFetchClassified(`/proc/spawn`, {
|
|
208
|
+
method: "POST",
|
|
209
|
+
headers: { "Content-Type": "application/json" },
|
|
210
|
+
body: JSON.stringify(spec),
|
|
211
|
+
}, spawnTimeoutOverride ?? SPAWN_TIMEOUT_MS, { bypassCooldown: true });
|
|
212
|
+
if (!res) {
|
|
213
|
+
return failure === "no-connection"
|
|
214
|
+
? { unavailable: "broker unreachable — connection never established" }
|
|
215
|
+
: { uncertain: "spawn request timed out or the connection was lost mid-flight" };
|
|
216
|
+
}
|
|
217
|
+
if (res.status === 404 || res.status === 401)
|
|
218
|
+
return {
|
|
219
|
+
unavailable: res.status === 404
|
|
220
|
+
? "/proc/spawn not available on this supervisor build"
|
|
221
|
+
: "broker rejected the bearer secret",
|
|
222
|
+
};
|
|
223
|
+
try {
|
|
224
|
+
const body = (await res.json());
|
|
225
|
+
if (res.ok && body.ok && typeof body.pid === "number" && body.pid > 0) {
|
|
226
|
+
return {
|
|
227
|
+
pid: body.pid,
|
|
228
|
+
startTimeTicks: body.startTimeTicks ?? 0,
|
|
229
|
+
startTimeMs: body.startTimeMs ?? Date.now(),
|
|
230
|
+
jobName: body.jobName ?? null,
|
|
231
|
+
jobAssignFailed: body.jobAssignFailed ?? false,
|
|
232
|
+
existing: body.existing ?? false,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return { error: body.error ?? `broker answered HTTP ${res.status} without an error detail` };
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// A 200 the broker sent but we could not read — the spawn may well have
|
|
239
|
+
// happened. Only a non-OK status is a definitive failure.
|
|
240
|
+
return res.ok
|
|
241
|
+
? { uncertain: `broker answered HTTP ${res.status} but the body was unreadable` }
|
|
242
|
+
: { error: `broker answered HTTP ${res.status} with an unparseable body` };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* The broker's live process list for a thread (job members, falling back to the
|
|
247
|
+
* registry root's tree). This is the reconcile source of truth after an
|
|
248
|
+
* uncertain spawn: a live entry here means the thread HAS its process — adopt
|
|
249
|
+
* it, never spawn another. `known:false` → the broker answered and has no
|
|
250
|
+
* record of the thread. Null → broker could not answer.
|
|
251
|
+
*/
|
|
252
|
+
export async function brokerListThread(threadId) {
|
|
253
|
+
const { res } = await brokerFetchClassified(`/proc/list?threadId=${threadId}`, undefined, REQUEST_TIMEOUT_MS, {
|
|
254
|
+
bypassCooldown: true,
|
|
255
|
+
});
|
|
256
|
+
if (!res)
|
|
257
|
+
return null;
|
|
258
|
+
if (res.status === 404)
|
|
259
|
+
return { known: false, processes: [] };
|
|
260
|
+
if (!res.ok)
|
|
261
|
+
return null;
|
|
262
|
+
try {
|
|
263
|
+
const body = (await res.json());
|
|
264
|
+
return { known: true, processes: body.processes ?? [] };
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// ── Adopt (safe-cutover migration) ──────────────────────────────────────────
|
|
271
|
+
/**
|
|
272
|
+
* Ask the broker to adopt an already-running process (spawned before the broker
|
|
273
|
+
* owned spawning, or during a broker outage) into the thread's job + registry.
|
|
274
|
+
* Idempotent server-side. Best-effort: null when the broker cannot answer.
|
|
275
|
+
*/
|
|
276
|
+
export async function brokerAdopt(threadId, pid, startedAtMs, role) {
|
|
277
|
+
const res = await brokerFetch(`/proc/adopt`, {
|
|
278
|
+
method: "POST",
|
|
279
|
+
headers: { "Content-Type": "application/json" },
|
|
280
|
+
body: JSON.stringify({
|
|
281
|
+
threadId,
|
|
282
|
+
pid,
|
|
283
|
+
startMs: startedAtMs !== undefined ? Math.round(startedAtMs) : undefined,
|
|
284
|
+
role,
|
|
285
|
+
}),
|
|
286
|
+
},
|
|
287
|
+
// Adopt walks and job-assigns a whole tree — give it the mutate budget.
|
|
288
|
+
MUTATE_TIMEOUT_MS);
|
|
289
|
+
if (!res || !res.ok)
|
|
290
|
+
return null;
|
|
291
|
+
try {
|
|
292
|
+
return (await res.json());
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Ask the supervisor — the single process-lifecycle owner — to tear down and
|
|
300
|
+
* respawn THIS server (self-update path). The supervisor answers 202 before
|
|
301
|
+
* doing anything: the requester is the process about to be killed, so it can
|
|
302
|
+
* never observe completion. 409 means a restart is already in progress, which
|
|
303
|
+
* delivers exactly what the caller wants — treat it as success.
|
|
304
|
+
*
|
|
305
|
+
* Returns null when the supervisor cannot answer (unreachable, or an old
|
|
306
|
+
* binary without /restart → 404/401). The caller decides between the flagged
|
|
307
|
+
* legacy self-spawn fallback and a loud abort — same contract as brokerSpawn.
|
|
308
|
+
*/
|
|
309
|
+
export async function brokerRequestRestart(reason) {
|
|
310
|
+
const res = await brokerFetch(`/restart`, {
|
|
311
|
+
method: "POST",
|
|
312
|
+
headers: { "Content-Type": "application/json" },
|
|
313
|
+
body: JSON.stringify({ reason }),
|
|
314
|
+
});
|
|
315
|
+
if (!res)
|
|
316
|
+
return null;
|
|
317
|
+
if (res.status === 202)
|
|
318
|
+
return "accepted";
|
|
319
|
+
if (res.status === 409)
|
|
320
|
+
return "in-progress";
|
|
321
|
+
return null; // 404 = old supervisor binary; 401 = misconfigured secret
|
|
322
|
+
}
|
|
323
|
+
/** Load a thread's persisted keeper counters. Null → broker unreachable OR no
|
|
324
|
+
* state saved yet (both mean "start from defaults"). */
|
|
325
|
+
export async function brokerGetKeeperState(threadId) {
|
|
326
|
+
const res = await brokerFetch(`/proc/keeper?threadId=${threadId}`);
|
|
327
|
+
if (!res || !res.ok)
|
|
328
|
+
return null;
|
|
329
|
+
try {
|
|
330
|
+
const body = (await res.json());
|
|
331
|
+
return body.found && body.state ? body.state : null;
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/** Persist a thread's keeper counters (fire-and-forget from the keeper; a lost
|
|
338
|
+
* write degrades to today's in-memory behavior, already logged at WARN by the
|
|
339
|
+
* unreachable path). */
|
|
340
|
+
export async function brokerSaveKeeperState(state) {
|
|
341
|
+
await brokerFetch(`/proc/keeper`, {
|
|
342
|
+
method: "POST",
|
|
343
|
+
headers: { "Content-Type": "application/json" },
|
|
344
|
+
body: JSON.stringify(state),
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
/** Test hook: reset the unreachable-cooldown state. */
|
|
348
|
+
export function resetBrokerClientState() {
|
|
349
|
+
unreachableUntil = 0;
|
|
350
|
+
unreachableLogged = false;
|
|
351
|
+
lastFailureKind = "uncertain";
|
|
352
|
+
}
|
|
353
|
+
/** Test hook: shrink the spawn liveness backstop so timeout-class tests don't
|
|
354
|
+
* wait 30s. Pass null to restore the default. */
|
|
355
|
+
let spawnTimeoutOverride = null;
|
|
356
|
+
export function brokerSpawnTimeoutForTest(ms) {
|
|
357
|
+
spawnTimeoutOverride = ms;
|
|
358
|
+
}
|
|
359
|
+
//# sourceMappingURL=broker-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-client.js","sourceRoot":"","sources":["../../src/services/broker-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
import type { ThreadLifecycleService } from "./thread-lifecycle.service.js";
|
|
6
6
|
import { type SpawnResult } from "./spawn-common.js";
|
|
7
7
|
export declare const resolveClaudePath: () => string | null;
|
|
8
|
-
export declare function spawnAgentProcess(claudePath: string, name: string, threadId: number, threadLifecycle: ThreadLifecycleService, workingDirectory?: string, memorySourceThreadId?: number, threadType?: "worker" | "branch", modelOverride?: string): SpawnResult
|
|
8
|
+
export declare function spawnAgentProcess(claudePath: string, name: string, threadId: number, threadLifecycle: ThreadLifecycleService, workingDirectory?: string, memorySourceThreadId?: number, threadType?: "worker" | "branch", modelOverride?: string): Promise<SpawnResult>;
|
|
9
9
|
//# sourceMappingURL=claude-spawn.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-spawn.service.d.ts","sourceRoot":"","sources":["../../src/services/claude-spawn.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"claude-spawn.service.d.ts","sourceRoot":"","sources":["../../src/services/claude-spawn.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0BH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EAWL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,iBAAiB,QAAO,MAAM,GAAG,IAQ7C,CAAC;AAqDF,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,sBAAsB,EACvC,gBAAgB,CAAC,EAAE,MAAM,EACzB,oBAAoB,CAAC,EAAE,MAAM,EAC7B,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,EAChC,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,WAAW,CAAC,CA4HtB"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Claude-specific spawn logic: CLI-path resolution and the Claude Code process
|
|
3
3
|
* launch (per-thread config dir, OAuth-token handling, git-bash discovery).
|
|
4
4
|
*/
|
|
5
|
-
import { spawn } from "node:child_process";
|
|
6
5
|
import { copyFileSync, existsSync, mkdirSync, unlinkSync, readFileSync, writeFileSync, } from "node:fs";
|
|
7
6
|
import { homedir } from "node:os";
|
|
8
7
|
import { join } from "node:path";
|
|
@@ -11,7 +10,7 @@ import { log } from "../lib/logger.js";
|
|
|
11
10
|
import { errorMessage } from "../lib/utils.js";
|
|
12
11
|
import { PROCESS_BASE_DIR, PROCESS_LOGS_DIR } from "./process.service.js";
|
|
13
12
|
import { buildClaudeMcpConfig } from "./mcp-config.service.js";
|
|
14
|
-
import { sanitizeSpawnEnv, resolveCliPath, resolveWindowsCliPath, normalizeWorkingDirectory, isStartupCleanupInProgress, checkSpawnPreconditions, buildThreadLogPath, buildSessionPrompt,
|
|
13
|
+
import { sanitizeSpawnEnv, resolveCliPath, resolveWindowsCliPath, normalizeWorkingDirectory, isStartupCleanupInProgress, checkSpawnPreconditions, buildThreadLogPath, buildSessionPrompt, launchAgent, stripDenylistedEnvVars, } from "./spawn-common.js";
|
|
15
14
|
export const resolveClaudePath = () => {
|
|
16
15
|
const envCmd = process.env.CLAUDE_CLI_CMD ?? getClaudeCliPath();
|
|
17
16
|
if (envCmd)
|
|
@@ -73,7 +72,7 @@ function buildClaudeDebugArgs(threadId) {
|
|
|
73
72
|
return [];
|
|
74
73
|
}
|
|
75
74
|
}
|
|
76
|
-
export function spawnAgentProcess(claudePath, name, threadId, threadLifecycle, workingDirectory, memorySourceThreadId, threadType, modelOverride) {
|
|
75
|
+
export async function spawnAgentProcess(claudePath, name, threadId, threadLifecycle, workingDirectory, memorySourceThreadId, threadType, modelOverride) {
|
|
77
76
|
if (isStartupCleanupInProgress())
|
|
78
77
|
return { error: "Server startup cleanup in progress - try again in a few seconds" };
|
|
79
78
|
const pre = checkSpawnPreconditions("Claude");
|
|
@@ -170,7 +169,12 @@ export function spawnAgentProcess(claudePath, name, threadId, threadLifecycle, w
|
|
|
170
169
|
break;
|
|
171
170
|
}
|
|
172
171
|
}
|
|
173
|
-
|
|
172
|
+
const claudeModel = modelOverride
|
|
173
|
+
? modelOverride
|
|
174
|
+
: threadType === "worker"
|
|
175
|
+
? process.env.CLAUDE_WORKER_MODEL || getDefaultWorkerModel()
|
|
176
|
+
: process.env.CLAUDE_MODEL || getDefaultThreadModel();
|
|
177
|
+
return launchAgent({
|
|
174
178
|
threadId,
|
|
175
179
|
name,
|
|
176
180
|
logFilePath,
|
|
@@ -178,27 +182,23 @@ export function spawnAgentProcess(claudePath, name, threadId, threadLifecycle, w
|
|
|
178
182
|
agentLabel: "Claude",
|
|
179
183
|
memorySourceThreadId,
|
|
180
184
|
threadType,
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
"--output-format",
|
|
199
|
-
"stream-json",
|
|
200
|
-
], detachedChildOptions(claudePath, outFd, spawnEnv, workingDirectory));
|
|
201
|
-
},
|
|
185
|
+
exe: claudePath,
|
|
186
|
+
args: [
|
|
187
|
+
"--verbose",
|
|
188
|
+
"--dangerously-skip-permissions",
|
|
189
|
+
// DIAGNOSTIC (logging-only): agent-side api+mcp debug to a file (not stdout).
|
|
190
|
+
...buildClaudeDebugArgs(threadId),
|
|
191
|
+
"--mcp-config",
|
|
192
|
+
effectiveConfigPath,
|
|
193
|
+
"--model",
|
|
194
|
+
claudeModel,
|
|
195
|
+
"-p",
|
|
196
|
+
buildSessionPrompt(name, threadId),
|
|
197
|
+
"--output-format",
|
|
198
|
+
"stream-json",
|
|
199
|
+
],
|
|
200
|
+
env: spawnEnv,
|
|
201
|
+
cwd: workingDirectory,
|
|
202
202
|
}, threadLifecycle);
|
|
203
203
|
}
|
|
204
204
|
//# sourceMappingURL=claude-spawn.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-spawn.service.js","sourceRoot":"","sources":["../../src/services/claude-spawn.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"claude-spawn.service.js","sourceRoot":"","sources":["../../src/services/claude-spawn.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
import type { ThreadLifecycleService } from "./thread-lifecycle.service.js";
|
|
6
6
|
import { type SpawnResult } from "./spawn-common.js";
|
|
7
7
|
export declare const resolveCodexPath: () => string | null;
|
|
8
|
-
export declare function spawnCodexProcess(codexPath: string, name: string, threadId: number, threadLifecycle: ThreadLifecycleService, workingDirectory?: string, memorySourceThreadId?: number, threadType?: "worker" | "branch"): SpawnResult
|
|
8
|
+
export declare function spawnCodexProcess(codexPath: string, name: string, threadId: number, threadLifecycle: ThreadLifecycleService, workingDirectory?: string, memorySourceThreadId?: number, threadType?: "worker" | "branch"): Promise<SpawnResult>;
|
|
9
9
|
//# sourceMappingURL=codex-spawn.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-spawn.service.d.ts","sourceRoot":"","sources":["../../src/services/codex-spawn.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,OAAO,
|
|
1
|
+
{"version":3,"file":"codex-spawn.service.d.ts","sourceRoot":"","sources":["../../src/services/codex-spawn.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EAQL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAK3B,eAAO,MAAM,gBAAgB,QAAO,MAAM,GAAG,IAC4C,CAAC;AA6E1F,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,sBAAsB,EACvC,gBAAgB,CAAC,EAAE,MAAM,EACzB,oBAAoB,CAAC,EAAE,MAAM,EAC7B,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAC/B,OAAO,CAAC,WAAW,CAAC,CAqDtB"}
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* Codex-specific spawn logic: CLI/native-exe resolution (including Volta layout
|
|
3
3
|
* discovery on Windows) and the Codex `exec` process launch.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
6
|
import { existsSync, readdirSync } from "node:fs";
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { log } from "../lib/logger.js";
|
|
10
10
|
import { PROCESS_BASE_DIR } from "./process.service.js";
|
|
11
11
|
import { buildCodexMcpArgs } from "./mcp-config.service.js";
|
|
12
|
-
import { sanitizeSpawnEnv, resolveCliPath, resolveWindowsCliPath, normalizeWorkingDirectory, checkSpawnPreconditions, buildThreadLogPath,
|
|
12
|
+
import { sanitizeSpawnEnv, resolveCliPath, resolveWindowsCliPath, normalizeWorkingDirectory, checkSpawnPreconditions, buildThreadLogPath, launchAgent, } from "./spawn-common.js";
|
|
13
13
|
const CODEX_HOME_DIR = join(PROCESS_BASE_DIR, "codex-home");
|
|
14
14
|
const DEFAULT_CODEX_MODEL = "";
|
|
15
15
|
export const resolveCodexPath = () => process.platform === "win32" ? resolveWindowsCliPath("codex") : resolveCliPath("codex");
|
|
@@ -58,7 +58,7 @@ const resolveCodexExe = () => {
|
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
|
-
export function spawnCodexProcess(codexPath, name, threadId, threadLifecycle, workingDirectory, memorySourceThreadId, threadType) {
|
|
61
|
+
export async function spawnCodexProcess(codexPath, name, threadId, threadLifecycle, workingDirectory, memorySourceThreadId, threadType) {
|
|
62
62
|
const pre = checkSpawnPreconditions("Codex");
|
|
63
63
|
if ("error" in pre)
|
|
64
64
|
return pre;
|
|
@@ -85,7 +85,16 @@ export function spawnCodexProcess(codexPath, name, threadId, threadLifecycle, wo
|
|
|
85
85
|
...(pre.transport.secret ? { SENSORIUM_MCP_SECRET: pre.transport.secret } : {}),
|
|
86
86
|
...mcpEnv,
|
|
87
87
|
});
|
|
88
|
-
|
|
88
|
+
// Resolve the actual executable once, shared by the broker and local paths:
|
|
89
|
+
// native codex.exe when present, else node.exe + codex.js (Volta layout), else
|
|
90
|
+
// the .cmd shim as-is.
|
|
91
|
+
const nativeExe = resolveCodexExe();
|
|
92
|
+
const nodeExeResult = !nativeExe && process.platform === "win32" && /\.(cmd|bat)$/i.test(codexPath)
|
|
93
|
+
? resolveCodexNodeExe()
|
|
94
|
+
: null;
|
|
95
|
+
const exe = nativeExe ?? nodeExeResult?.nodeExe ?? codexPath;
|
|
96
|
+
const args = nodeExeResult ? [nodeExeResult.codexJs, ...cliArgs] : cliArgs;
|
|
97
|
+
return launchAgent({
|
|
89
98
|
threadId,
|
|
90
99
|
name,
|
|
91
100
|
logFilePath,
|
|
@@ -93,26 +102,12 @@ export function spawnCodexProcess(codexPath, name, threadId, threadLifecycle, wo
|
|
|
93
102
|
agentLabel: "Codex",
|
|
94
103
|
memorySourceThreadId,
|
|
95
104
|
threadType,
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const child = nativeExe
|
|
103
|
-
? spawn(nativeExe, cliArgs, detachedChildOptions(nativeExe, outFd, spawnEnv, workingDirectory, "pipe"))
|
|
104
|
-
: nodeExeResult
|
|
105
|
-
? spawn(nodeExeResult.nodeExe, [nodeExeResult.codexJs, ...cliArgs], detachedChildOptions(nodeExeResult.nodeExe, outFd, spawnEnv, workingDirectory, "pipe"))
|
|
106
|
-
: spawn(codexPath, cliArgs, detachedChildOptions(codexPath, outFd, spawnEnv, workingDirectory, "pipe"));
|
|
107
|
-
try {
|
|
108
|
-
child.stdin?.write(prompt + "\n");
|
|
109
|
-
child.stdin?.end();
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
/* child died at spawn — the exit handler reports it */
|
|
113
|
-
}
|
|
114
|
-
return child;
|
|
115
|
-
},
|
|
105
|
+
exe,
|
|
106
|
+
args,
|
|
107
|
+
env: spawnEnv,
|
|
108
|
+
cwd: workingDirectory,
|
|
109
|
+
// stdin is a pipe — the autonomous-loop prompt is delivered over it.
|
|
110
|
+
stdinData: prompt + "\n",
|
|
116
111
|
}, threadLifecycle);
|
|
117
112
|
}
|
|
118
113
|
//# sourceMappingURL=codex-spawn.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-spawn.service.js","sourceRoot":"","sources":["../../src/services/codex-spawn.service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"codex-spawn.service.js","sourceRoot":"","sources":["../../src/services/codex-spawn.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
import type { ThreadLifecycleService } from "./thread-lifecycle.service.js";
|
|
7
7
|
import { type SpawnResult } from "./spawn-common.js";
|
|
8
8
|
export declare const resolveCopilotPath: () => string | null;
|
|
9
|
-
export declare function spawnCopilotProcess(copilotPath: string, name: string, threadId: number, threadLifecycle: ThreadLifecycleService, workingDirectory?: string, memorySourceThreadId?: number, threadType?: "worker" | "branch"): SpawnResult
|
|
9
|
+
export declare function spawnCopilotProcess(copilotPath: string, name: string, threadId: number, threadLifecycle: ThreadLifecycleService, workingDirectory?: string, memorySourceThreadId?: number, threadType?: "worker" | "branch"): Promise<SpawnResult>;
|
|
10
10
|
//# sourceMappingURL=copilot-spawn.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot-spawn.service.d.ts","sourceRoot":"","sources":["../../src/services/copilot-spawn.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"copilot-spawn.service.d.ts","sourceRoot":"","sources":["../../src/services/copilot-spawn.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EAUL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAsF3B,eAAO,MAAM,kBAAkB,QAAO,MAAM,GAAG,IAGL,CAAC;AAE3C,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,sBAAsB,EACvC,gBAAgB,CAAC,EAAE,MAAM,EACzB,oBAAoB,CAAC,EAAE,MAAM,EAC7B,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAC/B,OAAO,CAAC,WAAW,CAAC,CAuDtB"}
|