@martinloop/mcp 0.3.5 → 0.3.7

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 (118) hide show
  1. package/README.md +137 -137
  2. package/dist/discovery-metadata.d.ts +1 -1
  3. package/dist/discovery-metadata.js +2 -0
  4. package/dist/prompts.js +19 -1
  5. package/dist/resources.d.ts +3 -0
  6. package/dist/resources.js +125 -17
  7. package/dist/server-validation.d.ts +1 -1
  8. package/dist/server-validation.js +12 -0
  9. package/dist/server.js +18 -7
  10. package/dist/tools/doctor.js +6 -0
  11. package/dist/tools/run-loop.d.ts +2 -1
  12. package/dist/tools/run-loop.js +5 -1
  13. package/dist/tools/tool-support.d.ts +1 -1
  14. package/dist/tools/tool-support.js +2 -1
  15. package/dist/vendor/adapters/adapters/src/claude-cli.d.ts +146 -0
  16. package/dist/vendor/adapters/adapters/src/claude-cli.js +1100 -0
  17. package/dist/vendor/adapters/adapters/src/cli-bridge.d.ts +103 -0
  18. package/dist/vendor/adapters/adapters/src/cli-bridge.js +569 -0
  19. package/dist/vendor/adapters/adapters/src/codex-launcher.d.ts +78 -0
  20. package/dist/vendor/adapters/adapters/src/codex-launcher.js +663 -0
  21. package/dist/vendor/adapters/adapters/src/direct-provider.d.ts +10 -0
  22. package/dist/vendor/adapters/adapters/src/direct-provider.js +40 -0
  23. package/dist/vendor/adapters/adapters/src/index.d.ts +8 -0
  24. package/dist/vendor/adapters/adapters/src/index.js +8 -0
  25. package/dist/vendor/adapters/adapters/src/openai-compatible.d.ts +62 -0
  26. package/dist/vendor/adapters/adapters/src/openai-compatible.js +306 -0
  27. package/dist/vendor/adapters/adapters/src/runtime-support.d.ts +17 -0
  28. package/dist/vendor/adapters/adapters/src/runtime-support.js +59 -0
  29. package/dist/vendor/adapters/adapters/src/stub-agent-cli.d.ts +8 -0
  30. package/dist/vendor/adapters/adapters/src/stub-agent-cli.js +40 -0
  31. package/dist/vendor/adapters/adapters/src/stub-direct-provider.d.ts +8 -0
  32. package/dist/vendor/adapters/adapters/src/stub-direct-provider.js +12 -0
  33. package/dist/vendor/adapters/adapters/src/verifier-only.d.ts +9 -0
  34. package/dist/vendor/adapters/adapters/src/verifier-only.js +63 -0
  35. package/dist/vendor/adapters/claude-cli.js +21 -20
  36. package/dist/vendor/adapters/cli-bridge.d.ts +7 -0
  37. package/dist/vendor/adapters/cli-bridge.js +94 -8
  38. package/dist/vendor/adapters/codex-launcher.js +18 -7
  39. package/dist/vendor/adapters/contracts/src/context-graph.d.ts +48 -0
  40. package/dist/vendor/adapters/contracts/src/context-graph.js +26 -0
  41. package/dist/vendor/adapters/contracts/src/execution-policy.d.ts +78 -0
  42. package/dist/vendor/adapters/contracts/src/execution-policy.js +43 -0
  43. package/dist/vendor/adapters/contracts/src/governance.d.ts +24 -0
  44. package/dist/vendor/adapters/contracts/src/governance.js +11 -0
  45. package/dist/vendor/adapters/contracts/src/identity.d.ts +29 -0
  46. package/dist/vendor/adapters/contracts/src/identity.js +30 -0
  47. package/dist/vendor/adapters/contracts/src/index.d.ts +412 -0
  48. package/dist/vendor/adapters/contracts/src/index.js +225 -0
  49. package/dist/vendor/adapters/contracts/src/operator.d.ts +19 -0
  50. package/dist/vendor/adapters/contracts/src/operator.js +11 -0
  51. package/dist/vendor/adapters/contracts/src/trajectory.d.ts +26 -0
  52. package/dist/vendor/adapters/contracts/src/trajectory.js +27 -0
  53. package/dist/vendor/adapters/core/src/compiler.d.ts +52 -0
  54. package/dist/vendor/adapters/core/src/compiler.js +52 -0
  55. package/dist/vendor/adapters/core/src/context-graph.d.ts +3 -0
  56. package/dist/vendor/adapters/core/src/context-graph.js +371 -0
  57. package/dist/vendor/adapters/core/src/context-integrity.d.ts +26 -0
  58. package/dist/vendor/adapters/core/src/context-integrity.js +80 -0
  59. package/dist/vendor/adapters/core/src/grounding.d.ts +38 -0
  60. package/dist/vendor/adapters/core/src/grounding.js +273 -0
  61. package/dist/vendor/adapters/core/src/identity.d.ts +20 -0
  62. package/dist/vendor/adapters/core/src/identity.js +86 -0
  63. package/dist/vendor/adapters/core/src/index.d.ts +186 -0
  64. package/dist/vendor/adapters/core/src/index.js +1495 -0
  65. package/dist/vendor/adapters/core/src/leash.d.ts +48 -0
  66. package/dist/vendor/adapters/core/src/leash.js +497 -0
  67. package/dist/vendor/adapters/core/src/persistence/compiler.d.ts +18 -0
  68. package/dist/vendor/adapters/core/src/persistence/compiler.js +34 -0
  69. package/dist/vendor/adapters/core/src/persistence/index.d.ts +10 -0
  70. package/dist/vendor/adapters/core/src/persistence/index.js +5 -0
  71. package/dist/vendor/adapters/core/src/persistence/integrity.d.ts +39 -0
  72. package/dist/vendor/adapters/core/src/persistence/integrity.js +252 -0
  73. package/dist/vendor/adapters/core/src/persistence/ledger.d.ts +23 -0
  74. package/dist/vendor/adapters/core/src/persistence/ledger.js +9 -0
  75. package/dist/vendor/adapters/core/src/persistence/memory-store.d.ts +63 -0
  76. package/dist/vendor/adapters/core/src/persistence/memory-store.js +115 -0
  77. package/dist/vendor/adapters/core/src/persistence/runs-reader.d.ts +66 -0
  78. package/dist/vendor/adapters/core/src/persistence/runs-reader.js +140 -0
  79. package/dist/vendor/adapters/core/src/persistence/store.d.ts +89 -0
  80. package/dist/vendor/adapters/core/src/persistence/store.js +125 -0
  81. package/dist/vendor/adapters/core/src/persistence/trace-store.d.ts +85 -0
  82. package/dist/vendor/adapters/core/src/persistence/trace-store.js +125 -0
  83. package/dist/vendor/adapters/core/src/policy-compiler.d.ts +2 -0
  84. package/dist/vendor/adapters/core/src/policy-compiler.js +195 -0
  85. package/dist/vendor/adapters/core/src/policy.d.ts +156 -0
  86. package/dist/vendor/adapters/core/src/policy.js +704 -0
  87. package/dist/vendor/adapters/core/src/repo-analyzer.d.ts +53 -0
  88. package/dist/vendor/adapters/core/src/repo-analyzer.js +263 -0
  89. package/dist/vendor/adapters/core/src/rollback.d.ts +15 -0
  90. package/dist/vendor/adapters/core/src/rollback.js +253 -0
  91. package/dist/vendor/adapters/core/src/routing.d.ts +82 -0
  92. package/dist/vendor/adapters/core/src/routing.js +336 -0
  93. package/dist/vendor/adapters/core/src/test-integrity.d.ts +64 -0
  94. package/dist/vendor/adapters/core/src/test-integrity.js +197 -0
  95. package/dist/vendor/adapters/core/src/trajectory.d.ts +18 -0
  96. package/dist/vendor/adapters/core/src/trajectory.js +295 -0
  97. package/dist/vendor/adapters/openai-compatible.js +84 -51
  98. package/dist/vendor/adapters/verifier-only.js +2 -2
  99. package/dist/vendor/contracts/index.d.ts +2 -2
  100. package/dist/vendor/contracts/index.js +1 -0
  101. package/dist/vendor/core/compiler.js +4 -9
  102. package/dist/vendor/core/index.d.ts +10 -2
  103. package/dist/vendor/core/index.js +32 -91
  104. package/dist/vendor/core/persistence/memory-store.d.ts +63 -0
  105. package/dist/vendor/core/persistence/memory-store.js +115 -0
  106. package/dist/vendor/core/persistence/trace-store.d.ts +85 -0
  107. package/dist/vendor/core/persistence/trace-store.js +125 -0
  108. package/dist/vendor/core/repo-analyzer.d.ts +53 -0
  109. package/dist/vendor/core/repo-analyzer.js +263 -0
  110. package/dist/vendor/core/rollback.js +2 -3
  111. package/dist/vendor/core/routing.d.ts +42 -0
  112. package/dist/vendor/core/routing.js +156 -5
  113. package/dist/vendor/core/test-integrity.d.ts +64 -0
  114. package/dist/vendor/core/test-integrity.js +197 -0
  115. package/dist/workflow-state.d.ts +1 -1
  116. package/dist/workflow-state.js +12 -4
  117. package/package.json +1 -1
  118. package/server.json +2 -2
@@ -1,4 +1,4 @@
1
- type ToolName = "martin_run" | "martin_inspect" | "martin_status" | "martin_doctor" | "martin_plan" | "martin_preflight" | "martin_logs" | "martin_cancel" | "martin_pause" | "martin_continue" | "martin_list_runs" | "martin_triage_runs" | "martin_get_run" | "martin_get_attempt" | "martin_get_verification_results" | "martin_run_dossier" | "martin_dossier" | "martin_eval" | "martin_pr_summary" | "martin_create_pr" | "martin_review_pr";
1
+ type ToolName = "martin_run" | "martin_inspect" | "martin_status" | "martin_doctor" | "martin_estimate" | "martin_plan" | "martin_preflight" | "martin_logs" | "martin_cancel" | "martin_pause" | "martin_continue" | "martin_list_runs" | "martin_triage_runs" | "martin_get_run" | "martin_get_attempt" | "martin_get_verification_results" | "martin_run_dossier" | "martin_dossier" | "martin_eval" | "martin_pr_summary" | "martin_create_pr" | "martin_review_pr";
2
2
  export { sanitizeToolErrorMessage } from "./tools/tool-errors.js";
3
3
  export declare function validateToolInput(name: ToolName, args: unknown): unknown;
4
4
  export declare function resolveSafeRepoRoot(repoRoot?: string, workspaceRoot?: string): string;
@@ -14,6 +14,8 @@ export function validateToolInput(name, args) {
14
14
  return validateStatusInput(args);
15
15
  case "martin_doctor":
16
16
  return validateDoctorInput(args);
17
+ case "martin_estimate":
18
+ return validateEstimateInput(args);
17
19
  case "martin_plan":
18
20
  return validatePlanInput(args);
19
21
  case "martin_preflight":
@@ -252,6 +254,16 @@ function validateDoctorInput(args) {
252
254
  ...optionalEnumAsObject(record.engine, "engine", MARTIN_ENGINE_VALUES)
253
255
  };
254
256
  }
257
+ function validateEstimateInput(args) {
258
+ const record = requireObject(args);
259
+ assertAllowedKeys(record, ["objective", "engine", "budgetUsd", "fileScope"]);
260
+ return {
261
+ objective: requireString(record.objective, "objective"),
262
+ ...optionalEnumAsObject(record.engine, "engine", MARTIN_ENGINE_VALUES),
263
+ ...optionalPositiveNumber(record.budgetUsd, "budgetUsd"),
264
+ ...optionalStringArrayAsObject(record.fileScope, "fileScope")
265
+ };
266
+ }
255
267
  function validatePreflightInput(args) {
256
268
  return validateRunInput(args);
257
269
  }
package/dist/server.js CHANGED
@@ -721,7 +721,7 @@ export function createMartinMcpServer(serverInfo) {
721
721
  tools: [
722
722
  {
723
723
  name: "martin_run",
724
- description: "Execute a governed Martin Loop run on a coding task and return the run summary, spend, artifact rollup, and verification state. This hard-blocks until martin_doctor, martin_plan, and martin_preflight receipts exist for the same task.",
724
+ description: "Execute a governed Martin Loop run on a coding task and return the run summary, spend, artifact rollup, and verification state. This hard-blocks until martin_doctor, martin_estimate, martin_plan, and martin_preflight receipts exist for the same task.",
725
725
  annotations: {
726
726
  destructiveHint: true,
727
727
  idempotentHint: false,
@@ -1518,7 +1518,7 @@ export function createMartinMcpServer(serverInfo) {
1518
1518
  workingDirectory: output.environment.workingDirectory,
1519
1519
  engine: input.engine,
1520
1520
  receiptScope: output.receiptScope
1521
- }).catch(() => { });
1521
+ });
1522
1522
  return createToolSuccessResult(output, output.summary);
1523
1523
  }
1524
1524
  if (name === "martin_plan") {
@@ -1535,7 +1535,7 @@ export function createMartinMcpServer(serverInfo) {
1535
1535
  repoRoot: output.workingDirectory,
1536
1536
  runsRoot: resolveRunsRoot(process.env)
1537
1537
  }
1538
- }).catch(() => { });
1538
+ });
1539
1539
  return createToolSuccessResult(output, `Plan ready for ${output.objective} with ${output.risk.level} risk and ${output.approvalRecommendation.replace(/_/gu, " ")} approval.`);
1540
1540
  }
1541
1541
  if (name === "martin_preflight") {
@@ -1553,7 +1553,7 @@ export function createMartinMcpServer(serverInfo) {
1553
1553
  allowedPaths: output.normalized.allowedPaths,
1554
1554
  deniedPaths: output.normalized.deniedPaths,
1555
1555
  budget: output.normalized.budget
1556
- }).catch(() => { });
1556
+ });
1557
1557
  }
1558
1558
  return createToolSuccessResult(output, output.summary);
1559
1559
  }
@@ -1635,11 +1635,13 @@ export function createMartinMcpServer(serverInfo) {
1635
1635
  return createToolSuccessResult(output, `PR review verdict for ${output.loopId}: ${output.verdict}.`);
1636
1636
  }
1637
1637
  if (name === "martin_estimate") {
1638
- const input = args;
1638
+ const input = validateToolInput("martin_estimate", args);
1639
1639
  const objective = input.objective;
1640
1640
  const engine = input.engine ?? "claude";
1641
1641
  const budgetUsd = input.budgetUsd ?? 5;
1642
1642
  const fileScope = input.fileScope ?? [];
1643
+ const workingDirectory = resolveSafeRepoRoot();
1644
+ const runsRoot = resolveRunsRoot(process.env);
1643
1645
  const route = classifyRoute({
1644
1646
  objective,
1645
1647
  verificationPlan: [],
@@ -1662,9 +1664,18 @@ export function createMartinMcpServer(serverInfo) {
1662
1664
  blockedSteps: route.blockedSteps,
1663
1665
  compressed: route.compressed,
1664
1666
  ...(route.compressionSummary ? { compressionSummary: route.compressionSummary } : {}),
1665
- recommendedBudgetUsd
1667
+ recommendedBudgetUsd,
1668
+ recommendedModelTier: route.recommendedModelTier,
1669
+ estimatedSavingVsSonnetUsd: route.estimatedSavingVsSonnetUsd
1666
1670
  };
1667
- return createToolSuccessResult(output, `Estimate: ${route.selectedMode} route, ~$${route.expectedCostUsd.toFixed(2)} expected cost, ${route.expectedPreworkBurnPct}% pre-work burn. Recommended budget: $${recommendedBudgetUsd.toFixed(2)}.`);
1671
+ await recordMcpWorkflowStep({
1672
+ runsRoot,
1673
+ step: "estimate",
1674
+ workingDirectory,
1675
+ objective,
1676
+ engine
1677
+ });
1678
+ return createToolSuccessResult(output, `Estimate: ${route.selectedMode} route (${route.recommendedModelTier}), ~$${route.expectedCostUsd.toFixed(2)} expected cost, ${route.expectedPreworkBurnPct}% pre-work burn. Recommended budget: $${recommendedBudgetUsd.toFixed(2)}.`);
1668
1679
  }
1669
1680
  return createToolErrorResult(toToolFailure(new Error(`Unknown tool: ${name}`)));
1670
1681
  }
@@ -113,6 +113,12 @@ export async function martinDoctorTool(input) {
113
113
  available: gemini.available,
114
114
  detail: gemini.detail,
115
115
  ...(gemini.resolvedPath ? { resolvedPath: gemini.resolvedPath } : {})
116
+ },
117
+ openai: {
118
+ available: Boolean(process.env.MARTIN_OPENAI_API_KEY),
119
+ detail: process.env.MARTIN_OPENAI_API_KEY
120
+ ? `OpenAI-compatible endpoint configured (model: ${process.env.MARTIN_OPENAI_MODEL ?? "gpt-4.1-mini"})`
121
+ : "Set MARTIN_OPENAI_API_KEY and optionally MARTIN_OPENAI_BASE_URL + MARTIN_OPENAI_MODEL to enable."
116
122
  }
117
123
  },
118
124
  ...(input.engine ? { requestedEngine: input.engine } : {}),
@@ -1,5 +1,5 @@
1
1
  import { type SpawnLike } from "../vendor/adapters/index.js";
2
- import { type RunStore } from "../vendor/core/index.js";
2
+ import { type RunStore, type RunMartinInput, type RunMartinResult } from "../vendor/core/index.js";
3
3
  import type { LoopBudget, ReceiptScope } from "../vendor/contracts/index.js";
4
4
  import { buildArtifactSummary, buildVerificationSummary, buildLoopPreview, type MartinEngine } from "./tool-support.js";
5
5
  export interface RunLoopInput {
@@ -46,4 +46,5 @@ export interface RunLoopOutput {
46
46
  }
47
47
  export declare function __setProofModeVerifierSpawnImplForTests(spawnImpl?: SpawnLike): void;
48
48
  export declare function __setRunStoreOverrideForTests(store?: RunStore): void;
49
+ export declare function __setRunMartinImplForTests(impl?: (input: RunMartinInput) => Promise<RunMartinResult>): void;
49
50
  export declare function runLoopTool(input: RunLoopInput): Promise<RunLoopOutput>;
@@ -6,12 +6,16 @@ import { buildArtifactSummary, buildVerificationSummary, buildLoopPreview, build
6
6
  import { normalizeLoopBudget } from "./workflow-governance.js";
7
7
  let proofModeVerifierSpawnImpl;
8
8
  let runStoreOverrideForTests;
9
+ let runMartinImpl = runMartin;
9
10
  export function __setProofModeVerifierSpawnImplForTests(spawnImpl) {
10
11
  proofModeVerifierSpawnImpl = spawnImpl;
11
12
  }
12
13
  export function __setRunStoreOverrideForTests(store) {
13
14
  runStoreOverrideForTests = store;
14
15
  }
16
+ export function __setRunMartinImplForTests(impl) {
17
+ runMartinImpl = impl ?? runMartin;
18
+ }
15
19
  export async function runLoopTool(input) {
16
20
  const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
17
21
  const engine = input.engine ?? "claude";
@@ -98,7 +102,7 @@ export async function runLoopTool(input) {
98
102
  partialBudget.maxTokens = input.maxTokens;
99
103
  }
100
104
  const budget = normalizeLoopBudget(partialBudget);
101
- const result = await runMartin({
105
+ const result = await runMartinImpl({
102
106
  workspaceId: input.workspaceId ?? "ws_mcp",
103
107
  projectId: input.projectId ?? "proj_mcp",
104
108
  store: runStoreOverrideForTests ?? createFileRunStore({ runsRoot }),
@@ -1,6 +1,6 @@
1
1
  import type { LoopArtifact, LoopBudget, LoopCost, LoopEvent, LoopTask, ReceiptIntegritySummary, ReceiptScope } from "../vendor/contracts/index.js";
2
2
  import { type LedgerEvent, type LoopAttemptRecord, type LoopRunRecord } from "../vendor/core/index.js";
3
- export declare const MARTIN_ENGINE_VALUES: readonly ["claude", "codex", "gemini"];
3
+ export declare const MARTIN_ENGINE_VALUES: readonly ["claude", "codex", "gemini", "openai"];
4
4
  export type MartinEngine = (typeof MARTIN_ENGINE_VALUES)[number];
5
5
  export interface InspectableLoopAttempt extends LoopAttemptRecord {
6
6
  attemptId?: string;
@@ -3,7 +3,7 @@ import { readdir, stat } from "node:fs/promises";
3
3
  import { join } from "node:path";
4
4
  import { evaluateCostGovernor, resolveRunsRoot } from "../vendor/core/index.js";
5
5
  import { readAllLoopRecordsSafely } from "./run-store.js";
6
- export const MARTIN_ENGINE_VALUES = ["claude", "codex", "gemini"];
6
+ export const MARTIN_ENGINE_VALUES = ["claude", "codex", "gemini", "openai"];
7
7
  const CLI_CACHE_TTL_MS = 60_000;
8
8
  const RUN_STORE_CACHE_TTL_MS = 5_000;
9
9
  const cliAvailabilityCache = new Map();
@@ -429,6 +429,7 @@ export function buildSuggestedResourceUris(loopId) {
429
429
  "martin://runs/triage",
430
430
  "martin://runs/latest",
431
431
  "martin://runs/latest/summary",
432
+ "martin://runs/latest/receipt",
432
433
  "martin://runs/latest/proof-card",
433
434
  "martin://runs/latest/budget-status",
434
435
  "martin://runs/latest/verifier-evidence",
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Real agent-CLI adapters.
3
+ *
4
+ * Exports a generic factory (`createAgentCliAdapter`) and two pre-configured
5
+ * factories (`createClaudeCliAdapter`, `createCodexCliAdapter`) that spawn
6
+ * the respective AI coding CLI as a child subprocess.
7
+ *
8
+ * Usage in CLI:
9
+ * createClaudeCliAdapter({ workingDirectory: process.cwd() })
10
+ * createCodexCliAdapter({ workingDirectory: process.cwd() })
11
+ *
12
+ * MCP tools and integration tests use the same factories.
13
+ */
14
+ import type { MartinAdapter, MartinAdapterRequest } from "../../../core/index.js";
15
+ import { type SpawnLike } from "./cli-bridge.js";
16
+ /**
17
+ * Given a prompt string, returns the full argv array to pass to spawn().
18
+ * Example for Claude: () => ["--output-format", "json", "--print"]
19
+ * Example for Codex: () => ["exec", "--sandbox", "workspace-write", "-"]
20
+ */
21
+ export type CliArgsBuilder = (prompt: string, request: MartinAdapterRequest) => string[];
22
+ export type CliStdinBuilder = (prompt: string) => string | undefined;
23
+ export interface AgentCliAdapterOptions {
24
+ /** The executable to spawn (e.g. "claude", "codex"). */
25
+ command: string;
26
+ /** Converts a prompt string into the argv array passed to spawn(). */
27
+ argsBuilder: CliArgsBuilder;
28
+ /** Optional stdin payload for CLIs that accept prompt input via stdin or `-`. */
29
+ stdinBuilder?: CliStdinBuilder;
30
+ /** Adapter ID suffix. Defaults to command. */
31
+ adapterIdSuffix?: string;
32
+ /** Working directory for all subprocesses. Defaults to process.cwd(). */
33
+ workingDirectory?: string;
34
+ /** Timeout for the agent subprocess in ms. Defaults to 300_000 (5 min). */
35
+ timeoutMs?: number;
36
+ /** Timeout per verification command in ms. Defaults to 120_000 (2 min). */
37
+ verifyTimeoutMs?: number;
38
+ /** Human-readable label shown in loop records. */
39
+ label?: string;
40
+ /** Model name surfaced in adapter metadata (also used for cost estimation). */
41
+ model?: string;
42
+ /**
43
+ * Whether the CLI outputs JSON when --output-format json is passed.
44
+ * Set to false for CLIs that don't support this flag (e.g. Codex).
45
+ * Defaults to true for Claude.
46
+ */
47
+ supportsJsonOutput?: boolean;
48
+ /**
49
+ * Set when `argsBuilder` requests `--output-format stream-json` (newline-
50
+ * delimited JSON events) rather than single-blob `json`. Enables (a)
51
+ * incremental result parsing that scans for the final `result` event, and
52
+ * (b) a live cumulative-cost circuit breaker that terminates the subprocess
53
+ * the moment projected spend crosses the remaining per-attempt budget,
54
+ * rather than only learning about an overspend after the process exits.
55
+ */
56
+ streamingUsageCap?: boolean;
57
+ /** Test-only override for subprocess spawning. */
58
+ spawnImpl?: SpawnLike;
59
+ }
60
+ export interface ClaudeCliAdapterOptions {
61
+ workingDirectory?: string;
62
+ timeoutMs?: number;
63
+ verifyTimeoutMs?: number;
64
+ label?: string;
65
+ /** Override the model passed via --model flag. */
66
+ model?: string;
67
+ /** Extra args appended after core args (before prompt). */
68
+ extraArgs?: string[];
69
+ spawnImpl?: SpawnLike;
70
+ }
71
+ export interface CodexCliAdapterOptions {
72
+ /** Override the executable or absolute command path used to launch Codex. */
73
+ command?: string;
74
+ workingDirectory?: string;
75
+ timeoutMs?: number;
76
+ verifyTimeoutMs?: number;
77
+ label?: string;
78
+ /** Override the model passed via --model flag. */
79
+ model?: string;
80
+ /**
81
+ * Deprecated no-op retained for compatibility.
82
+ *
83
+ * Codex CLI's supported non-interactive entrypoint is `codex exec`.
84
+ * MartinLoop now uses explicit sandboxing instead of the legacy
85
+ * `--full-auto` compatibility path, which can exit before verifier execution.
86
+ */
87
+ fullAuto?: boolean;
88
+ /** Codex sandbox mode for model-generated commands. Defaults to workspace-write. */
89
+ sandbox?: "read-only" | "workspace-write" | "danger-full-access";
90
+ /** Extra args appended after core args (before prompt). */
91
+ extraArgs?: string[];
92
+ spawnImpl?: SpawnLike;
93
+ }
94
+ export interface GeminiCliAdapterOptions {
95
+ workingDirectory?: string;
96
+ timeoutMs?: number;
97
+ verifyTimeoutMs?: number;
98
+ label?: string;
99
+ /** Override the model passed via --model flag. Defaults to the Gemini `flash` alias. */
100
+ model?: string;
101
+ /** Approval mode for headless Gemini runs. Defaults to yolo for autonomous execution. */
102
+ approvalMode?: "default" | "auto_edit" | "yolo" | "plan";
103
+ /** Enable Gemini sandbox mode when the host is configured for it. Disabled by default. */
104
+ sandbox?: boolean;
105
+ /** Extra args appended after core args. */
106
+ extraArgs?: string[];
107
+ spawnImpl?: SpawnLike;
108
+ }
109
+ export declare function createAgentCliAdapter(options: AgentCliAdapterOptions): MartinAdapter;
110
+ /**
111
+ * Spawns `claude --output-format stream-json --verbose --print "<prompt>" [extraArgs]`.
112
+ *
113
+ * `stream-json` emits one JSON event per line — including per-turn usage on
114
+ * each `assistant` message and a final `result` event carrying the same
115
+ * `result`/`usage`/`total_cost_usd` fields as single-blob `json` output — so
116
+ * MartinLoop can both (a) recover real token usage/cost as before, and
117
+ * (b) watch cumulative spend live and self-terminate the subprocess the
118
+ * moment it crosses the remaining per-attempt budget (see
119
+ * `streamingUsageCap` / `createStreamingUsageInspector`), instead of only
120
+ * discovering an overspend after the whole process has already exited.
121
+ *
122
+ * Requires the Claude Code CLI to be installed and authenticated:
123
+ * https://docs.anthropic.com/claude-code
124
+ */
125
+ export declare function createClaudeCliAdapter(options?: ClaudeCliAdapterOptions): MartinAdapter;
126
+ /**
127
+ * Spawns `codex exec --cd <workspace> --sandbox <mode> [--model <model>] [extraArgs] -`.
128
+ *
129
+ * The prompt is delivered via stdin so Windows shell quoting cannot truncate or
130
+ * reinterpret long MartinLoop prompts that contain paths, deny rules, or budget
131
+ * context.
132
+ *
133
+ * Requires the Codex CLI to be installed and authenticated:
134
+ * npm install -g @openai/codex
135
+ */
136
+ export declare function createCodexCliAdapter(options?: CodexCliAdapterOptions): MartinAdapter;
137
+ /**
138
+ * Spawns `gemini --model <model> --prompt "" --approval-mode <mode> --output-format json [...]`.
139
+ *
140
+ * The prompt is delivered via stdin while forcing headless mode with `--prompt ""`,
141
+ * which keeps large MartinLoop prompts off the command line on Windows.
142
+ *
143
+ * Requires the Gemini CLI to be installed and authenticated:
144
+ * npm install -g @google/gemini-cli
145
+ */
146
+ export declare function createGeminiCliAdapter(options?: GeminiCliAdapterOptions): MartinAdapter;