@martinloop/mcp 0.3.5 → 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +137 -137
  2. package/dist/discovery-metadata.d.ts +1 -1
  3. package/dist/discovery-metadata.js +2 -0
  4. package/dist/prompts.js +19 -1
  5. package/dist/resources.d.ts +3 -0
  6. package/dist/resources.js +125 -17
  7. package/dist/server-validation.d.ts +1 -1
  8. package/dist/server-validation.js +12 -0
  9. package/dist/server.js +18 -7
  10. package/dist/tools/doctor.js +6 -0
  11. package/dist/tools/run-loop.d.ts +2 -1
  12. package/dist/tools/run-loop.js +5 -1
  13. package/dist/tools/tool-support.d.ts +1 -1
  14. package/dist/tools/tool-support.js +2 -1
  15. package/dist/vendor/adapters/adapters/src/claude-cli.d.ts +146 -0
  16. package/dist/vendor/adapters/adapters/src/claude-cli.js +1100 -0
  17. package/dist/vendor/adapters/adapters/src/cli-bridge.d.ts +103 -0
  18. package/dist/vendor/adapters/adapters/src/cli-bridge.js +569 -0
  19. package/dist/vendor/adapters/adapters/src/codex-launcher.d.ts +78 -0
  20. package/dist/vendor/adapters/adapters/src/codex-launcher.js +663 -0
  21. package/dist/vendor/adapters/adapters/src/direct-provider.d.ts +10 -0
  22. package/dist/vendor/adapters/adapters/src/direct-provider.js +40 -0
  23. package/dist/vendor/adapters/adapters/src/index.d.ts +8 -0
  24. package/dist/vendor/adapters/adapters/src/index.js +8 -0
  25. package/dist/vendor/adapters/adapters/src/openai-compatible.d.ts +62 -0
  26. package/dist/vendor/adapters/adapters/src/openai-compatible.js +306 -0
  27. package/dist/vendor/adapters/adapters/src/runtime-support.d.ts +17 -0
  28. package/dist/vendor/adapters/adapters/src/runtime-support.js +59 -0
  29. package/dist/vendor/adapters/adapters/src/stub-agent-cli.d.ts +8 -0
  30. package/dist/vendor/adapters/adapters/src/stub-agent-cli.js +40 -0
  31. package/dist/vendor/adapters/adapters/src/stub-direct-provider.d.ts +8 -0
  32. package/dist/vendor/adapters/adapters/src/stub-direct-provider.js +12 -0
  33. package/dist/vendor/adapters/adapters/src/verifier-only.d.ts +9 -0
  34. package/dist/vendor/adapters/adapters/src/verifier-only.js +63 -0
  35. package/dist/vendor/adapters/claude-cli.js +21 -20
  36. package/dist/vendor/adapters/cli-bridge.d.ts +7 -0
  37. package/dist/vendor/adapters/cli-bridge.js +94 -8
  38. package/dist/vendor/adapters/codex-launcher.js +18 -7
  39. package/dist/vendor/adapters/contracts/src/context-graph.d.ts +48 -0
  40. package/dist/vendor/adapters/contracts/src/context-graph.js +26 -0
  41. package/dist/vendor/adapters/contracts/src/execution-policy.d.ts +78 -0
  42. package/dist/vendor/adapters/contracts/src/execution-policy.js +43 -0
  43. package/dist/vendor/adapters/contracts/src/governance.d.ts +24 -0
  44. package/dist/vendor/adapters/contracts/src/governance.js +11 -0
  45. package/dist/vendor/adapters/contracts/src/identity.d.ts +29 -0
  46. package/dist/vendor/adapters/contracts/src/identity.js +30 -0
  47. package/dist/vendor/adapters/contracts/src/index.d.ts +412 -0
  48. package/dist/vendor/adapters/contracts/src/index.js +225 -0
  49. package/dist/vendor/adapters/contracts/src/operator.d.ts +19 -0
  50. package/dist/vendor/adapters/contracts/src/operator.js +11 -0
  51. package/dist/vendor/adapters/contracts/src/trajectory.d.ts +26 -0
  52. package/dist/vendor/adapters/contracts/src/trajectory.js +27 -0
  53. package/dist/vendor/adapters/core/src/compiler.d.ts +52 -0
  54. package/dist/vendor/adapters/core/src/compiler.js +52 -0
  55. package/dist/vendor/adapters/core/src/context-graph.d.ts +3 -0
  56. package/dist/vendor/adapters/core/src/context-graph.js +371 -0
  57. package/dist/vendor/adapters/core/src/context-integrity.d.ts +26 -0
  58. package/dist/vendor/adapters/core/src/context-integrity.js +80 -0
  59. package/dist/vendor/adapters/core/src/grounding.d.ts +38 -0
  60. package/dist/vendor/adapters/core/src/grounding.js +273 -0
  61. package/dist/vendor/adapters/core/src/identity.d.ts +20 -0
  62. package/dist/vendor/adapters/core/src/identity.js +86 -0
  63. package/dist/vendor/adapters/core/src/index.d.ts +186 -0
  64. package/dist/vendor/adapters/core/src/index.js +1495 -0
  65. package/dist/vendor/adapters/core/src/leash.d.ts +48 -0
  66. package/dist/vendor/adapters/core/src/leash.js +497 -0
  67. package/dist/vendor/adapters/core/src/persistence/compiler.d.ts +18 -0
  68. package/dist/vendor/adapters/core/src/persistence/compiler.js +34 -0
  69. package/dist/vendor/adapters/core/src/persistence/index.d.ts +10 -0
  70. package/dist/vendor/adapters/core/src/persistence/index.js +5 -0
  71. package/dist/vendor/adapters/core/src/persistence/integrity.d.ts +39 -0
  72. package/dist/vendor/adapters/core/src/persistence/integrity.js +252 -0
  73. package/dist/vendor/adapters/core/src/persistence/ledger.d.ts +23 -0
  74. package/dist/vendor/adapters/core/src/persistence/ledger.js +9 -0
  75. package/dist/vendor/adapters/core/src/persistence/memory-store.d.ts +63 -0
  76. package/dist/vendor/adapters/core/src/persistence/memory-store.js +115 -0
  77. package/dist/vendor/adapters/core/src/persistence/runs-reader.d.ts +66 -0
  78. package/dist/vendor/adapters/core/src/persistence/runs-reader.js +140 -0
  79. package/dist/vendor/adapters/core/src/persistence/store.d.ts +89 -0
  80. package/dist/vendor/adapters/core/src/persistence/store.js +125 -0
  81. package/dist/vendor/adapters/core/src/persistence/trace-store.d.ts +85 -0
  82. package/dist/vendor/adapters/core/src/persistence/trace-store.js +125 -0
  83. package/dist/vendor/adapters/core/src/policy-compiler.d.ts +2 -0
  84. package/dist/vendor/adapters/core/src/policy-compiler.js +195 -0
  85. package/dist/vendor/adapters/core/src/policy.d.ts +156 -0
  86. package/dist/vendor/adapters/core/src/policy.js +704 -0
  87. package/dist/vendor/adapters/core/src/repo-analyzer.d.ts +53 -0
  88. package/dist/vendor/adapters/core/src/repo-analyzer.js +263 -0
  89. package/dist/vendor/adapters/core/src/rollback.d.ts +15 -0
  90. package/dist/vendor/adapters/core/src/rollback.js +253 -0
  91. package/dist/vendor/adapters/core/src/routing.d.ts +82 -0
  92. package/dist/vendor/adapters/core/src/routing.js +336 -0
  93. package/dist/vendor/adapters/core/src/test-integrity.d.ts +64 -0
  94. package/dist/vendor/adapters/core/src/test-integrity.js +197 -0
  95. package/dist/vendor/adapters/core/src/trajectory.d.ts +18 -0
  96. package/dist/vendor/adapters/core/src/trajectory.js +295 -0
  97. package/dist/vendor/adapters/openai-compatible.js +84 -51
  98. package/dist/vendor/adapters/verifier-only.js +2 -2
  99. package/dist/vendor/contracts/index.d.ts +2 -2
  100. package/dist/vendor/contracts/index.js +1 -0
  101. package/dist/vendor/core/compiler.js +4 -9
  102. package/dist/vendor/core/index.d.ts +10 -2
  103. package/dist/vendor/core/index.js +32 -91
  104. package/dist/vendor/core/persistence/memory-store.d.ts +63 -0
  105. package/dist/vendor/core/persistence/memory-store.js +115 -0
  106. package/dist/vendor/core/persistence/trace-store.d.ts +85 -0
  107. package/dist/vendor/core/persistence/trace-store.js +125 -0
  108. package/dist/vendor/core/repo-analyzer.d.ts +53 -0
  109. package/dist/vendor/core/repo-analyzer.js +263 -0
  110. package/dist/vendor/core/rollback.js +2 -3
  111. package/dist/vendor/core/routing.d.ts +42 -0
  112. package/dist/vendor/core/routing.js +156 -5
  113. package/dist/vendor/core/test-integrity.d.ts +64 -0
  114. package/dist/vendor/core/test-integrity.js +197 -0
  115. package/dist/workflow-state.d.ts +1 -1
  116. package/dist/workflow-state.js +12 -4
  117. package/package.json +1 -1
  118. package/server.json +2 -2
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", "You are helping prepare a Martin Loop coding run. Keep the plan governed: validate the environment first, plan before spend, preflight non-trivial work, preserve scope discipline, and make verification requirements explicit. Do not skip Martin commands and do not treat Martin as optional."),
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)),
@@ -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: "Small Markdown receipt showing what happened, what Martin prevented, and the next safe action.",
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
- : !hasPlan
610
- ? "Run martin_plan with your objective to scope the task."
611
- : !hasPreflight
612
- ? "Run martin_preflight to validate the run contract before execution."
613
- : "Governance complete. You may proceed with martin_run.";
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 proof card before spending another attempt."
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.latestProofCard,
680
- instruction: "Read the proof card and full dossier before sharing or promoting the result."
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.latestProofCard}\` before asking for full JSON.
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 a shareable proof object: \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`
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: {