@seawork/server 1.0.21 → 1.0.22-rc.2

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.
Files changed (62) hide show
  1. package/dist/scripts/supervisor-entrypoint.js +22 -0
  2. package/dist/scripts/supervisor-entrypoint.js.map +1 -1
  3. package/dist/scripts/supervisor-native-classifier.js +60 -0
  4. package/dist/scripts/supervisor-native-classifier.js.map +1 -0
  5. package/dist/server/client/daemon-client.d.ts +7 -1
  6. package/dist/server/client/daemon-client.d.ts.map +1 -1
  7. package/dist/server/client/daemon-client.js +13 -0
  8. package/dist/server/client/daemon-client.js.map +1 -1
  9. package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
  10. package/dist/server/server/agent/agent-manager.js +14 -0
  11. package/dist/server/server/agent/agent-manager.js.map +1 -1
  12. package/dist/server/server/agent/install-state.d.ts +248 -0
  13. package/dist/server/server/agent/install-state.d.ts.map +1 -0
  14. package/dist/server/server/agent/install-state.js +126 -0
  15. package/dist/server/server/agent/install-state.js.map +1 -0
  16. package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
  17. package/dist/server/server/agent/providers/claude-agent.js +8 -8
  18. package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
  19. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
  20. package/dist/server/server/agent/providers/codex-app-server-agent.js +96 -29
  21. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
  22. package/dist/server/server/agent/providers/codex-binary-resolver.d.ts +23 -0
  23. package/dist/server/server/agent/providers/codex-binary-resolver.d.ts.map +1 -0
  24. package/dist/server/server/agent/providers/codex-binary-resolver.js +175 -0
  25. package/dist/server/server/agent/providers/codex-binary-resolver.js.map +1 -0
  26. package/dist/server/server/agent/providers/codex-health-probe.d.ts +16 -0
  27. package/dist/server/server/agent/providers/codex-health-probe.d.ts.map +1 -0
  28. package/dist/server/server/agent/providers/codex-health-probe.js +161 -0
  29. package/dist/server/server/agent/providers/codex-health-probe.js.map +1 -0
  30. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +5 -1
  31. package/dist/server/server/agent/providers/diagnostic-utils.d.ts.map +1 -1
  32. package/dist/server/server/agent/providers/diagnostic-utils.js +105 -8
  33. package/dist/server/server/agent/providers/diagnostic-utils.js.map +1 -1
  34. package/dist/server/server/exports.d.ts +4 -1
  35. package/dist/server/server/exports.d.ts.map +1 -1
  36. package/dist/server/server/exports.js +7 -1
  37. package/dist/server/server/exports.js.map +1 -1
  38. package/dist/server/server/file-explorer/service.d.ts +8 -0
  39. package/dist/server/server/file-explorer/service.d.ts.map +1 -1
  40. package/dist/server/server/file-explorer/service.js +43 -0
  41. package/dist/server/server/file-explorer/service.js.map +1 -1
  42. package/dist/server/server/latency-tracker.d.ts +9 -0
  43. package/dist/server/server/latency-tracker.d.ts.map +1 -1
  44. package/dist/server/server/latency-tracker.js +111 -0
  45. package/dist/server/server/latency-tracker.js.map +1 -1
  46. package/dist/server/server/session.d.ts +1 -0
  47. package/dist/server/server/session.d.ts.map +1 -1
  48. package/dist/server/server/session.js +53 -2
  49. package/dist/server/server/session.js.map +1 -1
  50. package/dist/server/shared/messages.d.ts +964 -0
  51. package/dist/server/shared/messages.d.ts.map +1 -1
  52. package/dist/server/shared/messages.js +34 -0
  53. package/dist/server/shared/messages.js.map +1 -1
  54. package/dist/server/utils/electron-helper.d.ts +16 -0
  55. package/dist/server/utils/electron-helper.d.ts.map +1 -1
  56. package/dist/server/utils/electron-helper.js +34 -0
  57. package/dist/server/utils/electron-helper.js.map +1 -1
  58. package/dist/server/utils/executable.d.ts +3 -1
  59. package/dist/server/utils/executable.d.ts.map +1 -1
  60. package/dist/server/utils/executable.js +112 -2
  61. package/dist/server/utils/executable.js.map +1 -1
  62. package/package.json +3 -3
@@ -0,0 +1,23 @@
1
+ import type { Logger } from "pino";
2
+ import { findExecutable } from "../../../utils/executable.js";
3
+ import type { ProviderRuntimeSettings } from "../provider-launch-config.js";
4
+ import { probeCodexBinary } from "./codex-health-probe.js";
5
+ export interface CodexBinarySelection {
6
+ binary: string;
7
+ source: "command-override" | "install-state" | "install-state-stale" | "path";
8
+ installStateRejected?: string;
9
+ }
10
+ export interface SelectCodexOptions {
11
+ logger?: Logger;
12
+ env?: NodeJS.ProcessEnv;
13
+ spawnEnv?: NodeJS.ProcessEnv;
14
+ probe?: typeof probeCodexBinary;
15
+ findExecutable?: typeof findExecutable;
16
+ }
17
+ export declare function selectCodexBinary(options?: SelectCodexOptions): Promise<CodexBinarySelection>;
18
+ export declare function selectEffectiveCodexBinary(runtimeSettings?: ProviderRuntimeSettings, options?: SelectCodexOptions): Promise<CodexBinarySelection>;
19
+ export declare function verifyCommandAvailable(command: string, options?: {
20
+ findExecutable?: typeof findExecutable;
21
+ spawnEnv?: NodeJS.ProcessEnv;
22
+ }): Promise<boolean>;
23
+ //# sourceMappingURL=codex-binary-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-binary-resolver.d.ts","sourceRoot":"","sources":["../../../../../src/server/agent/providers/codex-binary-resolver.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IAOf,MAAM,EAAE,kBAAkB,GAAG,eAAe,GAAG,qBAAqB,GAAG,MAAM,CAAC;IAG9E,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAOxB,QAAQ,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAC7B,KAAK,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAChC,cAAc,CAAC,EAAE,OAAO,cAAc,CAAC;CACxC;AAED,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,oBAAoB,CAAC,CAyF/B;AAUD,wBAAsB,0BAA0B,CAC9C,eAAe,CAAC,EAAE,uBAAuB,EACzC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,oBAAoB,CAAC,CAM/B;AAcD,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,cAAc,CAAC,EAAE,OAAO,cAAc,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,GACL,OAAO,CAAC,OAAO,CAAC,CAQlB"}
@@ -0,0 +1,175 @@
1
+ // Selector for the codex binary used by daemon spawn, desktop install
2
+ // detection, and doctor. Preference order — kept in lockstep with what the
3
+ // daemon actually executes (see resolveProviderCommandPrefix):
4
+ //
5
+ // 1. User override `agents.providers.codex.command` (mode=replace/append)
6
+ // — the highest signal a user can give.
7
+ // 2. Seawork-recorded install path that passes a health probe.
8
+ // 3. `where.exe codex` / `which codex` — whatever PATH says.
9
+ //
10
+ // Why centralized: on some Windows machines the first hit on PATH is a stale
11
+ // npm-global shim or a literal fake test stub. The daemon, the install-status
12
+ // UI, and doctor must all agree on which codex is *the* one Seawork will run,
13
+ // otherwise users with a `command.replace` override see "Binary: not found"
14
+ // in diagnostics even though the daemon launches their custom path fine.
15
+ import { accessSync, constants as fsConstants, realpathSync, statSync } from "node:fs";
16
+ import { findExecutable } from "../../../utils/executable.js";
17
+ import { readAgentInstallEntry, recordAgentInstallHealth } from "../install-state.js";
18
+ import { probeCodexBinary } from "./codex-health-probe.js";
19
+ export async function selectCodexBinary(options = {}) {
20
+ const { logger, env, spawnEnv, probe = probeCodexBinary, findExecutable: find = findExecutable, } = options;
21
+ const recorded = readAgentInstallEntry("codex", env);
22
+ if (recorded?.binary) {
23
+ const probeResult = await probe(recorded.binary, { spawnEnv });
24
+ if (probeResult.ok) {
25
+ try {
26
+ recordAgentInstallHealth("codex", { ok: true }, env);
27
+ }
28
+ catch {
29
+ // Best-effort; resolver must not fail because of a state write.
30
+ }
31
+ logger?.debug({ binary: recorded.binary, source: "install-state" }, "Resolved codex binary from install state");
32
+ return { binary: recorded.binary, source: "install-state" };
33
+ }
34
+ try {
35
+ recordAgentInstallHealth("codex", { ok: false, reason: probeResult.reason }, env);
36
+ }
37
+ catch {
38
+ // ignore
39
+ }
40
+ logger?.warn({ binary: recorded.binary, reason: probeResult.reason }, "Recorded codex install failed health probe; falling back to PATH");
41
+ const found = await find("codex", spawnEnv ? { env: spawnEnv } : undefined);
42
+ if (found) {
43
+ // Health-probe the PATH candidate too. Without this, the same
44
+ // class of "fake / stale shim wins on PATH" the install-state
45
+ // mechanism is meant to fix would silently re-creep in here:
46
+ // PATH lookup itself only validates the file is launchable, not
47
+ // that it is actually codex. If PATH fallback also fails the
48
+ // probe, prefer surfacing the unhealthy recorded path as
49
+ // `install-state-stale` so diagnostics expose the real misconfig
50
+ // rather than silently accepting an unverified PATH binary.
51
+ const pathProbe = await probe(found, { spawnEnv });
52
+ if (pathProbe.ok) {
53
+ return {
54
+ binary: found,
55
+ source: "path",
56
+ installStateRejected: probeResult.reason ?? "unhealthy",
57
+ };
58
+ }
59
+ logger?.warn({ binary: found, reason: pathProbe.reason }, "PATH fallback codex also failed health probe; treating recorded path as stale");
60
+ }
61
+ // PATH has nothing OR PATH candidate also fails probe — surface the
62
+ // unhealthy recorded path so callers see a real spawn error rather
63
+ // than silently accepting another unverified candidate.
64
+ return {
65
+ binary: recorded.binary,
66
+ source: "install-state-stale",
67
+ installStateRejected: probeResult.reason ?? "unhealthy",
68
+ };
69
+ }
70
+ // No install-state recorded — fall back to PATH, but health-probe the
71
+ // candidate so a fake/stale shim sitting on PATH doesn't silently win.
72
+ // If the probe fails, surface the binary anyway with `installStateRejected`
73
+ // set so diagnostics flag the inconsistency; spawn-time error will then
74
+ // tell the user what's actually wrong.
75
+ const found = await find("codex", spawnEnv ? { env: spawnEnv } : undefined);
76
+ if (found) {
77
+ const pathProbe = await probe(found, { spawnEnv });
78
+ if (pathProbe.ok) {
79
+ return { binary: found, source: "path" };
80
+ }
81
+ logger?.warn({ binary: found, reason: pathProbe.reason }, "PATH-resolved codex failed health probe; selecting it anyway so spawn surfaces the real error");
82
+ return {
83
+ binary: found,
84
+ source: "path",
85
+ installStateRejected: pathProbe.reason ?? "path-unhealthy",
86
+ };
87
+ }
88
+ throw new Error("Codex binary not found. Install the Codex CLI (https://github.com/openai/codex) and ensure it is available in your shell PATH.");
89
+ }
90
+ // Resolve the codex binary the daemon would *actually* spawn given the
91
+ // user's runtime settings. Three callers — `getDiagnostic`, desktop
92
+ // `checkAgentInstalls`, and doctor — share this so they never disagree
93
+ // with daemon. When `command.replace` is set, the override path wins
94
+ // unconditionally; with `command.append` or `command.default` we fall
95
+ // through to `selectCodexBinary`. We do NOT health-probe the override —
96
+ // it is an explicit user signal; if the path is broken, the spawn error
97
+ // is what the user wants to see, not a silently demoted fallback.
98
+ export async function selectEffectiveCodexBinary(runtimeSettings, options = {}) {
99
+ const command = runtimeSettings?.command;
100
+ if (command?.mode === "replace" && command.argv[0]) {
101
+ return { binary: command.argv[0], source: "command-override" };
102
+ }
103
+ return selectCodexBinary(options);
104
+ }
105
+ // Verify that a command is plausibly spawnable. Accepts both
106
+ // absolute/relative paths and bare command names like `docker` or `codex`
107
+ // (resolved via PATH lookup, matching what cmd.exe / sh would do at spawn
108
+ // time). For path-style inputs we also require it to be a regular file
109
+ // with execute permission — otherwise directories, plain text files, and
110
+ // broken shims would falsely report "available" while the actual spawn
111
+ // errors out immediately. This is intentionally cheap (no fork/exec); a
112
+ // real version probe is layered on top by getDiagnostic for codex.
113
+ //
114
+ // `spawnEnv` lets callers pass the same env daemon would build at spawn
115
+ // time (e.g. `applyProviderEnv(process.env, runtimeSettings)` for codex)
116
+ // so provider-level `env.PATH` overrides are honored consistently.
117
+ export async function verifyCommandAvailable(command, options = {}) {
118
+ if (!command)
119
+ return false;
120
+ if (command.includes("/") || command.includes("\\")) {
121
+ return isRegularExecutable(command);
122
+ }
123
+ const find = options.findExecutable ?? findExecutable;
124
+ const resolved = await find(command, { env: options.spawnEnv });
125
+ return resolved !== null && isRegularExecutable(resolved);
126
+ }
127
+ function isRegularExecutable(p) {
128
+ try {
129
+ const stat = statSync(p);
130
+ if (!stat.isFile())
131
+ return false;
132
+ }
133
+ catch {
134
+ return false;
135
+ }
136
+ // `.js` entry points are spawnable inside packaged Electron via the
137
+ // ELECTRON_RUN_AS_NODE fallback in electron-helper.applyJsShebangFallback,
138
+ // even without an exec bit. Match that semantics here — but ONLY when
139
+ // we're actually running under Electron. A standalone Node daemon
140
+ // would still need exec permission to launch `codex.js`, so reporting
141
+ // available there would be a fresh availability/spawn mismatch.
142
+ if (process.versions.electron) {
143
+ let resolved = p;
144
+ try {
145
+ resolved = realpathSync(p);
146
+ }
147
+ catch {
148
+ // Broken symlink etc. — fall through; suffix check below uses `p`.
149
+ }
150
+ if (resolved.toLowerCase().endsWith(".js")) {
151
+ return true;
152
+ }
153
+ }
154
+ if (process.platform === "win32") {
155
+ // X_OK is essentially a no-op on NTFS (no exec bit); a `.txt` file
156
+ // would pass it. Approximate "executable" by checking the suffix is
157
+ // in PATHEXT — same heuristic cmd.exe uses to decide whether a path
158
+ // can be invoked. Without this, a path-style override pointing at
159
+ // `C:\tmp\codex.txt` would look available but fail at spawn time.
160
+ const exts = (process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD")
161
+ .split(";")
162
+ .map((e) => e.trim().toLowerCase())
163
+ .filter((e) => e.length > 0);
164
+ const lower = p.toLowerCase();
165
+ return exts.some((e) => lower.endsWith(e));
166
+ }
167
+ try {
168
+ accessSync(p, fsConstants.X_OK);
169
+ return true;
170
+ }
171
+ catch {
172
+ return false;
173
+ }
174
+ }
175
+ //# sourceMappingURL=codex-binary-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-binary-resolver.js","sourceRoot":"","sources":["../../../../../src/server/agent/providers/codex-binary-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface CodexHealthResult {
2
+ ok: boolean;
3
+ reason?: string;
4
+ helpOutput?: string;
5
+ }
6
+ export interface CodexHealthOptions {
7
+ timeoutMs?: number;
8
+ spawnEnv?: NodeJS.ProcessEnv;
9
+ spawn?: (command: string, args: string[]) => Promise<{
10
+ stdout: string;
11
+ stderr: string;
12
+ code: number | null;
13
+ }>;
14
+ }
15
+ export declare function probeCodexBinary(candidatePath: string, options?: CodexHealthOptions): Promise<CodexHealthResult>;
16
+ //# sourceMappingURL=codex-health-probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-health-probe.d.ts","sourceRoot":"","sources":["../../../../../src/server/agent/providers/codex-health-probe.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IASnB,QAAQ,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAM7B,KAAK,CAAC,EAAE,CACN,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,KACX,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACvE;AA2ED,wBAAsB,gBAAgB,CACpC,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CA2E5B"}
@@ -0,0 +1,161 @@
1
+ // Capability probe used to validate a candidate codex binary (e.g. the one
2
+ // recorded in install-state) before we trust it.
3
+ //
4
+ // Why not just `--version`? On the test box we found a `codex.cmd` shim that
5
+ // contained literally `@ECHO off\necho codex-cli 0.129.0` — it passes
6
+ // `--version` perfectly while not being codex at all. Real `codex --help`
7
+ // emits a multi-line "Usage:" block listing subcommands including
8
+ // `app-server`. A single-line echo can't satisfy both substrings without
9
+ // turning into a real CLI by accident.
10
+ //
11
+ // Windows batch wrappers (`.cmd`/`.bat`) cannot be spawned via execFile —
12
+ // the kernel `CreateProcess` path doesn't know how to interpret them. We
13
+ // reuse `spawnProcess`, which already routes Windows calls through
14
+ // `cmd.exe` via `shell: true` and quotes paths with spaces. This is the
15
+ // same path daemon takes when actually launching Codex, so a probe pass
16
+ // is a fair predictor of real spawn behavior.
17
+ import { existsSync, statSync } from "node:fs";
18
+ import path from "node:path";
19
+ import { applyJsShebangFallback } from "../../../utils/electron-helper.js";
20
+ import { spawnProcess } from "../../../utils/spawn.js";
21
+ const DEFAULT_TIMEOUT_MS = 3000;
22
+ const REQUIRED_HELP_SUBSTRINGS = ["Usage:", "app-server"];
23
+ function runSpawn(command, args, timeoutMs, extraEnv) {
24
+ return new Promise((resolve, reject) => {
25
+ const child = spawnProcess(command, args, {
26
+ stdio: ["ignore", "pipe", "pipe"],
27
+ env: extraEnv ? { ...process.env, ...extraEnv } : undefined,
28
+ });
29
+ let stdout = "";
30
+ let stderr = "";
31
+ let timedOut = false;
32
+ const timer = setTimeout(() => {
33
+ timedOut = true;
34
+ try {
35
+ // SIGTERM first; escalate to SIGKILL after a brief grace period so
36
+ // shells/wrappers that ignore SIGTERM (busybox sleep, some `.cmd`
37
+ // trampolines) still die and let `close` fire.
38
+ child.kill("SIGTERM");
39
+ setTimeout(() => {
40
+ try {
41
+ child.kill("SIGKILL");
42
+ }
43
+ catch {
44
+ // ignore — already dead
45
+ }
46
+ }, 200).unref();
47
+ }
48
+ catch {
49
+ // ignore — child may already be dead
50
+ }
51
+ }, timeoutMs);
52
+ child.stdout?.setEncoding("utf8");
53
+ child.stderr?.setEncoding("utf8");
54
+ child.stdout?.on("data", (chunk) => {
55
+ if (stdout.length < 256 * 1024)
56
+ stdout += chunk;
57
+ });
58
+ child.stderr?.on("data", (chunk) => {
59
+ if (stderr.length < 256 * 1024)
60
+ stderr += chunk;
61
+ });
62
+ child.on("error", (err) => {
63
+ clearTimeout(timer);
64
+ reject(err);
65
+ });
66
+ child.on("close", (code, signal) => {
67
+ clearTimeout(timer);
68
+ if (timedOut) {
69
+ const err = new Error("timeout");
70
+ err.code = "ETIMEDOUT";
71
+ reject(err);
72
+ return;
73
+ }
74
+ // Signal-terminated (SIGTERM, SIGKILL, etc.) without our own timeout
75
+ // firing — treat as unhealthy. `close` reports `(null, signal)` for
76
+ // signal kills; resolving normally would let a process that crashed
77
+ // mid-output look fine if it had already printed matching text.
78
+ if (signal) {
79
+ const err = new Error(`terminated by signal ${signal}`);
80
+ err.code = "ESIGNAL";
81
+ err.signal = signal;
82
+ reject(err);
83
+ return;
84
+ }
85
+ resolve({ stdout, stderr, code });
86
+ });
87
+ });
88
+ }
89
+ export async function probeCodexBinary(candidatePath, options = {}) {
90
+ if (!candidatePath)
91
+ return { ok: false, reason: "empty-path" };
92
+ if (!path.isAbsolute(candidatePath)) {
93
+ return { ok: false, reason: "not-absolute" };
94
+ }
95
+ if (!existsSync(candidatePath)) {
96
+ return { ok: false, reason: "missing" };
97
+ }
98
+ try {
99
+ const stat = statSync(candidatePath);
100
+ if (!stat.isFile()) {
101
+ return { ok: false, reason: "not-a-file" };
102
+ }
103
+ }
104
+ catch (err) {
105
+ return { ok: false, reason: `stat-failed: ${err.message}` };
106
+ }
107
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
108
+ // Mirror daemon's `.js` shebang fallback so a bun-installed
109
+ // `~/.bun/bin/codex -> codex.js` probes cleanly even on machines
110
+ // without a system `node` (we route through the bundled Electron
111
+ // runtime + ELECTRON_RUN_AS_NODE=1, same as actual spawn does).
112
+ // Without this, the probe fails with code 127 / ENOENT and the
113
+ // resolver falls back to PATH — re-exposing the very "stale shim
114
+ // wins" problem this PR is meant to fix.
115
+ const { command: spawnCmd, args: spawnArgs, env: shebangEnv, } = applyJsShebangFallback(candidatePath, ["--help"]);
116
+ // Merge: caller-supplied spawnEnv (e.g. buildCodexAppServerEnv) goes
117
+ // BELOW the shebang fallback env so ELECTRON_RUN_AS_NODE wins when
118
+ // both are present. This is what daemon's real spawn does too: the
119
+ // `.js` fallback sets ELECTRON_RUN_AS_NODE last after the provider
120
+ // env merge.
121
+ const callerEnv = options.spawnEnv;
122
+ const mergedEnv = callerEnv || Object.keys(shebangEnv).length > 0
123
+ ? { ...(callerEnv ?? {}), ...shebangEnv }
124
+ : undefined;
125
+ const doSpawn = options.spawn ?? ((c, a) => runSpawn(c, a, timeoutMs, mergedEnv));
126
+ try {
127
+ const { stdout, stderr, code } = await doSpawn(spawnCmd, spawnArgs);
128
+ const combined = `${stdout}\n${stderr}`;
129
+ // Reject non-zero exits — `execFile` did this automatically; our
130
+ // spawnProcess-based path does not. A `.cmd` that errors but still
131
+ // prints "Usage:..." on its way out would otherwise look healthy.
132
+ if (code !== 0 && code !== null) {
133
+ return {
134
+ ok: false,
135
+ reason: `help-exit:${code}`,
136
+ helpOutput: combined.slice(0, 512),
137
+ };
138
+ }
139
+ for (const needle of REQUIRED_HELP_SUBSTRINGS) {
140
+ if (!combined.includes(needle)) {
141
+ return {
142
+ ok: false,
143
+ reason: `help-missing-substring:${needle}`,
144
+ helpOutput: combined.slice(0, 512),
145
+ };
146
+ }
147
+ }
148
+ return { ok: true, helpOutput: combined.slice(0, 512) };
149
+ }
150
+ catch (err) {
151
+ const e = err;
152
+ if (e.code === "ETIMEDOUT") {
153
+ return { ok: false, reason: "help-timeout" };
154
+ }
155
+ if (e.code === "ESIGNAL" && e.signal) {
156
+ return { ok: false, reason: `help-killed:${e.signal}` };
157
+ }
158
+ return { ok: false, reason: `help-spawn-error:${e.code ?? e.message}` };
159
+ }
160
+ }
161
+ //# sourceMappingURL=codex-health-probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-health-probe.js","sourceRoot":"","sources":["../../../../../src/server/agent/providers/codex-health-probe.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,iDAAiD;AACjD,EAAE;AACF,6EAA6E;AAC7E,sEAAsE;AACtE,0EAA0E;AAC1E,kEAAkE;AAClE,yEAAyE;AACzE,uCAAuC;AACvC,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,mEAAmE;AACnE,wEAAwE;AACxE,wEAAwE;AACxE,8CAA8C;AAG9C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAQvD,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,MAAM,wBAAwB,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;AAwB1D,SAAS,QAAQ,CACf,OAAe,EACf,IAAc,EACd,SAAiB,EACjB,QAA4B;IAM5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAiB,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE;YACtD,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS;SAC5D,CAAC,CAAC;QACH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,CAAC;gBACH,mEAAmE;gBACnE,kEAAkE;gBAClE,+CAA+C;gBAC/C,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtB,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC;wBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACxB,CAAC;oBAAC,MAAM,CAAC;wBACP,wBAAwB;oBAC1B,CAAC;gBACH,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,qCAAqC;YACvC,CAAC;QACH,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC;QAClD,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC;QAClD,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YACjC,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,SAAS,CAA0B,CAAC;gBAC1D,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC;gBACvB,MAAM,CAAC,GAAG,CAAC,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,qEAAqE;YACrE,oEAAoE;YACpE,oEAAoE;YACpE,gEAAgE;YAChE,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,wBAAwB,MAAM,EAAE,CAA0B,CAAC;gBACjF,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC;gBACpB,GAAmD,CAAC,MAAM,GAAG,MAAM,CAAC;gBACrE,MAAM,CAAC,GAAG,CAAC,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,aAAqB,EACrB,UAA8B,EAAE;IAEhC,IAAI,CAAC,aAAa;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAC/D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAC/C,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC1C,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACnB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;QAC7C,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAiB,GAAa,CAAC,OAAO,EAAE,EAAE,CAAC;IACzE,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAC;IAC1D,4DAA4D;IAC5D,iEAAiE;IACjE,iEAAiE;IACjE,gEAAgE;IAChE,+DAA+D;IAC/D,iEAAiE;IACjE,yCAAyC;IACzC,MAAM,EACJ,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,UAAU,GAChB,GAAG,sBAAsB,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtD,qEAAqE;IACrE,mEAAmE;IACnE,mEAAmE;IACnE,mEAAmE;IACnE,aAAa;IACb,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;IACnC,MAAM,SAAS,GACb,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC;QAC7C,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,GAAG,UAAU,EAAE;QACzC,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IAElF,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,GAAG,MAAM,KAAK,MAAM,EAAE,CAAC;QACxC,iEAAiE;QACjE,mEAAmE;QACnE,kEAAkE;QAClE,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,aAAa,IAAI,EAAE;gBAC3B,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;aACnC,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,wBAAwB,EAAE,CAAC;YAC9C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/B,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,MAAM,EAAE,0BAA0B,MAAM,EAAE;oBAC1C,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;iBACnC,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IAC1D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,GAAiE,CAAC;QAC5E,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACrC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1D,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;IAC1E,CAAC;AACH,CAAC"}
@@ -1,4 +1,8 @@
1
1
  import type { ProviderRuntimeSettings } from "../provider-launch-config.js";
2
+ export declare function collectStdout(command: string, args: string[], options: {
3
+ timeoutMs: number;
4
+ env?: NodeJS.ProcessEnv;
5
+ }): Promise<string>;
2
6
  type DiagnosticEntry = {
3
7
  label: string;
4
8
  value: string;
@@ -11,7 +15,7 @@ export declare function formatDiagnosticStatus(available: boolean, error?: {
11
15
  cause: unknown;
12
16
  }): string;
13
17
  export declare function toDiagnosticErrorMessage(error: unknown): string;
14
- export declare function resolveBinaryVersion(binaryPath: string): Promise<string>;
18
+ export declare function resolveBinaryVersion(command: string, args?: string[], env?: NodeJS.ProcessEnv): Promise<string>;
15
19
  export declare function formatConfiguredCommand(defaultArgv: readonly string[], runtimeSettings?: ProviderRuntimeSettings): string;
16
20
  export {};
17
21
  //# sourceMappingURL=diagnostic-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostic-utils.d.ts","sourceRoot":"","sources":["../../../../../src/server/agent/providers/diagnostic-utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAI5E,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAEjG;AAED,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAO1F;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAEnE;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,OAAO,EAClB,KAAK,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACzC,MAAM,CAKR;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQ/D;AAED,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW9E;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,eAAe,CAAC,EAAE,uBAAuB,GACxC,MAAM,CAWR"}
1
+ {"version":3,"file":"diagnostic-utils.d.ts","sourceRoot":"","sources":["../../../../../src/server/agent/providers/diagnostic-utils.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAO5E,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,GACtD,OAAO,CAAC,MAAM,CAAC,CA6DjB;AAED,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAEjG;AAED,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAO1F;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAEnE;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,OAAO,EAClB,KAAK,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACzC,MAAM,CAKR;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQ/D;AASD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAkB,EAC9B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GACtB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,eAAe,CAAC,EAAE,uBAAuB,GACxC,MAAM,CAWR"}
@@ -1,6 +1,73 @@
1
- import { execFile } from "node:child_process";
2
- import { promisify } from "node:util";
3
- const execFileAsync = promisify(execFile);
1
+ import { applyJsShebangFallback } from "../../../utils/electron-helper.js";
2
+ import { spawnProcess } from "../../../utils/spawn.js";
3
+ // Collect stdout/stderr from a short-lived child process, routed through
4
+ // the same `spawnProcess` that daemon uses for real provider launches.
5
+ // On Windows this means `.cmd`/`.bat` wrappers (used by some corp shims
6
+ // and a future scoop-style global install) launch correctly — bare
7
+ // `execFile` can't spawn them.
8
+ export async function collectStdout(command, args, options) {
9
+ return new Promise((resolve, reject) => {
10
+ const child = spawnProcess(command, args, {
11
+ stdio: ["ignore", "pipe", "pipe"],
12
+ env: options.env,
13
+ });
14
+ let stdout = "";
15
+ let stderr = "";
16
+ let timedOut = false;
17
+ const timer = setTimeout(() => {
18
+ timedOut = true;
19
+ try {
20
+ child.kill("SIGTERM");
21
+ setTimeout(() => {
22
+ try {
23
+ child.kill("SIGKILL");
24
+ }
25
+ catch {
26
+ // already dead
27
+ }
28
+ }, 200).unref();
29
+ }
30
+ catch {
31
+ // ignore — child may already be dead
32
+ }
33
+ }, options.timeoutMs);
34
+ child.stdout?.setEncoding("utf8");
35
+ child.stderr?.setEncoding("utf8");
36
+ child.stdout?.on("data", (chunk) => {
37
+ if (stdout.length < 256 * 1024)
38
+ stdout += chunk;
39
+ });
40
+ child.stderr?.on("data", (chunk) => {
41
+ if (stderr.length < 256 * 1024)
42
+ stderr += chunk;
43
+ });
44
+ child.on("error", (err) => {
45
+ clearTimeout(timer);
46
+ reject(err);
47
+ });
48
+ child.on("close", (code, signal) => {
49
+ clearTimeout(timer);
50
+ if (timedOut) {
51
+ const err = new Error("timeout");
52
+ err.code = "ETIMEDOUT";
53
+ reject(err);
54
+ return;
55
+ }
56
+ if (signal) {
57
+ // Signal-terminated (without our own timeout firing) — caller
58
+ // should not trust partial stdout.
59
+ reject(new Error(`process terminated by signal ${signal}`));
60
+ return;
61
+ }
62
+ if (code !== 0 && code !== null) {
63
+ const err = new Error(`process exited with code ${code}${stderr ? `: ${stderr.slice(0, 200)}` : ""}`);
64
+ reject(err);
65
+ return;
66
+ }
67
+ resolve(stdout);
68
+ });
69
+ });
70
+ }
4
71
  export function formatProviderDiagnostic(providerName, entries) {
5
72
  return [providerName, ...entries.map((entry) => ` ${entry.label}: ${entry.value}`)].join("\n");
6
73
  }
@@ -30,12 +97,42 @@ export function toDiagnosticErrorMessage(error) {
30
97
  }
31
98
  return "Unknown error";
32
99
  }
33
- export async function resolveBinaryVersion(binaryPath) {
100
+ // Run `<command> [args...]` (default args = ["--version"]) via the same
101
+ // spawnProcess path daemon uses, and return the first line of stdout.
102
+ // Codex passes its full launch prefix here so wrapper overrides like
103
+ // `docker run --rm my-wrapper codex --version` actually probe codex,
104
+ // not docker. The optional `env` argument lets callers pass the same
105
+ // env daemon would spawn with so provider-level `env.PATH` overrides
106
+ // resolve `command` consistently.
107
+ export async function resolveBinaryVersion(command, args = ["--version"], env) {
34
108
  try {
35
- const { stdout } = await execFileAsync(binaryPath, ["--version"], {
36
- encoding: "utf8",
37
- timeout: 5000,
38
- windowsHide: true,
109
+ // Mirror daemon's `.js` shebang fallback bun's `~/.bun/bin/codex`
110
+ // is a symlink to `codex.js`; without system node, daemon rewrites
111
+ // the spawn to `<electron-runtime> codex.js ...` with
112
+ // ELECTRON_RUN_AS_NODE=1. Version probes must do the same or this
113
+ // would report "unknown" / "Error" for a daemon-spawnable codex.
114
+ //
115
+ // When the caller didn't supply an env, leave it `undefined` so
116
+ // `spawnProcess` inherits `process.env`. If we DO need to inject
117
+ // ELECTRON_RUN_AS_NODE for a `.js` rewrite, merge it on top of
118
+ // process.env so the child still sees PATH/HOME etc. Without this,
119
+ // an empty `env: {}` would wipe the environment and break the spawn
120
+ // for reasons unrelated to the binary being probed.
121
+ const rewritten = applyJsShebangFallback(command, args, env);
122
+ const isElectronRewrite = rewritten.env.ELECTRON_RUN_AS_NODE === "1";
123
+ let spawnEnv;
124
+ if (env) {
125
+ spawnEnv = rewritten.env;
126
+ }
127
+ else if (isElectronRewrite) {
128
+ spawnEnv = { ...process.env, ...rewritten.env };
129
+ }
130
+ else {
131
+ spawnEnv = undefined;
132
+ }
133
+ const stdout = await collectStdout(rewritten.command, rewritten.args, {
134
+ timeoutMs: 5000,
135
+ env: spawnEnv,
39
136
  });
40
137
  return stdout.trim() || "unknown";
41
138
  }
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostic-utils.js","sourceRoot":"","sources":["../../../../../src/server/agent/providers/diagnostic-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAO1C,MAAM,UAAU,wBAAwB,CAAC,YAAoB,EAAE,OAA0B;IACvF,OAAO,CAAC,YAAY,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,YAAoB,EAAE,KAAc;IAChF,OAAO,wBAAwB,CAAC,YAAY,EAAE;QAC5C;YACE,KAAK,EAAE,OAAO;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,SAAkB;IACzD,OAAO,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,SAAkB,EAClB,KAA0C;IAE1C,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,UAAU,KAAK,CAAC,MAAM,YAAY,wBAAwB,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;IACpF,CAAC;IACD,OAAO,wBAAwB,CAAC,SAAS,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,UAAkB;IAC3D,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,EAAE;YAChE,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,IAAK;YACd,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,WAA8B,EAC9B,eAAyC;IAEzC,MAAM,OAAO,GAAG,eAAe,EAAE,OAAO,CAAC;IACzC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3C,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC;IAC9C,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtF,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"diagnostic-utils.js","sourceRoot":"","sources":["../../../../../src/server/agent/providers/diagnostic-utils.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ export { loadConfig, type CliConfigOverrides } from "./config.js";
3
3
  export { resolveSeaworkHome } from "./seawork-home.js";
4
4
  export { getOrCreateServerId } from "./server-id.js";
5
5
  export { createRootLogger, type LogLevel, type LogFormat } from "./logger.js";
6
- export { loadPersistedConfig, type PersistedConfig } from "./persisted-config.js";
6
+ export { loadPersistedConfig, tryLoadPersistedConfig, type PersistedConfig, } from "./persisted-config.js";
7
7
  export { generateLocalPairingOffer, type LocalPairingOffer } from "./pairing-offer.js";
8
8
  export { DaemonClient, type DaemonClientConfig, type ConnectionState, type DaemonEvent, } from "../client/daemon-client.js";
9
9
  export { ensureLocalSpeechModels, listLocalSpeechModels, type LocalSpeechModelId, type LocalSttModelId, type LocalTtsModelId, } from "./speech/providers/local/models.js";
@@ -11,6 +11,9 @@ export { applySherpaLoaderEnv, resolveSherpaLoaderEnv, sherpaLoaderEnvKey, sherp
11
11
  export { applyProviderEnv } from "./agent/provider-launch-config.js";
12
12
  export { findExecutable, findExecutableSync, quoteWindowsArgument, quoteWindowsCommand, } from "../utils/executable.js";
13
13
  export { spawnProcess } from "../utils/spawn.js";
14
+ export { readAgentInstallEntry, writeAgentInstallEntry, recordAgentInstallHealth, clearAgentInstallEntry, type AgentInstallEntry, } from "./agent/install-state.js";
15
+ export { probeCodexBinary, type CodexHealthResult, } from "./agent/providers/codex-health-probe.js";
16
+ export { selectCodexBinary, selectEffectiveCodexBinary, verifyCommandAvailable, type CodexBinarySelection, } from "./agent/providers/codex-binary-resolver.js";
14
17
  export { AGENT_PROVIDER_DEFINITIONS, type AgentProviderDefinition, } from "./agent/provider-manifest.js";
15
18
  export type { AgentMode, AgentProvider, AgentUsage, AgentCapabilityFlags, AgentPermissionRequest, AgentTimelineItem, } from "./agent/agent-sdk-types.js";
16
19
  export { curateAgentActivity } from "./agent/activity-curator.js";
@@ -1 +1 @@
1
- {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/server/exports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EACL,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,WAAW,GACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,GAC/B,MAAM,uDAAuD,CAAC;AAG/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EACL,0BAA0B,EAC1B,KAAK,uBAAuB,GAC7B,MAAM,8BAA8B,CAAC;AAGtC,YAAY,EACV,SAAS,EACT,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,EAC5B,4BAA4B,EAC5B,uCAAuC,EACvC,2CAA2C,EAC3C,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,gCAAgC,EACrC,KAAK,4CAA4C,EACjD,KAAK,8BAA8B,GACpC,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EACV,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAMvE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/server/exports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EACL,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,WAAW,GACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,GAC/B,MAAM,uDAAuD,CAAC;AAG/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKjD,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,iBAAiB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,gBAAgB,EAChB,KAAK,iBAAiB,GACvB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,sBAAsB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,4CAA4C,CAAC;AAGpD,OAAO,EACL,0BAA0B,EAC1B,KAAK,uBAAuB,GAC7B,MAAM,8BAA8B,CAAC;AAGtC,YAAY,EACV,SAAS,EACT,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,EAC5B,4BAA4B,EAC5B,uCAAuC,EACvC,2CAA2C,EAC3C,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,gCAAgC,EACrC,KAAK,4CAA4C,EACjD,KAAK,8BAA8B,GACpC,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EACV,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,+BAA+B,GAChC,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAMvE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC"}
@@ -4,7 +4,7 @@ export { loadConfig } from "./config.js";
4
4
  export { resolveSeaworkHome } from "./seawork-home.js";
5
5
  export { getOrCreateServerId } from "./server-id.js";
6
6
  export { createRootLogger } from "./logger.js";
7
- export { loadPersistedConfig } from "./persisted-config.js";
7
+ export { loadPersistedConfig, tryLoadPersistedConfig, } from "./persisted-config.js";
8
8
  export { generateLocalPairingOffer } from "./pairing-offer.js";
9
9
  export { DaemonClient, } from "../client/daemon-client.js";
10
10
  export { ensureLocalSpeechModels, listLocalSpeechModels, } from "./speech/providers/local/models.js";
@@ -13,6 +13,12 @@ export { applySherpaLoaderEnv, resolveSherpaLoaderEnv, sherpaLoaderEnvKey, sherp
13
13
  export { applyProviderEnv } from "./agent/provider-launch-config.js";
14
14
  export { findExecutable, findExecutableSync, quoteWindowsArgument, quoteWindowsCommand, } from "../utils/executable.js";
15
15
  export { spawnProcess } from "../utils/spawn.js";
16
+ // Agent install state — machine-local cache of "Seawork installed agent X
17
+ // at path Y", used to prefer that copy over whatever `where.exe` returns
18
+ // first. See packages/server/src/server/agent/install-state.ts for context.
19
+ export { readAgentInstallEntry, writeAgentInstallEntry, recordAgentInstallHealth, clearAgentInstallEntry, } from "./agent/install-state.js";
20
+ export { probeCodexBinary, } from "./agent/providers/codex-health-probe.js";
21
+ export { selectCodexBinary, selectEffectiveCodexBinary, verifyCommandAvailable, } from "./agent/providers/codex-binary-resolver.js";
16
22
  // Provider manifest (source of truth for provider definitions)
17
23
  export { AGENT_PROVIDER_DEFINITIONS, } from "./agent/provider-manifest.js";
18
24
  // Agent activity curator for CLI logs