@martinloop/mcp 0.3.0 → 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.
- package/README.md +4 -4
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/server.js +69 -7
- package/dist/tools/doctor.d.ts +27 -0
- package/dist/tools/doctor.js +39 -11
- package/dist/tools/get-run.d.ts +2 -1
- package/dist/tools/get-run.js +1 -0
- package/dist/tools/get-verification-results.d.ts +2 -1
- package/dist/tools/get-verification-results.js +1 -0
- package/dist/tools/plan.js +4 -2
- package/dist/tools/preflight.d.ts +27 -0
- package/dist/tools/preflight.js +44 -20
- package/dist/tools/run-dossier.d.ts +2 -1
- package/dist/tools/run-dossier.js +1 -0
- package/dist/tools/run-loop.d.ts +5 -1
- package/dist/tools/run-loop.js +20 -8
- package/dist/tools/run-store.js +67 -15
- package/dist/tools/tool-support.d.ts +2 -0
- package/dist/tools/tool-support.js +49 -13
- package/dist/tools/workflow-governance.d.ts +19 -3
- package/dist/tools/workflow-governance.js +107 -55
- package/dist/vendor/adapters/claude-cli.d.ts +20 -3
- package/dist/vendor/adapters/claude-cli.js +193 -33
- package/dist/vendor/adapters/cli-bridge.d.ts +45 -0
- package/dist/vendor/adapters/cli-bridge.js +107 -39
- package/dist/vendor/adapters/codex-launcher.d.ts +32 -0
- package/dist/vendor/adapters/codex-launcher.js +409 -118
- package/dist/vendor/adapters/openai-compatible.js +8 -2
- package/dist/vendor/adapters/runtime-support.js +1 -0
- package/dist/vendor/adapters/stub-direct-provider.js +3 -0
- package/dist/vendor/adapters/verifier-only.d.ts +2 -0
- package/dist/vendor/adapters/verifier-only.js +9 -3
- package/dist/vendor/core/context-integrity.js +28 -3
- package/dist/vendor/core/grounding.d.ts +1 -0
- package/dist/vendor/core/grounding.js +6 -2
- package/dist/vendor/core/index.d.ts +1 -0
- package/dist/vendor/core/index.js +25 -6
- package/dist/vendor/core/leash.js +85 -8
- package/dist/vendor/core/persistence/integrity.d.ts +1 -1
- package/dist/vendor/core/persistence/integrity.js +15 -6
- package/dist/workflow-state.d.ts +9 -0
- package/dist/workflow-state.js +46 -3
- package/package.json +2 -2
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Governed MCP server for AI coding agents over local stdio.
|
|
4
4
|
|
|
5
|
-
`@martinloop/mcp@0.
|
|
5
|
+
`@martinloop/mcp@0.3.0` is the live public baseline today. `0.3.1` is the current in-repo release candidate for the next public cut.
|
|
6
6
|
|
|
7
7
|
This package stays local-first and stdio-first in the public OSS lane.
|
|
8
8
|
|
|
9
9
|
## Public release train
|
|
10
10
|
|
|
11
11
|
- `0.2.7` made the guided MCP workflow easier to adopt and harder to misuse.
|
|
12
|
-
- `0.3.0` is the
|
|
13
|
-
- `0.3.1` is
|
|
14
|
-
- `0.3.2`
|
|
12
|
+
- `0.3.0` is the live adoption baseline that made host setup and onboarding clearer.
|
|
13
|
+
- `0.3.1` is the review and handoff release candidate currently staged in-repo.
|
|
14
|
+
- `0.3.2` remains the planned follow-on for opt-in execution controls.
|
|
15
15
|
|
|
16
16
|
## What ships today
|
|
17
17
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MARTIN_MCP_PACKAGE_VERSION = "0.3.
|
|
1
|
+
export declare const MARTIN_MCP_PACKAGE_VERSION = "0.3.1";
|
package/dist/package-version.js
CHANGED
package/dist/server.js
CHANGED
|
@@ -44,8 +44,9 @@ import { martinTriageRunsTool } from "./tools/triage-runs.js";
|
|
|
44
44
|
import { runLoopTool } from "./tools/run-loop.js";
|
|
45
45
|
import { createToolErrorResult, createToolSuccessResult } from "./tools/tool-response.js";
|
|
46
46
|
import { MartinToolError, toToolFailure } from "./tools/tool-errors.js";
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
47
|
+
import { normalizeLoopBudget } from "./tools/workflow-governance.js";
|
|
48
|
+
import { resolveSafeRepoRoot, sanitizeToolErrorMessage, validateToolInput } from "./server-validation.js";
|
|
49
|
+
import { evaluateMcpRunGate, recordMcpWorkflowStep } from "./workflow-state.js";
|
|
49
50
|
const stringArraySchema = {
|
|
50
51
|
type: "array",
|
|
51
52
|
items: { type: "string" }
|
|
@@ -142,6 +143,17 @@ const verificationSchema = {
|
|
|
142
143
|
},
|
|
143
144
|
required: ["status", "eventCount", "ledgerEventCount", "warnings"]
|
|
144
145
|
};
|
|
146
|
+
const receiptScopeSchema = {
|
|
147
|
+
type: "object",
|
|
148
|
+
additionalProperties: false,
|
|
149
|
+
properties: {
|
|
150
|
+
invocationRoot: { type: "string" },
|
|
151
|
+
workingDirectory: { type: "string" },
|
|
152
|
+
repoRoot: { type: "string" },
|
|
153
|
+
runsRoot: { type: "string" }
|
|
154
|
+
},
|
|
155
|
+
required: ["invocationRoot", "workingDirectory", "repoRoot", "runsRoot"]
|
|
156
|
+
};
|
|
145
157
|
const artifactSummarySchema = {
|
|
146
158
|
type: "object",
|
|
147
159
|
additionalProperties: true,
|
|
@@ -391,6 +403,7 @@ const doctorOutputSchema = {
|
|
|
391
403
|
},
|
|
392
404
|
required: ["workspaceRoot", "workingDirectory", "runsRoot", "mode", "liveMode"]
|
|
393
405
|
},
|
|
406
|
+
receiptScope: receiptScopeSchema,
|
|
394
407
|
engines: {
|
|
395
408
|
type: "object",
|
|
396
409
|
additionalProperties: true
|
|
@@ -408,7 +421,7 @@ const doctorOutputSchema = {
|
|
|
408
421
|
},
|
|
409
422
|
warnings: stringArraySchema
|
|
410
423
|
},
|
|
411
|
-
required: ["status", "summary", "server", "environment", "engines", "runStore", "warnings"]
|
|
424
|
+
required: ["status", "summary", "server", "environment", "receiptScope", "engines", "runStore", "warnings"]
|
|
412
425
|
};
|
|
413
426
|
const preflightOutputSchema = {
|
|
414
427
|
type: "object",
|
|
@@ -417,6 +430,7 @@ const preflightOutputSchema = {
|
|
|
417
430
|
ok: { type: "boolean" },
|
|
418
431
|
summary: { type: "string" },
|
|
419
432
|
warnings: stringArraySchema,
|
|
433
|
+
receiptScope: receiptScopeSchema,
|
|
420
434
|
readiness: {
|
|
421
435
|
type: "object",
|
|
422
436
|
additionalProperties: false,
|
|
@@ -492,7 +506,7 @@ const preflightOutputSchema = {
|
|
|
492
506
|
required: ["requestedEngine", "engineAvailability", "runsRoot", "pathScope", "expectedRunLayout"]
|
|
493
507
|
}
|
|
494
508
|
},
|
|
495
|
-
required: ["ok", "summary", "warnings", "readiness", "normalized", "execution"]
|
|
509
|
+
required: ["ok", "summary", "warnings", "receiptScope", "readiness", "normalized", "execution"]
|
|
496
510
|
};
|
|
497
511
|
const listRunsOutputSchema = {
|
|
498
512
|
type: "object",
|
|
@@ -1397,6 +1411,36 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1397
1411
|
try {
|
|
1398
1412
|
if (name === "martin_run") {
|
|
1399
1413
|
const input = validateToolInput("martin_run", args);
|
|
1414
|
+
const runsRoot = resolveRunsRoot(process.env);
|
|
1415
|
+
const workingDirectory = input.workingDirectory ?? resolveSafeRepoRoot();
|
|
1416
|
+
const receiptScope = {
|
|
1417
|
+
invocationRoot: resolveSafeRepoRoot(),
|
|
1418
|
+
workingDirectory,
|
|
1419
|
+
repoRoot: workingDirectory,
|
|
1420
|
+
runsRoot
|
|
1421
|
+
};
|
|
1422
|
+
const gate = await evaluateMcpRunGate({
|
|
1423
|
+
runsRoot,
|
|
1424
|
+
workingDirectory,
|
|
1425
|
+
objective: input.objective,
|
|
1426
|
+
engine: input.engine,
|
|
1427
|
+
verificationPlan: input.verificationPlan,
|
|
1428
|
+
receiptScope,
|
|
1429
|
+
allowedPaths: input.allowedPaths,
|
|
1430
|
+
deniedPaths: input.deniedPaths,
|
|
1431
|
+
budget: normalizeRunBudget(input)
|
|
1432
|
+
});
|
|
1433
|
+
if (!gate.allowed) {
|
|
1434
|
+
throw new MartinToolError("policy_blocked", gate.summary, {
|
|
1435
|
+
category: "policy_blocked",
|
|
1436
|
+
suggestion: gate.nextAction,
|
|
1437
|
+
retryable: false,
|
|
1438
|
+
details: {
|
|
1439
|
+
missingSteps: gate.missingSteps,
|
|
1440
|
+
receiptScope
|
|
1441
|
+
}
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1400
1444
|
const output = await runLoopTool(input);
|
|
1401
1445
|
return createToolSuccessResult(output, `Run ${output.loopId} is ${output.status}/${output.lifecycleState} after ${output.attempts} attempt(s); spend ${output.costUsd.toFixed(2)} USD.`);
|
|
1402
1446
|
}
|
|
@@ -1417,7 +1461,8 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1417
1461
|
runsRoot: output.environment.runsRoot,
|
|
1418
1462
|
step: "doctor",
|
|
1419
1463
|
workingDirectory: output.environment.workingDirectory,
|
|
1420
|
-
engine: input.engine
|
|
1464
|
+
engine: input.engine,
|
|
1465
|
+
receiptScope: output.receiptScope
|
|
1421
1466
|
}).catch(() => { });
|
|
1422
1467
|
return createToolSuccessResult(output, output.summary);
|
|
1423
1468
|
}
|
|
@@ -1428,7 +1473,13 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1428
1473
|
runsRoot: resolveRunsRoot(process.env),
|
|
1429
1474
|
step: "plan",
|
|
1430
1475
|
workingDirectory: output.workingDirectory,
|
|
1431
|
-
objective: output.objective
|
|
1476
|
+
objective: output.objective,
|
|
1477
|
+
receiptScope: {
|
|
1478
|
+
invocationRoot: resolveSafeRepoRoot(),
|
|
1479
|
+
workingDirectory: output.workingDirectory,
|
|
1480
|
+
repoRoot: output.workingDirectory,
|
|
1481
|
+
runsRoot: resolveRunsRoot(process.env)
|
|
1482
|
+
}
|
|
1432
1483
|
}).catch(() => { });
|
|
1433
1484
|
return createToolSuccessResult(output, `Plan ready for ${output.objective} with ${output.risk.level} risk and ${output.approvalRecommendation.replace(/_/gu, " ")} approval.`);
|
|
1434
1485
|
}
|
|
@@ -1442,7 +1493,11 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1442
1493
|
workingDirectory: output.normalized.workingDirectory,
|
|
1443
1494
|
objective: output.normalized.objective,
|
|
1444
1495
|
engine: output.normalized.engine,
|
|
1445
|
-
verificationPlan: output.normalized.verificationPlan
|
|
1496
|
+
verificationPlan: output.normalized.verificationPlan,
|
|
1497
|
+
receiptScope: output.receiptScope,
|
|
1498
|
+
allowedPaths: output.normalized.allowedPaths,
|
|
1499
|
+
deniedPaths: output.normalized.deniedPaths,
|
|
1500
|
+
budget: output.normalized.budget
|
|
1446
1501
|
}).catch(() => { });
|
|
1447
1502
|
}
|
|
1448
1503
|
return createToolSuccessResult(output, output.summary);
|
|
@@ -1532,6 +1587,13 @@ export function createMartinMcpServer(serverInfo) {
|
|
|
1532
1587
|
});
|
|
1533
1588
|
return server;
|
|
1534
1589
|
}
|
|
1590
|
+
function normalizeRunBudget(input) {
|
|
1591
|
+
return normalizeLoopBudget({
|
|
1592
|
+
maxUsd: input.maxUsd,
|
|
1593
|
+
maxIterations: input.maxIterations,
|
|
1594
|
+
maxTokens: input.maxTokens
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1535
1597
|
export async function connectMartinMcpStdioServer() {
|
|
1536
1598
|
const server = createMartinMcpServer();
|
|
1537
1599
|
const transport = new StdioServerTransport();
|
package/dist/tools/doctor.d.ts
CHANGED
|
@@ -27,14 +27,41 @@ export interface MartinDoctorOutput {
|
|
|
27
27
|
repoRoot: string;
|
|
28
28
|
runsRoot: string;
|
|
29
29
|
};
|
|
30
|
+
receiptScope: {
|
|
31
|
+
invocationRoot: string;
|
|
32
|
+
workingDirectory: string;
|
|
33
|
+
repoRoot: string;
|
|
34
|
+
runsRoot: string;
|
|
35
|
+
};
|
|
30
36
|
engines: Record<MartinEngine, {
|
|
31
37
|
available: boolean;
|
|
32
38
|
detail: string;
|
|
33
39
|
resolvedPath?: string;
|
|
40
|
+
candidatePaths?: string[];
|
|
41
|
+
selectedPath?: string;
|
|
34
42
|
hostPlatform?: CodexHostPlatform;
|
|
43
|
+
installKind?: string;
|
|
35
44
|
nativeInstallValid?: boolean;
|
|
45
|
+
invocationMode?: string;
|
|
46
|
+
sandboxMode?: string;
|
|
47
|
+
sandboxCompatible?: boolean;
|
|
48
|
+
nativeDependencyStatus?: string;
|
|
49
|
+
nativeDependencyPackage?: string;
|
|
36
50
|
launchReady?: boolean;
|
|
37
51
|
probeSummary?: string;
|
|
52
|
+
remediation?: string;
|
|
53
|
+
candidateProbeResults?: Array<{
|
|
54
|
+
path: string;
|
|
55
|
+
installKind: string;
|
|
56
|
+
invocationMode: string;
|
|
57
|
+
nativeInstallValid: boolean;
|
|
58
|
+
sandboxCompatible: boolean;
|
|
59
|
+
launchReady: boolean;
|
|
60
|
+
summary: string;
|
|
61
|
+
remediation?: string;
|
|
62
|
+
nativeDependencyStatus?: string;
|
|
63
|
+
nativeDependencyPackage?: string;
|
|
64
|
+
}>;
|
|
38
65
|
}>;
|
|
39
66
|
requestedEngine?: MartinEngine;
|
|
40
67
|
runStore: {
|
package/dist/tools/doctor.js
CHANGED
|
@@ -1,26 +1,40 @@
|
|
|
1
1
|
import { probeCodexLaunch, resolveCliCommandAvailability } from "../vendor/adapters/index.js";
|
|
2
2
|
import { resolveRunsRoot } from "../vendor/core/index.js";
|
|
3
3
|
import { resolveSafeRepoRoot, resolveSafeRunsRootPath } from "../server-validation.js";
|
|
4
|
-
import { getEngineAvailability, inspectRunsRoot, resolveExecutionMode } from "./tool-support.js";
|
|
4
|
+
import { createSkippedCliAvailability, getEngineAvailability, inspectRunsRoot, resolveExecutionMode } from "./tool-support.js";
|
|
5
5
|
import { buildReadinessReport, inspectRepoSignals } from "./workflow-governance.js";
|
|
6
6
|
export async function martinDoctorTool(input) {
|
|
7
7
|
const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
|
|
8
8
|
const runsRoot = resolveSafeRunsRootPath(input.runsDir, resolveRunsRoot(process.env));
|
|
9
9
|
const workspaceRoot = resolveSafeRepoRoot();
|
|
10
10
|
const executionMode = resolveExecutionMode();
|
|
11
|
-
const claude =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
11
|
+
const claude = executionMode.liveMode
|
|
12
|
+
? getEngineAvailability("claude")
|
|
13
|
+
: createSkippedCliAvailability("claude");
|
|
14
|
+
const codex = executionMode.liveMode
|
|
15
|
+
? resolveCliCommandAvailability("codex")
|
|
16
|
+
: createSkippedCliAvailability("codex");
|
|
17
|
+
const gemini = executionMode.liveMode
|
|
18
|
+
? getEngineAvailability("gemini")
|
|
19
|
+
: createSkippedCliAvailability("gemini");
|
|
20
|
+
const codexProbe = executionMode.liveMode && input.engine === "codex" && codex.available
|
|
15
21
|
? probeCodexLaunch({
|
|
16
22
|
workingDirectory,
|
|
17
23
|
availability: codex
|
|
18
24
|
})
|
|
19
25
|
: undefined;
|
|
20
26
|
const runStore = await inspectRunsRoot(runsRoot);
|
|
21
|
-
const signals = inspectRepoSignals(workingDirectory
|
|
27
|
+
const signals = inspectRepoSignals(workingDirectory, {
|
|
28
|
+
includeHostAvailability: executionMode.liveMode
|
|
29
|
+
});
|
|
22
30
|
const readiness = buildReadinessReport(signals, runStore);
|
|
23
31
|
const warnings = [];
|
|
32
|
+
const receiptScope = {
|
|
33
|
+
invocationRoot: workspaceRoot,
|
|
34
|
+
workingDirectory,
|
|
35
|
+
repoRoot: workingDirectory,
|
|
36
|
+
runsRoot
|
|
37
|
+
};
|
|
24
38
|
if (!runStore.exists) {
|
|
25
39
|
warnings.push("Configured Martin runs root does not exist yet.");
|
|
26
40
|
}
|
|
@@ -57,11 +71,9 @@ export async function martinDoctorTool(input) {
|
|
|
57
71
|
liveMode: executionMode.liveMode
|
|
58
72
|
},
|
|
59
73
|
scope: {
|
|
60
|
-
|
|
61
|
-
workingDirectory,
|
|
62
|
-
repoRoot: workingDirectory,
|
|
63
|
-
runsRoot
|
|
74
|
+
...receiptScope
|
|
64
75
|
},
|
|
76
|
+
receiptScope,
|
|
65
77
|
engines: {
|
|
66
78
|
claude: {
|
|
67
79
|
available: claude.available,
|
|
@@ -72,12 +84,28 @@ export async function martinDoctorTool(input) {
|
|
|
72
84
|
available: codex.available,
|
|
73
85
|
detail: codex.detail,
|
|
74
86
|
...(codex.resolvedPath ? { resolvedPath: codex.resolvedPath } : {}),
|
|
87
|
+
...(codex.candidatePaths?.length ? { candidatePaths: codex.candidatePaths } : {}),
|
|
75
88
|
...(codexProbe
|
|
76
89
|
? {
|
|
90
|
+
selectedPath: codexProbe.command,
|
|
77
91
|
hostPlatform: codexProbe.diagnosis.hostPlatform,
|
|
92
|
+
installKind: codexProbe.diagnosis.installKind,
|
|
78
93
|
nativeInstallValid: codexProbe.diagnosis.nativeInstallValid,
|
|
94
|
+
invocationMode: codexProbe.diagnosis.invocationMode,
|
|
95
|
+
sandboxMode: codexProbe.diagnosis.sandboxMode,
|
|
96
|
+
sandboxCompatible: codexProbe.diagnosis.sandboxCompatible,
|
|
97
|
+
...(codexProbe.diagnosis.nativeDependencyStatus
|
|
98
|
+
? { nativeDependencyStatus: codexProbe.diagnosis.nativeDependencyStatus }
|
|
99
|
+
: {}),
|
|
100
|
+
...(codexProbe.diagnosis.nativeDependencyPackage
|
|
101
|
+
? { nativeDependencyPackage: codexProbe.diagnosis.nativeDependencyPackage }
|
|
102
|
+
: {}),
|
|
79
103
|
launchReady: codexProbe.ok,
|
|
80
|
-
probeSummary: codexProbe.summary
|
|
104
|
+
probeSummary: codexProbe.summary,
|
|
105
|
+
...(codexProbe.diagnosis.remediation ? { remediation: codexProbe.diagnosis.remediation } : {}),
|
|
106
|
+
...(codexProbe.candidateProbeResults?.length
|
|
107
|
+
? { candidateProbeResults: codexProbe.candidateProbeResults }
|
|
108
|
+
: {})
|
|
81
109
|
}
|
|
82
110
|
: {})
|
|
83
111
|
},
|
package/dist/tools/get-run.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
2
|
-
import type { ReceiptIntegritySummary } from "../vendor/contracts/index.js";
|
|
2
|
+
import type { ReceiptIntegritySummary, ReceiptScope } from "../vendor/contracts/index.js";
|
|
3
3
|
export interface MartinGetRunInput {
|
|
4
4
|
file?: string;
|
|
5
5
|
loopId?: string;
|
|
@@ -14,6 +14,7 @@ export interface MartinGetRunOutput {
|
|
|
14
14
|
cost: ReturnType<typeof buildCostSnapshot>;
|
|
15
15
|
verification: ReturnType<typeof buildVerificationSummary>;
|
|
16
16
|
receiptIntegrity: ReceiptIntegritySummary;
|
|
17
|
+
receiptScope?: ReceiptScope;
|
|
17
18
|
artifacts: ReturnType<typeof buildArtifactSummary>;
|
|
18
19
|
inspection: {
|
|
19
20
|
runsRoot: string;
|
package/dist/tools/get-run.js
CHANGED
|
@@ -12,6 +12,7 @@ export async function martinGetRunTool(input) {
|
|
|
12
12
|
cost: buildCostSnapshot(detail.loop.cost),
|
|
13
13
|
verification,
|
|
14
14
|
receiptIntegrity: resolveReceiptIntegrity(detail.loop),
|
|
15
|
+
...(detail.loop.receiptScope ? { receiptScope: detail.loop.receiptScope } : {}),
|
|
15
16
|
artifacts: buildArtifactSummary(detail.loop),
|
|
16
17
|
inspection: {
|
|
17
18
|
runsRoot: detail.runsRoot,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
2
|
-
import type { ReceiptIntegritySummary } from "../vendor/contracts/index.js";
|
|
2
|
+
import type { ReceiptIntegritySummary, ReceiptScope } from "../vendor/contracts/index.js";
|
|
3
3
|
export interface MartinGetVerificationResultsInput {
|
|
4
4
|
file?: string;
|
|
5
5
|
loopId?: string;
|
|
@@ -11,6 +11,7 @@ export interface MartinGetVerificationResultsOutput {
|
|
|
11
11
|
loop: ReturnType<typeof buildLoopPreview>;
|
|
12
12
|
verification: ReturnType<typeof buildVerificationSummary>;
|
|
13
13
|
receiptIntegrity: ReceiptIntegritySummary;
|
|
14
|
+
receiptScope?: ReceiptScope;
|
|
14
15
|
warnings: string[];
|
|
15
16
|
}
|
|
16
17
|
export declare function martinGetVerificationResultsTool(input: MartinGetVerificationResultsInput): Promise<MartinGetVerificationResultsOutput>;
|
|
@@ -10,6 +10,7 @@ export async function martinGetVerificationResultsTool(input) {
|
|
|
10
10
|
loop: buildLoopPreview(detail.loop),
|
|
11
11
|
verification,
|
|
12
12
|
receiptIntegrity: resolveReceiptIntegrity(detail.loop),
|
|
13
|
+
...(detail.loop.receiptScope ? { receiptScope: detail.loop.receiptScope } : {}),
|
|
13
14
|
warnings: [...detail.warnings, ...verification.warnings]
|
|
14
15
|
};
|
|
15
16
|
}
|
package/dist/tools/plan.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { resolveSafeRepoRoot } from "../server-validation.js";
|
|
2
|
-
import { buildPlanProposal } from "./workflow-governance.js";
|
|
2
|
+
import { buildPlanProposal, inspectRepoSignals } from "./workflow-governance.js";
|
|
3
3
|
export async function martinPlanTool(input) {
|
|
4
4
|
const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
|
|
5
|
-
const proposal = buildPlanProposal(workingDirectory, input
|
|
5
|
+
const proposal = buildPlanProposal(workingDirectory, input, {
|
|
6
|
+
signals: inspectRepoSignals(workingDirectory, { includeHostAvailability: false })
|
|
7
|
+
});
|
|
6
8
|
return {
|
|
7
9
|
workingDirectory,
|
|
8
10
|
...proposal
|
|
@@ -24,6 +24,12 @@ export interface MartinPreflightOutput {
|
|
|
24
24
|
ok: boolean;
|
|
25
25
|
summary: string;
|
|
26
26
|
warnings: string[];
|
|
27
|
+
receiptScope: {
|
|
28
|
+
invocationRoot: string;
|
|
29
|
+
workingDirectory: string;
|
|
30
|
+
repoRoot: string;
|
|
31
|
+
runsRoot: string;
|
|
32
|
+
};
|
|
27
33
|
scope: {
|
|
28
34
|
invocationRoot: string;
|
|
29
35
|
workingDirectory: string;
|
|
@@ -58,12 +64,33 @@ export interface MartinPreflightOutput {
|
|
|
58
64
|
available: boolean;
|
|
59
65
|
detail: string;
|
|
60
66
|
resolvedPath?: string;
|
|
67
|
+
candidatePaths?: string[];
|
|
61
68
|
};
|
|
62
69
|
codexDiagnostics?: {
|
|
70
|
+
selectedPath?: string;
|
|
63
71
|
hostPlatform: CodexHostPlatform;
|
|
72
|
+
installKind: string;
|
|
64
73
|
nativeInstallValid: boolean;
|
|
74
|
+
invocationMode: string;
|
|
75
|
+
sandboxMode: string;
|
|
76
|
+
sandboxCompatible: boolean;
|
|
77
|
+
nativeDependencyStatus?: string;
|
|
78
|
+
nativeDependencyPackage?: string;
|
|
65
79
|
launchReady: boolean;
|
|
66
80
|
summary: string;
|
|
81
|
+
remediation?: string;
|
|
82
|
+
candidateProbeResults?: Array<{
|
|
83
|
+
path: string;
|
|
84
|
+
installKind: string;
|
|
85
|
+
invocationMode: string;
|
|
86
|
+
nativeInstallValid: boolean;
|
|
87
|
+
sandboxCompatible: boolean;
|
|
88
|
+
launchReady: boolean;
|
|
89
|
+
summary: string;
|
|
90
|
+
remediation?: string;
|
|
91
|
+
nativeDependencyStatus?: string;
|
|
92
|
+
nativeDependencyPackage?: string;
|
|
93
|
+
}>;
|
|
67
94
|
};
|
|
68
95
|
runsRoot: string;
|
|
69
96
|
pathScope: {
|
package/dist/tools/preflight.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { probeCodexLaunch, resolveCliCommandAvailability } from "../vendor/adapters/index.js";
|
|
2
|
-
import { DEFAULT_BUDGET } from "../vendor/contracts/index.js";
|
|
3
2
|
import { resolveRunsRoot } from "../vendor/core/index.js";
|
|
4
3
|
import { resolveSafeRepoRoot } from "../server-validation.js";
|
|
5
|
-
import { formatUsd, getEngineAvailability, resolveExecutionMode } from "./tool-support.js";
|
|
6
|
-
import { buildPlanProposal, buildRunContract, buildPolicyPackDefinition, inspectRepoSignals } from "./workflow-governance.js";
|
|
4
|
+
import { createSkippedCliAvailability, formatUsd, getEngineAvailability, resolveExecutionMode } from "./tool-support.js";
|
|
5
|
+
import { buildPlanProposal, normalizeLoopBudget, buildRunContract, buildPolicyPackDefinition, inspectRepoSignals } from "./workflow-governance.js";
|
|
7
6
|
export async function martinPreflightTool(input) {
|
|
8
7
|
const executionMode = resolveExecutionMode();
|
|
9
8
|
const workspaceRoot = resolveSafeRepoRoot();
|
|
10
9
|
const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
|
|
11
|
-
const signals = inspectRepoSignals(workingDirectory
|
|
10
|
+
const signals = inspectRepoSignals(workingDirectory, {
|
|
11
|
+
includeHostAvailability: executionMode.liveMode
|
|
12
|
+
});
|
|
12
13
|
const engine = input.engine ?? "claude";
|
|
13
|
-
const engineAvailability =
|
|
14
|
+
const engineAvailability = executionMode.liveMode
|
|
15
|
+
? engine === "codex"
|
|
16
|
+
? resolveCliCommandAvailability("codex")
|
|
17
|
+
: getEngineAvailability(engine)
|
|
18
|
+
: createSkippedCliAvailability(engine);
|
|
14
19
|
const codexProbe = executionMode.liveMode && engine === "codex" && engineAvailability.available
|
|
15
20
|
? probeCodexLaunch({
|
|
16
21
|
workingDirectory,
|
|
@@ -21,12 +26,11 @@ export async function martinPreflightTool(input) {
|
|
|
21
26
|
const allowedPaths = input.allowedPaths ?? [];
|
|
22
27
|
const deniedPaths = input.deniedPaths ?? [];
|
|
23
28
|
const overlappingScopes = allowedPaths.filter((candidate) => deniedPaths.includes(candidate));
|
|
24
|
-
const budget = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
29
|
+
const budget = normalizeLoopBudget({
|
|
30
|
+
maxUsd: input.maxUsd,
|
|
31
|
+
maxIterations: input.maxIterations,
|
|
32
|
+
maxTokens: input.maxTokens
|
|
33
|
+
});
|
|
30
34
|
if (!executionMode.liveMode) {
|
|
31
35
|
warnings.push("Proof mode is active; preflight only proves configuration shape, not live CLI readiness.");
|
|
32
36
|
}
|
|
@@ -45,12 +49,18 @@ export async function martinPreflightTool(input) {
|
|
|
45
49
|
if (overlappingScopes.length > 0) {
|
|
46
50
|
warnings.push(`Some path patterns appear in both allowedPaths and deniedPaths: ${overlappingScopes.join(", ")}.`);
|
|
47
51
|
}
|
|
48
|
-
const plan = buildPlanProposal(workingDirectory, input);
|
|
49
|
-
const runContract = buildRunContract(workingDirectory, input);
|
|
52
|
+
const plan = buildPlanProposal(workingDirectory, input, { signals });
|
|
53
|
+
const runContract = buildRunContract(workingDirectory, input, { signals, plan });
|
|
50
54
|
const policy = buildPolicyPackDefinition(input.policyPack, signals);
|
|
51
55
|
const engineReady = !executionMode.liveMode ||
|
|
52
56
|
(engineAvailability.available && (engine !== "codex" || codexProbe?.ok !== false));
|
|
53
57
|
const ok = engineReady;
|
|
58
|
+
const receiptScope = {
|
|
59
|
+
invocationRoot: workspaceRoot,
|
|
60
|
+
workingDirectory,
|
|
61
|
+
repoRoot: workingDirectory,
|
|
62
|
+
runsRoot: resolveRunsRoot(process.env)
|
|
63
|
+
};
|
|
54
64
|
return {
|
|
55
65
|
ok,
|
|
56
66
|
summary: ok
|
|
@@ -59,11 +69,9 @@ export async function martinPreflightTool(input) {
|
|
|
59
69
|
? codexProbe.summary
|
|
60
70
|
: `${engine} is not available for live execution.`}`,
|
|
61
71
|
warnings,
|
|
72
|
+
receiptScope,
|
|
62
73
|
scope: {
|
|
63
|
-
|
|
64
|
-
workingDirectory,
|
|
65
|
-
repoRoot: workingDirectory,
|
|
66
|
-
runsRoot: resolveRunsRoot(process.env)
|
|
74
|
+
...receiptScope
|
|
67
75
|
},
|
|
68
76
|
readiness: {
|
|
69
77
|
mode: executionMode.mode,
|
|
@@ -87,17 +95,33 @@ export async function martinPreflightTool(input) {
|
|
|
87
95
|
engineAvailability: {
|
|
88
96
|
available: engineAvailability.available,
|
|
89
97
|
detail: engineAvailability.detail,
|
|
90
|
-
...(engineAvailability.resolvedPath
|
|
91
|
-
|
|
98
|
+
...(engineAvailability.resolvedPath ? { resolvedPath: engineAvailability.resolvedPath } : {}),
|
|
99
|
+
...(engineAvailability.candidatePaths?.length
|
|
100
|
+
? { candidatePaths: engineAvailability.candidatePaths }
|
|
92
101
|
: {})
|
|
93
102
|
},
|
|
94
103
|
...(codexProbe
|
|
95
104
|
? {
|
|
96
105
|
codexDiagnostics: {
|
|
106
|
+
selectedPath: codexProbe.command,
|
|
97
107
|
hostPlatform: codexProbe.diagnosis.hostPlatform,
|
|
108
|
+
installKind: codexProbe.diagnosis.installKind,
|
|
98
109
|
nativeInstallValid: codexProbe.diagnosis.nativeInstallValid,
|
|
110
|
+
invocationMode: codexProbe.diagnosis.invocationMode,
|
|
111
|
+
sandboxMode: codexProbe.diagnosis.sandboxMode,
|
|
112
|
+
sandboxCompatible: codexProbe.diagnosis.sandboxCompatible,
|
|
113
|
+
...(codexProbe.diagnosis.nativeDependencyStatus
|
|
114
|
+
? { nativeDependencyStatus: codexProbe.diagnosis.nativeDependencyStatus }
|
|
115
|
+
: {}),
|
|
116
|
+
...(codexProbe.diagnosis.nativeDependencyPackage
|
|
117
|
+
? { nativeDependencyPackage: codexProbe.diagnosis.nativeDependencyPackage }
|
|
118
|
+
: {}),
|
|
99
119
|
launchReady: codexProbe.ok,
|
|
100
|
-
summary: codexProbe.summary
|
|
120
|
+
summary: codexProbe.summary,
|
|
121
|
+
...(codexProbe.diagnosis.remediation ? { remediation: codexProbe.diagnosis.remediation } : {}),
|
|
122
|
+
...(codexProbe.candidateProbeResults?.length
|
|
123
|
+
? { candidateProbeResults: codexProbe.candidateProbeResults }
|
|
124
|
+
: {})
|
|
101
125
|
}
|
|
102
126
|
}
|
|
103
127
|
: {}),
|
|
@@ -2,7 +2,7 @@ import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildEven
|
|
|
2
2
|
import { readRunControlState } from "./run-controls.js";
|
|
3
3
|
import { martinEvalTool } from "./eval.js";
|
|
4
4
|
import { assessRunRisk } from "./workflow-governance.js";
|
|
5
|
-
import type { ReceiptIntegritySummary } from "../vendor/contracts/index.js";
|
|
5
|
+
import type { ReceiptIntegritySummary, ReceiptScope } from "../vendor/contracts/index.js";
|
|
6
6
|
export interface MartinRunDossierInput {
|
|
7
7
|
file?: string;
|
|
8
8
|
loopId?: string;
|
|
@@ -17,6 +17,7 @@ export interface MartinRunDossierOutput {
|
|
|
17
17
|
budget: ReturnType<typeof buildBudgetSnapshot>;
|
|
18
18
|
cost: ReturnType<typeof buildCostSnapshot>;
|
|
19
19
|
receiptIntegrity: ReceiptIntegritySummary;
|
|
20
|
+
receiptScope?: ReceiptScope;
|
|
20
21
|
attempts: Array<{
|
|
21
22
|
index: number;
|
|
22
23
|
attemptId?: string;
|
|
@@ -53,6 +53,7 @@ export async function martinRunDossierTool(input) {
|
|
|
53
53
|
budget: buildBudgetSnapshot(detail.loop.budget),
|
|
54
54
|
cost: buildCostSnapshot(detail.loop.cost),
|
|
55
55
|
receiptIntegrity: resolveReceiptIntegrity(detail.loop),
|
|
56
|
+
...(detail.loop.receiptScope ? { receiptScope: detail.loop.receiptScope } : {}),
|
|
56
57
|
attempts,
|
|
57
58
|
verification,
|
|
58
59
|
artifacts: buildArtifactSummary(detail.loop),
|
package/dist/tools/run-loop.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type SpawnLike } from "../vendor/adapters/index.js";
|
|
2
|
+
import { type RunStore } from "../vendor/core/index.js";
|
|
3
|
+
import type { LoopBudget, ReceiptScope } from "../vendor/contracts/index.js";
|
|
2
4
|
import { buildArtifactSummary, buildVerificationSummary, buildLoopPreview, type MartinEngine } from "./tool-support.js";
|
|
3
5
|
export interface RunLoopInput {
|
|
4
6
|
objective: string;
|
|
@@ -41,4 +43,6 @@ export interface RunLoopOutput {
|
|
|
41
43
|
artifacts: ReturnType<typeof buildArtifactSummary>;
|
|
42
44
|
};
|
|
43
45
|
}
|
|
46
|
+
export declare function __setProofModeVerifierSpawnImplForTests(spawnImpl?: SpawnLike): void;
|
|
47
|
+
export declare function __setRunStoreOverrideForTests(store?: RunStore): void;
|
|
44
48
|
export declare function runLoopTool(input: RunLoopInput): Promise<RunLoopOutput>;
|
package/dist/tools/run-loop.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { createClaudeCliAdapter, createCodexCliAdapter, createGeminiCliAdapter, probeCodexLaunch, resolveCliCommandAvailability, createVerifierOnlyAdapter } from "../vendor/adapters/index.js";
|
|
2
2
|
import { createFileRunStore, evaluateCostGovernor, resolveRunsRoot, runMartin } from "../vendor/core/index.js";
|
|
3
|
-
import { DEFAULT_BUDGET } from "../vendor/contracts/index.js";
|
|
4
3
|
import { normalizeSafePathPatterns, resolveSafeRepoRoot } from "../server-validation.js";
|
|
5
4
|
import { MartinToolError } from "./tool-errors.js";
|
|
6
5
|
import { buildArtifactSummary, buildVerificationSummary, buildLoopPreview, buildRunRecordPaths, getEngineAvailability, resolveExecutionMode } from "./tool-support.js";
|
|
6
|
+
import { normalizeLoopBudget } from "./workflow-governance.js";
|
|
7
|
+
let proofModeVerifierSpawnImpl;
|
|
8
|
+
let runStoreOverrideForTests;
|
|
9
|
+
export function __setProofModeVerifierSpawnImplForTests(spawnImpl) {
|
|
10
|
+
proofModeVerifierSpawnImpl = spawnImpl;
|
|
11
|
+
}
|
|
12
|
+
export function __setRunStoreOverrideForTests(store) {
|
|
13
|
+
runStoreOverrideForTests = store;
|
|
14
|
+
}
|
|
7
15
|
export async function runLoopTool(input) {
|
|
8
16
|
const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
|
|
9
17
|
const engine = input.engine ?? "claude";
|
|
@@ -19,6 +27,7 @@ export async function runLoopTool(input) {
|
|
|
19
27
|
repoRoot: workingDirectory,
|
|
20
28
|
runsRoot
|
|
21
29
|
};
|
|
30
|
+
let codexCommandOverride;
|
|
22
31
|
if (executionMode.liveMode) {
|
|
23
32
|
if (engine === "codex") {
|
|
24
33
|
const engineAvailability = resolveCliCommandAvailability("codex");
|
|
@@ -40,6 +49,7 @@ export async function runLoopTool(input) {
|
|
|
40
49
|
retryable: false
|
|
41
50
|
});
|
|
42
51
|
}
|
|
52
|
+
codexCommandOverride = codexProbe.command;
|
|
43
53
|
}
|
|
44
54
|
else {
|
|
45
55
|
const engineAvailability = getEngineAvailability(engine);
|
|
@@ -55,10 +65,15 @@ export async function runLoopTool(input) {
|
|
|
55
65
|
const adapter = !executionMode.liveMode
|
|
56
66
|
? createVerifierOnlyAdapter({
|
|
57
67
|
workingDirectory,
|
|
58
|
-
label: "Proof mode adapter (MARTIN_LIVE=false)"
|
|
68
|
+
label: "Proof mode adapter (MARTIN_LIVE=false)",
|
|
69
|
+
...(proofModeVerifierSpawnImpl ? { spawnImpl: proofModeVerifierSpawnImpl } : {})
|
|
59
70
|
})
|
|
60
71
|
: engine === "codex"
|
|
61
|
-
? createCodexCliAdapter({
|
|
72
|
+
? createCodexCliAdapter({
|
|
73
|
+
workingDirectory,
|
|
74
|
+
...(model ? { model } : {}),
|
|
75
|
+
...(codexCommandOverride ? { command: codexCommandOverride } : {})
|
|
76
|
+
})
|
|
62
77
|
: engine === "gemini"
|
|
63
78
|
? createGeminiCliAdapter({ workingDirectory, ...(model ? { model } : {}) })
|
|
64
79
|
: createClaudeCliAdapter({ workingDirectory, ...(model ? { model } : {}) });
|
|
@@ -72,14 +87,11 @@ export async function runLoopTool(input) {
|
|
|
72
87
|
if (input.maxTokens !== undefined) {
|
|
73
88
|
partialBudget.maxTokens = input.maxTokens;
|
|
74
89
|
}
|
|
75
|
-
const budget =
|
|
76
|
-
...DEFAULT_BUDGET,
|
|
77
|
-
...partialBudget
|
|
78
|
-
};
|
|
90
|
+
const budget = normalizeLoopBudget(partialBudget);
|
|
79
91
|
const result = await runMartin({
|
|
80
92
|
workspaceId: input.workspaceId ?? "ws_mcp",
|
|
81
93
|
projectId: input.projectId ?? "proj_mcp",
|
|
82
|
-
store: createFileRunStore({ runsRoot }),
|
|
94
|
+
store: runStoreOverrideForTests ?? createFileRunStore({ runsRoot }),
|
|
83
95
|
receiptScope,
|
|
84
96
|
task: {
|
|
85
97
|
title: input.objective.slice(0, 100),
|