@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
package/README.md
CHANGED
|
@@ -1,137 +1,137 @@
|
|
|
1
|
-
# @martinloop/mcp
|
|
2
|
-
|
|
3
|
-
You give an AI agent a coding task. It runs. You get a bill.
|
|
4
|
-
|
|
5
|
-
But did it actually work? Did it pass your tests? How much did it spend? What files did it touch? Did it loop 47 times trying the same broken approach?
|
|
6
|
-
|
|
7
|
-
You don't know. And that's the problem.
|
|
8
|
-
|
|
9
|
-
## What This Does
|
|
10
|
-
|
|
11
|
-
MartinLoop is a governed loop for AI coding agents. You tell it what to do, set a budget, and point it at your test suite. It runs the agent, checks your tests after every attempt, and stops when either the tests pass or the money runs out.
|
|
12
|
-
|
|
13
|
-
When it's done, you get a receipt — not a vague summary, but a structured record: dollars spent, attempts made, verification results, files changed, and whether you got what you asked for.
|
|
14
|
-
|
|
15
|
-
**One line to connect it:**
|
|
16
|
-
|
|
17
|
-
```sh
|
|
18
|
-
claude mcp add martin-loop -- npx -y @martinloop/mcp
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
That's it. Your agent now runs governed.
|
|
22
|
-
|
|
23
|
-
## Real Numbers From Real Runs
|
|
24
|
-
|
|
25
|
-
We tested this against live repos with real API spend:
|
|
26
|
-
|
|
27
|
-
| What happened | Without MartinLoop | With MartinLoop |
|
|
28
|
-
|---|---|---|
|
|
29
|
-
| Budget: $1.50 task | Agent spent **$28.42** | Agent stopped at **$1.20** |
|
|
30
|
-
| Failing verifier | Retried indefinitely | Stopped after 3 attempts with diagnosis |
|
|
31
|
-
| CLI not on PATH | "not available on PATH" (dead stop) | Auto-discovered in AppData, kept running |
|
|
32
|
-
| `bun run lint && bun run test` | Passed `&&` as a literal arg (always fails) | Routed through shell, worked |
|
|
33
|
-
|
|
34
|
-
These aren't hypotheticals. The $28 overshoot happened in production testing. We fixed the circuit breaker in `0.3.8`.
|
|
35
|
-
|
|
36
|
-
## Install
|
|
37
|
-
|
|
38
|
-
### Claude Code
|
|
39
|
-
```sh
|
|
40
|
-
claude mcp add martin-loop -- npx -y @martinloop/mcp
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Windows:
|
|
44
|
-
```sh
|
|
45
|
-
claude mcp add --transport stdio --scope user martin-loop -- cmd /c npx -y @martinloop/mcp
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Codex
|
|
49
|
-
```sh
|
|
50
|
-
codex mcp add martin-loop -- npx -y @martinloop/mcp
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Gemini CLI
|
|
54
|
-
```sh
|
|
55
|
-
gemini mcp add martin-loop -- npx -y @martinloop/mcp
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### Any MCP Host
|
|
59
|
-
```sh
|
|
60
|
-
npx -y @martinloop/mcp
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## How a Governed Run Works
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
You: "Fix the auth bug. Budget $3. Verify: npm test"
|
|
67
|
-
|
|
68
|
-
martin_doctor → checks CLI, auth, environment
|
|
69
|
-
martin_plan → scopes the task, sets constraints
|
|
70
|
-
martin_preflight → validates before any spend
|
|
71
|
-
martin_run → agent works inside budget + verifier gates
|
|
72
|
-
martin_dossier → receipt: $1.40 spent, 2 attempts, tests pass
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Every attempt runs your verifier. Every dollar is tracked. If the agent drifts off-task, the scope contract catches it. If it blows the budget, the circuit breaker kills the subprocess mid-stream — not after the bill arrives.
|
|
76
|
-
|
|
77
|
-
## What Your Agent Gets
|
|
78
|
-
|
|
79
|
-
### 21 Tools
|
|
80
|
-
|
|
81
|
-
**Run the loop:**
|
|
82
|
-
`martin_doctor` `martin_plan` `martin_preflight` `martin_run` `martin_pause` `martin_continue` `martin_cancel`
|
|
83
|
-
|
|
84
|
-
**Inspect results:**
|
|
85
|
-
`martin_status` `martin_logs` `martin_dossier` `martin_eval` `martin_inspect` `martin_list_runs` `martin_get_run` `martin_get_attempt` `martin_get_verification_results` `martin_triage_runs`
|
|
86
|
-
|
|
87
|
-
**Ship the work:**
|
|
88
|
-
`martin_pr_summary` `martin_create_pr` `martin_review_pr`
|
|
89
|
-
|
|
90
|
-
### 11 Read-Only Resources
|
|
91
|
-
|
|
92
|
-
Your agent can pull context without side effects:
|
|
93
|
-
|
|
94
|
-
`martin://runs/latest` · `martin://runs/latest/proof-card` · `martin://runs/latest/budget-status` · `martin://runs/latest/verifier-evidence` · `martin://runs/recent` · `martin://server/health` · `martin://policies/current` · `martin://agent/next-step` · `martin://guides/mcp-usage` · `martin://guides/agent-start` · `martin://repo/risk-map`
|
|
95
|
-
|
|
96
|
-
### Configuration Profiles
|
|
97
|
-
|
|
98
|
-
Generate host config tuned to your workflow:
|
|
99
|
-
|
|
100
|
-
```sh
|
|
101
|
-
npx martin-loop mcp print-config --host claude --profile minimal # run + inspect
|
|
102
|
-
npx martin-loop mcp print-config --host claude --profile diagnostic # + doctor + triage
|
|
103
|
-
npx martin-loop mcp print-config --host claude --profile full-local # all local tools
|
|
104
|
-
npx martin-loop mcp print-config --host claude --profile github-review # + PR workflow
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## What Happens When Things Go Wrong
|
|
108
|
-
|
|
109
|
-
MartinLoop doesn't just report failures — it tries to fix them:
|
|
110
|
-
|
|
111
|
-
| Failure | Old behavior | Now |
|
|
112
|
-
|---|---|---|
|
|
113
|
-
| CLI not on PATH | Error message, dead stop | Searches npm global, homebrew, nvm, scoop — uses what it finds |
|
|
114
|
-
| Verifier says "command not found" | Generic "verification failed" | Tells the next attempt: "bun is missing, install with `npm i -g bun`" |
|
|
115
|
-
| `git restore` fails mid-rollback | Throws, leaves dirty state | Retries once, falls back to `git checkout`, cleans up |
|
|
116
|
-
| Invalid `--profile` flag | Crashes | Warns, falls back to `minimal`, keeps running |
|
|
117
|
-
|
|
118
|
-
## Who Uses This
|
|
119
|
-
|
|
120
|
-
- **Engineers running overnight agent loops** — you need a kill switch that actually works, and a receipt in the morning
|
|
121
|
-
- **Teams with shared API budgets** — you need per-task spend caps, not org-wide prayer
|
|
122
|
-
- **Anyone reviewing agent-generated PRs** — the dossier shows what the agent tried, what passed, and what didn't
|
|
123
|
-
|
|
124
|
-
## Requirements
|
|
125
|
-
|
|
126
|
-
- Node.js 20+
|
|
127
|
-
- One AI coding CLI: [Claude Code](https://docs.anthropic.com/claude-code), [Codex](https://github.com/openai/codex), or [Gemini CLI](https://github.com/google/gemini-cli)
|
|
128
|
-
|
|
129
|
-
## Links
|
|
130
|
-
|
|
131
|
-
- [martin-loop](https://www.npmjs.com/package/martin-loop) — the standalone CLI
|
|
132
|
-
- [GitHub](https://github.com/Keesan12/martin-loop) — source and issues
|
|
133
|
-
- [martinloop.com](https://martinloop.com)
|
|
134
|
-
|
|
135
|
-
## License
|
|
136
|
-
|
|
137
|
-
Apache-2.0
|
|
1
|
+
# @martinloop/mcp
|
|
2
|
+
|
|
3
|
+
You give an AI agent a coding task. It runs. You get a bill.
|
|
4
|
+
|
|
5
|
+
But did it actually work? Did it pass your tests? How much did it spend? What files did it touch? Did it loop 47 times trying the same broken approach?
|
|
6
|
+
|
|
7
|
+
You don't know. And that's the problem.
|
|
8
|
+
|
|
9
|
+
## What This Does
|
|
10
|
+
|
|
11
|
+
MartinLoop is a governed loop for AI coding agents. You tell it what to do, set a budget, and point it at your test suite. It runs the agent, checks your tests after every attempt, and stops when either the tests pass or the money runs out.
|
|
12
|
+
|
|
13
|
+
When it's done, you get a receipt — not a vague summary, but a structured record: dollars spent, attempts made, verification results, files changed, and whether you got what you asked for.
|
|
14
|
+
|
|
15
|
+
**One line to connect it:**
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
claude mcp add martin-loop -- npx -y @martinloop/mcp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
That's it. Your agent now runs governed.
|
|
22
|
+
|
|
23
|
+
## Real Numbers From Real Runs
|
|
24
|
+
|
|
25
|
+
We tested this against live repos with real API spend:
|
|
26
|
+
|
|
27
|
+
| What happened | Without MartinLoop | With MartinLoop |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| Budget: $1.50 task | Agent spent **$28.42** | Agent stopped at **$1.20** |
|
|
30
|
+
| Failing verifier | Retried indefinitely | Stopped after 3 attempts with diagnosis |
|
|
31
|
+
| CLI not on PATH | "not available on PATH" (dead stop) | Auto-discovered in AppData, kept running |
|
|
32
|
+
| `bun run lint && bun run test` | Passed `&&` as a literal arg (always fails) | Routed through shell, worked |
|
|
33
|
+
|
|
34
|
+
These aren't hypotheticals. The $28 overshoot happened in production testing. We fixed the circuit breaker in `0.3.8`.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
### Claude Code
|
|
39
|
+
```sh
|
|
40
|
+
claude mcp add martin-loop -- npx -y @martinloop/mcp
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Windows:
|
|
44
|
+
```sh
|
|
45
|
+
claude mcp add --transport stdio --scope user martin-loop -- cmd /c npx -y @martinloop/mcp
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Codex
|
|
49
|
+
```sh
|
|
50
|
+
codex mcp add martin-loop -- npx -y @martinloop/mcp
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Gemini CLI
|
|
54
|
+
```sh
|
|
55
|
+
gemini mcp add martin-loop -- npx -y @martinloop/mcp
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Any MCP Host
|
|
59
|
+
```sh
|
|
60
|
+
npx -y @martinloop/mcp
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## How a Governed Run Works
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
You: "Fix the auth bug. Budget $3. Verify: npm test"
|
|
67
|
+
|
|
68
|
+
martin_doctor → checks CLI, auth, environment
|
|
69
|
+
martin_plan → scopes the task, sets constraints
|
|
70
|
+
martin_preflight → validates before any spend
|
|
71
|
+
martin_run → agent works inside budget + verifier gates
|
|
72
|
+
martin_dossier → receipt: $1.40 spent, 2 attempts, tests pass
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Every attempt runs your verifier. Every dollar is tracked. If the agent drifts off-task, the scope contract catches it. If it blows the budget, the circuit breaker kills the subprocess mid-stream — not after the bill arrives.
|
|
76
|
+
|
|
77
|
+
## What Your Agent Gets
|
|
78
|
+
|
|
79
|
+
### 21 Tools
|
|
80
|
+
|
|
81
|
+
**Run the loop:**
|
|
82
|
+
`martin_doctor` `martin_plan` `martin_preflight` `martin_run` `martin_pause` `martin_continue` `martin_cancel`
|
|
83
|
+
|
|
84
|
+
**Inspect results:**
|
|
85
|
+
`martin_status` `martin_logs` `martin_dossier` `martin_eval` `martin_inspect` `martin_list_runs` `martin_get_run` `martin_get_attempt` `martin_get_verification_results` `martin_triage_runs`
|
|
86
|
+
|
|
87
|
+
**Ship the work:**
|
|
88
|
+
`martin_pr_summary` `martin_create_pr` `martin_review_pr`
|
|
89
|
+
|
|
90
|
+
### 11 Read-Only Resources
|
|
91
|
+
|
|
92
|
+
Your agent can pull context without side effects:
|
|
93
|
+
|
|
94
|
+
`martin://runs/latest` · `martin://runs/latest/summary` · `martin://runs/latest/receipt` · `martin://runs/latest/proof-card` · `martin://runs/latest/budget-status` · `martin://runs/latest/verifier-evidence` · `martin://runs/recent` · `martin://server/health` · `martin://policies/current` · `martin://agent/next-step` · `martin://guides/mcp-usage` · `martin://guides/agent-start` · `martin://repo/risk-map`
|
|
95
|
+
|
|
96
|
+
### Configuration Profiles
|
|
97
|
+
|
|
98
|
+
Generate host config tuned to your workflow:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
npx martin-loop mcp print-config --host claude --profile minimal # run + inspect
|
|
102
|
+
npx martin-loop mcp print-config --host claude --profile diagnostic # + doctor + triage
|
|
103
|
+
npx martin-loop mcp print-config --host claude --profile full-local # all local tools
|
|
104
|
+
npx martin-loop mcp print-config --host claude --profile github-review # + PR workflow
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## What Happens When Things Go Wrong
|
|
108
|
+
|
|
109
|
+
MartinLoop doesn't just report failures — it tries to fix them:
|
|
110
|
+
|
|
111
|
+
| Failure | Old behavior | Now |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| CLI not on PATH | Error message, dead stop | Searches npm global, homebrew, nvm, scoop — uses what it finds |
|
|
114
|
+
| Verifier says "command not found" | Generic "verification failed" | Tells the next attempt: "bun is missing, install with `npm i -g bun`" |
|
|
115
|
+
| `git restore` fails mid-rollback | Throws, leaves dirty state | Retries once, falls back to `git checkout`, cleans up |
|
|
116
|
+
| Invalid `--profile` flag | Crashes | Warns, falls back to `minimal`, keeps running |
|
|
117
|
+
|
|
118
|
+
## Who Uses This
|
|
119
|
+
|
|
120
|
+
- **Engineers running overnight agent loops** — you need a kill switch that actually works, and a receipt in the morning
|
|
121
|
+
- **Teams with shared API budgets** — you need per-task spend caps, not org-wide prayer
|
|
122
|
+
- **Anyone reviewing agent-generated PRs** — the dossier shows what the agent tried, what passed, and what didn't
|
|
123
|
+
|
|
124
|
+
## Requirements
|
|
125
|
+
|
|
126
|
+
- Node.js 20+
|
|
127
|
+
- One AI coding CLI: [Claude Code](https://docs.anthropic.com/claude-code), [Codex](https://github.com/openai/codex), or [Gemini CLI](https://github.com/google/gemini-cli)
|
|
128
|
+
|
|
129
|
+
## Links
|
|
130
|
+
|
|
131
|
+
- [martin-loop](https://www.npmjs.com/package/martin-loop) — the standalone CLI
|
|
132
|
+
- [GitHub](https://github.com/Keesan12/martin-loop) — source and issues
|
|
133
|
+
- [martinloop.com](https://martinloop.com)
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
Apache-2.0
|
|
@@ -4,7 +4,7 @@ export declare const MARTIN_MINIMAL_TOOL_NAMES: readonly ["martin_doctor", "mart
|
|
|
4
4
|
export declare const MARTIN_DIAGNOSTIC_TOOL_NAMES: readonly ["martin_doctor", "martin_plan", "martin_preflight", "martin_estimate", "martin_logs", "martin_list_runs", "martin_triage_runs", "martin_get_run", "martin_get_attempt", "martin_get_verification_results", "martin_dossier", "martin_eval"];
|
|
5
5
|
export declare const MARTIN_GITHUB_REVIEW_TOOL_NAMES: readonly ["martin_doctor", "martin_plan", "martin_preflight", "martin_dossier", "martin_eval", "martin_pr_summary", "martin_create_pr", "martin_review_pr"];
|
|
6
6
|
export declare const MARTIN_PAID_REMOTE_TOOL_NAMES: readonly ["martin_doctor", "martin_plan", "martin_preflight", "martin_estimate", "martin_run", "martin_list_runs", "martin_triage_runs", "martin_get_run", "martin_get_verification_results", "martin_dossier", "martin_eval"];
|
|
7
|
-
export declare const MARTIN_RESOURCE_URIS: readonly ["martin://server/health", "martin://runs/recent", "martin://runs/triage", "martin://runs/latest", "martin://runs/latest/summary", "martin://runs/latest/proof-card", "martin://runs/latest/budget-status", "martin://runs/latest/verifier-evidence", "martin://runs/latest/rollback-evidence", "martin://policies/current", "martin://repo/risk-map", "martin://verifiers/results", "martin://agent/next-step", "martin://agent/governance-status", "martin://guides/mcp-usage", "martin://guides/agent-start", "martin://guides/command-map", "martin://guides/ide-onboarding", "martin://guides/operating-rules", "martin://guides/publish-readiness"];
|
|
7
|
+
export declare const MARTIN_RESOURCE_URIS: readonly ["martin://server/health", "martin://runs/recent", "martin://runs/triage", "martin://runs/latest", "martin://runs/latest/summary", "martin://runs/latest/receipt", "martin://runs/latest/proof-card", "martin://runs/latest/budget-status", "martin://runs/latest/verifier-evidence", "martin://runs/latest/rollback-evidence", "martin://policies/current", "martin://repo/risk-map", "martin://verifiers/results", "martin://agent/next-step", "martin://agent/governance-status", "martin://agent/memory-summary", "martin://guides/mcp-usage", "martin://guides/agent-start", "martin://guides/command-map", "martin://guides/ide-onboarding", "martin://guides/operating-rules", "martin://guides/publish-readiness"];
|
|
8
8
|
export declare const MARTIN_RESOURCE_TEMPLATE_URIS: readonly ["martin://runs/{loopId}", "martin://runs/{loopId}/dossier", "martin://runs/{loopId}/attempts/{attemptIndex}", "martin://runs/{loopId}/verification"];
|
|
9
9
|
export declare const MARTIN_PROMPT_NAMES: readonly ["martin_start", "martin_preflight", "martin_triage", "martin_resume", "martin_prove", "martin_release_check", "martin_governed_coding_kickoff", "martin_debug_failed_run", "martin_publish_readiness_review", "martin_triage_run_store", "safe_bug_fix", "write_tests_first", "small_refactor", "security_review", "pr_review", "release_check"];
|
|
10
10
|
export interface MartinDiscoveryMetadata {
|
|
@@ -84,6 +84,7 @@ export const MARTIN_RESOURCE_URIS = [
|
|
|
84
84
|
"martin://runs/triage",
|
|
85
85
|
"martin://runs/latest",
|
|
86
86
|
"martin://runs/latest/summary",
|
|
87
|
+
"martin://runs/latest/receipt",
|
|
87
88
|
"martin://runs/latest/proof-card",
|
|
88
89
|
"martin://runs/latest/budget-status",
|
|
89
90
|
"martin://runs/latest/verifier-evidence",
|
|
@@ -93,6 +94,7 @@ export const MARTIN_RESOURCE_URIS = [
|
|
|
93
94
|
"martin://verifiers/results",
|
|
94
95
|
"martin://agent/next-step",
|
|
95
96
|
"martin://agent/governance-status",
|
|
97
|
+
"martin://agent/memory-summary",
|
|
96
98
|
"martin://guides/mcp-usage",
|
|
97
99
|
"martin://guides/agent-start",
|
|
98
100
|
"martin://guides/command-map",
|
package/dist/prompts.js
CHANGED
|
@@ -247,7 +247,25 @@ async function buildKickoffPrompt(input) {
|
|
|
247
247
|
return {
|
|
248
248
|
description: appendPromptMetadata("Kick off a Martin-governed coding session with explicit scope, budgets, and verification expectations."),
|
|
249
249
|
messages: [
|
|
250
|
-
textMessage("assistant",
|
|
250
|
+
textMessage("assistant", [
|
|
251
|
+
"You are operating under MartinLoop governance. All coding work MUST follow the governed sequence. This is not optional.",
|
|
252
|
+
"",
|
|
253
|
+
"REQUIRED before any code changes:",
|
|
254
|
+
"1. Read martin://agent/governance-status — check if this session is governed",
|
|
255
|
+
"2. Call martin_doctor — confirm environment readiness",
|
|
256
|
+
"3. Call martin_estimate — preview cost and recommended route BEFORE spending",
|
|
257
|
+
"4. Call martin_plan — scope the bounded approach",
|
|
258
|
+
"5. Call martin_preflight — validate the run contract",
|
|
259
|
+
"6. Only then call martin_run",
|
|
260
|
+
"7. Call martin_dossier — inspect what happened and generate receipt",
|
|
261
|
+
"",
|
|
262
|
+
"RULES:",
|
|
263
|
+
"- Never skip governance steps. Never claim success without verifier-backed evidence.",
|
|
264
|
+
"- Never generate fake tests. All tests must exercise real code paths with real assertions.",
|
|
265
|
+
"- Match the existing repo's code style (naming, formatting, test framework, module system).",
|
|
266
|
+
"- Budget caps are hard limits. If the estimate exceeds budget, ask the user before proceeding.",
|
|
267
|
+
"- Every run produces a receipt. No silent failures."
|
|
268
|
+
].join("\n")),
|
|
251
269
|
embeddedResourceMessage("assistant", firstResourceContent(usageGuide)),
|
|
252
270
|
embeddedResourceMessage("assistant", firstResourceContent(commandMapGuide)),
|
|
253
271
|
embeddedResourceMessage("assistant", firstResourceContent(operatingRulesGuide)),
|
package/dist/resources.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare const MARTIN_STATIC_RESOURCE_URIS: {
|
|
|
6
6
|
readonly triage: "martin://runs/triage";
|
|
7
7
|
readonly latestRun: "martin://runs/latest";
|
|
8
8
|
readonly latestSummary: "martin://runs/latest/summary";
|
|
9
|
+
readonly latestReceipt: "martin://runs/latest/receipt";
|
|
9
10
|
readonly latestProofCard: "martin://runs/latest/proof-card";
|
|
10
11
|
readonly latestBudgetStatus: "martin://runs/latest/budget-status";
|
|
11
12
|
readonly latestVerifierEvidence: "martin://runs/latest/verifier-evidence";
|
|
@@ -21,6 +22,8 @@ export declare const MARTIN_STATIC_RESOURCE_URIS: {
|
|
|
21
22
|
readonly operatingRulesGuide: "martin://guides/operating-rules";
|
|
22
23
|
readonly publishReadinessGuide: "martin://guides/publish-readiness";
|
|
23
24
|
readonly governanceStatus: "martin://agent/governance-status";
|
|
25
|
+
readonly memorySummary: "martin://agent/memory-summary";
|
|
26
|
+
readonly modeStatus: "martin://agent/mode-status";
|
|
24
27
|
};
|
|
25
28
|
export declare const MARTIN_RESOURCE_TEMPLATES: ResourceTemplate[];
|
|
26
29
|
export declare const MARTIN_STATIC_RESOURCES: Resource[];
|
package/dist/resources.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
1
4
|
import { buildMartinDiscoveryMetadata } from "./discovery-metadata.js";
|
|
2
5
|
import { MARTIN_MCP_PACKAGE_VERSION } from "./package-version.js";
|
|
3
6
|
import { inspectLoopTool } from "./tools/inspect-loop.js";
|
|
@@ -6,6 +9,7 @@ import { martinTriageRunsTool } from "./tools/triage-runs.js";
|
|
|
6
9
|
import { martinRunDossierTool } from "./tools/run-dossier.js";
|
|
7
10
|
import { inspectRepoSignals, buildPolicyPackDefinition, buildRepoRiskMap } from "./tools/workflow-governance.js";
|
|
8
11
|
import { readWorkflowState } from "./workflow-state.js";
|
|
12
|
+
import { readMemoryEntries, buildMemorySummary } from "./vendor/core/index.js";
|
|
9
13
|
import { buildAttemptSnapshot, buildPersistedLoopPreview, buildVerificationHistorySnapshot, parseAttemptIndex, resolveMartinDiscoveryContext, toPrettyJson } from "./discovery-support.js";
|
|
10
14
|
import { loadDetailedLoopRecord, readLedgerEvents } from "./tools/run-store.js";
|
|
11
15
|
import { invalidArgumentsError, MartinToolError } from "./tools/tool-errors.js";
|
|
@@ -15,6 +19,7 @@ export const MARTIN_STATIC_RESOURCE_URIS = {
|
|
|
15
19
|
triage: "martin://runs/triage",
|
|
16
20
|
latestRun: "martin://runs/latest",
|
|
17
21
|
latestSummary: "martin://runs/latest/summary",
|
|
22
|
+
latestReceipt: "martin://runs/latest/receipt",
|
|
18
23
|
latestProofCard: "martin://runs/latest/proof-card",
|
|
19
24
|
latestBudgetStatus: "martin://runs/latest/budget-status",
|
|
20
25
|
latestVerifierEvidence: "martin://runs/latest/verifier-evidence",
|
|
@@ -29,7 +34,9 @@ export const MARTIN_STATIC_RESOURCE_URIS = {
|
|
|
29
34
|
ideOnboardingGuide: "martin://guides/ide-onboarding",
|
|
30
35
|
operatingRulesGuide: "martin://guides/operating-rules",
|
|
31
36
|
publishReadinessGuide: "martin://guides/publish-readiness",
|
|
32
|
-
governanceStatus: "martin://agent/governance-status"
|
|
37
|
+
governanceStatus: "martin://agent/governance-status",
|
|
38
|
+
memorySummary: "martin://agent/memory-summary",
|
|
39
|
+
modeStatus: "martin://agent/mode-status"
|
|
33
40
|
};
|
|
34
41
|
export const MARTIN_RESOURCE_TEMPLATES = [
|
|
35
42
|
{
|
|
@@ -93,11 +100,18 @@ export const MARTIN_STATIC_RESOURCES = [
|
|
|
93
100
|
description: "Compact latest-run summary for context-constrained agents.",
|
|
94
101
|
mimeType: "application/json"
|
|
95
102
|
},
|
|
103
|
+
{
|
|
104
|
+
uri: MARTIN_STATIC_RESOURCE_URIS.latestReceipt,
|
|
105
|
+
name: "martin_latest_receipt",
|
|
106
|
+
title: "Martin Latest Receipt",
|
|
107
|
+
description: "Canonical structured receipt for the latest run; use this before optional proof-card views.",
|
|
108
|
+
mimeType: "application/json"
|
|
109
|
+
},
|
|
96
110
|
{
|
|
97
111
|
uri: MARTIN_STATIC_RESOURCE_URIS.latestProofCard,
|
|
98
112
|
name: "martin_latest_proof_card",
|
|
99
113
|
title: "Martin Latest Proof Card",
|
|
100
|
-
description: "
|
|
114
|
+
description: "Optional Markdown proof view derived from the latest receipt.",
|
|
101
115
|
mimeType: "text/markdown"
|
|
102
116
|
},
|
|
103
117
|
{
|
|
@@ -197,6 +211,20 @@ export const MARTIN_STATIC_RESOURCES = [
|
|
|
197
211
|
title: "Martin Governance Status",
|
|
198
212
|
description: "Proactive governance status: whether work is governed, budget remaining, unreceipted runs, and recommended next action. Read this before starting agent work.",
|
|
199
213
|
mimeType: "application/json"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
uri: MARTIN_STATIC_RESOURCE_URIS.memorySummary,
|
|
217
|
+
name: "martin_memory_summary",
|
|
218
|
+
title: "Martin Memory Summary",
|
|
219
|
+
description: "MartinLoop persistent memory: user preferences, consent signals, budget patterns, and behavioral observations aggregated over time. Read at session start to personalize recommendations.",
|
|
220
|
+
mimeType: "application/json"
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
uri: MARTIN_STATIC_RESOURCE_URIS.modeStatus,
|
|
224
|
+
name: "martin_mode_status",
|
|
225
|
+
title: "Martin Mode Status",
|
|
226
|
+
description: "Current Martin working mode (auto, plan, or edits) and consent state. Read before starting agent work to confirm whether the user expects autonomous execution, plan approval, or per-edit review.",
|
|
227
|
+
mimeType: "application/json"
|
|
200
228
|
}
|
|
201
229
|
];
|
|
202
230
|
export function listMartinResources() {
|
|
@@ -232,6 +260,8 @@ export async function readMartinResource(input) {
|
|
|
232
260
|
return jsonResource(input.uri, withDiscoveryMetadata(await martinRunDossierTool({ latest: true, runsDir: context.runsRoot }), context.runsRoot));
|
|
233
261
|
case MARTIN_STATIC_RESOURCE_URIS.latestSummary:
|
|
234
262
|
return jsonResource(input.uri, withDiscoveryMetadata(await buildLatestSummaryResource(context.runsRoot), context.runsRoot));
|
|
263
|
+
case MARTIN_STATIC_RESOURCE_URIS.latestReceipt:
|
|
264
|
+
return jsonResource(input.uri, withDiscoveryMetadata(await buildLatestReceiptResource(context.runsRoot), context.runsRoot));
|
|
235
265
|
case MARTIN_STATIC_RESOURCE_URIS.latestProofCard:
|
|
236
266
|
return textResource(input.uri, "text/markdown", await buildLatestProofCardResource(context.runsRoot));
|
|
237
267
|
case MARTIN_STATIC_RESOURCE_URIS.latestBudgetStatus:
|
|
@@ -246,8 +276,15 @@ export async function readMartinResource(input) {
|
|
|
246
276
|
return jsonResource(input.uri, withDiscoveryMetadata(buildRepoRiskMap(inspectRepoSignals(context.workingDirectory)), context.runsRoot));
|
|
247
277
|
case MARTIN_STATIC_RESOURCE_URIS.verifierResults:
|
|
248
278
|
return jsonResource(input.uri, withDiscoveryMetadata(await buildLatestVerifierEvidenceResource(context.runsRoot), context.runsRoot));
|
|
279
|
+
case MARTIN_STATIC_RESOURCE_URIS.memorySummary: {
|
|
280
|
+
const entries = await readMemoryEntries(context.runsRoot);
|
|
281
|
+
const summary = buildMemorySummary(entries);
|
|
282
|
+
return jsonResource(input.uri, withDiscoveryMetadata(summary, context.runsRoot));
|
|
283
|
+
}
|
|
249
284
|
case MARTIN_STATIC_RESOURCE_URIS.governanceStatus:
|
|
250
285
|
return jsonResource(input.uri, withDiscoveryMetadata(await buildGovernanceStatusResource(context.runsRoot, context.workingDirectory), context.runsRoot));
|
|
286
|
+
case MARTIN_STATIC_RESOURCE_URIS.modeStatus:
|
|
287
|
+
return jsonResource(input.uri, withDiscoveryMetadata(await buildModeStatusResource(), context.runsRoot));
|
|
251
288
|
case MARTIN_STATIC_RESOURCE_URIS.agentNextStep:
|
|
252
289
|
return jsonResource(input.uri, withDiscoveryMetadata(await buildAgentNextStepResource(context.runsRoot), context.runsRoot));
|
|
253
290
|
case MARTIN_STATIC_RESOURCE_URIS.mcpUsageGuide:
|
|
@@ -396,6 +433,44 @@ async function buildLatestSummaryResource(runsRoot) {
|
|
|
396
433
|
warnings: [...latest.detail.warnings, ...verification.warnings]
|
|
397
434
|
};
|
|
398
435
|
}
|
|
436
|
+
async function buildLatestReceiptResource(runsRoot) {
|
|
437
|
+
const latest = await loadLatestRunForCompactResource(runsRoot);
|
|
438
|
+
if (latest.empty || !latest.detail) {
|
|
439
|
+
return compactEmptyState("latest-receipt", runsRoot, latest.warnings);
|
|
440
|
+
}
|
|
441
|
+
const ledgerEvents = await readLedgerEvents(latest.detail);
|
|
442
|
+
const loop = latest.detail.loop;
|
|
443
|
+
const verification = buildVerificationHistorySnapshot(loop, ledgerEvents);
|
|
444
|
+
const preview = buildPersistedLoopPreview(loop);
|
|
445
|
+
return {
|
|
446
|
+
kind: "latest-receipt",
|
|
447
|
+
loop: preview,
|
|
448
|
+
task: {
|
|
449
|
+
title: loop.task?.title,
|
|
450
|
+
objective: loop.task?.objective,
|
|
451
|
+
verificationPlan: loop.task?.verificationPlan ?? []
|
|
452
|
+
},
|
|
453
|
+
receiptIntegrity: latest.detail.loop.receiptIntegrity,
|
|
454
|
+
verification: {
|
|
455
|
+
status: verification.latestVerification?.passed === true
|
|
456
|
+
? "passed"
|
|
457
|
+
: verification.latestVerification?.passed === false
|
|
458
|
+
? "failed"
|
|
459
|
+
: "unavailable",
|
|
460
|
+
summary: verification.latestVerification?.summary,
|
|
461
|
+
latest: verification.latestVerification,
|
|
462
|
+
count: verification.verificationCount
|
|
463
|
+
},
|
|
464
|
+
whatHappened: loop.attempts.at(-1)?.summary ?? verification.latestVerification?.summary ?? loop.task?.objective,
|
|
465
|
+
whatMartinPrevented: describePrevention(loop),
|
|
466
|
+
nextSafeAction: inferAgentNextStep(loop, verification),
|
|
467
|
+
proofCard: {
|
|
468
|
+
artifactGuaranteed: false,
|
|
469
|
+
resource: MARTIN_STATIC_RESOURCE_URIS.latestProofCard
|
|
470
|
+
},
|
|
471
|
+
warnings: [...latest.detail.warnings, ...verification.warnings]
|
|
472
|
+
};
|
|
473
|
+
}
|
|
399
474
|
async function buildLatestBudgetStatusResource(runsRoot) {
|
|
400
475
|
const latest = await loadLatestRunForCompactResource(runsRoot);
|
|
401
476
|
if (latest.empty || !latest.detail) {
|
|
@@ -526,7 +601,7 @@ async function buildLatestProofCardResource(runsRoot) {
|
|
|
526
601
|
"",
|
|
527
602
|
"What happened: Martin has not found a local run record in this runs root.",
|
|
528
603
|
"What Martin prevented: unknown until a governed run executes.",
|
|
529
|
-
"Next safe action: call `martin_doctor`, run `npx martin-loop demo`, then inspect `martin://runs/latest/summary`.",
|
|
604
|
+
"Next safe action: call `martin_doctor`, run `npx martin-loop demo`, then inspect `martin://runs/latest/receipt` or `martin://runs/latest/summary`.",
|
|
530
605
|
"",
|
|
531
606
|
"Estimate note: no cost or token savings are claimed without run evidence.",
|
|
532
607
|
""
|
|
@@ -580,9 +655,10 @@ async function buildGovernanceStatusResource(runsRoot, workingDirectory) {
|
|
|
580
655
|
const state = await readWorkflowState(runsRoot);
|
|
581
656
|
const mcpState = state.mcp ?? {};
|
|
582
657
|
const hasDoctor = Boolean(mcpState.doctor);
|
|
658
|
+
const hasEstimate = Boolean(mcpState.estimate);
|
|
583
659
|
const hasPlan = Boolean(mcpState.plan);
|
|
584
660
|
const hasPreflight = Boolean(mcpState.preflight);
|
|
585
|
-
const governed = hasDoctor && hasPlan && hasPreflight;
|
|
661
|
+
const governed = hasDoctor && hasEstimate && hasPlan && hasPreflight;
|
|
586
662
|
const latest = await loadLatestRunForCompactResource(runsRoot);
|
|
587
663
|
const budgetRemaining = (!latest.empty && latest.detail)
|
|
588
664
|
? buildPersistedLoopPreview(latest.detail.loop).remainingBudgetUsd
|
|
@@ -600,22 +676,27 @@ async function buildGovernanceStatusResource(runsRoot, workingDirectory) {
|
|
|
600
676
|
const missingSteps = [];
|
|
601
677
|
if (!hasDoctor)
|
|
602
678
|
missingSteps.push("martin_doctor");
|
|
679
|
+
if (!hasEstimate)
|
|
680
|
+
missingSteps.push("martin_estimate");
|
|
603
681
|
if (!hasPlan)
|
|
604
682
|
missingSteps.push("martin_plan");
|
|
605
683
|
if (!hasPreflight)
|
|
606
684
|
missingSteps.push("martin_preflight");
|
|
607
685
|
const recommendedAction = !hasDoctor
|
|
608
686
|
? "Run martin_doctor to confirm environment before any work."
|
|
609
|
-
: !
|
|
610
|
-
? "Run
|
|
611
|
-
: !
|
|
612
|
-
? "Run
|
|
613
|
-
:
|
|
687
|
+
: !hasEstimate
|
|
688
|
+
? "Run martin_estimate to preview cost and route before spending."
|
|
689
|
+
: !hasPlan
|
|
690
|
+
? "Run martin_plan with your objective to scope the task."
|
|
691
|
+
: !hasPreflight
|
|
692
|
+
? "Run martin_preflight to validate the run contract before execution."
|
|
693
|
+
: "Governance complete. You may proceed with martin_run.";
|
|
614
694
|
return {
|
|
615
695
|
kind: "governance-status",
|
|
616
696
|
governed,
|
|
617
697
|
workflowReceipts: {
|
|
618
698
|
doctor: hasDoctor ? { recordedAt: mcpState.doctor.recordedAt } : null,
|
|
699
|
+
estimate: hasEstimate ? { recordedAt: mcpState.estimate.recordedAt } : null,
|
|
619
700
|
plan: hasPlan ? { recordedAt: mcpState.plan.recordedAt } : null,
|
|
620
701
|
preflight: hasPreflight ? { recordedAt: mcpState.preflight.recordedAt } : null
|
|
621
702
|
},
|
|
@@ -623,7 +704,7 @@ async function buildGovernanceStatusResource(runsRoot, workingDirectory) {
|
|
|
623
704
|
budgetRemaining,
|
|
624
705
|
unreceiptedRuns,
|
|
625
706
|
recommendedAction,
|
|
626
|
-
requiredSequence: ["martin_doctor", "martin_plan", "martin_preflight", "martin_run", "martin_dossier"],
|
|
707
|
+
requiredSequence: ["martin_doctor", "martin_estimate", "martin_plan", "martin_preflight", "martin_run", "martin_dossier"],
|
|
627
708
|
warning: governed ? undefined : "This session is NOT governed. Complete the required sequence before making changes."
|
|
628
709
|
};
|
|
629
710
|
}
|
|
@@ -670,14 +751,14 @@ function inferAgentNextStep(loop, verification) {
|
|
|
670
751
|
return {
|
|
671
752
|
action: "triage_before_retry",
|
|
672
753
|
toolOrResource: "martin_triage_runs",
|
|
673
|
-
instruction: "Call `martin_triage_runs` and inspect the
|
|
754
|
+
instruction: "Call `martin_triage_runs` and inspect the latest receipt before spending another attempt."
|
|
674
755
|
};
|
|
675
756
|
}
|
|
676
757
|
if (loop.status === "completed" && verification.latestVerification?.passed === true) {
|
|
677
758
|
return {
|
|
678
759
|
action: "prove_and_share",
|
|
679
|
-
toolOrResource: MARTIN_STATIC_RESOURCE_URIS.
|
|
680
|
-
instruction: "Read the
|
|
760
|
+
toolOrResource: MARTIN_STATIC_RESOURCE_URIS.latestReceipt,
|
|
761
|
+
instruction: "Read the latest receipt and full dossier before sharing or promoting the result; generate a proof card only when a visual artifact is explicitly needed."
|
|
681
762
|
};
|
|
682
763
|
}
|
|
683
764
|
return {
|
|
@@ -702,14 +783,14 @@ Martin Loop exposes governed coding workflows over MCP. Use the server health an
|
|
|
702
783
|
2. Use the \`martin_governed_coding_kickoff\` prompt to frame a governed coding request.
|
|
703
784
|
3. Call \`martin_preflight\` before \`martin_run\` when the task or safety envelope is non-trivial.
|
|
704
785
|
4. After execution, inspect \`${MARTIN_STATIC_RESOURCE_URIS.recentRuns}\`, \`martin://runs/{loopId}\`, and \`martin://runs/{loopId}/verification\`.
|
|
705
|
-
5. For low-context agents, read \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`, or \`${MARTIN_STATIC_RESOURCE_URIS.
|
|
786
|
+
5. For low-context agents, read \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`, or \`${MARTIN_STATIC_RESOURCE_URIS.latestReceipt}\` before asking for full JSON. Treat \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\` as an optional derived view.
|
|
706
787
|
6. Read \`${MARTIN_STATIC_RESOURCE_URIS.triage}\` or call \`martin_triage_runs\` to prioritize which run needs attention first.
|
|
707
788
|
7. Use \`martin_debug_failed_run\` when a loop exits failed, budget-bound, or escalated.
|
|
708
789
|
|
|
709
790
|
## Current Martin MCP Surface
|
|
710
791
|
|
|
711
792
|
- Tools: \`martin_run\`, \`martin_inspect\`, \`martin_status\`, \`martin_doctor\`, \`martin_preflight\`, \`martin_list_runs\`, \`martin_triage_runs\`, \`martin_get_run\`, \`martin_get_attempt\`, \`martin_get_verification_results\`, \`martin_run_dossier\`
|
|
712
|
-
- Static resources: \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\`, \`${MARTIN_STATIC_RESOURCE_URIS.recentRuns}\`, \`${MARTIN_STATIC_RESOURCE_URIS.triage}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestBudgetStatus}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestVerifierEvidence}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestRollbackEvidence}\`, \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`, \`${MARTIN_STATIC_RESOURCE_URIS.mcpUsageGuide}\`, \`${MARTIN_STATIC_RESOURCE_URIS.agentStartGuide}\`, \`${MARTIN_STATIC_RESOURCE_URIS.publishReadinessGuide}\`
|
|
793
|
+
- Static resources: \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\`, \`${MARTIN_STATIC_RESOURCE_URIS.recentRuns}\`, \`${MARTIN_STATIC_RESOURCE_URIS.triage}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestReceipt}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestBudgetStatus}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestVerifierEvidence}\`, \`${MARTIN_STATIC_RESOURCE_URIS.latestRollbackEvidence}\`, \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`, \`${MARTIN_STATIC_RESOURCE_URIS.mcpUsageGuide}\`, \`${MARTIN_STATIC_RESOURCE_URIS.agentStartGuide}\`, \`${MARTIN_STATIC_RESOURCE_URIS.publishReadinessGuide}\`
|
|
713
794
|
- Resource templates: \`martin://runs/{loopId}\`, \`martin://runs/{loopId}/attempts/{attemptIndex}\`, \`martin://runs/{loopId}/verification\`
|
|
714
795
|
- Prompts: \`martin_start\`, \`martin_preflight\`, \`martin_triage\`, \`martin_resume\`, \`martin_prove\`, \`martin_release_check\`, \`martin_governed_coding_kickoff\`, \`martin_debug_failed_run\`, \`martin_publish_readiness_review\`, \`martin_triage_run_store\`
|
|
715
796
|
|
|
@@ -736,7 +817,7 @@ Use Martin Loop as the local governor before you spend agent tokens or retry a f
|
|
|
736
817
|
2. If no runs exist, call \`martin_doctor\`, then \`martin_preflight\`.
|
|
737
818
|
3. If a run exists, read \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\` before reading full run JSON.
|
|
738
819
|
4. If the verifier failed, use prompt \`martin_debug_failed_run\` or \`martin_triage\`.
|
|
739
|
-
5. If you need a shareable receipt, read \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}
|
|
820
|
+
5. If you need a shareable receipt, read \`${MARTIN_STATIC_RESOURCE_URIS.latestReceipt}\` first. Generate or inspect \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\` only when a visual artifact is explicitly required.
|
|
740
821
|
|
|
741
822
|
## Install Profiles
|
|
742
823
|
|
|
@@ -774,7 +855,8 @@ Use this guide when an IDE or agent needs to know which Martin surface to call n
|
|
|
774
855
|
|
|
775
856
|
- Need the smallest next action: \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`
|
|
776
857
|
- Need a quick receipt: \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`
|
|
777
|
-
- Need
|
|
858
|
+
- Need the structured receipt source of truth: \`${MARTIN_STATIC_RESOURCE_URIS.latestReceipt}\`
|
|
859
|
+
- Need an optional visual proof object: \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`
|
|
778
860
|
- Need a full run review: \`martin_dossier\`
|
|
779
861
|
- Need to decide whether to retry: \`martin_triage_runs\`
|
|
780
862
|
- Need IDE setup guidance: \`${MARTIN_STATIC_RESOURCE_URIS.ideOnboardingGuide}\`
|
|
@@ -857,6 +939,32 @@ Use this guide when reviewing whether the public MCP package is ready to publish
|
|
|
857
939
|
- If a discovery helper exists but is not yet wired into the server, report that as an integration gap instead of treating the capability as fully shipped.
|
|
858
940
|
`;
|
|
859
941
|
}
|
|
942
|
+
async function buildModeStatusResource() {
|
|
943
|
+
let currentMode = "auto";
|
|
944
|
+
let modeConfigured = false;
|
|
945
|
+
try {
|
|
946
|
+
const config = JSON.parse(await readFile(join(homedir(), ".martin", "config.json"), "utf8"));
|
|
947
|
+
if (config.defaultMode) {
|
|
948
|
+
currentMode = config.defaultMode;
|
|
949
|
+
modeConfigured = true;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
catch { /* fresh install — default to auto */ }
|
|
953
|
+
return {
|
|
954
|
+
kind: "mode-status",
|
|
955
|
+
currentMode,
|
|
956
|
+
modeConfigured,
|
|
957
|
+
modes: {
|
|
958
|
+
auto: "MartinLoop governs autonomously — estimate, preflight, run, receipt without per-step approval.",
|
|
959
|
+
plan: "MartinLoop shows the proposed plan before executing. Agent waits for user approval.",
|
|
960
|
+
edits: "MartinLoop shows each file change before writing. Maximum human control."
|
|
961
|
+
},
|
|
962
|
+
agentGuidance: modeConfigured
|
|
963
|
+
? `User has explicitly set mode to "${currentMode}". Respect this preference during the session.`
|
|
964
|
+
: "Mode not explicitly configured. Defaulting to auto. Suggest running `martin mode auto|plan|edits` to set a preference.",
|
|
965
|
+
changeCommand: "martin mode auto | plan | edits"
|
|
966
|
+
};
|
|
967
|
+
}
|
|
860
968
|
function withDiscoveryMetadata(value, runsRoot) {
|
|
861
969
|
return {
|
|
862
970
|
metadata: {
|