@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.
- package/README.md +137 -137
- package/dist/discovery-metadata.d.ts +1 -1
- package/dist/discovery-metadata.js +2 -0
- package/dist/prompts.js +19 -1
- package/dist/resources.d.ts +3 -0
- package/dist/resources.js +125 -17
- package/dist/server-validation.d.ts +1 -1
- package/dist/server-validation.js +12 -0
- package/dist/server.js +18 -7
- package/dist/tools/doctor.js +6 -0
- package/dist/tools/run-loop.d.ts +2 -1
- package/dist/tools/run-loop.js +5 -1
- package/dist/tools/tool-support.d.ts +1 -1
- package/dist/tools/tool-support.js +2 -1
- package/dist/vendor/adapters/adapters/src/claude-cli.d.ts +146 -0
- package/dist/vendor/adapters/adapters/src/claude-cli.js +1100 -0
- package/dist/vendor/adapters/adapters/src/cli-bridge.d.ts +103 -0
- package/dist/vendor/adapters/adapters/src/cli-bridge.js +569 -0
- package/dist/vendor/adapters/adapters/src/codex-launcher.d.ts +78 -0
- package/dist/vendor/adapters/adapters/src/codex-launcher.js +663 -0
- package/dist/vendor/adapters/adapters/src/direct-provider.d.ts +10 -0
- package/dist/vendor/adapters/adapters/src/direct-provider.js +40 -0
- package/dist/vendor/adapters/adapters/src/index.d.ts +8 -0
- package/dist/vendor/adapters/adapters/src/index.js +8 -0
- package/dist/vendor/adapters/adapters/src/openai-compatible.d.ts +62 -0
- package/dist/vendor/adapters/adapters/src/openai-compatible.js +306 -0
- package/dist/vendor/adapters/adapters/src/runtime-support.d.ts +17 -0
- package/dist/vendor/adapters/adapters/src/runtime-support.js +59 -0
- package/dist/vendor/adapters/adapters/src/stub-agent-cli.d.ts +8 -0
- package/dist/vendor/adapters/adapters/src/stub-agent-cli.js +40 -0
- package/dist/vendor/adapters/adapters/src/stub-direct-provider.d.ts +8 -0
- package/dist/vendor/adapters/adapters/src/stub-direct-provider.js +12 -0
- package/dist/vendor/adapters/adapters/src/verifier-only.d.ts +9 -0
- package/dist/vendor/adapters/adapters/src/verifier-only.js +63 -0
- package/dist/vendor/adapters/claude-cli.js +21 -20
- package/dist/vendor/adapters/cli-bridge.d.ts +7 -0
- package/dist/vendor/adapters/cli-bridge.js +94 -8
- package/dist/vendor/adapters/codex-launcher.js +18 -7
- package/dist/vendor/adapters/contracts/src/context-graph.d.ts +48 -0
- package/dist/vendor/adapters/contracts/src/context-graph.js +26 -0
- package/dist/vendor/adapters/contracts/src/execution-policy.d.ts +78 -0
- package/dist/vendor/adapters/contracts/src/execution-policy.js +43 -0
- package/dist/vendor/adapters/contracts/src/governance.d.ts +24 -0
- package/dist/vendor/adapters/contracts/src/governance.js +11 -0
- package/dist/vendor/adapters/contracts/src/identity.d.ts +29 -0
- package/dist/vendor/adapters/contracts/src/identity.js +30 -0
- package/dist/vendor/adapters/contracts/src/index.d.ts +412 -0
- package/dist/vendor/adapters/contracts/src/index.js +225 -0
- package/dist/vendor/adapters/contracts/src/operator.d.ts +19 -0
- package/dist/vendor/adapters/contracts/src/operator.js +11 -0
- package/dist/vendor/adapters/contracts/src/trajectory.d.ts +26 -0
- package/dist/vendor/adapters/contracts/src/trajectory.js +27 -0
- package/dist/vendor/adapters/core/src/compiler.d.ts +52 -0
- package/dist/vendor/adapters/core/src/compiler.js +52 -0
- package/dist/vendor/adapters/core/src/context-graph.d.ts +3 -0
- package/dist/vendor/adapters/core/src/context-graph.js +371 -0
- package/dist/vendor/adapters/core/src/context-integrity.d.ts +26 -0
- package/dist/vendor/adapters/core/src/context-integrity.js +80 -0
- package/dist/vendor/adapters/core/src/grounding.d.ts +38 -0
- package/dist/vendor/adapters/core/src/grounding.js +273 -0
- package/dist/vendor/adapters/core/src/identity.d.ts +20 -0
- package/dist/vendor/adapters/core/src/identity.js +86 -0
- package/dist/vendor/adapters/core/src/index.d.ts +186 -0
- package/dist/vendor/adapters/core/src/index.js +1495 -0
- package/dist/vendor/adapters/core/src/leash.d.ts +48 -0
- package/dist/vendor/adapters/core/src/leash.js +497 -0
- package/dist/vendor/adapters/core/src/persistence/compiler.d.ts +18 -0
- package/dist/vendor/adapters/core/src/persistence/compiler.js +34 -0
- package/dist/vendor/adapters/core/src/persistence/index.d.ts +10 -0
- package/dist/vendor/adapters/core/src/persistence/index.js +5 -0
- package/dist/vendor/adapters/core/src/persistence/integrity.d.ts +39 -0
- package/dist/vendor/adapters/core/src/persistence/integrity.js +252 -0
- package/dist/vendor/adapters/core/src/persistence/ledger.d.ts +23 -0
- package/dist/vendor/adapters/core/src/persistence/ledger.js +9 -0
- package/dist/vendor/adapters/core/src/persistence/memory-store.d.ts +63 -0
- package/dist/vendor/adapters/core/src/persistence/memory-store.js +115 -0
- package/dist/vendor/adapters/core/src/persistence/runs-reader.d.ts +66 -0
- package/dist/vendor/adapters/core/src/persistence/runs-reader.js +140 -0
- package/dist/vendor/adapters/core/src/persistence/store.d.ts +89 -0
- package/dist/vendor/adapters/core/src/persistence/store.js +125 -0
- package/dist/vendor/adapters/core/src/persistence/trace-store.d.ts +85 -0
- package/dist/vendor/adapters/core/src/persistence/trace-store.js +125 -0
- package/dist/vendor/adapters/core/src/policy-compiler.d.ts +2 -0
- package/dist/vendor/adapters/core/src/policy-compiler.js +195 -0
- package/dist/vendor/adapters/core/src/policy.d.ts +156 -0
- package/dist/vendor/adapters/core/src/policy.js +704 -0
- package/dist/vendor/adapters/core/src/repo-analyzer.d.ts +53 -0
- package/dist/vendor/adapters/core/src/repo-analyzer.js +263 -0
- package/dist/vendor/adapters/core/src/rollback.d.ts +15 -0
- package/dist/vendor/adapters/core/src/rollback.js +253 -0
- package/dist/vendor/adapters/core/src/routing.d.ts +82 -0
- package/dist/vendor/adapters/core/src/routing.js +336 -0
- package/dist/vendor/adapters/core/src/test-integrity.d.ts +64 -0
- package/dist/vendor/adapters/core/src/test-integrity.js +197 -0
- package/dist/vendor/adapters/core/src/trajectory.d.ts +18 -0
- package/dist/vendor/adapters/core/src/trajectory.js +295 -0
- package/dist/vendor/adapters/openai-compatible.js +84 -51
- package/dist/vendor/adapters/verifier-only.js +2 -2
- package/dist/vendor/contracts/index.d.ts +2 -2
- package/dist/vendor/contracts/index.js +1 -0
- package/dist/vendor/core/compiler.js +4 -9
- package/dist/vendor/core/index.d.ts +10 -2
- package/dist/vendor/core/index.js +32 -91
- package/dist/vendor/core/persistence/memory-store.d.ts +63 -0
- package/dist/vendor/core/persistence/memory-store.js +115 -0
- package/dist/vendor/core/persistence/trace-store.d.ts +85 -0
- package/dist/vendor/core/persistence/trace-store.js +125 -0
- package/dist/vendor/core/repo-analyzer.d.ts +53 -0
- package/dist/vendor/core/repo-analyzer.js +263 -0
- package/dist/vendor/core/rollback.js +2 -3
- package/dist/vendor/core/routing.d.ts +42 -0
- package/dist/vendor/core/routing.js +156 -5
- package/dist/vendor/core/test-integrity.d.ts +64 -0
- package/dist/vendor/core/test-integrity.js +197 -0
- package/dist/workflow-state.d.ts +1 -1
- package/dist/workflow-state.js +12 -4
- package/package.json +1 -1
- 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
|
-
})
|
|
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
|
-
})
|
|
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
|
-
})
|
|
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
|
-
|
|
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
|
}
|
package/dist/tools/doctor.js
CHANGED
|
@@ -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 } : {}),
|
package/dist/tools/run-loop.d.ts
CHANGED
|
@@ -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>;
|
package/dist/tools/run-loop.js
CHANGED
|
@@ -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
|
|
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;
|