@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
@@ -0,0 +1,148 @@
1
+ import { renderTable } from "./table.js";
2
+ import { horizontalRule, terminalWidth, truncateVisible } from "./text.js";
3
+ import { bold, paint, } from "./theme.js";
4
+ function outcomeTone(outcome) {
5
+ if (outcome === "VERIFIED") {
6
+ return "success";
7
+ }
8
+ if (outcome === "STOPPED") {
9
+ return "danger";
10
+ }
11
+ return "warning";
12
+ }
13
+ function evidenceTone(status) {
14
+ if (status === "PASSED") {
15
+ return "success";
16
+ }
17
+ if (status === "FAILED" || status === "CONTRADICTED") {
18
+ return "danger";
19
+ }
20
+ return "warning";
21
+ }
22
+ function humanize(value) {
23
+ return value.replaceAll("_", " ").toLowerCase();
24
+ }
25
+ function checkSymbol(status) {
26
+ if (status === "PASSED") {
27
+ return "✓";
28
+ }
29
+ if (status === "FAILED" || status === "CONTRADICTED") {
30
+ return "✕";
31
+ }
32
+ return "•";
33
+ }
34
+ function formatCost(usd, provenance) {
35
+ if (provenance === "unavailable")
36
+ return "unavailable";
37
+ const amount = "$" + usd.toFixed(2);
38
+ if (provenance === "actual")
39
+ return amount + " provider-settled actual";
40
+ if (provenance === "calculated")
41
+ return amount + " calculated from observed usage";
42
+ return amount + " estimated";
43
+ }
44
+ /**
45
+ * Single source of truth for the trust-authority outcome calculation.
46
+ * Both terminal and Markdown renderers call this — never duplicate.
47
+ * Fail-closed: omitting executionMode or governanceClaimEligible downgrades
48
+ * VERIFIED → NEEDS_REVIEW, so legacy handoffs cannot claim full governance.
49
+ */
50
+ function resolveHandoffAuthority(handoff) {
51
+ const executionMode = handoff.executionMode ?? "simulated";
52
+ const governanceClaimEligible = executionMode === "governed" && handoff.governanceClaimEligible === true;
53
+ const effectiveOutcome = handoff.outcome === "VERIFIED" && !governanceClaimEligible
54
+ ? "NEEDS_REVIEW"
55
+ : handoff.outcome;
56
+ return { executionMode, governanceClaimEligible, effectiveOutcome };
57
+ }
58
+ export function renderVerifiedHandoff(handoff, options = {}) {
59
+ const environment = options.environment ?? {};
60
+ const width = terminalWidth(options.width);
61
+ const bounded = (line) => truncateVisible(line, width);
62
+ const { executionMode, governanceClaimEligible, effectiveOutcome } = resolveHandoffAuthority(handoff);
63
+ const outcome = effectiveOutcome.replace("_", " ");
64
+ const checks = handoff.verification.checks.map((check) => ({
65
+ check: check.command,
66
+ status: paint(checkSymbol(check.status) + " " + check.status.replace("_", " "), evidenceTone(check.status), environment),
67
+ }));
68
+ const lines = [
69
+ horizontalRule(width, "━"),
70
+ bold("MARTINLOOP VERIFIED HANDOFF", environment) +
71
+ " — " +
72
+ paint(outcome, outcomeTone(effectiveOutcome), environment),
73
+ horizontalRule(width, "━"),
74
+ "",
75
+ bounded("Task".padEnd(20) + handoff.task.objective),
76
+ bounded("Run".padEnd(20) + handoff.loopId),
77
+ bounded("Execution Mode".padEnd(20) + executionMode.replaceAll("_", " ")),
78
+ bounded("Governed Claim".padEnd(20) + (governanceClaimEligible ? "ELIGIBLE" : "INELIGIBLE")),
79
+ bounded("Verification".padEnd(20) + handoff.verification.status.replace("_", " ")),
80
+ bounded("Scope".padEnd(20) + handoff.scope.status.replaceAll("_", " ")),
81
+ bounded("Test Integrity".padEnd(20) + handoff.testIntegrity.verdict),
82
+ bounded("Receipt Integrity".padEnd(20) + handoff.receiptIntegrity.state),
83
+ bounded("Attempts".padEnd(20) + handoff.usage.attempts),
84
+ bounded("Cost".padEnd(20) +
85
+ formatCost(handoff.usage.actualUsd, handoff.usage.costProvenance)),
86
+ ];
87
+ if (checks.length > 0) {
88
+ lines.push("", bold("VERIFICATION EVIDENCE", environment), renderTable(checks, [
89
+ { header: "CHECK", value: (row) => row.check, minWidth: 24 },
90
+ { header: "STATUS", value: (row) => row.status, minWidth: 18 },
91
+ ], width));
92
+ }
93
+ if (handoff.stopReason) {
94
+ lines.push("", bold("STOP REASON", environment), bounded(" " + paint(humanize(handoff.stopReason), "danger", environment)));
95
+ }
96
+ lines.push("", bold("UNRESOLVED", environment));
97
+ if (handoff.unresolvedWork.length === 0) {
98
+ lines.push(" None recorded.");
99
+ }
100
+ else {
101
+ lines.push(...handoff.unresolvedWork.map((item) => bounded(" - " + item)));
102
+ }
103
+ lines.push("", bold("RECOVERY", environment), bounded(" " + handoff.recovery.summary), "", bold("NEXT", environment), bounded(" " + handoff.nextAction), horizontalRule(width, "━"));
104
+ return lines.map(bounded).join("\n");
105
+ }
106
+ /**
107
+ * Renders a VerifiedHandoffV1 as plain Markdown (no ANSI).
108
+ *
109
+ * CRITICAL: replicates the exact effectiveOutcome trust-authority check from
110
+ * renderVerifiedHandoff so that CLI and MCP surfaces always agree on
111
+ * VERIFIED / NEEDS REVIEW / STOPPED for the same input.
112
+ */
113
+ export function renderVerifiedHandoffMarkdown(handoff, options = {}) {
114
+ void options; // width/environment unused in plain Markdown
115
+ const { executionMode, governanceClaimEligible, effectiveOutcome } = resolveHandoffAuthority(handoff);
116
+ const outcome = effectiveOutcome.replace("_", " ");
117
+ const lines = [
118
+ `## MartinLoop Verified Handoff — ${outcome}`,
119
+ "",
120
+ "| Field | Value |",
121
+ "|-------|-------|",
122
+ `| Task | ${handoff.task.objective} |`,
123
+ `| Run | ${handoff.loopId} |`,
124
+ `| Execution Mode | ${executionMode.replaceAll("_", " ")} |`,
125
+ `| Governed Claim | ${governanceClaimEligible ? "ELIGIBLE" : "INELIGIBLE"} |`,
126
+ `| Verification | ${handoff.verification.status.replace("_", " ")} |`,
127
+ `| Scope | ${handoff.scope.status.replaceAll("_", " ")} |`,
128
+ `| Test Integrity | ${handoff.testIntegrity.verdict} |`,
129
+ `| Receipt Integrity | ${handoff.receiptIntegrity.state} |`,
130
+ `| Attempts | ${handoff.usage.attempts} |`,
131
+ `| Cost | ${formatCost(handoff.usage.actualUsd, handoff.usage.costProvenance)} |`,
132
+ ];
133
+ if (handoff.verification.checks.length > 0) {
134
+ lines.push("", "### Verification Evidence", "", "| Check | Status |", "|-------|--------|", ...handoff.verification.checks.map((check) => `| ${check.command} | ${checkSymbol(check.status)} ${check.status.replace("_", " ")} |`));
135
+ }
136
+ if (handoff.stopReason) {
137
+ lines.push("", "### Stop Reason", "", handoff.stopReason.replaceAll("_", " ").toLowerCase());
138
+ }
139
+ lines.push("", "### Unresolved");
140
+ if (handoff.unresolvedWork.length === 0) {
141
+ lines.push("", "None recorded.");
142
+ }
143
+ else {
144
+ lines.push("", ...handoff.unresolvedWork.map((item) => `- ${item}`));
145
+ }
146
+ lines.push("", "### Recovery", "", handoff.recovery.summary, "", "### Next", "", handoff.nextAction);
147
+ return lines.join("\n");
148
+ }
package/package.json CHANGED
@@ -1,80 +1,81 @@
1
- {
2
- "name": "@martinloop/mcp",
3
- "version": "0.5.3",
4
- "mcpName": "io.github.Keesan12/martin-loop",
5
- "private": false,
6
- "type": "module",
7
- "description": "MCP server for AI coding agents — verifier gates, stop limits, and Verified Handoffs.",
8
- "license": "Apache-2.0",
9
- "author": "MartinLoop contributors",
10
- "homepage": "https://martinloop.com/",
11
- "repository": {
12
- "type": "git",
13
- "url": "git+https://github.com/Keesan12/martin-loop.git",
14
- "directory": "packages/mcp"
15
- },
16
- "bugs": {
17
- "url": "https://github.com/Keesan12/martin-loop/issues"
18
- },
19
- "keywords": [
20
- "mcp",
21
- "model-context-protocol",
22
- "martin-loop",
23
- "ai-agent",
24
- "claude",
25
- "codex",
26
- "martin_doctor",
27
- "martin_triage_runs",
28
- "martin_run_dossier",
29
- "mcp-resources",
30
- "mcp-prompts"
31
- ],
32
- "bin": {
33
- "mcp": "./dist/server.js",
34
- "martin-loop-mcp": "./dist/server.js"
35
- },
36
- "exports": {
37
- "./server.json": "./server.json",
38
- "./package.json": "./package.json"
39
- },
40
- "files": [
41
- "dist",
42
- "README.md",
43
- "server.json"
44
- ],
45
- "engines": {
46
- "node": ">=20.0.0"
47
- },
48
- "publishConfig": {
49
- "access": "public"
50
- },
51
- "scripts": {
52
- "build": "node ./scripts/build-package.mjs",
53
- "prepack": "pnpm build",
54
- "smoke:pack": "node ./scripts/smoke-package.mjs",
55
- "smoke:published": "node ./scripts/smoke-published-package.mjs",
56
- "smoke:published:pack": "node ./scripts/smoke-published-package.mjs --package-spec=pack",
57
- "verify:release": "node --test ../../scripts/tests/publish-mcp-workflow.test.mjs ../../scripts/tests/mcp-publish-reliability.test.mjs ../../scripts/tests/mcp-release-docs.test.mjs",
58
- "test:baseline": "node ./scripts/run-test-lane.mjs baseline",
59
- "test": "vitest run --maxWorkers=1",
60
- "lint": "tsc -p tsconfig.json --noEmit",
61
- "start": "node dist/server.js",
62
- "inspect:live": "node ./scripts/inspect-live.mjs",
63
- "mcpb:build": "node ./mcpb/build-mcpb.mjs",
64
- "mcpb:validate": "mcpb validate ./dist-mcpb/martinloop",
65
- "mcpb:smoke": "node ./mcpb/smoke-mcpb.mjs"
66
- },
67
- "dependencies": {
68
- "@modelcontextprotocol/sdk": "^1.29.0",
69
- "@open-policy-agent/opa-wasm": "^1.10.0",
70
- "@opentelemetry/api-logs": "^0.214.0",
71
- "@opentelemetry/exporter-logs-otlp-http": "^0.214.0",
72
- "@opentelemetry/resources": "^2.6.1",
73
- "@opentelemetry/sdk-logs": "^0.214.0",
74
- "ts-morph": "^21.0.0"
75
- },
76
- "devDependencies": {
77
- "@anthropic-ai/mcpb": "2.1.2",
78
- "@martin/contracts": "workspace:*"
79
- }
80
- }
1
+ {
2
+ "name": "@martinloop/mcp",
3
+ "version": "0.5.6",
4
+ "mcpName": "io.github.Keesan12/martin-loop",
5
+ "private": false,
6
+ "type": "module",
7
+ "description": "MCP server for AI coding agents — verifier gates, stop limits, and Verified Handoffs.",
8
+ "license": "Apache-2.0",
9
+ "author": "MartinLoop contributors",
10
+ "homepage": "https://martinloop.com/",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/Keesan12/martin-loop.git",
14
+ "directory": "packages/mcp"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/Keesan12/martin-loop/issues"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "martin-loop",
23
+ "ai-agent",
24
+ "claude",
25
+ "codex",
26
+ "martin_doctor",
27
+ "martin_triage_runs",
28
+ "martin_run_dossier",
29
+ "mcp-resources",
30
+ "mcp-prompts"
31
+ ],
32
+ "bin": {
33
+ "mcp": "./dist/server.js",
34
+ "martin-loop-mcp": "./dist/server.js"
35
+ },
36
+ "exports": {
37
+ "./server.json": "./server.json",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "README.md",
43
+ "server.json"
44
+ ],
45
+ "engines": {
46
+ "node": ">=20.0.0"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
51
+ "scripts": {
52
+ "build": "node ./scripts/build-package.mjs",
53
+ "prepack": "pnpm build",
54
+ "smoke:pack": "node ./scripts/smoke-package.mjs",
55
+ "smoke:published": "node ./scripts/smoke-published-package.mjs",
56
+ "smoke:published:pack": "node ./scripts/smoke-published-package.mjs --package-spec=pack",
57
+ "verify:release": "node --test ../../scripts/tests/publish-mcp-workflow.test.mjs ../../scripts/tests/mcp-publish-reliability.test.mjs ../../scripts/tests/mcp-release-docs.test.mjs",
58
+ "test:baseline": "node ./scripts/run-test-lane.mjs baseline",
59
+ "test": "vitest run --maxWorkers=1",
60
+ "lint": "tsc -p tsconfig.json --noEmit",
61
+ "start": "node dist/server.js",
62
+ "inspect:live": "node ./scripts/inspect-live.mjs",
63
+ "mcpb:build": "node ./mcpb/build-mcpb.mjs",
64
+ "mcpb:validate": "mcpb validate ./dist-mcpb/martinloop",
65
+ "mcpb:smoke": "node ./mcpb/smoke-mcpb.mjs"
66
+ },
67
+ "dependencies": {
68
+ "@modelcontextprotocol/sdk": "^1.29.0",
69
+ "@open-policy-agent/opa-wasm": "^1.10.0",
70
+ "@opentelemetry/api-logs": "^0.214.0",
71
+ "@opentelemetry/exporter-logs-otlp-http": "^0.214.0",
72
+ "@opentelemetry/resources": "^2.6.1",
73
+ "@opentelemetry/sdk-logs": "^0.214.0",
74
+ "ts-morph": "^21.0.0"
75
+ },
76
+ "devDependencies": {
77
+ "@anthropic-ai/mcpb": "2.1.2",
78
+ "@martin/contracts": "workspace:*",
79
+ "@martin/presentation": "workspace:*"
80
+ }
81
+ }
package/server.json CHANGED
@@ -1,21 +1,21 @@
1
- {
2
- "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
- "name": "io.github.Keesan12/martin-loop",
4
- "title": "Martin Loop",
5
- "description": "MCP server for AI coding agents — verifier gates, stop limits, and Verified Handoffs.",
6
- "repository": {
7
- "url": "https://github.com/Keesan12/martin-loop",
8
- "source": "github"
9
- },
10
- "version": "0.5.3",
11
- "packages": [
12
- {
13
- "registryType": "npm",
14
- "identifier": "@martinloop/mcp",
15
- "version": "0.5.3",
16
- "transport": {
17
- "type": "stdio"
18
- }
19
- }
20
- ]
21
- }
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.Keesan12/martin-loop",
4
+ "title": "Martin Loop",
5
+ "description": "MCP server for AI coding agents — verifier gates, stop limits, and Verified Handoffs.",
6
+ "repository": {
7
+ "url": "https://github.com/Keesan12/martin-loop",
8
+ "source": "github"
9
+ },
10
+ "version": "0.5.6",
11
+ "packages": [
12
+ {
13
+ "registryType": "npm",
14
+ "identifier": "@martinloop/mcp",
15
+ "version": "0.5.6",
16
+ "transport": {
17
+ "type": "stdio"
18
+ }
19
+ }
20
+ ]
21
+ }