@martinloop/mcp 0.2.7 → 0.3.1

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 (64) hide show
  1. package/README.md +49 -104
  2. package/dist/package-version.d.ts +1 -1
  3. package/dist/package-version.js +1 -1
  4. package/dist/prompts.d.ts +1 -1
  5. package/dist/resources.d.ts +1 -1
  6. package/dist/resources.js +2 -2
  7. package/dist/server-validation.d.ts +1 -0
  8. package/dist/server-validation.js +8 -0
  9. package/dist/server.js +87 -9
  10. package/dist/tools/doctor.d.ts +39 -1
  11. package/dist/tools/doctor.js +68 -9
  12. package/dist/tools/eval.js +3 -2
  13. package/dist/tools/get-run.d.ts +3 -0
  14. package/dist/tools/get-run.js +3 -1
  15. package/dist/tools/get-verification-results.d.ts +3 -0
  16. package/dist/tools/get-verification-results.js +3 -1
  17. package/dist/tools/plan.js +4 -2
  18. package/dist/tools/pr-tools.js +2 -1
  19. package/dist/tools/preflight.d.ts +41 -1
  20. package/dist/tools/preflight.js +74 -19
  21. package/dist/tools/run-dossier.d.ts +3 -0
  22. package/dist/tools/run-dossier.js +5 -2
  23. package/dist/tools/run-loop.d.ts +7 -2
  24. package/dist/tools/run-loop.js +67 -35
  25. package/dist/tools/run-store.js +67 -15
  26. package/dist/tools/tool-errors.js +1 -1
  27. package/dist/tools/tool-support.d.ts +8 -3
  28. package/dist/tools/tool-support.js +61 -18
  29. package/dist/tools/workflow-governance.d.ts +19 -3
  30. package/dist/tools/workflow-governance.js +107 -55
  31. package/dist/vendor/adapters/claude-cli.d.ts +45 -3
  32. package/dist/vendor/adapters/claude-cli.js +465 -45
  33. package/dist/vendor/adapters/cli-bridge.d.ts +46 -0
  34. package/dist/vendor/adapters/cli-bridge.js +147 -38
  35. package/dist/vendor/adapters/codex-launcher.d.ts +76 -0
  36. package/dist/vendor/adapters/codex-launcher.js +538 -0
  37. package/dist/vendor/adapters/index.d.ts +3 -2
  38. package/dist/vendor/adapters/index.js +3 -2
  39. package/dist/vendor/adapters/openai-compatible.d.ts +19 -4
  40. package/dist/vendor/adapters/openai-compatible.js +50 -19
  41. package/dist/vendor/adapters/runtime-support.d.ts +3 -0
  42. package/dist/vendor/adapters/runtime-support.js +9 -1
  43. package/dist/vendor/adapters/stub-direct-provider.js +3 -0
  44. package/dist/vendor/adapters/verifier-only.d.ts +2 -0
  45. package/dist/vendor/adapters/verifier-only.js +11 -4
  46. package/dist/vendor/contracts/index.d.ts +39 -0
  47. package/dist/vendor/contracts/index.js +2 -0
  48. package/dist/vendor/core/context-integrity.js +28 -3
  49. package/dist/vendor/core/grounding.d.ts +1 -0
  50. package/dist/vendor/core/grounding.js +6 -2
  51. package/dist/vendor/core/index.d.ts +24 -3
  52. package/dist/vendor/core/index.js +113 -21
  53. package/dist/vendor/core/leash.js +85 -8
  54. package/dist/vendor/core/persistence/index.d.ts +2 -0
  55. package/dist/vendor/core/persistence/index.js +1 -0
  56. package/dist/vendor/core/persistence/integrity.d.ts +38 -0
  57. package/dist/vendor/core/persistence/integrity.js +248 -0
  58. package/dist/vendor/core/persistence/store.d.ts +7 -0
  59. package/dist/vendor/core/persistence/store.js +25 -1
  60. package/dist/vendor/core/policy.d.ts +9 -0
  61. package/dist/workflow-state.d.ts +9 -0
  62. package/dist/workflow-state.js +46 -3
  63. package/package.json +2 -2
  64. package/server.json +2 -2
@@ -6,16 +6,60 @@ export interface SubprocessResult {
6
6
  stdout: string;
7
7
  stderr: string;
8
8
  timedOut: boolean;
9
+ /**
10
+ * True when the subprocess was terminated early because its combined
11
+ * stdout+stderr exceeded `maxOutputBytes` — a circuit breaker against
12
+ * runaway agent sessions that would otherwise burn far more cost/tokens
13
+ * than the loop budget allows before MartinLoop can observe the final
14
+ * (post-hoc) usage report. See `claude-cli.ts` execute() for how this
15
+ * cap is derived from the remaining loop budget.
16
+ */
17
+ outputCapped: boolean;
18
+ /**
19
+ * Set to the inspector's reason string when an `onStdoutChunk` callback
20
+ * requested early termination (e.g. a streaming usage/cost circuit breaker
21
+ * that detected the agent is on track to blow through its budget). Distinct
22
+ * from `outputCapped`, which fires on raw byte volume rather than parsed
23
+ * semantic content.
24
+ */
25
+ terminationReason?: string;
26
+ launched: boolean;
9
27
  }
10
28
  export interface VerificationOutcome {
11
29
  passed: boolean;
12
30
  summary: string;
31
+ steps: VerificationStepOutcome[];
32
+ warnings?: string[];
33
+ }
34
+ export interface VerificationStepOutcome {
35
+ command: string;
36
+ launched: boolean;
37
+ exitCode?: number;
38
+ timedOut: boolean;
39
+ fastFail: boolean;
40
+ detail?: string;
13
41
  }
14
42
  export declare function runSubprocess(command: string, args: string[], options: {
15
43
  cwd: string;
16
44
  timeoutMs: number;
17
45
  spawnImpl?: SpawnLike;
18
46
  stdinData?: string;
47
+ /**
48
+ * Optional circuit breaker: terminate the subprocess once combined
49
+ * stdout+stderr bytes exceed this threshold, instead of waiting for
50
+ * natural completion. Used to bound runaway agent-CLI cost/token spend
51
+ * that can't otherwise be observed until the process exits.
52
+ */
53
+ maxOutputBytes?: number;
54
+ /**
55
+ * Optional semantic inspector invoked with each raw stdout chunk. Used to
56
+ * parse streaming structured output (e.g. Claude's `stream-json` usage
57
+ * events) and request early termination via the supplied `terminate`
58
+ * callback once a semantic threshold (such as cumulative cost) is
59
+ * crossed — well before the subprocess would exit naturally and report
60
+ * a runaway final usage figure.
61
+ */
62
+ onStdoutChunk?: (chunk: Buffer, terminate: (reason: string) => void) => void;
19
63
  }): Promise<SubprocessResult>;
20
64
  export declare function runVerification(commands: string[], cwd: string, timeoutMs: number, verificationStack?: Array<{
21
65
  command: string;
@@ -26,6 +70,8 @@ export declare function readGitExecutionArtifacts(repoRoot: string, timeoutMs: n
26
70
  changedFiles?: string[];
27
71
  diffStats?: ReturnType<typeof diffStatsFromNumstat>;
28
72
  }>;
73
+ export declare function readGitChangedFiles(repoRoot: string, timeoutMs: number, spawnImpl?: SpawnLike): Promise<string[]>;
74
+ export declare function resolveGitRepositoryRoot(workingDirectory: string): string | undefined;
29
75
  export interface SpawnPlan {
30
76
  command: string;
31
77
  args: string[];
@@ -1,11 +1,15 @@
1
1
  import { spawn } from "node:child_process";
2
- import { delimiter, extname, isAbsolute, join, resolve } from "node:path";
2
+ import { delimiter, dirname, extname, isAbsolute, join, resolve } from "node:path";
3
3
  import { existsSync } from "node:fs";
4
4
  import { diffStatsFromNumstat } from "./runtime-support.js";
5
+ const gitRepositoryRootCache = new Map();
5
6
  export async function runSubprocess(command, args, options) {
6
7
  return new Promise((resolve) => {
7
8
  let timedOut = false;
9
+ let outputCapped = false;
10
+ let terminationReason;
8
11
  let settled = false;
12
+ let outputBytes = 0;
9
13
  const stdoutChunks = [];
10
14
  const stderrChunks = [];
11
15
  const stdinMode = options.stdinData !== undefined ? "pipe" : "ignore";
@@ -14,7 +18,7 @@ export async function runSubprocess(command, args, options) {
14
18
  return;
15
19
  }
16
20
  settled = true;
17
- resolve(result);
21
+ resolve({ ...result, timedOut, outputCapped, ...(terminationReason ? { terminationReason } : {}) });
18
22
  };
19
23
  let proc;
20
24
  try {
@@ -27,19 +31,33 @@ export async function runSubprocess(command, args, options) {
27
31
  }
28
32
  catch (error) {
29
33
  const message = error instanceof Error ? error.message : String(error);
30
- resolveOnce({
31
- exitCode: 1,
32
- stdout: "",
33
- stderr: message,
34
- timedOut: false
35
- });
34
+ resolveOnce({ exitCode: 1, stdout: "", stderr: message, launched: false });
36
35
  return;
37
36
  }
37
+ const trackOutput = (chunks, chunk) => {
38
+ chunks.push(chunk);
39
+ outputBytes += chunk.byteLength;
40
+ if (options.maxOutputBytes !== undefined &&
41
+ !outputCapped &&
42
+ !timedOut &&
43
+ outputBytes > options.maxOutputBytes) {
44
+ outputCapped = true;
45
+ proc.kill("SIGTERM");
46
+ }
47
+ };
48
+ const terminateEarly = (reason) => {
49
+ if (terminationReason || timedOut || outputCapped) {
50
+ return;
51
+ }
52
+ terminationReason = reason;
53
+ proc.kill("SIGTERM");
54
+ };
38
55
  proc.stdout?.on("data", (chunk) => {
39
- stdoutChunks.push(chunk);
56
+ trackOutput(stdoutChunks, chunk);
57
+ options.onStdoutChunk?.(chunk, terminateEarly);
40
58
  });
41
59
  proc.stderr?.on("data", (chunk) => {
42
- stderrChunks.push(chunk);
60
+ trackOutput(stderrChunks, chunk);
43
61
  });
44
62
  proc.stdin?.on("error", (error) => {
45
63
  // Some CLIs exit before consuming stdin in tests and on fast-fail paths.
@@ -55,12 +73,7 @@ export async function runSubprocess(command, args, options) {
55
73
  }, options.timeoutMs);
56
74
  proc.on("error", (error) => {
57
75
  clearTimeout(timer);
58
- resolveOnce({
59
- exitCode: 1,
60
- stdout: "",
61
- stderr: error.message,
62
- timedOut: false
63
- });
76
+ resolveOnce({ exitCode: 1, stdout: "", stderr: error.message, launched: false });
64
77
  });
65
78
  proc.on("close", (code) => {
66
79
  clearTimeout(timer);
@@ -68,7 +81,7 @@ export async function runSubprocess(command, args, options) {
68
81
  exitCode: code ?? 1,
69
82
  stdout: Buffer.concat(stdoutChunks).toString("utf8"),
70
83
  stderr: Buffer.concat(stderrChunks).toString("utf8"),
71
- timedOut
84
+ launched: true
72
85
  });
73
86
  });
74
87
  if (options.stdinData !== undefined && proc.stdin) {
@@ -83,7 +96,7 @@ export async function runSubprocess(command, args, options) {
83
96
  exitCode: 1,
84
97
  stdout: Buffer.concat(stdoutChunks).toString("utf8"),
85
98
  stderr: stdinError.message,
86
- timedOut: false
99
+ launched: false
87
100
  });
88
101
  }
89
102
  }
@@ -98,9 +111,11 @@ export async function runVerification(commands, cwd, timeoutMs, verificationStac
98
111
  }))
99
112
  : commands.map((command) => ({ command, fastFail: true }));
100
113
  if (steps.length === 0) {
101
- return { passed: true, summary: "No verification commands specified." };
114
+ return { passed: true, summary: "No verification commands specified.", steps: [] };
102
115
  }
103
116
  const failedSteps = [];
117
+ const stepOutcomes = [];
118
+ const warnings = [];
104
119
  for (const step of steps) {
105
120
  const parts = splitCommand(step.command);
106
121
  const [bin, ...args] = parts;
@@ -108,24 +123,53 @@ export async function runVerification(commands, cwd, timeoutMs, verificationStac
108
123
  continue;
109
124
  }
110
125
  const result = await runSubprocess(bin, args, { cwd, timeoutMs, spawnImpl });
126
+ const detail = truncate(result.stderr.trim() || result.stdout.trim(), 500);
127
+ stepOutcomes.push({
128
+ command: step.command,
129
+ launched: result.launched,
130
+ exitCode: result.exitCode,
131
+ timedOut: result.timedOut,
132
+ fastFail: step.fastFail,
133
+ ...(detail ? { detail } : {})
134
+ });
111
135
  if (result.timedOut) {
112
- return { passed: false, summary: `Verification timed out: ${step.command}` };
136
+ return {
137
+ passed: false,
138
+ summary: `Verification timed out: ${step.command}`,
139
+ steps: stepOutcomes,
140
+ ...(warnings.length ? { warnings } : {})
141
+ };
113
142
  }
114
143
  if (result.exitCode !== 0) {
115
- const detail = truncate(result.stderr.trim() || result.stdout.trim(), 500);
116
144
  const summary = `Verification failed: ${step.command}\n${detail}`;
145
+ if (!result.launched) {
146
+ warnings.push(`Verifier never launched: ${step.command}`);
147
+ }
117
148
  if (step.fastFail) {
118
- return { passed: false, summary };
149
+ return { passed: false, summary, steps: stepOutcomes, ...(warnings.length ? { warnings } : {}) };
119
150
  }
120
151
  failedSteps.push(step.command);
121
152
  }
122
153
  }
123
154
  if (failedSteps.length > 0) {
124
- return { passed: false, summary: `Failed steps: ${failedSteps.join(", ")}` };
155
+ return {
156
+ passed: false,
157
+ summary: `Failed steps: ${failedSteps.join(", ")}`,
158
+ steps: stepOutcomes,
159
+ ...(warnings.length ? { warnings } : {})
160
+ };
125
161
  }
126
- return { passed: true, summary: `All ${String(steps.length)} verification step(s) passed.` };
162
+ return {
163
+ passed: true,
164
+ summary: `All ${String(steps.length)} verification step(s) passed.`,
165
+ steps: stepOutcomes,
166
+ ...(warnings.length ? { warnings } : {})
167
+ };
127
168
  }
128
169
  export async function readGitExecutionArtifacts(repoRoot, timeoutMs, spawnImpl) {
170
+ if (!resolveGitRepositoryRoot(repoRoot)) {
171
+ return {};
172
+ }
129
173
  const changedFilesResult = await runSubprocess("git", ["diff", "--name-only", "HEAD"], { cwd: repoRoot, timeoutMs, spawnImpl });
130
174
  const numstatResult = await runSubprocess("git", ["diff", "--numstat", "HEAD"], { cwd: repoRoot, timeoutMs, spawnImpl });
131
175
  const changedFiles = changedFilesResult.exitCode === 0
@@ -140,6 +184,49 @@ export async function readGitExecutionArtifacts(repoRoot, timeoutMs, spawnImpl)
140
184
  ...(diffStats ? { diffStats } : {})
141
185
  };
142
186
  }
187
+ export async function readGitChangedFiles(repoRoot, timeoutMs, spawnImpl) {
188
+ if (!resolveGitRepositoryRoot(repoRoot)) {
189
+ return [];
190
+ }
191
+ const statusResult = await runSubprocess("git", ["status", "-z", "--porcelain=v1", "--untracked-files=all", "--ignore-submodules=all", "--", "."], { cwd: repoRoot, timeoutMs, spawnImpl });
192
+ if (statusResult.exitCode !== 0) {
193
+ return [];
194
+ }
195
+ return parsePorcelainEntries(statusResult.stdout).filter((entry) => typeof entry === "string" && entry.length > 0);
196
+ }
197
+ export function resolveGitRepositoryRoot(workingDirectory) {
198
+ const resolvedWorkingDirectory = resolve(workingDirectory);
199
+ const cached = gitRepositoryRootCache.get(resolvedWorkingDirectory);
200
+ if (cached !== undefined) {
201
+ return cached ?? undefined;
202
+ }
203
+ const visited = [];
204
+ let current = resolvedWorkingDirectory;
205
+ while (true) {
206
+ visited.push(current);
207
+ const currentCached = gitRepositoryRootCache.get(current);
208
+ if (currentCached !== undefined) {
209
+ for (const candidate of visited) {
210
+ gitRepositoryRootCache.set(candidate, currentCached);
211
+ }
212
+ return currentCached ?? undefined;
213
+ }
214
+ if (existsSync(resolve(current, ".git"))) {
215
+ for (const candidate of visited) {
216
+ gitRepositoryRootCache.set(candidate, current);
217
+ }
218
+ return current;
219
+ }
220
+ const parent = dirname(current);
221
+ if (parent === current) {
222
+ for (const candidate of visited) {
223
+ gitRepositoryRootCache.set(candidate, null);
224
+ }
225
+ return undefined;
226
+ }
227
+ current = parent;
228
+ }
229
+ }
143
230
  export function createSpawnPlan(command, args, cwd, preserveRawForInjectedSpawn) {
144
231
  if (preserveRawForInjectedSpawn || process.platform !== "win32") {
145
232
  return { command, args };
@@ -150,17 +237,22 @@ export function createSpawnPlan(command, args, cwd, preserveRawForInjectedSpawn)
150
237
  // Windows can resolve the command itself — this covers cases like `pnpm` where the npm global
151
238
  // bin directory is present in the shell PATH but not yet visible to this Node.js process.
152
239
  if (resolvedOrUndefined === undefined) {
153
- const cmdStr = [quoteWindowsCmdArg(command), ...args.map(quoteWindowsCmdArg)].join(" ");
154
240
  return {
155
241
  command: process.env.ComSpec || "cmd.exe",
156
- args: ["/d", "/s", "/c", cmdStr]
242
+ args: ["/d", "/c", command, ...args]
157
243
  };
158
244
  }
159
245
  const extension = extname(resolvedOrUndefined).toLowerCase();
160
246
  if (extension === ".cmd" || extension === ".bat") {
161
247
  return {
162
248
  command: process.env.ComSpec || "cmd.exe",
163
- args: ["/d", "/s", "/c", [quoteWindowsCmdArg(resolvedOrUndefined), ...args.map(quoteWindowsCmdArg)].join(" ")]
249
+ args: ["/d", "/c", resolvedOrUndefined, ...args]
250
+ };
251
+ }
252
+ if (extension === ".ps1") {
253
+ return {
254
+ command: "powershell.exe",
255
+ args: ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", resolvedOrUndefined, ...args]
164
256
  };
165
257
  }
166
258
  return { command: resolvedOrUndefined, args };
@@ -186,11 +278,38 @@ function expandWindowsCommandCandidates(command) {
186
278
  return [command];
187
279
  }
188
280
  const pathExt = process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD";
189
- return pathExt
281
+ const fromPathExt = pathExt
190
282
  .split(";")
191
283
  .map((extension) => extension.trim())
192
284
  .filter(Boolean)
193
285
  .map((extension) => `${command}${extension.toLowerCase()}`);
286
+ const candidates = [...fromPathExt, `${command}.ps1`];
287
+ return Array.from(new Set(candidates));
288
+ }
289
+ function parsePorcelainEntries(stdout) {
290
+ const entries = stdout.split("\u0000").filter((entry) => entry.length > 0);
291
+ const changedFiles = [];
292
+ for (let index = 0; index < entries.length; index += 1) {
293
+ const entry = entries[index];
294
+ if (entry === undefined || entry.length < 4) {
295
+ continue;
296
+ }
297
+ const status = entry.slice(0, 2);
298
+ const payload = entry.slice(3);
299
+ if (!payload) {
300
+ continue;
301
+ }
302
+ if (status.includes("R") || status.includes("C")) {
303
+ const renamedPath = entries[index + 1];
304
+ if (renamedPath && renamedPath.length > 0) {
305
+ changedFiles.push(renamedPath);
306
+ index += 1;
307
+ continue;
308
+ }
309
+ }
310
+ changedFiles.push(payload);
311
+ }
312
+ return changedFiles;
194
313
  }
195
314
  function windowsPathDirectories() {
196
315
  const rawPath = process.env.Path ?? process.env.PATH ?? "";
@@ -199,16 +318,6 @@ function windowsPathDirectories() {
199
318
  .map((entry) => entry.trim().replace(/^"|"$/g, ""))
200
319
  .filter(Boolean);
201
320
  }
202
- function quoteWindowsCmdArg(value) {
203
- const normalized = value.replace(/\r?\n/gu, " ");
204
- const escaped = normalized
205
- .replace(/\^/gu, "^^")
206
- .replace(/"/gu, '^"')
207
- .replace(/%/gu, "%%")
208
- .replace(/!/gu, "^^!")
209
- .replace(/[&|<>()]/gu, (match) => `^${match}`);
210
- return `"${escaped}"`;
211
- }
212
321
  export function splitCommand(command) {
213
322
  const tokens = [];
214
323
  let current = "";
@@ -0,0 +1,76 @@
1
+ import { spawnSync } from "node:child_process";
2
+ export interface CliCommandAvailability {
3
+ command: string;
4
+ available: boolean;
5
+ locator: string;
6
+ detail: string;
7
+ resolvedPath?: string;
8
+ candidatePaths?: string[];
9
+ }
10
+ export type CodexHostPlatform = "windows" | "linux" | "wsl" | "macos";
11
+ export type CodexInstallKind = "missing" | "native" | "windows_shim" | "windows_mounted_path";
12
+ export type CodexInvocationMode = "direct" | "cmd_shell" | "powershell";
13
+ export interface CodexHostDiagnosis {
14
+ hostPlatform: CodexHostPlatform;
15
+ nativeInstallValid: boolean;
16
+ installKind: CodexInstallKind;
17
+ invocationMode: CodexInvocationMode;
18
+ sandboxMode: "workspace-write";
19
+ sandboxCompatible: boolean;
20
+ resolvedPath?: string;
21
+ nativeDependencyStatus?: "unknown" | "missing";
22
+ nativeDependencyPackage?: string;
23
+ warnings: string[];
24
+ remediation?: string;
25
+ }
26
+ export interface CodexLaunchProbeResult {
27
+ ok: boolean;
28
+ summary: string;
29
+ availability: CliCommandAvailability;
30
+ diagnosis: CodexHostDiagnosis;
31
+ command: string;
32
+ args: string[];
33
+ exitCode?: number;
34
+ stdout?: string;
35
+ stderr?: string;
36
+ candidateProbeResults?: CodexProbeCandidateResult[];
37
+ }
38
+ export interface CodexExecArgsOptions {
39
+ workingDirectory: string;
40
+ sandbox?: "read-only" | "workspace-write" | "danger-full-access";
41
+ model?: string;
42
+ extraArgs?: string[];
43
+ mode?: "prompt" | "probe";
44
+ }
45
+ type SpawnSyncLike = typeof spawnSync;
46
+ export interface CodexProbeCandidateResult {
47
+ path: string;
48
+ installKind: CodexInstallKind;
49
+ invocationMode: CodexInvocationMode;
50
+ nativeInstallValid: boolean;
51
+ sandboxCompatible: boolean;
52
+ launchReady: boolean;
53
+ summary: string;
54
+ remediation?: string;
55
+ nativeDependencyStatus?: "unknown" | "missing";
56
+ nativeDependencyPackage?: string;
57
+ }
58
+ export declare function buildCodexExecArgs(options: CodexExecArgsOptions): string[];
59
+ export declare function resolveCliCommandAvailability(command: string, options?: {
60
+ platform?: NodeJS.Platform;
61
+ env?: NodeJS.ProcessEnv;
62
+ spawnSyncImpl?: SpawnSyncLike;
63
+ }): CliCommandAvailability;
64
+ export declare function detectCodexHostPlatform(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): CodexHostPlatform;
65
+ export declare function diagnoseCodexHost(availability: CliCommandAvailability, options?: {
66
+ env?: NodeJS.ProcessEnv;
67
+ platform?: NodeJS.Platform;
68
+ }): CodexHostDiagnosis;
69
+ export declare function probeCodexLaunch(input: {
70
+ workingDirectory: string;
71
+ availability?: CliCommandAvailability;
72
+ env?: NodeJS.ProcessEnv;
73
+ platform?: NodeJS.Platform;
74
+ spawnSyncImpl?: SpawnSyncLike;
75
+ }): CodexLaunchProbeResult;
76
+ export {};