@martinloop/mcp 0.5.3 → 0.5.6

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 (65) hide show
  1. package/README.md +175 -175
  2. package/dist/arcade/capabilities.d.ts +36 -0
  3. package/dist/arcade/capabilities.js +37 -0
  4. package/dist/arcade/resource.d.ts +31 -0
  5. package/dist/arcade/resource.js +52 -0
  6. package/dist/arcade/status.d.ts +23 -0
  7. package/dist/arcade/status.js +25 -0
  8. package/dist/package-version.d.ts +1 -1
  9. package/dist/package-version.js +3 -3
  10. package/dist/resources.js +147 -147
  11. package/dist/server-validation.js +2 -0
  12. package/dist/server.js +79 -35
  13. package/dist/tools/run-loop.d.ts +2 -2
  14. package/dist/tools/run-loop.js +26 -6
  15. package/dist/tools/tool-response.d.ts +9 -1
  16. package/dist/tools/tool-response.js +7 -5
  17. package/dist/tools/tool-support.js +62 -271
  18. package/dist/vendor/adapters/claude-cli.d.ts +9 -0
  19. package/dist/vendor/adapters/claude-cli.js +21 -3
  20. package/dist/vendor/adapters/cli-bridge.js +7 -1
  21. package/dist/vendor/adapters/codex-capabilities.d.ts +12 -3
  22. package/dist/vendor/adapters/codex-capabilities.js +46 -18
  23. package/dist/vendor/adapters/codex-cli.d.ts +2 -1
  24. package/dist/vendor/adapters/codex-cli.js +12 -2
  25. package/dist/vendor/adapters/codex-host.d.ts +4 -1
  26. package/dist/vendor/adapters/codex-host.js +34 -16
  27. package/dist/vendor/adapters/codex-launcher.d.ts +1 -1
  28. package/dist/vendor/adapters/codex-launcher.js +1 -1
  29. package/dist/vendor/adapters/index.d.ts +3 -1
  30. package/dist/vendor/adapters/index.js +2 -0
  31. package/dist/vendor/adapters/openai-compatible.js +12 -9
  32. package/dist/vendor/adapters/stub-agent-cli.d.ts +9 -0
  33. package/dist/vendor/adapters/stub-agent-cli.js +43 -0
  34. package/dist/vendor/adapters/stub-direct-provider.d.ts +8 -0
  35. package/dist/vendor/adapters/stub-direct-provider.js +16 -0
  36. package/dist/vendor/contracts/agent-execution.d.ts +9 -0
  37. package/dist/vendor/contracts/agent-execution.js +14 -0
  38. package/dist/vendor/contracts/index.d.ts +9 -0
  39. package/dist/vendor/contracts/index.js +1 -0
  40. package/dist/vendor/core/grounding.js +42 -7
  41. package/dist/vendor/core/index.d.ts +5 -2
  42. package/dist/vendor/core/index.js +20 -66
  43. package/dist/vendor/core/policy.d.ts +1 -0
  44. package/dist/vendor/core/policy.js +8 -0
  45. package/dist/vendor/core/rollback.d.ts +3 -0
  46. package/dist/vendor/core/rollback.js +33 -20
  47. package/dist/vendor/core/verified-handoff.js +25 -6
  48. package/dist/vendor/presentation/governed-plan.d.ts +33 -0
  49. package/dist/vendor/presentation/governed-plan.js +146 -0
  50. package/dist/vendor/presentation/index.d.ts +7 -0
  51. package/dist/vendor/presentation/index.js +7 -0
  52. package/dist/vendor/presentation/motion.d.ts +12 -0
  53. package/dist/vendor/presentation/motion.js +123 -0
  54. package/dist/vendor/presentation/status.d.ts +8 -0
  55. package/dist/vendor/presentation/status.js +11 -0
  56. package/dist/vendor/presentation/table.d.ts +11 -0
  57. package/dist/vendor/presentation/table.js +47 -0
  58. package/dist/vendor/presentation/text.d.ts +6 -0
  59. package/dist/vendor/presentation/text.js +30 -0
  60. package/dist/vendor/presentation/theme.d.ts +31 -0
  61. package/dist/vendor/presentation/theme.js +82 -0
  62. package/dist/vendor/presentation/verified-handoff.d.ts +15 -0
  63. package/dist/vendor/presentation/verified-handoff.js +148 -0
  64. package/package.json +81 -80
  65. package/server.json +21 -21
package/dist/resources.js CHANGED
@@ -760,173 +760,173 @@ function inferAgentNextStep(loop, verification) {
760
760
  }
761
761
  function buildMcpUsageGuide(runsRoot) {
762
762
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
763
- return `# Martin Loop MCP Usage
764
-
765
- Discovery revision: \`${metadata.discoveryRevision}\`
766
- Server version: \`${metadata.serverVersion}\`
767
- Runs root: \`${runsRoot}\`
768
-
769
- 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.
770
-
771
- ## Recommended Flow
772
-
773
- 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\` or call \`martin_doctor\` to confirm the environment and run-store visibility.
774
- 2. Use the \`martin_governed_coding_kickoff\` prompt to frame a governed coding request.
775
- 3. Call \`martin_preflight\` before \`martin_run\` when the task or safety envelope is non-trivial.
776
- 4. After execution, inspect \`${MARTIN_STATIC_RESOURCE_URIS.recentRuns}\`, \`martin://runs/{loopId}\`, and \`martin://runs/{loopId}/verification\`.
777
- 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.
778
- 6. Read \`${MARTIN_STATIC_RESOURCE_URIS.triage}\` or call \`martin_triage_runs\` to prioritize which run needs attention first.
779
- 7. Use \`martin_debug_failed_run\` when a loop exits failed, budget-bound, or escalated.
780
-
781
- ## Current Martin MCP Surface
782
-
783
- - 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\`
784
- - 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}\`
785
- - Resource templates: \`martin://runs/{loopId}\`, \`martin://runs/{loopId}/attempts/{attemptIndex}\`, \`martin://runs/{loopId}/verification\`
786
- - 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\`
787
-
788
- ## Notes
789
-
790
- - Discovery helpers read the existing Martin run-store; they do not create new schema.
791
- - Verification history is derived from persisted \`verification.completed\` evidence in loop records and ledgers.
792
- - Attempt inspection stays aligned with the same loop selectors used by \`martin_status\` and \`martin_inspect\`.
763
+ return `# Martin Loop MCP Usage
764
+
765
+ Discovery revision: \`${metadata.discoveryRevision}\`
766
+ Server version: \`${metadata.serverVersion}\`
767
+ Runs root: \`${runsRoot}\`
768
+
769
+ 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.
770
+
771
+ ## Recommended Flow
772
+
773
+ 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\` or call \`martin_doctor\` to confirm the environment and run-store visibility.
774
+ 2. Use the \`martin_governed_coding_kickoff\` prompt to frame a governed coding request.
775
+ 3. Call \`martin_preflight\` before \`martin_run\` when the task or safety envelope is non-trivial.
776
+ 4. After execution, inspect \`${MARTIN_STATIC_RESOURCE_URIS.recentRuns}\`, \`martin://runs/{loopId}\`, and \`martin://runs/{loopId}/verification\`.
777
+ 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.
778
+ 6. Read \`${MARTIN_STATIC_RESOURCE_URIS.triage}\` or call \`martin_triage_runs\` to prioritize which run needs attention first.
779
+ 7. Use \`martin_debug_failed_run\` when a loop exits failed, budget-bound, or escalated.
780
+
781
+ ## Current Martin MCP Surface
782
+
783
+ - 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\`
784
+ - 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}\`
785
+ - Resource templates: \`martin://runs/{loopId}\`, \`martin://runs/{loopId}/attempts/{attemptIndex}\`, \`martin://runs/{loopId}/verification\`
786
+ - 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\`
787
+
788
+ ## Notes
789
+
790
+ - Discovery helpers read the existing Martin run-store; they do not create new schema.
791
+ - Verification history is derived from persisted \`verification.completed\` evidence in loop records and ledgers.
792
+ - Attempt inspection stays aligned with the same loop selectors used by \`martin_status\` and \`martin_inspect\`.
793
793
  `;
794
794
  }
795
795
  function buildAgentStartGuide(runsRoot) {
796
796
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
797
- return `# Agent Start Here
798
-
799
- Discovery revision: \`${metadata.discoveryRevision}\`
800
- Server version: \`${metadata.serverVersion}\`
801
- Runs root: \`${runsRoot}\`
802
-
803
- Use Martin Loop as the local governor before you spend agent tokens or retry a failed coding loop.
804
-
805
- ## Cheap Default Flow
806
-
807
- 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\` first. It is the smallest "what should I do now?" payload.
808
- 2. If no runs exist, call \`martin_doctor\`, then \`martin_preflight\`.
809
- 3. If a run exists, read \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\` before reading full run JSON.
810
- 4. If the verifier failed, use prompt \`martin_debug_failed_run\` or \`martin_triage\`.
811
- 5. If you need a shareable receipt, read \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`.
812
-
813
- ## Install Profiles
814
-
815
- - \`minimal\` (default): doctor, preflight, list, triage, dossier. Good for low tool bloat.
816
- - \`diagnostic\`: read-only inspection tools for debugging without execution.
817
- - \`full-local\`: all local tools, including \`martin_run\`.
818
- - \`github-review\`: review-oriented local profile for PR drafting and reviewer evidence.
819
- - \`starter\` and \`full\`: compatibility aliases.
820
-
821
- ## Copy-Paste Agent Rule
822
-
823
- 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.
797
+ return `# Agent Start Here
798
+
799
+ Discovery revision: \`${metadata.discoveryRevision}\`
800
+ Server version: \`${metadata.serverVersion}\`
801
+ Runs root: \`${runsRoot}\`
802
+
803
+ Use Martin Loop as the local governor before you spend agent tokens or retry a failed coding loop.
804
+
805
+ ## Cheap Default Flow
806
+
807
+ 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\` first. It is the smallest "what should I do now?" payload.
808
+ 2. If no runs exist, call \`martin_doctor\`, then \`martin_preflight\`.
809
+ 3. If a run exists, read \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\` before reading full run JSON.
810
+ 4. If the verifier failed, use prompt \`martin_debug_failed_run\` or \`martin_triage\`.
811
+ 5. If you need a shareable receipt, read \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`.
812
+
813
+ ## Install Profiles
814
+
815
+ - \`minimal\` (default): doctor, preflight, list, triage, dossier. Good for low tool bloat.
816
+ - \`diagnostic\`: read-only inspection tools for debugging without execution.
817
+ - \`full-local\`: all local tools, including \`martin_run\`.
818
+ - \`github-review\`: review-oriented local profile for PR drafting and reviewer evidence.
819
+ - \`starter\` and \`full\`: compatibility aliases.
820
+
821
+ ## Copy-Paste Agent Rule
822
+
823
+ 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.
824
824
  `;
825
825
  }
826
826
  function buildCommandMapGuide(runsRoot) {
827
827
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
828
- return `# Martin Command Map
829
-
830
- Discovery revision: \`${metadata.discoveryRevision}\`
831
- Server version: \`${metadata.serverVersion}\`
832
- Runs root: \`${runsRoot}\`
833
-
834
- Use this guide when an IDE or agent needs to know which Martin surface to call next.
835
-
836
- ## Default Governed Sequence
837
-
838
- 1. \`martin_doctor\` — confirm environment and visibility.
839
- 2. \`martin_plan\` — propose the bounded approach without spending a run.
840
- 3. \`martin_preflight\` — turn the plan into an explicit contract.
841
- 4. \`martin_run\` — execute only after the contract is safe.
842
- 5. \`martin_dossier\` — inspect what happened and what Martin prevented.
843
- 6. \`martin_eval\` — convert the result into review posture when needed.
844
-
845
- ## When To Use Which Surface
846
-
847
- - Need the smallest next action: \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`
848
- - Need a quick receipt: \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`
849
- - Need a shareable proof object: \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`
850
- - Need a full run review: \`martin_dossier\`
851
- - Need to decide whether to retry: \`martin_triage_runs\`
852
- - Need IDE setup guidance: \`${MARTIN_STATIC_RESOURCE_URIS.ideOnboardingGuide}\`
828
+ return `# Martin Command Map
829
+
830
+ Discovery revision: \`${metadata.discoveryRevision}\`
831
+ Server version: \`${metadata.serverVersion}\`
832
+ Runs root: \`${runsRoot}\`
833
+
834
+ Use this guide when an IDE or agent needs to know which Martin surface to call next.
835
+
836
+ ## Default Governed Sequence
837
+
838
+ 1. \`martin_doctor\` — confirm environment and visibility.
839
+ 2. \`martin_plan\` — propose the bounded approach without spending a run.
840
+ 3. \`martin_preflight\` — turn the plan into an explicit contract.
841
+ 4. \`martin_run\` — execute only after the contract is safe.
842
+ 5. \`martin_dossier\` — inspect what happened and what Martin prevented.
843
+ 6. \`martin_eval\` — convert the result into review posture when needed.
844
+
845
+ ## When To Use Which Surface
846
+
847
+ - Need the smallest next action: \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`
848
+ - Need a quick receipt: \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`
849
+ - Need a shareable proof object: \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`
850
+ - Need a full run review: \`martin_dossier\`
851
+ - Need to decide whether to retry: \`martin_triage_runs\`
852
+ - Need IDE setup guidance: \`${MARTIN_STATIC_RESOURCE_URIS.ideOnboardingGuide}\`
853
853
  `;
854
854
  }
855
855
  function buildIdeOnboardingGuide(runsRoot) {
856
856
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
857
- return `# Martin IDE Onboarding
858
-
859
- Discovery revision: \`${metadata.discoveryRevision}\`
860
- Server version: \`${metadata.serverVersion}\`
861
- Runs root: \`${runsRoot}\`
862
-
863
- Use this guide after the MCP server is installed so the host naturally uses MartinLoop during real work.
864
-
865
- ## IDE Default Flow
866
-
867
- 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.agentStartGuide}\`
868
- 2. Read \`${MARTIN_STATIC_RESOURCE_URIS.operatingRulesGuide}\`
869
- 3. Use prompt \`martin_start\` or \`martin_governed_coding_kickoff\`
870
- 4. Call \`martin_doctor\`
871
- 5. Call \`martin_plan\`
872
- 6. Call \`martin_preflight\`
873
- 7. Only then call \`martin_run\`
874
-
875
- ## Goal
876
-
877
- MartinLoop should become the normal path for coding work in the host, not a manual extra step the human has to remember.
857
+ return `# Martin IDE Onboarding
858
+
859
+ Discovery revision: \`${metadata.discoveryRevision}\`
860
+ Server version: \`${metadata.serverVersion}\`
861
+ Runs root: \`${runsRoot}\`
862
+
863
+ Use this guide after the MCP server is installed so the host naturally uses MartinLoop during real work.
864
+
865
+ ## IDE Default Flow
866
+
867
+ 1. Read \`${MARTIN_STATIC_RESOURCE_URIS.agentStartGuide}\`
868
+ 2. Read \`${MARTIN_STATIC_RESOURCE_URIS.operatingRulesGuide}\`
869
+ 3. Use prompt \`martin_start\` or \`martin_governed_coding_kickoff\`
870
+ 4. Call \`martin_doctor\`
871
+ 5. Call \`martin_plan\`
872
+ 6. Call \`martin_preflight\`
873
+ 7. Only then call \`martin_run\`
874
+
875
+ ## Goal
876
+
877
+ MartinLoop should become the normal path for coding work in the host, not a manual extra step the human has to remember.
878
878
  `;
879
879
  }
880
880
  function buildOperatingRulesGuide(runsRoot) {
881
881
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
882
- return `# Martin Operating Rules
883
-
884
- Discovery revision: \`${metadata.discoveryRevision}\`
885
- Server version: \`${metadata.serverVersion}\`
886
- Runs root: \`${runsRoot}\`
887
-
888
- Use these rules inside the IDE or MCP host as the default MartinLoop operating posture.
889
-
890
- ## Required Sequence Before Real Work
891
-
892
- 1. \`martin_doctor\`
893
- 2. \`martin_plan\`
894
- 3. \`martin_preflight\`
895
- 4. \`martin_run\`
896
- 5. \`martin_dossier\`
897
-
898
- ## Enforcement Rule
899
-
900
- Do not execute real coding work through MartinLoop until doctor and preflight have both been used for the current task.
901
-
902
- ## Completion Rule
903
-
904
- Do not claim success until MartinLoop shows verifier-backed completion or an explicit blocked reason backed by evidence.
882
+ return `# Martin Operating Rules
883
+
884
+ Discovery revision: \`${metadata.discoveryRevision}\`
885
+ Server version: \`${metadata.serverVersion}\`
886
+ Runs root: \`${runsRoot}\`
887
+
888
+ Use these rules inside the IDE or MCP host as the default MartinLoop operating posture.
889
+
890
+ ## Required Sequence Before Real Work
891
+
892
+ 1. \`martin_doctor\`
893
+ 2. \`martin_plan\`
894
+ 3. \`martin_preflight\`
895
+ 4. \`martin_run\`
896
+ 5. \`martin_dossier\`
897
+
898
+ ## Enforcement Rule
899
+
900
+ Do not execute real coding work through MartinLoop until doctor and preflight have both been used for the current task.
901
+
902
+ ## Completion Rule
903
+
904
+ Do not claim success until MartinLoop shows verifier-backed completion or an explicit blocked reason backed by evidence.
905
905
  `;
906
906
  }
907
907
  function buildPublishReadinessGuide(runsRoot) {
908
908
  const metadata = buildMartinDiscoveryMetadata(MARTIN_MCP_PACKAGE_VERSION);
909
- return `# Martin MCP Publish Readiness
910
-
911
- Discovery revision: \`${metadata.discoveryRevision}\`
912
- Server version: \`${metadata.serverVersion}\`
913
- Runs root: \`${runsRoot}\`
914
-
915
- Use this guide when reviewing whether the public MCP package is ready to publish, promote, or hand off for registry submission.
916
-
917
- ## Review Areas
918
-
919
- 1. Environment health: confirm \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\` shows a sane working directory, runs root, and engine availability for the target mode.
920
- 2. Discovery surface: verify tools, prompts, static resources, and resource templates are all discoverable and named consistently.
921
- 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.
922
- 4. Packaging lane: run the MCP package test, build, and smoke-pack commands before calling the package publish-ready.
923
- 5. Findings-first reporting: call out missing schema, integration gaps, triage-critical runs, and verification blockers before summarizing strengths.
924
-
925
- ## Evidence Expectations
926
-
927
- - Prefer concrete run IDs, attempt indices, and verification summaries over vague statements.
928
- - Distinguish local package validation from live registry readiness.
929
- - 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.
909
+ return `# Martin MCP Publish Readiness
910
+
911
+ Discovery revision: \`${metadata.discoveryRevision}\`
912
+ Server version: \`${metadata.serverVersion}\`
913
+ Runs root: \`${runsRoot}\`
914
+
915
+ Use this guide when reviewing whether the public MCP package is ready to publish, promote, or hand off for registry submission.
916
+
917
+ ## Review Areas
918
+
919
+ 1. Environment health: confirm \`${MARTIN_STATIC_RESOURCE_URIS.serverHealth}\` shows a sane working directory, runs root, and engine availability for the target mode.
920
+ 2. Discovery surface: verify tools, prompts, static resources, and resource templates are all discoverable and named consistently.
921
+ 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.
922
+ 4. Packaging lane: run the MCP package test, build, and smoke-pack commands before calling the package publish-ready.
923
+ 5. Findings-first reporting: call out missing schema, integration gaps, triage-critical runs, and verification blockers before summarizing strengths.
924
+
925
+ ## Evidence Expectations
926
+
927
+ - Prefer concrete run IDs, attempt indices, and verification summaries over vague statements.
928
+ - Distinguish local package validation from live registry readiness.
929
+ - 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.
930
930
  `;
931
931
  }
932
932
  function withDiscoveryMetadata(value, runsRoot) {
@@ -151,6 +151,7 @@ function validateRunInput(args) {
151
151
  "maxIterations",
152
152
  "maxTokens",
153
153
  "verifyTimeoutMs",
154
+ "providerExecutionTimeoutMs",
154
155
  "maxMinutes",
155
156
  "maxFilesChanged",
156
157
  "maxCommands",
@@ -180,6 +181,7 @@ function validateRunInput(args) {
180
181
  ...optionalPositiveInteger(record.maxIterations, "maxIterations"),
181
182
  ...optionalPositiveInteger(record.maxTokens, "maxTokens"),
182
183
  ...optionalPositiveInteger(record.verifyTimeoutMs, "verifyTimeoutMs"),
184
+ ...optionalPositiveInteger(record.providerExecutionTimeoutMs, "providerExecutionTimeoutMs"),
183
185
  ...optionalPositiveInteger(record.maxMinutes, "maxMinutes"),
184
186
  ...optionalPositiveInteger(record.maxFilesChanged, "maxFilesChanged"),
185
187
  ...optionalPositiveInteger(record.maxCommands, "maxCommands"),
package/dist/server.js CHANGED
@@ -26,6 +26,9 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
26
26
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
27
27
  import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";
28
28
  import { MARTIN_MCP_PACKAGE_VERSION } from "./package-version.js";
29
+ import { MARTIN_ARCADE_FALLBACK_TEXT, MARTIN_ARCADE_MIME_TYPE, MARTIN_ARCADE_RESOURCE_URI, MARTIN_ARCADE_UI_EXTENSION_ID, buildArcadeToolDefinitions, supportsMartinArcadeApp } from "./arcade/capabilities.js";
30
+ import { listArcadeResources, readArcadeResource } from "./arcade/resource.js";
31
+ import { readArcadeStatus } from "./arcade/status.js";
29
32
  import { getMartinPrompt, listMartinPrompts } from "./prompts.js";
30
33
  import { listMartinResources, listMartinResourceTemplates, readMartinResource } from "./resources.js";
31
34
  import { martinDoctorTool } from "./tools/doctor.js";
@@ -47,6 +50,7 @@ import { runLoopTool } from "./tools/run-loop.js";
47
50
  import { MARTIN_ENGINE_VALUES } from "./tools/tool-support.js";
48
51
  import { classifyRoute } from "./vendor/core/index.js";
49
52
  import { createToolErrorResult, createToolSuccessResult } from "./tools/tool-response.js";
53
+ import { buildGovernedPlanStages, renderGovernedRunPlanMarkdown, renderVerifiedHandoffMarkdown } from "./vendor/presentation/index.js";
50
54
  import { MartinToolError, toToolFailure } from "./tools/tool-errors.js";
51
55
  import { normalizeLoopBudget } from "./tools/workflow-governance.js";
52
56
  import { resolveSafeRepoRoot, sanitizeToolErrorMessage, validateToolInput } from "./server-validation.js";
@@ -55,15 +59,6 @@ const stringArraySchema = {
55
59
  type: "array",
56
60
  items: { type: "string" }
57
61
  };
58
- function describeCostProvenance(provenance) {
59
- if (provenance === "actual")
60
- return "provider-settled actual";
61
- if (provenance === "calculated")
62
- return "calculated from observed usage";
63
- if (provenance === "estimated")
64
- return "estimated";
65
- return "unavailable";
66
- }
67
62
  const loopPreviewSchema = {
68
63
  type: "object",
69
64
  additionalProperties: true,
@@ -77,10 +72,6 @@ const loopPreviewSchema = {
77
72
  updatedAt: { type: "string" },
78
73
  attempts: { type: "integer" },
79
74
  costUsd: { type: "number" },
80
- costProvenance: {
81
- type: "string",
82
- enum: ["actual", "calculated", "estimated", "unavailable"]
83
- },
84
75
  avoidedUsd: { type: "number" },
85
76
  pressure: { type: "string" },
86
77
  shouldStop: { type: "boolean" },
@@ -100,7 +91,6 @@ const loopPreviewSchema = {
100
91
  "lifecycleState",
101
92
  "attempts",
102
93
  "costUsd",
103
- "costProvenance",
104
94
  "avoidedUsd",
105
95
  "pressure",
106
96
  "shouldStop",
@@ -266,10 +256,6 @@ const runOutputSchema = {
266
256
  reason: { type: "string" },
267
257
  attempts: { type: "integer" },
268
258
  costUsd: { type: "number" },
269
- costProvenance: {
270
- type: "string",
271
- enum: ["actual", "calculated", "estimated", "unavailable"]
272
- },
273
259
  verificationPassed: { type: "boolean" },
274
260
  loopId: { type: "string" },
275
261
  pressure: { type: "string" },
@@ -301,7 +287,6 @@ const runOutputSchema = {
301
287
  "reason",
302
288
  "attempts",
303
289
  "costUsd",
304
- "costProvenance",
305
290
  "verificationPassed",
306
291
  "loopId",
307
292
  "pressure",
@@ -369,10 +354,6 @@ const statusOutputSchema = {
369
354
  lifecycleState: { type: "string" },
370
355
  attempts: { type: "integer" },
371
356
  costUsd: { type: "number" },
372
- costProvenance: {
373
- type: "string",
374
- enum: ["actual", "calculated", "estimated", "unavailable"]
375
- },
376
357
  avoidedUsd: { type: "number" },
377
358
  pressure: { type: "string" },
378
359
  shouldStop: { type: "boolean" },
@@ -396,7 +377,6 @@ const statusOutputSchema = {
396
377
  "lifecycleState",
397
378
  "attempts",
398
379
  "costUsd",
399
- "costProvenance",
400
380
  "avoidedUsd",
401
381
  "pressure",
402
382
  "shouldStop",
@@ -746,7 +726,16 @@ export function createMartinMcpServer(serverInfo) {
746
726
  const server = new Server({
747
727
  name: serverInfo?.name ?? "martin-loop",
748
728
  version: serverInfo?.version ?? MARTIN_MCP_PACKAGE_VERSION
749
- }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
729
+ }, {
730
+ capabilities: {
731
+ tools: {},
732
+ resources: {},
733
+ prompts: {},
734
+ extensions: {
735
+ [MARTIN_ARCADE_UI_EXTENSION_ID]: { mimeTypes: [MARTIN_ARCADE_MIME_TYPE] }
736
+ }
737
+ }
738
+ });
750
739
  server.setRequestHandler(ListToolsRequestSchema, () => ({
751
740
  tools: [
752
741
  {
@@ -793,6 +782,16 @@ export function createMartinMcpServer(serverInfo) {
793
782
  exclusiveMinimum: 0,
794
783
  description: "Maximum total tokens across all attempts."
795
784
  },
785
+ verifyTimeoutMs: {
786
+ type: "integer",
787
+ exclusiveMinimum: 0,
788
+ description: "Hard timeout for each verifier command in milliseconds."
789
+ },
790
+ providerExecutionTimeoutMs: {
791
+ type: "integer",
792
+ exclusiveMinimum: 0,
793
+ description: "Hard timeout for each provider coding process in milliseconds."
794
+ },
796
795
  verificationPlan: {
797
796
  type: "array",
798
797
  items: { type: "string" },
@@ -1458,17 +1457,23 @@ export function createMartinMcpServer(serverInfo) {
1458
1457
  },
1459
1458
  required: ["objective", "engine", "budgetUsd", "selectedMode", "confidence", "expectedCostUsd", "expectedPreworkBurnPct", "reason"]
1460
1459
  }
1461
- }
1460
+ },
1461
+ ...buildArcadeToolDefinitions(server.getClientCapabilities())
1462
1462
  ]
1463
1463
  }));
1464
- server.setRequestHandler(ListResourcesRequestSchema, () => ({
1465
- ...listMartinResources()
1466
- }));
1464
+ server.setRequestHandler(ListResourcesRequestSchema, () => {
1465
+ const listed = listMartinResources();
1466
+ const arcade = listArcadeResources(server.getClientCapabilities());
1467
+ return { resources: [...listed.resources, ...arcade.resources] };
1468
+ });
1467
1469
  server.setRequestHandler(ListResourceTemplatesRequestSchema, () => ({
1468
1470
  ...listMartinResourceTemplates()
1469
1471
  }));
1470
1472
  server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
1471
1473
  try {
1474
+ if (request.params.uri === MARTIN_ARCADE_RESOURCE_URI) {
1475
+ return await readArcadeResource(request.params.uri);
1476
+ }
1472
1477
  return await readMartinResource({ uri: request.params.uri });
1473
1478
  }
1474
1479
  catch (error) {
@@ -1498,6 +1503,29 @@ export function createMartinMcpServer(serverInfo) {
1498
1503
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
1499
1504
  const { name, arguments: args } = request.params;
1500
1505
  try {
1506
+ if (name === "martin_arcade") {
1507
+ const available = supportsMartinArcadeApp(server.getClientCapabilities());
1508
+ return createToolSuccessResult({
1509
+ available,
1510
+ resourceUri: available ? MARTIN_ARCADE_RESOURCE_URI : null
1511
+ }, MARTIN_ARCADE_FALLBACK_TEXT, { human: MARTIN_ARCADE_FALLBACK_TEXT });
1512
+ }
1513
+ if (name === "martin_arcade_status") {
1514
+ const input = args ?? {};
1515
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
1516
+ throw new MartinToolError("invalid_arguments", "Arcade status input must be an object.", {
1517
+ category: "invalid_input"
1518
+ });
1519
+ }
1520
+ const keys = Object.keys(input);
1521
+ if (keys.some((key) => key !== "loopId") || ("loopId" in input && typeof input.loopId !== "string")) {
1522
+ throw new MartinToolError("invalid_arguments", "Arcade status accepts only an optional loopId.", {
1523
+ category: "invalid_input"
1524
+ });
1525
+ }
1526
+ const output = await readArcadeStatus(input);
1527
+ return createToolSuccessResult(output, `MartinLoop Arcade status for ${output.loopId}: ${output.displayOutcome ?? output.lifecycleState}.`);
1528
+ }
1501
1529
  if (name === "martin_run") {
1502
1530
  const input = validateToolInput("martin_run", args);
1503
1531
  const runsRoot = resolveRunsRoot(process.env);
@@ -1533,7 +1561,7 @@ export function createMartinMcpServer(serverInfo) {
1533
1561
  const output = await runLoopTool(input);
1534
1562
  return createToolSuccessResult(output, [
1535
1563
  `Run ${output.loopId} is ${output.status}/${output.lifecycleState}`,
1536
- `after ${output.attempts} attempt(s); recorded cost ${output.costUsd.toFixed(2)} USD (${describeCostProvenance(output.costProvenance)}).`,
1564
+ `after ${output.attempts} attempt(s); spend ${output.costUsd.toFixed(2)} USD.`,
1537
1565
  `Execution mode: ${output.executionMode}; governance claim eligible:`,
1538
1566
  `${output.governanceClaimEligible ? "yes" : "no"}.`
1539
1567
  ].join(" "));
@@ -1541,12 +1569,12 @@ export function createMartinMcpServer(serverInfo) {
1541
1569
  if (name === "martin_inspect") {
1542
1570
  const input = validateToolInput("martin_inspect", args);
1543
1571
  const output = await inspectLoopTool(input);
1544
- return createToolSuccessResult(output, `Inspected ${output.loopCount} run(s) from ${output.source}; total recorded cost ${output.portfolio.totalActualUsd.toFixed(2)} USD.`);
1572
+ return createToolSuccessResult(output, `Inspected ${output.loopCount} run(s) from ${output.source}; total actual spend ${output.portfolio.totalActualUsd.toFixed(2)} USD.`);
1545
1573
  }
1546
1574
  if (name === "martin_status") {
1547
1575
  const input = validateToolInput("martin_status", args);
1548
1576
  const output = await getStatusTool(input);
1549
- return createToolSuccessResult(output, `Loop ${output.loopId} is ${output.status}/${output.lifecycleState}; recorded cost is ${output.costUsd.toFixed(2)} USD (${describeCostProvenance(output.costProvenance)}), and pressure is ${output.pressure} with ${output.remainingBudgetUsd.toFixed(2)} USD remaining.`);
1577
+ return createToolSuccessResult(output, `Loop ${output.loopId} is ${output.status}/${output.lifecycleState}; pressure is ${output.pressure} with ${output.remainingBudgetUsd.toFixed(2)} USD remaining.`);
1550
1578
  }
1551
1579
  if (name === "martin_doctor") {
1552
1580
  const input = validateToolInput("martin_doctor", args);
@@ -1594,7 +1622,23 @@ export function createMartinMcpServer(serverInfo) {
1594
1622
  budget: output.normalized.budget
1595
1623
  }).catch(() => { });
1596
1624
  }
1597
- return createToolSuccessResult(output, output.summary);
1625
+ const prefPlanView = {
1626
+ ready: output.ok,
1627
+ task: output.normalized.objective,
1628
+ engine: output.normalized.engine,
1629
+ mode: output.readiness.liveMode ? "live" : "proof",
1630
+ budget: output.normalized.budget,
1631
+ verifier: output.normalized.verificationPlan,
1632
+ receiptScope: output.receiptScope,
1633
+ policyProfile: output.policy.name,
1634
+ blockingIssues: output.ok ? [] : [output.summary],
1635
+ warnings: output.warnings,
1636
+ stages: []
1637
+ };
1638
+ prefPlanView.stages = buildGovernedPlanStages(prefPlanView);
1639
+ return createToolSuccessResult(output, output.summary, {
1640
+ human: renderGovernedRunPlanMarkdown(prefPlanView)
1641
+ });
1598
1642
  }
1599
1643
  if (name === "martin_logs") {
1600
1644
  const input = validateToolInput("martin_logs", args);
@@ -1644,12 +1688,12 @@ export function createMartinMcpServer(serverInfo) {
1644
1688
  if (name === "martin_run_dossier") {
1645
1689
  const input = validateToolInput("martin_run_dossier", args);
1646
1690
  const output = await martinRunDossierTool(input);
1647
- return createToolSuccessResult(output, `Dossier ready for Martin run ${output.loop.loopId} with ${output.attempts.length} attempt(s).`);
1691
+ return createToolSuccessResult(output, `Dossier ready for Martin run ${output.loop.loopId} with ${output.attempts.length} attempt(s).`, { human: renderVerifiedHandoffMarkdown(output.verifiedHandoff) });
1648
1692
  }
1649
1693
  if (name === "martin_dossier") {
1650
1694
  const input = validateToolInput("martin_dossier", args);
1651
1695
  const output = await martinRunDossierTool(input);
1652
- return createToolSuccessResult(output, `Dossier ready for Martin run ${output.loop.loopId} in ${output.format} format.`);
1696
+ return createToolSuccessResult(output, `Dossier ready for Martin run ${output.loop.loopId} in ${output.format} format.`, { human: renderVerifiedHandoffMarkdown(output.verifiedHandoff) });
1653
1697
  }
1654
1698
  if (name === "martin_eval") {
1655
1699
  const input = validateToolInput("martin_eval", args);
@@ -1,6 +1,6 @@
1
1
  import { type SpawnLike } from "../vendor/adapters/index.js";
2
2
  import { type RunStore } from "../vendor/core/index.js";
3
- import type { CostProvenance, ExecutionMode, LoopBudget, ReceiptScope } from "../vendor/contracts/index.js";
3
+ import type { ExecutionMode, LoopBudget, ReceiptScope } from "../vendor/contracts/index.js";
4
4
  import { buildArtifactSummary, buildVerificationSummary, buildLoopPreview, type MartinEngine } from "./tool-support.js";
5
5
  export interface RunLoopInput {
6
6
  objective: string;
@@ -11,6 +11,7 @@ export interface RunLoopInput {
11
11
  maxIterations?: number;
12
12
  maxTokens?: number;
13
13
  verifyTimeoutMs?: number;
14
+ providerExecutionTimeoutMs?: number;
14
15
  verificationPlan?: string[];
15
16
  allowedPaths?: string[];
16
17
  deniedPaths?: string[];
@@ -23,7 +24,6 @@ export interface RunLoopOutput {
23
24
  reason: string;
24
25
  attempts: number;
25
26
  costUsd: number;
26
- costProvenance: CostProvenance;
27
27
  verificationPassed: boolean;
28
28
  executionMode: ExecutionMode;
29
29
  governanceClaimEligible: boolean;