@martinloop/mcp 0.3.6 → 0.3.8

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 (119) hide show
  1. package/LICENSE +216 -0
  2. package/README.md +105 -97
  3. package/dist/discovery-metadata.d.ts +1 -1
  4. package/dist/discovery-metadata.js +1 -1
  5. package/dist/package-version.d.ts +1 -1
  6. package/dist/package-version.js +1 -1
  7. package/dist/resources.d.ts +2 -1
  8. package/dist/resources.js +251 -197
  9. package/dist/server-validation.d.ts +1 -1
  10. package/dist/server-validation.js +11 -16
  11. package/dist/server.d.ts +0 -23
  12. package/dist/server.js +7 -152
  13. package/dist/tools/preflight.d.ts +2 -0
  14. package/dist/tools/preflight.js +42 -2
  15. package/dist/tools/run-loop.d.ts +2 -1
  16. package/dist/tools/run-loop.js +5 -1
  17. package/dist/tools/tool-support.js +12 -1
  18. package/dist/vendor/adapters/adapters/src/claude-cli.d.ts +146 -0
  19. package/dist/vendor/adapters/adapters/src/claude-cli.js +1100 -0
  20. package/dist/vendor/adapters/adapters/src/cli-bridge.d.ts +103 -0
  21. package/dist/vendor/adapters/adapters/src/cli-bridge.js +569 -0
  22. package/dist/vendor/adapters/adapters/src/codex-launcher.d.ts +78 -0
  23. package/dist/vendor/adapters/adapters/src/codex-launcher.js +663 -0
  24. package/dist/vendor/adapters/adapters/src/direct-provider.d.ts +10 -0
  25. package/dist/vendor/adapters/adapters/src/direct-provider.js +40 -0
  26. package/dist/vendor/adapters/adapters/src/index.d.ts +8 -0
  27. package/dist/vendor/adapters/adapters/src/index.js +8 -0
  28. package/dist/vendor/adapters/adapters/src/openai-compatible.d.ts +62 -0
  29. package/dist/vendor/adapters/adapters/src/openai-compatible.js +306 -0
  30. package/dist/vendor/adapters/adapters/src/runtime-support.d.ts +17 -0
  31. package/dist/vendor/adapters/adapters/src/runtime-support.js +59 -0
  32. package/dist/vendor/adapters/adapters/src/stub-agent-cli.d.ts +8 -0
  33. package/dist/vendor/adapters/adapters/src/stub-agent-cli.js +40 -0
  34. package/dist/vendor/adapters/adapters/src/stub-direct-provider.d.ts +8 -0
  35. package/dist/vendor/adapters/adapters/src/stub-direct-provider.js +12 -0
  36. package/dist/vendor/adapters/adapters/src/verifier-only.d.ts +9 -0
  37. package/dist/vendor/adapters/adapters/src/verifier-only.js +63 -0
  38. package/dist/vendor/adapters/claude-cli.js +130 -68
  39. package/dist/vendor/adapters/codex-launcher.js +10 -1
  40. package/dist/vendor/adapters/contracts/src/context-graph.d.ts +48 -0
  41. package/dist/vendor/adapters/contracts/src/context-graph.js +26 -0
  42. package/dist/vendor/adapters/contracts/src/execution-policy.d.ts +78 -0
  43. package/dist/vendor/adapters/contracts/src/execution-policy.js +43 -0
  44. package/dist/vendor/adapters/contracts/src/governance.d.ts +24 -0
  45. package/dist/vendor/adapters/contracts/src/governance.js +11 -0
  46. package/dist/vendor/adapters/contracts/src/identity.d.ts +29 -0
  47. package/dist/vendor/adapters/contracts/src/identity.js +30 -0
  48. package/dist/vendor/adapters/contracts/src/index.d.ts +412 -0
  49. package/dist/vendor/adapters/contracts/src/index.js +225 -0
  50. package/dist/vendor/adapters/contracts/src/operator.d.ts +19 -0
  51. package/dist/vendor/adapters/contracts/src/operator.js +11 -0
  52. package/dist/vendor/adapters/contracts/src/trajectory.d.ts +26 -0
  53. package/dist/vendor/adapters/contracts/src/trajectory.js +27 -0
  54. package/dist/vendor/adapters/core/src/compiler.d.ts +52 -0
  55. package/dist/vendor/adapters/core/src/compiler.js +52 -0
  56. package/dist/vendor/adapters/core/src/context-graph.d.ts +3 -0
  57. package/dist/vendor/adapters/core/src/context-graph.js +371 -0
  58. package/dist/vendor/adapters/core/src/context-integrity.d.ts +26 -0
  59. package/dist/vendor/adapters/core/src/context-integrity.js +80 -0
  60. package/dist/vendor/adapters/core/src/grounding.d.ts +38 -0
  61. package/dist/vendor/adapters/core/src/grounding.js +273 -0
  62. package/dist/vendor/adapters/core/src/identity.d.ts +20 -0
  63. package/dist/vendor/adapters/core/src/identity.js +86 -0
  64. package/dist/vendor/adapters/core/src/index.d.ts +186 -0
  65. package/dist/vendor/adapters/core/src/index.js +1495 -0
  66. package/dist/vendor/adapters/core/src/leash.d.ts +48 -0
  67. package/dist/vendor/adapters/core/src/leash.js +497 -0
  68. package/dist/vendor/adapters/core/src/persistence/compiler.d.ts +18 -0
  69. package/dist/vendor/adapters/core/src/persistence/compiler.js +34 -0
  70. package/dist/vendor/adapters/core/src/persistence/index.d.ts +10 -0
  71. package/dist/vendor/adapters/core/src/persistence/index.js +5 -0
  72. package/dist/vendor/adapters/core/src/persistence/integrity.d.ts +39 -0
  73. package/dist/vendor/adapters/core/src/persistence/integrity.js +252 -0
  74. package/dist/vendor/adapters/core/src/persistence/ledger.d.ts +23 -0
  75. package/dist/vendor/adapters/core/src/persistence/ledger.js +9 -0
  76. package/dist/vendor/adapters/core/src/persistence/memory-store.d.ts +63 -0
  77. package/dist/vendor/adapters/core/src/persistence/memory-store.js +115 -0
  78. package/dist/vendor/adapters/core/src/persistence/runs-reader.d.ts +66 -0
  79. package/dist/vendor/adapters/core/src/persistence/runs-reader.js +140 -0
  80. package/dist/vendor/adapters/core/src/persistence/store.d.ts +89 -0
  81. package/dist/vendor/adapters/core/src/persistence/store.js +125 -0
  82. package/dist/vendor/adapters/core/src/persistence/trace-store.d.ts +85 -0
  83. package/dist/vendor/adapters/core/src/persistence/trace-store.js +125 -0
  84. package/dist/vendor/adapters/core/src/policy-compiler.d.ts +2 -0
  85. package/dist/vendor/adapters/core/src/policy-compiler.js +195 -0
  86. package/dist/vendor/adapters/core/src/policy.d.ts +156 -0
  87. package/dist/vendor/adapters/core/src/policy.js +704 -0
  88. package/dist/vendor/adapters/core/src/repo-analyzer.d.ts +53 -0
  89. package/dist/vendor/adapters/core/src/repo-analyzer.js +263 -0
  90. package/dist/vendor/adapters/core/src/rollback.d.ts +15 -0
  91. package/dist/vendor/adapters/core/src/rollback.js +253 -0
  92. package/dist/vendor/adapters/core/src/routing.d.ts +82 -0
  93. package/dist/vendor/adapters/core/src/routing.js +336 -0
  94. package/dist/vendor/adapters/core/src/test-integrity.d.ts +64 -0
  95. package/dist/vendor/adapters/core/src/test-integrity.js +197 -0
  96. package/dist/vendor/adapters/core/src/trajectory.d.ts +18 -0
  97. package/dist/vendor/adapters/core/src/trajectory.js +295 -0
  98. package/dist/vendor/adapters/openai-compatible.js +6 -6
  99. package/dist/vendor/adapters/verifier-only.js +2 -2
  100. package/dist/vendor/contracts/delivery.d.ts +47 -0
  101. package/dist/vendor/contracts/delivery.js +18 -0
  102. package/dist/vendor/contracts/index.d.ts +3 -1
  103. package/dist/vendor/contracts/index.js +2 -0
  104. package/dist/vendor/core/compiler.js +4 -9
  105. package/dist/vendor/core/delivery/index.d.ts +6 -0
  106. package/dist/vendor/core/delivery/index.js +4 -0
  107. package/dist/vendor/core/delivery/message-client.d.ts +18 -0
  108. package/dist/vendor/core/delivery/message-client.js +38 -0
  109. package/dist/vendor/core/delivery/message-ledger.d.ts +35 -0
  110. package/dist/vendor/core/delivery/message-ledger.js +97 -0
  111. package/dist/vendor/core/delivery/message-schema.d.ts +16 -0
  112. package/dist/vendor/core/delivery/message-schema.js +111 -0
  113. package/dist/vendor/core/delivery/update-check.d.ts +19 -0
  114. package/dist/vendor/core/delivery/update-check.js +107 -0
  115. package/dist/vendor/core/index.d.ts +2 -0
  116. package/dist/vendor/core/index.js +3 -88
  117. package/dist/vendor/core/rollback.js +2 -3
  118. package/package.json +83 -76
  119. package/server.json +21 -21
package/dist/resources.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { readFile } from "node:fs/promises";
2
- import { homedir } from "node:os";
3
2
  import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
4
  import { buildMartinDiscoveryMetadata } from "./discovery-metadata.js";
5
5
  import { MARTIN_MCP_PACKAGE_VERSION } from "./package-version.js";
6
6
  import { inspectLoopTool } from "./tools/inspect-loop.js";
@@ -19,6 +19,7 @@ export const MARTIN_STATIC_RESOURCE_URIS = {
19
19
  triage: "martin://runs/triage",
20
20
  latestRun: "martin://runs/latest",
21
21
  latestSummary: "martin://runs/latest/summary",
22
+ latestReceipt: "martin://runs/latest/receipt",
22
23
  latestProofCard: "martin://runs/latest/proof-card",
23
24
  latestBudgetStatus: "martin://runs/latest/budget-status",
24
25
  latestVerifierEvidence: "martin://runs/latest/verifier-evidence",
@@ -34,8 +35,8 @@ export const MARTIN_STATIC_RESOURCE_URIS = {
34
35
  operatingRulesGuide: "martin://guides/operating-rules",
35
36
  publishReadinessGuide: "martin://guides/publish-readiness",
36
37
  governanceStatus: "martin://agent/governance-status",
37
- modeStatus: "martin://agent/mode-status",
38
- memorySummary: "martin://agent/memory-summary"
38
+ memorySummary: "martin://agent/memory-summary",
39
+ modeStatus: "martin://agent/mode-status"
39
40
  };
40
41
  export const MARTIN_RESOURCE_TEMPLATES = [
41
42
  {
@@ -99,11 +100,18 @@ export const MARTIN_STATIC_RESOURCES = [
99
100
  description: "Compact latest-run summary for context-constrained agents.",
100
101
  mimeType: "application/json"
101
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
+ },
102
110
  {
103
111
  uri: MARTIN_STATIC_RESOURCE_URIS.latestProofCard,
104
112
  name: "martin_latest_proof_card",
105
113
  title: "Martin Latest Proof Card",
106
- 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.",
107
115
  mimeType: "text/markdown"
108
116
  },
109
117
  {
@@ -204,19 +212,19 @@ export const MARTIN_STATIC_RESOURCES = [
204
212
  description: "Proactive governance status: whether work is governed, budget remaining, unreceipted runs, and recommended next action. Read this before starting agent work.",
205
213
  mimeType: "application/json"
206
214
  },
207
- {
208
- uri: MARTIN_STATIC_RESOURCE_URIS.modeStatus,
209
- name: "martin_mode_status",
210
- title: "Martin Mode Status",
211
- description: "Current MartinLoop working mode, whether it is inherited or explicitly configured, and how to switch it.",
212
- mimeType: "application/json"
213
- },
214
215
  {
215
216
  uri: MARTIN_STATIC_RESOURCE_URIS.memorySummary,
216
217
  name: "martin_memory_summary",
217
218
  title: "Martin Memory Summary",
218
219
  description: "MartinLoop persistent memory: user preferences, consent signals, budget patterns, and behavioral observations aggregated over time. Read at session start to personalize recommendations.",
219
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"
220
228
  }
221
229
  ];
222
230
  export function listMartinResources() {
@@ -252,6 +260,8 @@ export async function readMartinResource(input) {
252
260
  return jsonResource(input.uri, withDiscoveryMetadata(await martinRunDossierTool({ latest: true, runsDir: context.runsRoot }), context.runsRoot));
253
261
  case MARTIN_STATIC_RESOURCE_URIS.latestSummary:
254
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));
255
265
  case MARTIN_STATIC_RESOURCE_URIS.latestProofCard:
256
266
  return textResource(input.uri, "text/markdown", await buildLatestProofCardResource(context.runsRoot));
257
267
  case MARTIN_STATIC_RESOURCE_URIS.latestBudgetStatus:
@@ -274,7 +284,7 @@ export async function readMartinResource(input) {
274
284
  case MARTIN_STATIC_RESOURCE_URIS.governanceStatus:
275
285
  return jsonResource(input.uri, withDiscoveryMetadata(await buildGovernanceStatusResource(context.runsRoot, context.workingDirectory), context.runsRoot));
276
286
  case MARTIN_STATIC_RESOURCE_URIS.modeStatus:
277
- return jsonResource(input.uri, withDiscoveryMetadata(await buildModeStatusResource(context.workingDirectory), context.runsRoot));
287
+ return jsonResource(input.uri, withDiscoveryMetadata(await buildModeStatusResource(), context.runsRoot));
278
288
  case MARTIN_STATIC_RESOURCE_URIS.agentNextStep:
279
289
  return jsonResource(input.uri, withDiscoveryMetadata(await buildAgentNextStepResource(context.runsRoot), context.runsRoot));
280
290
  case MARTIN_STATIC_RESOURCE_URIS.mcpUsageGuide:
@@ -423,6 +433,44 @@ async function buildLatestSummaryResource(runsRoot) {
423
433
  warnings: [...latest.detail.warnings, ...verification.warnings]
424
434
  };
425
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
+ }
426
474
  async function buildLatestBudgetStatusResource(runsRoot) {
427
475
  const latest = await loadLatestRunForCompactResource(runsRoot);
428
476
  if (latest.empty || !latest.detail) {
@@ -553,7 +601,7 @@ async function buildLatestProofCardResource(runsRoot) {
553
601
  "",
554
602
  "What happened: Martin has not found a local run record in this runs root.",
555
603
  "What Martin prevented: unknown until a governed run executes.",
556
- "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`.",
557
605
  "",
558
606
  "Estimate note: no cost or token savings are claimed without run evidence.",
559
607
  ""
@@ -607,9 +655,10 @@ async function buildGovernanceStatusResource(runsRoot, workingDirectory) {
607
655
  const state = await readWorkflowState(runsRoot);
608
656
  const mcpState = state.mcp ?? {};
609
657
  const hasDoctor = Boolean(mcpState.doctor);
658
+ const hasEstimate = Boolean(mcpState.estimate);
610
659
  const hasPlan = Boolean(mcpState.plan);
611
660
  const hasPreflight = Boolean(mcpState.preflight);
612
- const governed = hasDoctor && hasPlan && hasPreflight;
661
+ const governed = hasDoctor && hasEstimate && hasPlan && hasPreflight;
613
662
  const latest = await loadLatestRunForCompactResource(runsRoot);
614
663
  const budgetRemaining = (!latest.empty && latest.detail)
615
664
  ? buildPersistedLoopPreview(latest.detail.loop).remainingBudgetUsd
@@ -627,22 +676,27 @@ async function buildGovernanceStatusResource(runsRoot, workingDirectory) {
627
676
  const missingSteps = [];
628
677
  if (!hasDoctor)
629
678
  missingSteps.push("martin_doctor");
679
+ if (!hasEstimate)
680
+ missingSteps.push("martin_estimate");
630
681
  if (!hasPlan)
631
682
  missingSteps.push("martin_plan");
632
683
  if (!hasPreflight)
633
684
  missingSteps.push("martin_preflight");
634
685
  const recommendedAction = !hasDoctor
635
686
  ? "Run martin_doctor to confirm environment before any work."
636
- : !hasPlan
637
- ? "Run martin_plan with your objective to scope the task."
638
- : !hasPreflight
639
- ? "Run martin_preflight to validate the run contract before execution."
640
- : "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.";
641
694
  return {
642
695
  kind: "governance-status",
643
696
  governed,
644
697
  workflowReceipts: {
645
698
  doctor: hasDoctor ? { recordedAt: mcpState.doctor.recordedAt } : null,
699
+ estimate: hasEstimate ? { recordedAt: mcpState.estimate.recordedAt } : null,
646
700
  plan: hasPlan ? { recordedAt: mcpState.plan.recordedAt } : null,
647
701
  preflight: hasPreflight ? { recordedAt: mcpState.preflight.recordedAt } : null
648
702
  },
@@ -650,37 +704,10 @@ async function buildGovernanceStatusResource(runsRoot, workingDirectory) {
650
704
  budgetRemaining,
651
705
  unreceiptedRuns,
652
706
  recommendedAction,
653
- 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"],
654
708
  warning: governed ? undefined : "This session is NOT governed. Complete the required sequence before making changes."
655
709
  };
656
710
  }
657
- async function buildModeStatusResource(workingDirectory) {
658
- const configPath = join(homedir(), ".martin", "config.json");
659
- let config = {};
660
- try {
661
- config = JSON.parse(await readFile(configPath, "utf8"));
662
- }
663
- catch {
664
- // Fresh config means the implicit auto default is in effect.
665
- }
666
- const projectMode = config.projectOverrides?.[workingDirectory];
667
- const defaultMode = config.defaultMode ?? "auto";
668
- const effectiveMode = projectMode ?? defaultMode;
669
- return {
670
- kind: "mode-status",
671
- effectiveMode,
672
- defaultMode,
673
- scope: projectMode ? "project" : config.defaultMode ? "global" : "implicit_default",
674
- configured: Boolean(projectMode || config.defaultMode),
675
- projectOverride: projectMode ?? null,
676
- workingDirectory,
677
- switchCommands: {
678
- auto: "martin mode auto",
679
- plan: "martin mode plan",
680
- edits: "martin mode edits"
681
- }
682
- };
683
- }
684
711
  function buildCurrentPoliciesResource(workingDirectory) {
685
712
  const signals = inspectRepoSignals(workingDirectory);
686
713
  const recommended = buildPolicyPackDefinition(undefined, signals);
@@ -724,14 +751,14 @@ function inferAgentNextStep(loop, verification) {
724
751
  return {
725
752
  action: "triage_before_retry",
726
753
  toolOrResource: "martin_triage_runs",
727
- 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."
728
755
  };
729
756
  }
730
757
  if (loop.status === "completed" && verification.latestVerification?.passed === true) {
731
758
  return {
732
759
  action: "prove_and_share",
733
- toolOrResource: MARTIN_STATIC_RESOURCE_URIS.latestProofCard,
734
- 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."
735
762
  };
736
763
  }
737
764
  return {
@@ -742,175 +769,202 @@ function inferAgentNextStep(loop, verification) {
742
769
  }
743
770
  function buildMcpUsageGuide(runsRoot) {
744
771
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
745
- return `# Martin Loop MCP Usage
746
-
747
- Discovery revision: \`${metadata.discoveryRevision}\`
748
- Server version: \`${metadata.serverVersion}\`
749
- Runs root: \`${runsRoot}\`
750
-
751
- Martin Loop exposes governed coding workflows over MCP. Use the server health and run-store views to decide when to preflight, execute, inspect, or escalate.
752
-
753
- ## Recommended Flow
754
-
755
- 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\` or call \`martin_doctor\` to confirm the environment and run-store visibility.
756
- 2. Use the \`martin_governed_coding_kickoff\` prompt to frame a governed coding request.
757
- 3. Call \`martin_preflight\` before \`martin_run\` when the task or safety envelope is non-trivial.
758
- 4. After execution, inspect \`${MARTIN_STATIC_RESOURCE_URIS.recentRuns}\`, \`martin://runs/{loopId}\`, and \`martin://runs/{loopId}/verification\`.
759
- 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.
760
- 6. Read \`${MARTIN_STATIC_RESOURCE_URIS.triage}\` or call \`martin_triage_runs\` to prioritize which run needs attention first.
761
- 7. Use \`martin_debug_failed_run\` when a loop exits failed, budget-bound, or escalated.
762
-
763
- ## Current Martin MCP Surface
764
-
765
- - 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\`
766
- - 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.governanceStatus}\`, \`${MARTIN_STATIC_RESOURCE_URIS.modeStatus}\`, \`${MARTIN_STATIC_RESOURCE_URIS.memorySummary}\`, \`${MARTIN_STATIC_RESOURCE_URIS.mcpUsageGuide}\`, \`${MARTIN_STATIC_RESOURCE_URIS.agentStartGuide}\`, \`${MARTIN_STATIC_RESOURCE_URIS.publishReadinessGuide}\`
767
- - Resource templates: \`martin://runs/{loopId}\`, \`martin://runs/{loopId}/attempts/{attemptIndex}\`, \`martin://runs/{loopId}/verification\`
768
- - 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\`
769
-
770
- ## Notes
771
-
772
- - Discovery helpers read the existing Martin run-store; they do not create new schema.
773
- - Verification history is derived from persisted \`verification.completed\` evidence in loop records and ledgers.
774
- - Attempt inspection stays aligned with the same loop selectors used by \`martin_status\` and \`martin_inspect\`.
772
+ return `# Martin Loop MCP Usage
773
+
774
+ Discovery revision: \`${metadata.discoveryRevision}\`
775
+ Server version: \`${metadata.serverVersion}\`
776
+ Runs root: \`${runsRoot}\`
777
+
778
+ Martin Loop exposes governed coding workflows over MCP. Use the server health and run-store views to decide when to preflight, execute, inspect, or escalate.
779
+
780
+ ## Recommended Flow
781
+
782
+ 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\` or call \`martin_doctor\` to confirm the environment and run-store visibility.
783
+ 2. Use the \`martin_governed_coding_kickoff\` prompt to frame a governed coding request.
784
+ 3. Call \`martin_preflight\` before \`martin_run\` when the task or safety envelope is non-trivial.
785
+ 4. After execution, inspect \`${MARTIN_STATIC_RESOURCE_URIS.recentRuns}\`, \`martin://runs/{loopId}\`, and \`martin://runs/{loopId}/verification\`.
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.
787
+ 6. Read \`${MARTIN_STATIC_RESOURCE_URIS.triage}\` or call \`martin_triage_runs\` to prioritize which run needs attention first.
788
+ 7. Use \`martin_debug_failed_run\` when a loop exits failed, budget-bound, or escalated.
789
+
790
+ ## Current Martin MCP Surface
791
+
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\`
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}\`
794
+ - Resource templates: \`martin://runs/{loopId}\`, \`martin://runs/{loopId}/attempts/{attemptIndex}\`, \`martin://runs/{loopId}/verification\`
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\`
796
+
797
+ ## Notes
798
+
799
+ - Discovery helpers read the existing Martin run-store; they do not create new schema.
800
+ - Verification history is derived from persisted \`verification.completed\` evidence in loop records and ledgers.
801
+ - Attempt inspection stays aligned with the same loop selectors used by \`martin_status\` and \`martin_inspect\`.
775
802
  `;
776
803
  }
777
804
  function buildAgentStartGuide(runsRoot) {
778
805
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
779
- return `# Agent Start Here
780
-
781
- Discovery revision: \`${metadata.discoveryRevision}\`
782
- Server version: \`${metadata.serverVersion}\`
783
- Runs root: \`${runsRoot}\`
784
-
785
- Use Martin Loop as the local governor before you spend agent tokens or retry a failed coding loop.
786
-
787
- ## Cheap Default Flow
788
-
789
- 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\` first. It is the smallest "what should I do now?" payload.
790
- 2. If no runs exist, call \`martin_doctor\`, then \`martin_preflight\`.
791
- 3. If a run exists, read \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\` before reading full run JSON.
792
- 4. If the verifier failed, use prompt \`martin_debug_failed_run\` or \`martin_triage\`.
793
- 5. If you need a shareable receipt, read \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`.
794
-
795
- ## Install Profiles
796
-
797
- - \`minimal\` (default): doctor, preflight, list, triage, dossier. Good for low tool bloat.
798
- - \`diagnostic\`: read-only inspection tools for debugging without execution.
799
- - \`full-local\`: all local tools, including \`martin_run\`.
800
- - \`github-review\`: review-oriented local profile for PR drafting and reviewer evidence.
801
- - \`starter\` and \`full\`: compatibility aliases.
802
-
803
- ## Copy-Paste Agent Rule
804
-
805
- Before running or retrying an autonomous coding task, call Martin. Prefer compact resources first, then full dossiers only when the compact receipt says more evidence is needed. Never claim success unless Martin shows verifier-backed completion or a clear blocked reason.
806
+ return `# Agent Start Here
807
+
808
+ Discovery revision: \`${metadata.discoveryRevision}\`
809
+ Server version: \`${metadata.serverVersion}\`
810
+ Runs root: \`${runsRoot}\`
811
+
812
+ Use Martin Loop as the local governor before you spend agent tokens or retry a failed coding loop.
813
+
814
+ ## Cheap Default Flow
815
+
816
+ 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\` first. It is the smallest "what should I do now?" payload.
817
+ 2. If no runs exist, call \`martin_doctor\`, then \`martin_preflight\`.
818
+ 3. If a run exists, read \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\` before reading full run JSON.
819
+ 4. If the verifier failed, use prompt \`martin_debug_failed_run\` or \`martin_triage\`.
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.
821
+
822
+ ## Install Profiles
823
+
824
+ - \`minimal\` (default): doctor, preflight, list, triage, dossier. Good for low tool bloat.
825
+ - \`diagnostic\`: read-only inspection tools for debugging without execution.
826
+ - \`full-local\`: all local tools, including \`martin_run\`.
827
+ - \`github-review\`: review-oriented local profile for PR drafting and reviewer evidence.
828
+ - \`starter\` and \`full\`: compatibility aliases.
829
+
830
+ ## Copy-Paste Agent Rule
831
+
832
+ Before running or retrying an autonomous coding task, call Martin. Prefer compact resources first, then full dossiers only when the compact receipt says more evidence is needed. Never claim success unless Martin shows verifier-backed completion or a clear blocked reason.
806
833
  `;
807
834
  }
808
835
  function buildCommandMapGuide(runsRoot) {
809
836
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
810
- return `# Martin Command Map
811
-
812
- Discovery revision: \`${metadata.discoveryRevision}\`
813
- Server version: \`${metadata.serverVersion}\`
814
- Runs root: \`${runsRoot}\`
815
-
816
- Use this guide when an IDE or agent needs to know which Martin surface to call next.
817
-
818
- ## Default Governed Sequence
819
-
820
- 1. \`martin_doctor\` — confirm environment and visibility.
821
- 2. \`martin_plan\` — propose the bounded approach without spending a run.
822
- 3. \`martin_preflight\` — turn the plan into an explicit contract.
823
- 4. \`martin_run\` — execute only after the contract is safe.
824
- 5. \`martin_dossier\` — inspect what happened and what Martin prevented.
825
- 6. \`martin_eval\` — convert the result into review posture when needed.
826
-
827
- ## When To Use Which Surface
828
-
829
- - Need the smallest next action: \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`
830
- - Need a quick receipt: \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`
831
- - Need a shareable proof object: \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`
832
- - Need a full run review: \`martin_dossier\`
833
- - Need to decide whether to retry: \`martin_triage_runs\`
834
- - Need IDE setup guidance: \`${MARTIN_STATIC_RESOURCE_URIS.ideOnboardingGuide}\`
837
+ return `# Martin Command Map
838
+
839
+ Discovery revision: \`${metadata.discoveryRevision}\`
840
+ Server version: \`${metadata.serverVersion}\`
841
+ Runs root: \`${runsRoot}\`
842
+
843
+ Use this guide when an IDE or agent needs to know which Martin surface to call next.
844
+
845
+ ## Default Governed Sequence
846
+
847
+ 1. \`martin_doctor\` — confirm environment and visibility.
848
+ 2. \`martin_plan\` — propose the bounded approach without spending a run.
849
+ 3. \`martin_preflight\` — turn the plan into an explicit contract.
850
+ 4. \`martin_run\` — execute only after the contract is safe.
851
+ 5. \`martin_dossier\` — inspect what happened and what Martin prevented.
852
+ 6. \`martin_eval\` — convert the result into review posture when needed.
853
+
854
+ ## When To Use Which Surface
855
+
856
+ - Need the smallest next action: \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`
857
+ - Need a quick receipt: \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`
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}\`
860
+ - Need a full run review: \`martin_dossier\`
861
+ - Need to decide whether to retry: \`martin_triage_runs\`
862
+ - Need IDE setup guidance: \`${MARTIN_STATIC_RESOURCE_URIS.ideOnboardingGuide}\`
835
863
  `;
836
864
  }
837
865
  function buildIdeOnboardingGuide(runsRoot) {
838
866
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
839
- return `# Martin IDE Onboarding
840
-
841
- Discovery revision: \`${metadata.discoveryRevision}\`
842
- Server version: \`${metadata.serverVersion}\`
843
- Runs root: \`${runsRoot}\`
844
-
845
- Use this guide after the MCP server is installed so the host naturally uses MartinLoop during real work.
846
-
847
- ## IDE Default Flow
848
-
849
- 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.agentStartGuide}\`
850
- 2. Read \`${MARTIN_STATIC_RESOURCE_URIS.operatingRulesGuide}\`
851
- 3. Use prompt \`martin_start\` or \`martin_governed_coding_kickoff\`
852
- 4. Call \`martin_doctor\`
853
- 5. Call \`martin_plan\`
854
- 6. Call \`martin_preflight\`
855
- 7. Only then call \`martin_run\`
856
-
857
- ## Goal
858
-
859
- MartinLoop should become the normal path for coding work in the host, not a manual extra step the human has to remember.
867
+ return `# Martin IDE Onboarding
868
+
869
+ Discovery revision: \`${metadata.discoveryRevision}\`
870
+ Server version: \`${metadata.serverVersion}\`
871
+ Runs root: \`${runsRoot}\`
872
+
873
+ Use this guide after the MCP server is installed so the host naturally uses MartinLoop during real work.
874
+
875
+ ## IDE Default Flow
876
+
877
+ 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.agentStartGuide}\`
878
+ 2. Read \`${MARTIN_STATIC_RESOURCE_URIS.operatingRulesGuide}\`
879
+ 3. Use prompt \`martin_start\` or \`martin_governed_coding_kickoff\`
880
+ 4. Call \`martin_doctor\`
881
+ 5. Call \`martin_plan\`
882
+ 6. Call \`martin_preflight\`
883
+ 7. Only then call \`martin_run\`
884
+
885
+ ## Goal
886
+
887
+ MartinLoop should become the normal path for coding work in the host, not a manual extra step the human has to remember.
860
888
  `;
861
889
  }
862
890
  function buildOperatingRulesGuide(runsRoot) {
863
891
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
864
- return `# Martin Operating Rules
865
-
866
- Discovery revision: \`${metadata.discoveryRevision}\`
867
- Server version: \`${metadata.serverVersion}\`
868
- Runs root: \`${runsRoot}\`
869
-
870
- Use these rules inside the IDE or MCP host as the default MartinLoop operating posture.
871
-
872
- ## Required Sequence Before Real Work
873
-
874
- 1. \`martin_doctor\`
875
- 2. \`martin_plan\`
876
- 3. \`martin_preflight\`
877
- 4. \`martin_run\`
878
- 5. \`martin_dossier\`
879
-
880
- ## Enforcement Rule
881
-
882
- Do not execute real coding work through MartinLoop until doctor and preflight have both been used for the current task.
883
-
884
- ## Completion Rule
885
-
886
- Do not claim success until MartinLoop shows verifier-backed completion or an explicit blocked reason backed by evidence.
892
+ return `# Martin Operating Rules
893
+
894
+ Discovery revision: \`${metadata.discoveryRevision}\`
895
+ Server version: \`${metadata.serverVersion}\`
896
+ Runs root: \`${runsRoot}\`
897
+
898
+ Use these rules inside the IDE or MCP host as the default MartinLoop operating posture.
899
+
900
+ ## Required Sequence Before Real Work
901
+
902
+ 1. \`martin_doctor\`
903
+ 2. \`martin_plan\`
904
+ 3. \`martin_preflight\`
905
+ 4. \`martin_run\`
906
+ 5. \`martin_dossier\`
907
+
908
+ ## Enforcement Rule
909
+
910
+ Do not execute real coding work through MartinLoop until doctor and preflight have both been used for the current task.
911
+
912
+ ## Completion Rule
913
+
914
+ Do not claim success until MartinLoop shows verifier-backed completion or an explicit blocked reason backed by evidence.
887
915
  `;
888
916
  }
889
917
  function buildPublishReadinessGuide(runsRoot) {
890
918
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
891
- return `# Martin MCP Publish Readiness
892
-
893
- Discovery revision: \`${metadata.discoveryRevision}\`
894
- Server version: \`${metadata.serverVersion}\`
895
- Runs root: \`${runsRoot}\`
896
-
897
- Use this guide when reviewing whether the public MCP package is ready to publish, promote, or hand off for registry submission.
898
-
899
- ## Review Areas
900
-
901
- 1. Environment health: confirm \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\` shows a sane working directory, runs root, and engine availability for the target mode.
902
- 2. Discovery surface: verify tools, prompts, static resources, and resource templates are all discoverable and named consistently.
903
- 3. Run evidence: inspect \`${MARTIN_STATIC_RESOURCE_URIS.recentRuns}\` and, when relevant, \`martin://runs/{loopId}/verification\` to confirm verification outcomes are explainable from persisted data.
904
- 4. Packaging lane: run the MCP package test, build, and smoke-pack commands before calling the package publish-ready.
905
- 5. Findings-first reporting: call out missing schema, integration gaps, triage-critical runs, and verification blockers before summarizing strengths.
906
-
907
- ## Evidence Expectations
908
-
909
- - Prefer concrete run IDs, attempt indices, and verification summaries over vague statements.
910
- - Distinguish local package validation from live registry readiness.
911
- - 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.
919
+ return `# Martin MCP Publish Readiness
920
+
921
+ Discovery revision: \`${metadata.discoveryRevision}\`
922
+ Server version: \`${metadata.serverVersion}\`
923
+ Runs root: \`${runsRoot}\`
924
+
925
+ Use this guide when reviewing whether the public MCP package is ready to publish, promote, or hand off for registry submission.
926
+
927
+ ## Review Areas
928
+
929
+ 1. Environment health: confirm \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\` shows a sane working directory, runs root, and engine availability for the target mode.
930
+ 2. Discovery surface: verify tools, prompts, static resources, and resource templates are all discoverable and named consistently.
931
+ 3. Run evidence: inspect \`${MARTIN_STATIC_RESOURCE_URIS.recentRuns}\` and, when relevant, \`martin://runs/{loopId}/verification\` to confirm verification outcomes are explainable from persisted data.
932
+ 4. Packaging lane: run the MCP package test, build, and smoke-pack commands before calling the package publish-ready.
933
+ 5. Findings-first reporting: call out missing schema, integration gaps, triage-critical runs, and verification blockers before summarizing strengths.
934
+
935
+ ## Evidence Expectations
936
+
937
+ - Prefer concrete run IDs, attempt indices, and verification summaries over vague statements.
938
+ - Distinguish local package validation from live registry readiness.
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.
912
940
  `;
913
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
+ }
914
968
  function withDiscoveryMetadata(value, runsRoot) {
915
969
  return {
916
970
  metadata: {
@@ -1,4 +1,4 @@
1
- type ToolName = "martin_run" | "martin_inspect" | "martin_status" | "martin_doctor" | "martin_plan" | "martin_preflight" | "martin_estimate" | "martin_logs" | "martin_cancel" | "martin_pause" | "martin_continue" | "martin_list_runs" | "martin_triage_runs" | "martin_get_run" | "martin_get_attempt" | "martin_get_verification_results" | "martin_run_dossier" | "martin_dossier" | "martin_eval" | "martin_pr_summary" | "martin_create_pr" | "martin_review_pr";
1
+ type ToolName = "martin_run" | "martin_inspect" | "martin_status" | "martin_doctor" | "martin_estimate" | "martin_plan" | "martin_preflight" | "martin_logs" | "martin_cancel" | "martin_pause" | "martin_continue" | "martin_list_runs" | "martin_triage_runs" | "martin_get_run" | "martin_get_attempt" | "martin_get_verification_results" | "martin_run_dossier" | "martin_dossier" | "martin_eval" | "martin_pr_summary" | "martin_create_pr" | "martin_review_pr";
2
2
  export { sanitizeToolErrorMessage } from "./tools/tool-errors.js";
3
3
  export declare function validateToolInput(name: ToolName, args: unknown): unknown;
4
4
  export declare function resolveSafeRepoRoot(repoRoot?: string, workspaceRoot?: string): string;