@martinloop/mcp 0.2.7 → 0.3.0
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 +49 -104
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/prompts.d.ts +1 -1
- package/dist/resources.d.ts +1 -1
- package/dist/resources.js +2 -2
- package/dist/server-validation.d.ts +1 -0
- package/dist/server-validation.js +8 -0
- package/dist/server.js +18 -2
- package/dist/tools/doctor.d.ts +12 -1
- package/dist/tools/doctor.js +37 -6
- package/dist/tools/eval.js +3 -2
- package/dist/tools/get-run.d.ts +2 -0
- package/dist/tools/get-run.js +2 -1
- package/dist/tools/get-verification-results.d.ts +2 -0
- package/dist/tools/get-verification-results.js +2 -1
- package/dist/tools/pr-tools.js +2 -1
- package/dist/tools/preflight.d.ts +14 -1
- package/dist/tools/preflight.js +36 -5
- package/dist/tools/run-dossier.d.ts +2 -0
- package/dist/tools/run-dossier.js +4 -2
- package/dist/tools/run-loop.d.ts +3 -2
- package/dist/tools/run-loop.js +48 -28
- package/dist/tools/tool-errors.js +1 -1
- package/dist/tools/tool-support.d.ts +6 -3
- package/dist/tools/tool-support.js +12 -5
- package/dist/vendor/adapters/claude-cli.d.ts +25 -0
- package/dist/vendor/adapters/claude-cli.js +279 -19
- package/dist/vendor/adapters/cli-bridge.d.ts +1 -0
- package/dist/vendor/adapters/cli-bridge.js +44 -3
- package/dist/vendor/adapters/codex-launcher.d.ts +44 -0
- package/dist/vendor/adapters/codex-launcher.js +247 -0
- package/dist/vendor/adapters/index.d.ts +3 -2
- package/dist/vendor/adapters/index.js +3 -2
- package/dist/vendor/adapters/openai-compatible.d.ts +19 -4
- package/dist/vendor/adapters/openai-compatible.js +44 -19
- package/dist/vendor/adapters/runtime-support.d.ts +3 -0
- package/dist/vendor/adapters/runtime-support.js +8 -1
- package/dist/vendor/adapters/verifier-only.js +4 -3
- package/dist/vendor/contracts/index.d.ts +39 -0
- package/dist/vendor/contracts/index.js +2 -0
- package/dist/vendor/core/index.d.ts +23 -3
- package/dist/vendor/core/index.js +88 -15
- package/dist/vendor/core/persistence/index.d.ts +2 -0
- package/dist/vendor/core/persistence/index.js +1 -0
- package/dist/vendor/core/persistence/integrity.d.ts +38 -0
- package/dist/vendor/core/persistence/integrity.js +239 -0
- package/dist/vendor/core/persistence/store.d.ts +7 -0
- package/dist/vendor/core/persistence/store.js +25 -1
- package/dist/vendor/core/policy.d.ts +9 -0
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -1,79 +1,21 @@
|
|
|
1
1
|
# @martinloop/mcp
|
|
2
2
|
|
|
3
|
-
Governed MCP server for AI coding agents
|
|
3
|
+
Governed MCP server for AI coding agents over local stdio.
|
|
4
4
|
|
|
5
|
-
`@martinloop/mcp` is the
|
|
5
|
+
`@martinloop/mcp@0.2.7` is the current public baseline. It gives hosts one bounded execution entrypoint, strong read-only inspection, clear next-step guidance, and a safer default MartinLoop workflow.
|
|
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
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
11
|
+
- `0.2.7` made the guided MCP workflow easier to adopt and harder to misuse.
|
|
12
|
+
- `0.3.0` is the next adoption release.
|
|
13
|
+
- `0.3.1` is planned for review and handoff controls.
|
|
14
|
+
- `0.3.2` is planned for opt-in execution controls.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
## What ships today
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
npx martin-loop start
|
|
19
|
-
npx martin-loop tour
|
|
20
|
-
npx martin-loop doctor
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Install
|
|
24
|
-
|
|
25
|
-
Run the packaged server directly:
|
|
26
|
-
|
|
27
|
-
```sh
|
|
28
|
-
npx -y @martinloop/mcp
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Add it to Codex:
|
|
32
|
-
|
|
33
|
-
```sh
|
|
34
|
-
codex mcp add martin-loop -- npx -y @martinloop/mcp
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Add it to Claude Code:
|
|
38
|
-
|
|
39
|
-
```sh
|
|
40
|
-
claude mcp add --transport stdio --scope user martin-loop -- npx -y @martinloop/mcp
|
|
41
|
-
claude mcp add --transport stdio --scope user martin-loop -- cmd /c npx -y @martinloop/mcp
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Generate host config from the root CLI:
|
|
45
|
-
|
|
46
|
-
```sh
|
|
47
|
-
npx martin-loop mcp print-config --host codex --transport stdio --profile minimal
|
|
48
|
-
npx martin-loop mcp print-config --host claude --transport stdio --profile diagnostic
|
|
49
|
-
npx martin-loop mcp print-config --host gemini --transport stdio --profile full-local
|
|
50
|
-
npx martin-loop mcp print-config --host generic --transport stdio --profile github-review
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Registry/server identifier: `io.github.Keesan12/martin-loop`
|
|
54
|
-
|
|
55
|
-
## Recommended Flow
|
|
56
|
-
|
|
57
|
-
1. `martin_doctor`
|
|
58
|
-
2. `martin_plan`
|
|
59
|
-
3. `martin_preflight`
|
|
60
|
-
4. `martin_run`
|
|
61
|
-
5. `martin_status` or `martin_logs`
|
|
62
|
-
6. `martin_dossier` or the `martin_get_*` tools
|
|
63
|
-
7. `martin_eval`
|
|
64
|
-
8. `martin_pr_summary` or `martin_review_pr` when a host is preparing GitHub review output
|
|
65
|
-
|
|
66
|
-
`martin_run` is the primary coding execution entrypoint. In `0.2.7`, it hard-blocks until the matching readiness, planning, and preflight receipts exist for the same task. That keeps the default flow honest for both humans and agents.
|
|
67
|
-
|
|
68
|
-
## Profiles
|
|
69
|
-
|
|
70
|
-
- `minimal`: read-heavy default for safe host setup
|
|
71
|
-
- `diagnostic`: deeper inspection and evaluator support
|
|
72
|
-
- `full-local`: includes execution and run-control helpers for local workflows
|
|
73
|
-
- `github-review`: adds PR review helpers for GitHub-oriented hosts
|
|
74
|
-
- `starter` and `full`: compatibility aliases that map onto the same discovery surface
|
|
75
|
-
|
|
76
|
-
## Tools
|
|
18
|
+
### Tools
|
|
77
19
|
|
|
78
20
|
- `martin_doctor`
|
|
79
21
|
- `martin_plan`
|
|
@@ -97,7 +39,7 @@ Registry/server identifier: `io.github.Keesan12/martin-loop`
|
|
|
97
39
|
- `martin_create_pr`
|
|
98
40
|
- `martin_review_pr`
|
|
99
41
|
|
|
100
|
-
|
|
42
|
+
### Resources
|
|
101
43
|
|
|
102
44
|
- `martin://server/health`
|
|
103
45
|
- `martin://runs/recent`
|
|
@@ -114,19 +56,9 @@ Registry/server identifier: `io.github.Keesan12/martin-loop`
|
|
|
114
56
|
- `martin://agent/next-step`
|
|
115
57
|
- `martin://guides/mcp-usage`
|
|
116
58
|
- `martin://guides/agent-start`
|
|
117
|
-
- `martin://guides/command-map`
|
|
118
|
-
- `martin://guides/ide-onboarding`
|
|
119
|
-
- `martin://guides/operating-rules`
|
|
120
59
|
- `martin://guides/publish-readiness`
|
|
121
60
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
- `martin://runs/{loopId}`
|
|
125
|
-
- `martin://runs/{loopId}/dossier`
|
|
126
|
-
- `martin://runs/{loopId}/attempts/{attemptIndex}`
|
|
127
|
-
- `martin://runs/{loopId}/verification`
|
|
128
|
-
|
|
129
|
-
## Prompts
|
|
61
|
+
### Prompts
|
|
130
62
|
|
|
131
63
|
- `martin_start`
|
|
132
64
|
- `martin_preflight`
|
|
@@ -138,40 +70,56 @@ Registry/server identifier: `io.github.Keesan12/martin-loop`
|
|
|
138
70
|
- `martin_debug_failed_run`
|
|
139
71
|
- `martin_publish_readiness_review`
|
|
140
72
|
- `martin_triage_run_store`
|
|
141
|
-
- `safe_bug_fix`
|
|
142
|
-
- `write_tests_first`
|
|
143
|
-
- `small_refactor`
|
|
144
|
-
- `security_review`
|
|
145
|
-
- `pr_review`
|
|
146
|
-
- `release_check`
|
|
147
73
|
|
|
148
|
-
##
|
|
74
|
+
## Recommended flow
|
|
149
75
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
76
|
+
1. `martin_doctor`
|
|
77
|
+
2. `martin_plan`
|
|
78
|
+
3. `martin_preflight`
|
|
79
|
+
4. `martin_run`
|
|
80
|
+
5. `martin_status` or `martin_logs`
|
|
81
|
+
6. `martin_dossier`
|
|
82
|
+
7. `martin_eval`
|
|
157
83
|
|
|
158
|
-
##
|
|
84
|
+
## Install
|
|
159
85
|
|
|
160
|
-
|
|
86
|
+
```sh
|
|
87
|
+
npx -y @martinloop/mcp
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Codex:
|
|
161
91
|
|
|
162
92
|
```sh
|
|
163
|
-
|
|
93
|
+
codex mcp add martin-loop -- npx -y @martinloop/mcp
|
|
164
94
|
```
|
|
165
95
|
|
|
166
|
-
|
|
96
|
+
Claude Code:
|
|
167
97
|
|
|
168
98
|
```sh
|
|
169
|
-
|
|
99
|
+
# macOS/Linux
|
|
100
|
+
claude mcp add --transport stdio --scope user martin-loop -- npx -y @martinloop/mcp
|
|
101
|
+
|
|
102
|
+
# Windows PowerShell or cmd.exe
|
|
103
|
+
claude mcp add --transport stdio --scope user martin-loop -- cmd /c npx -y @martinloop/mcp
|
|
170
104
|
```
|
|
171
105
|
|
|
172
|
-
|
|
106
|
+
If you want generated host config, use the MartinLoop CLI:
|
|
173
107
|
|
|
174
|
-
|
|
108
|
+
```sh
|
|
109
|
+
martin mcp print-config --host codex --transport stdio --profile minimal
|
|
110
|
+
martin mcp print-config --host claude --transport stdio --profile diagnostic
|
|
111
|
+
martin mcp print-config --host gemini --transport stdio --profile full-local
|
|
112
|
+
martin mcp print-config --host generic --transport stdio --profile github-review
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Compatibility posture
|
|
116
|
+
|
|
117
|
+
- `martin_run` remains the single execution entrypoint.
|
|
118
|
+
- Read-only inspection stays available without execution-capable profiles.
|
|
119
|
+
- The OSS package stays focused on local stdio workflows. Hosted and team features live on a separate product track.
|
|
120
|
+
- Later `0.3.x` releases should widen adoption and guidance without blurring those boundaries.
|
|
121
|
+
|
|
122
|
+
## Verification
|
|
175
123
|
|
|
176
124
|
```sh
|
|
177
125
|
pnpm --filter @martinloop/mcp lint
|
|
@@ -180,7 +128,4 @@ pnpm --filter @martinloop/mcp build
|
|
|
180
128
|
pnpm --filter @martinloop/mcp smoke:pack
|
|
181
129
|
pnpm --filter @martinloop/mcp smoke:published:pack
|
|
182
130
|
pnpm --filter @martinloop/mcp verify:release
|
|
183
|
-
pnpm --filter @martin/cli verify:hosts:live
|
|
184
131
|
```
|
|
185
|
-
|
|
186
|
-
See [MCP setup](../../docs/getting-started/mcp.md), [MCP tool reference](../../docs/reference/mcp-tools.md), and [MCP compatibility](../../docs/reference/mcp-compatibility.md).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MARTIN_MCP_PACKAGE_VERSION = "0.
|
|
1
|
+
export declare const MARTIN_MCP_PACKAGE_VERSION = "0.3.0";
|
package/dist/package-version.js
CHANGED
package/dist/prompts.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface MartinGetPromptInput {
|
|
|
5
5
|
arguments?: Record<string, string>;
|
|
6
6
|
runsDir?: string;
|
|
7
7
|
workingDirectory?: string;
|
|
8
|
-
engine?: "claude" | "codex";
|
|
8
|
+
engine?: "claude" | "codex" | "gemini";
|
|
9
9
|
}
|
|
10
10
|
export declare function listMartinPrompts(): {
|
|
11
11
|
prompts: Prompt[];
|
package/dist/resources.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export interface MartinReadResourceInput {
|
|
|
26
26
|
uri: string;
|
|
27
27
|
runsDir?: string;
|
|
28
28
|
workingDirectory?: string;
|
|
29
|
-
engine?: "claude" | "codex";
|
|
29
|
+
engine?: "claude" | "codex" | "gemini";
|
|
30
30
|
}
|
|
31
31
|
export declare function listMartinResources(): {
|
|
32
32
|
resources: Resource[];
|
package/dist/resources.js
CHANGED
|
@@ -338,7 +338,7 @@ async function loadLatestRunForCompactResource(runsRoot) {
|
|
|
338
338
|
empty: true,
|
|
339
339
|
warnings: [
|
|
340
340
|
"No Martin run records were found yet.",
|
|
341
|
-
"Run `npx martin-loop demo`, then run
|
|
341
|
+
"Run `npx martin-loop demo`, then run `npx martin-loop run ... --proof --verify <command>` for a no-spend local proof pass."
|
|
342
342
|
]
|
|
343
343
|
};
|
|
344
344
|
}
|
|
@@ -561,7 +561,7 @@ function compactEmptyState(kind, runsRoot, warnings) {
|
|
|
561
561
|
status: "empty",
|
|
562
562
|
runsRoot,
|
|
563
563
|
summary: "No Martin run records are available yet.",
|
|
564
|
-
nextStep: "Run `martin doctor`, create the demo workspace with `npx martin-loop demo`, then run
|
|
564
|
+
nextStep: "Run `npx martin-loop doctor`, create the demo workspace with `npx martin-loop demo`, then run `npx martin-loop run ... --proof --verify <command>`.",
|
|
565
565
|
warnings
|
|
566
566
|
};
|
|
567
567
|
}
|
|
@@ -2,6 +2,7 @@ type ToolName = "martin_run" | "martin_inspect" | "martin_status" | "martin_doct
|
|
|
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;
|
|
5
|
+
export declare function resolveTrustedLoopRepoRoot(repoRoot?: string, workspaceRoot?: string): string;
|
|
5
6
|
export declare function resolveSafeRunsJsonPath(file: string, runsRoot?: string): string;
|
|
6
7
|
export declare function resolveSafeRunsPath(file: string, runsRoot?: string): string;
|
|
7
8
|
export declare function resolveSafeRunsRootPath(runsRoot?: string, fallbackRunsRoot?: string): string;
|
|
@@ -57,6 +57,14 @@ export function resolveSafeRepoRoot(repoRoot, workspaceRoot = process.env.MARTIN
|
|
|
57
57
|
});
|
|
58
58
|
return candidate;
|
|
59
59
|
}
|
|
60
|
+
export function resolveTrustedLoopRepoRoot(repoRoot, workspaceRoot = process.env.MARTIN_MCP_WORKSPACE_ROOT ?? process.cwd()) {
|
|
61
|
+
try {
|
|
62
|
+
return resolveSafeRepoRoot(repoRoot, workspaceRoot);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
throw invalidPathError("Run record points outside the trusted workspace.", "Inspect or promote only loop records that were created under the current workspace root.");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
60
68
|
export function resolveSafeRunsJsonPath(file, runsRoot = resolveRunsRoot(process.env)) {
|
|
61
69
|
const baseRoot = resolve(runsRoot);
|
|
62
70
|
const candidate = resolve(baseRoot, file);
|
package/dist/server.js
CHANGED
|
@@ -122,6 +122,22 @@ const verificationSchema = {
|
|
|
122
122
|
latestAttemptIndex: { type: "integer" },
|
|
123
123
|
completedAt: { type: "string" },
|
|
124
124
|
summary: { type: "string" },
|
|
125
|
+
steps: {
|
|
126
|
+
type: "array",
|
|
127
|
+
items: {
|
|
128
|
+
type: "object",
|
|
129
|
+
additionalProperties: true,
|
|
130
|
+
properties: {
|
|
131
|
+
command: { type: "string" },
|
|
132
|
+
launched: { type: "boolean" },
|
|
133
|
+
exitCode: { type: "integer" },
|
|
134
|
+
timedOut: { type: "boolean" },
|
|
135
|
+
fastFail: { type: "boolean" },
|
|
136
|
+
detail: { type: "string" }
|
|
137
|
+
},
|
|
138
|
+
required: ["command", "launched"]
|
|
139
|
+
}
|
|
140
|
+
},
|
|
125
141
|
warnings: stringArraySchema
|
|
126
142
|
},
|
|
127
143
|
required: ["status", "eventCount", "ledgerEventCount", "warnings"]
|
|
@@ -370,7 +386,7 @@ const doctorOutputSchema = {
|
|
|
370
386
|
workspaceRoot: { type: "string" },
|
|
371
387
|
workingDirectory: { type: "string" },
|
|
372
388
|
runsRoot: { type: "string" },
|
|
373
|
-
mode: { type: "string", enum: ["live", "
|
|
389
|
+
mode: { type: "string", enum: ["live", "proof"] },
|
|
374
390
|
liveMode: { type: "boolean" }
|
|
375
391
|
},
|
|
376
392
|
required: ["workspaceRoot", "workingDirectory", "runsRoot", "mode", "liveMode"]
|
|
@@ -405,7 +421,7 @@ const preflightOutputSchema = {
|
|
|
405
421
|
type: "object",
|
|
406
422
|
additionalProperties: false,
|
|
407
423
|
properties: {
|
|
408
|
-
mode: { type: "string", enum: ["live", "
|
|
424
|
+
mode: { type: "string", enum: ["live", "proof"] },
|
|
409
425
|
liveMode: { type: "boolean" },
|
|
410
426
|
engineReady: { type: "boolean" }
|
|
411
427
|
},
|
package/dist/tools/doctor.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CodexHostPlatform } from "../vendor/adapters/index.js";
|
|
1
2
|
import { type LoopPreview, type MartinEngine } from "./tool-support.js";
|
|
2
3
|
import { type MartinReadinessReport } from "./workflow-governance.js";
|
|
3
4
|
export interface MartinDoctorInput {
|
|
@@ -17,13 +18,23 @@ export interface MartinDoctorOutput {
|
|
|
17
18
|
workspaceRoot: string;
|
|
18
19
|
workingDirectory: string;
|
|
19
20
|
runsRoot: string;
|
|
20
|
-
mode: "live" | "
|
|
21
|
+
mode: "live" | "proof";
|
|
21
22
|
liveMode: boolean;
|
|
22
23
|
};
|
|
24
|
+
scope: {
|
|
25
|
+
invocationRoot: string;
|
|
26
|
+
workingDirectory: string;
|
|
27
|
+
repoRoot: string;
|
|
28
|
+
runsRoot: string;
|
|
29
|
+
};
|
|
23
30
|
engines: Record<MartinEngine, {
|
|
24
31
|
available: boolean;
|
|
25
32
|
detail: string;
|
|
26
33
|
resolvedPath?: string;
|
|
34
|
+
hostPlatform?: CodexHostPlatform;
|
|
35
|
+
nativeInstallValid?: boolean;
|
|
36
|
+
launchReady?: boolean;
|
|
37
|
+
probeSummary?: string;
|
|
27
38
|
}>;
|
|
28
39
|
requestedEngine?: MartinEngine;
|
|
29
40
|
runStore: {
|
package/dist/tools/doctor.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { probeCodexLaunch, resolveCliCommandAvailability } from "../vendor/adapters/index.js";
|
|
1
2
|
import { resolveRunsRoot } from "../vendor/core/index.js";
|
|
2
3
|
import { resolveSafeRepoRoot, resolveSafeRunsRootPath } from "../server-validation.js";
|
|
3
4
|
import { getEngineAvailability, inspectRunsRoot, resolveExecutionMode } from "./tool-support.js";
|
|
@@ -5,9 +6,17 @@ import { buildReadinessReport, inspectRepoSignals } from "./workflow-governance.
|
|
|
5
6
|
export async function martinDoctorTool(input) {
|
|
6
7
|
const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
|
|
7
8
|
const runsRoot = resolveSafeRunsRootPath(input.runsDir, resolveRunsRoot(process.env));
|
|
9
|
+
const workspaceRoot = resolveSafeRepoRoot();
|
|
8
10
|
const executionMode = resolveExecutionMode();
|
|
9
11
|
const claude = getEngineAvailability("claude");
|
|
10
|
-
const codex =
|
|
12
|
+
const codex = resolveCliCommandAvailability("codex");
|
|
13
|
+
const gemini = getEngineAvailability("gemini");
|
|
14
|
+
const codexProbe = executionMode.liveMode && codex.available
|
|
15
|
+
? probeCodexLaunch({
|
|
16
|
+
workingDirectory,
|
|
17
|
+
availability: codex
|
|
18
|
+
})
|
|
19
|
+
: undefined;
|
|
11
20
|
const runStore = await inspectRunsRoot(runsRoot);
|
|
12
21
|
const signals = inspectRepoSignals(workingDirectory);
|
|
13
22
|
const readiness = buildReadinessReport(signals, runStore);
|
|
@@ -15,14 +24,17 @@ export async function martinDoctorTool(input) {
|
|
|
15
24
|
if (!runStore.exists) {
|
|
16
25
|
warnings.push("Configured Martin runs root does not exist yet.");
|
|
17
26
|
}
|
|
18
|
-
if (executionMode.liveMode && !claude.available && !codex.available) {
|
|
19
|
-
warnings.push("
|
|
27
|
+
if (executionMode.liveMode && !claude.available && !codex.available && !gemini.available) {
|
|
28
|
+
warnings.push("None of claude, codex, or gemini is currently available on PATH for live runs.");
|
|
20
29
|
}
|
|
21
30
|
if (input.engine && executionMode.liveMode) {
|
|
22
|
-
const selected = input.engine === "claude" ? claude : codex;
|
|
31
|
+
const selected = input.engine === "claude" ? claude : input.engine === "gemini" ? gemini : codex;
|
|
23
32
|
if (!selected.available) {
|
|
24
33
|
warnings.push(`Requested engine '${input.engine}' is not available on PATH.`);
|
|
25
34
|
}
|
|
35
|
+
if (input.engine === "codex" && codexProbe && !codexProbe.ok) {
|
|
36
|
+
warnings.push(codexProbe.summary);
|
|
37
|
+
}
|
|
26
38
|
}
|
|
27
39
|
warnings.push(...runStore.warnings);
|
|
28
40
|
const status = warnings.length === 0 ? "ok" : "degraded";
|
|
@@ -38,12 +50,18 @@ export async function martinDoctorTool(input) {
|
|
|
38
50
|
platform: process.platform
|
|
39
51
|
},
|
|
40
52
|
environment: {
|
|
41
|
-
workspaceRoot
|
|
53
|
+
workspaceRoot,
|
|
42
54
|
workingDirectory,
|
|
43
55
|
runsRoot,
|
|
44
56
|
mode: executionMode.mode,
|
|
45
57
|
liveMode: executionMode.liveMode
|
|
46
58
|
},
|
|
59
|
+
scope: {
|
|
60
|
+
invocationRoot: workspaceRoot,
|
|
61
|
+
workingDirectory,
|
|
62
|
+
repoRoot: workingDirectory,
|
|
63
|
+
runsRoot
|
|
64
|
+
},
|
|
47
65
|
engines: {
|
|
48
66
|
claude: {
|
|
49
67
|
available: claude.available,
|
|
@@ -53,7 +71,20 @@ export async function martinDoctorTool(input) {
|
|
|
53
71
|
codex: {
|
|
54
72
|
available: codex.available,
|
|
55
73
|
detail: codex.detail,
|
|
56
|
-
...(codex.resolvedPath ? { resolvedPath: codex.resolvedPath } : {})
|
|
74
|
+
...(codex.resolvedPath ? { resolvedPath: codex.resolvedPath } : {}),
|
|
75
|
+
...(codexProbe
|
|
76
|
+
? {
|
|
77
|
+
hostPlatform: codexProbe.diagnosis.hostPlatform,
|
|
78
|
+
nativeInstallValid: codexProbe.diagnosis.nativeInstallValid,
|
|
79
|
+
launchReady: codexProbe.ok,
|
|
80
|
+
probeSummary: codexProbe.summary
|
|
81
|
+
}
|
|
82
|
+
: {})
|
|
83
|
+
},
|
|
84
|
+
gemini: {
|
|
85
|
+
available: gemini.available,
|
|
86
|
+
detail: gemini.detail,
|
|
87
|
+
...(gemini.resolvedPath ? { resolvedPath: gemini.resolvedPath } : {})
|
|
57
88
|
}
|
|
58
89
|
},
|
|
59
90
|
...(input.engine ? { requestedEngine: input.engine } : {}),
|
package/dist/tools/eval.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { loadDetailedLoopRecord, readLedgerEvents } from "./run-store.js";
|
|
2
|
+
import { resolveTrustedLoopRepoRoot } from "../server-validation.js";
|
|
2
3
|
import { buildVerificationSummary } from "./tool-support.js";
|
|
3
4
|
import { assessRunRisk, inspectRepoSignals } from "./workflow-governance.js";
|
|
4
5
|
export async function martinEvalTool(input) {
|
|
5
6
|
const detail = await loadDetailedLoopRecord(input);
|
|
6
7
|
const ledgerEvents = await readLedgerEvents(detail);
|
|
7
8
|
const verification = buildVerificationSummary(detail.loop, ledgerEvents);
|
|
8
|
-
const repoRoot = detail.loop.task?.repoRoot;
|
|
9
|
-
const signals = inspectRepoSignals(repoRoot
|
|
9
|
+
const repoRoot = resolveTrustedLoopRepoRoot(detail.loop.task?.repoRoot);
|
|
10
|
+
const signals = inspectRepoSignals(repoRoot);
|
|
10
11
|
const risk = assessRunRisk({
|
|
11
12
|
objective: detail.loop.task?.objective ?? detail.loop.loopId,
|
|
12
13
|
allowedPaths: detail.loop.task?.allowedPaths ?? [],
|
package/dist/tools/get-run.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
2
|
+
import type { ReceiptIntegritySummary } from "../vendor/contracts/index.js";
|
|
2
3
|
export interface MartinGetRunInput {
|
|
3
4
|
file?: string;
|
|
4
5
|
loopId?: string;
|
|
@@ -12,6 +13,7 @@ export interface MartinGetRunOutput {
|
|
|
12
13
|
budget: ReturnType<typeof buildBudgetSnapshot>;
|
|
13
14
|
cost: ReturnType<typeof buildCostSnapshot>;
|
|
14
15
|
verification: ReturnType<typeof buildVerificationSummary>;
|
|
16
|
+
receiptIntegrity: ReceiptIntegritySummary;
|
|
15
17
|
artifacts: ReturnType<typeof buildArtifactSummary>;
|
|
16
18
|
inspection: {
|
|
17
19
|
runsRoot: string;
|
package/dist/tools/get-run.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
1
|
+
import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildLoopPreview, resolveReceiptIntegrity, buildVerificationSummary } from "./tool-support.js";
|
|
2
2
|
import { loadDetailedLoopRecord, readLedgerEvents } from "./run-store.js";
|
|
3
3
|
export async function martinGetRunTool(input) {
|
|
4
4
|
const detail = await loadDetailedLoopRecord(input);
|
|
@@ -11,6 +11,7 @@ export async function martinGetRunTool(input) {
|
|
|
11
11
|
budget: buildBudgetSnapshot(detail.loop.budget),
|
|
12
12
|
cost: buildCostSnapshot(detail.loop.cost),
|
|
13
13
|
verification,
|
|
14
|
+
receiptIntegrity: resolveReceiptIntegrity(detail.loop),
|
|
14
15
|
artifacts: buildArtifactSummary(detail.loop),
|
|
15
16
|
inspection: {
|
|
16
17
|
runsRoot: detail.runsRoot,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
2
|
+
import type { ReceiptIntegritySummary } from "../vendor/contracts/index.js";
|
|
2
3
|
export interface MartinGetVerificationResultsInput {
|
|
3
4
|
file?: string;
|
|
4
5
|
loopId?: string;
|
|
@@ -9,6 +10,7 @@ export interface MartinGetVerificationResultsOutput {
|
|
|
9
10
|
sourceKind: "file" | "loop_id" | "latest" | "runs_root";
|
|
10
11
|
loop: ReturnType<typeof buildLoopPreview>;
|
|
11
12
|
verification: ReturnType<typeof buildVerificationSummary>;
|
|
13
|
+
receiptIntegrity: ReceiptIntegritySummary;
|
|
12
14
|
warnings: string[];
|
|
13
15
|
}
|
|
14
16
|
export declare function martinGetVerificationResultsTool(input: MartinGetVerificationResultsInput): Promise<MartinGetVerificationResultsOutput>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
|
|
1
|
+
import { buildLoopPreview, buildVerificationSummary, resolveReceiptIntegrity } from "./tool-support.js";
|
|
2
2
|
import { loadDetailedLoopRecord, readLedgerEvents } from "./run-store.js";
|
|
3
3
|
export async function martinGetVerificationResultsTool(input) {
|
|
4
4
|
const detail = await loadDetailedLoopRecord(input);
|
|
@@ -9,6 +9,7 @@ export async function martinGetVerificationResultsTool(input) {
|
|
|
9
9
|
sourceKind: detail.sourceKind,
|
|
10
10
|
loop: buildLoopPreview(detail.loop),
|
|
11
11
|
verification,
|
|
12
|
+
receiptIntegrity: resolveReceiptIntegrity(detail.loop),
|
|
12
13
|
warnings: [...detail.warnings, ...verification.warnings]
|
|
13
14
|
};
|
|
14
15
|
}
|
package/dist/tools/pr-tools.js
CHANGED
|
@@ -2,6 +2,7 @@ import { spawnSync } from "node:child_process";
|
|
|
2
2
|
import { loadDetailedLoopRecord } from "./run-store.js";
|
|
3
3
|
import { martinRunDossierTool } from "./run-dossier.js";
|
|
4
4
|
import { martinEvalTool } from "./eval.js";
|
|
5
|
+
import { resolveTrustedLoopRepoRoot } from "../server-validation.js";
|
|
5
6
|
import { detectCliAvailability } from "./tool-support.js";
|
|
6
7
|
import { MartinToolError } from "./tool-errors.js";
|
|
7
8
|
export async function martinPrSummaryTool(input) {
|
|
@@ -20,7 +21,7 @@ export async function martinPrSummaryTool(input) {
|
|
|
20
21
|
export async function martinCreatePrTool(input) {
|
|
21
22
|
const summary = await martinPrSummaryTool(input);
|
|
22
23
|
const detail = await loadDetailedLoopRecord(input);
|
|
23
|
-
const repoRoot = detail.loop.task?.repoRoot
|
|
24
|
+
const repoRoot = resolveTrustedLoopRepoRoot(detail.loop.task?.repoRoot);
|
|
24
25
|
const branch = readGitValue(repoRoot, ["branch", "--show-current"]);
|
|
25
26
|
const title = input.title?.trim() || summary.title;
|
|
26
27
|
if (!input.execute) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type CodexHostPlatform } from "../vendor/adapters/index.js";
|
|
1
2
|
import { type MartinEngine } from "./tool-support.js";
|
|
2
3
|
import { buildPolicyPackDefinition, type MartinPlanProposal, type MartinPolicyPack, type MartinRiskAssessment, type MartinRunContract } from "./workflow-governance.js";
|
|
3
4
|
export interface MartinPreflightInput {
|
|
@@ -23,8 +24,14 @@ export interface MartinPreflightOutput {
|
|
|
23
24
|
ok: boolean;
|
|
24
25
|
summary: string;
|
|
25
26
|
warnings: string[];
|
|
27
|
+
scope: {
|
|
28
|
+
invocationRoot: string;
|
|
29
|
+
workingDirectory: string;
|
|
30
|
+
repoRoot: string;
|
|
31
|
+
runsRoot: string;
|
|
32
|
+
};
|
|
26
33
|
readiness: {
|
|
27
|
-
mode: "live" | "
|
|
34
|
+
mode: "live" | "proof";
|
|
28
35
|
liveMode: boolean;
|
|
29
36
|
engineReady: boolean;
|
|
30
37
|
};
|
|
@@ -52,6 +59,12 @@ export interface MartinPreflightOutput {
|
|
|
52
59
|
detail: string;
|
|
53
60
|
resolvedPath?: string;
|
|
54
61
|
};
|
|
62
|
+
codexDiagnostics?: {
|
|
63
|
+
hostPlatform: CodexHostPlatform;
|
|
64
|
+
nativeInstallValid: boolean;
|
|
65
|
+
launchReady: boolean;
|
|
66
|
+
summary: string;
|
|
67
|
+
};
|
|
55
68
|
runsRoot: string;
|
|
56
69
|
pathScope: {
|
|
57
70
|
repoRoot: string;
|
package/dist/tools/preflight.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { probeCodexLaunch, resolveCliCommandAvailability } from "../vendor/adapters/index.js";
|
|
1
2
|
import { DEFAULT_BUDGET } from "../vendor/contracts/index.js";
|
|
2
3
|
import { resolveRunsRoot } from "../vendor/core/index.js";
|
|
3
4
|
import { resolveSafeRepoRoot } from "../server-validation.js";
|
|
@@ -5,10 +6,17 @@ import { formatUsd, getEngineAvailability, resolveExecutionMode } from "./tool-s
|
|
|
5
6
|
import { buildPlanProposal, buildRunContract, buildPolicyPackDefinition, inspectRepoSignals } from "./workflow-governance.js";
|
|
6
7
|
export async function martinPreflightTool(input) {
|
|
7
8
|
const executionMode = resolveExecutionMode();
|
|
9
|
+
const workspaceRoot = resolveSafeRepoRoot();
|
|
8
10
|
const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
|
|
9
11
|
const signals = inspectRepoSignals(workingDirectory);
|
|
10
12
|
const engine = input.engine ?? "claude";
|
|
11
|
-
const engineAvailability = getEngineAvailability(engine);
|
|
13
|
+
const engineAvailability = engine === "codex" ? resolveCliCommandAvailability("codex") : getEngineAvailability(engine);
|
|
14
|
+
const codexProbe = executionMode.liveMode && engine === "codex" && engineAvailability.available
|
|
15
|
+
? probeCodexLaunch({
|
|
16
|
+
workingDirectory,
|
|
17
|
+
availability: engineAvailability
|
|
18
|
+
})
|
|
19
|
+
: undefined;
|
|
12
20
|
const warnings = [];
|
|
13
21
|
const allowedPaths = input.allowedPaths ?? [];
|
|
14
22
|
const deniedPaths = input.deniedPaths ?? [];
|
|
@@ -20,11 +28,14 @@ export async function martinPreflightTool(input) {
|
|
|
20
28
|
...(input.maxTokens !== undefined ? { maxTokens: input.maxTokens } : {})
|
|
21
29
|
};
|
|
22
30
|
if (!executionMode.liveMode) {
|
|
23
|
-
warnings.push("
|
|
31
|
+
warnings.push("Proof mode is active; preflight only proves configuration shape, not live CLI readiness.");
|
|
24
32
|
}
|
|
25
33
|
else if (!engineAvailability.available) {
|
|
26
34
|
warnings.push(`Requested engine '${engine}' is not available on PATH.`);
|
|
27
35
|
}
|
|
36
|
+
else if (engine === "codex" && codexProbe && !codexProbe.ok) {
|
|
37
|
+
warnings.push(codexProbe.summary);
|
|
38
|
+
}
|
|
28
39
|
if ((input.verificationPlan?.length ?? 0) === 0) {
|
|
29
40
|
warnings.push("No verificationPlan was provided; Martin can run, but completion confidence will be lower.");
|
|
30
41
|
}
|
|
@@ -37,17 +48,27 @@ export async function martinPreflightTool(input) {
|
|
|
37
48
|
const plan = buildPlanProposal(workingDirectory, input);
|
|
38
49
|
const runContract = buildRunContract(workingDirectory, input);
|
|
39
50
|
const policy = buildPolicyPackDefinition(input.policyPack, signals);
|
|
40
|
-
const
|
|
51
|
+
const engineReady = !executionMode.liveMode ||
|
|
52
|
+
(engineAvailability.available && (engine !== "codex" || codexProbe?.ok !== false));
|
|
53
|
+
const ok = engineReady;
|
|
41
54
|
return {
|
|
42
55
|
ok,
|
|
43
56
|
summary: ok
|
|
44
57
|
? `Preflight ready for ${engine} in ${workingDirectory} with a ${formatUsd(budget.maxUsd)} budget cap and ${runContract.risk.level} risk.`
|
|
45
|
-
: `Preflight blocked: ${engine
|
|
58
|
+
: `Preflight blocked: ${engine === "codex" && codexProbe && !codexProbe.ok
|
|
59
|
+
? codexProbe.summary
|
|
60
|
+
: `${engine} is not available for live execution.`}`,
|
|
46
61
|
warnings,
|
|
62
|
+
scope: {
|
|
63
|
+
invocationRoot: workspaceRoot,
|
|
64
|
+
workingDirectory,
|
|
65
|
+
repoRoot: workingDirectory,
|
|
66
|
+
runsRoot: resolveRunsRoot(process.env)
|
|
67
|
+
},
|
|
47
68
|
readiness: {
|
|
48
69
|
mode: executionMode.mode,
|
|
49
70
|
liveMode: executionMode.liveMode,
|
|
50
|
-
engineReady
|
|
71
|
+
engineReady
|
|
51
72
|
},
|
|
52
73
|
normalized: {
|
|
53
74
|
objective: input.objective,
|
|
@@ -70,6 +91,16 @@ export async function martinPreflightTool(input) {
|
|
|
70
91
|
? { resolvedPath: engineAvailability.resolvedPath }
|
|
71
92
|
: {})
|
|
72
93
|
},
|
|
94
|
+
...(codexProbe
|
|
95
|
+
? {
|
|
96
|
+
codexDiagnostics: {
|
|
97
|
+
hostPlatform: codexProbe.diagnosis.hostPlatform,
|
|
98
|
+
nativeInstallValid: codexProbe.diagnosis.nativeInstallValid,
|
|
99
|
+
launchReady: codexProbe.ok,
|
|
100
|
+
summary: codexProbe.summary
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
: {}),
|
|
73
104
|
runsRoot: resolveRunsRoot(process.env),
|
|
74
105
|
pathScope: {
|
|
75
106
|
repoRoot: workingDirectory,
|