@martinloop/mcp 0.3.9 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -141
- package/dist/discovery-metadata.d.ts +1 -1
- package/dist/discovery-metadata.js +1 -1
- package/dist/resources.d.ts +1 -2
- package/dist/resources.js +62 -98
- package/dist/server-validation.d.ts +1 -1
- package/dist/server-validation.js +16 -11
- package/dist/server.d.ts +23 -0
- package/dist/server.js +192 -15
- package/dist/tools/doctor.js +5 -4
- package/dist/tools/get-status.d.ts +2 -0
- package/dist/tools/get-status.js +1 -0
- package/dist/tools/preflight.d.ts +2 -0
- package/dist/tools/preflight.js +43 -3
- package/dist/tools/run-dossier.d.ts +3 -1
- package/dist/tools/run-dossier.js +40 -2
- package/dist/tools/run-loop.d.ts +5 -3
- package/dist/tools/run-loop.js +15 -9
- package/dist/tools/tool-errors.js +1 -1
- package/dist/tools/tool-response.js +9 -2
- package/dist/tools/tool-support.d.ts +4 -2
- package/dist/tools/tool-support.js +6 -15
- package/dist/vendor/adapters/claude-cli.d.ts +2 -2
- package/dist/vendor/adapters/claude-cli.js +97 -69
- package/dist/vendor/adapters/cli-bridge.d.ts +9 -1
- package/dist/vendor/adapters/cli-bridge.js +54 -13
- package/dist/vendor/adapters/codex-launcher.d.ts +61 -1
- package/dist/vendor/adapters/codex-launcher.js +118 -19
- package/dist/vendor/adapters/index.d.ts +2 -4
- package/dist/vendor/adapters/index.js +2 -4
- package/dist/vendor/adapters/openai-compatible.d.ts +2 -3
- package/dist/vendor/adapters/openai-compatible.js +80 -15
- package/dist/vendor/adapters/verifier-only.js +9 -4
- package/dist/vendor/contracts/adapter-capabilities.d.ts +1 -1
- package/dist/vendor/contracts/context-handoff.d.ts +100 -0
- package/dist/vendor/contracts/context-handoff.js +11 -0
- package/dist/vendor/contracts/context-manifest.d.ts +195 -0
- package/dist/vendor/contracts/context-manifest.js +17 -0
- package/dist/vendor/contracts/context-shadow.d.ts +75 -0
- package/dist/vendor/contracts/context-shadow.js +8 -0
- package/dist/vendor/contracts/delivery.d.ts +47 -0
- package/dist/vendor/contracts/delivery.js +18 -0
- package/dist/vendor/contracts/exits.d.ts +126 -0
- package/dist/vendor/contracts/exits.js +32 -0
- package/dist/vendor/contracts/index.d.ts +55 -6
- package/dist/vendor/contracts/index.js +24 -0
- package/dist/vendor/contracts/mission.d.ts +102 -0
- package/dist/vendor/contracts/mission.js +64 -0
- package/dist/vendor/contracts/operator.d.ts +3 -1
- package/dist/vendor/contracts/operator.js +2 -1
- package/dist/vendor/contracts/verified-handoff.d.ts +106 -0
- package/dist/vendor/contracts/verified-handoff.js +40 -0
- package/dist/vendor/core/context-chain-gate.d.ts +89 -0
- package/dist/vendor/core/context-chain-gate.js +173 -0
- package/dist/vendor/core/context-compiler.d.ts +53 -0
- package/dist/vendor/core/context-compiler.js +261 -0
- package/dist/vendor/core/context-handoff.d.ts +42 -0
- package/dist/vendor/core/context-handoff.js +167 -0
- package/dist/vendor/core/context-shadow.d.ts +39 -0
- package/dist/vendor/core/context-shadow.js +200 -0
- package/dist/vendor/core/delivery/index.d.ts +6 -0
- package/dist/vendor/core/delivery/index.js +4 -0
- package/dist/vendor/core/delivery/message-client.d.ts +18 -0
- package/dist/vendor/core/delivery/message-client.js +38 -0
- package/dist/vendor/core/delivery/message-ledger.d.ts +35 -0
- package/dist/vendor/core/delivery/message-ledger.js +97 -0
- package/dist/vendor/core/delivery/message-schema.d.ts +16 -0
- package/dist/vendor/core/delivery/message-schema.js +111 -0
- package/dist/vendor/core/delivery/update-check.d.ts +19 -0
- package/dist/vendor/core/delivery/update-check.js +107 -0
- package/dist/vendor/core/exit-signal.d.ts +88 -0
- package/dist/vendor/core/exit-signal.js +339 -0
- package/dist/vendor/core/exits.d.ts +41 -0
- package/dist/vendor/core/exits.js +258 -0
- package/dist/vendor/core/grounding.d.ts +2 -1
- package/dist/vendor/core/grounding.js +40 -5
- package/dist/vendor/core/index.d.ts +47 -6
- package/dist/vendor/core/index.js +1102 -670
- package/dist/vendor/core/mission/aggregate.d.ts +27 -0
- package/dist/vendor/core/mission/aggregate.js +42 -0
- package/dist/vendor/core/mission/index.d.ts +2 -0
- package/dist/vendor/core/mission/index.js +1 -0
- package/dist/vendor/core/persistence/compiler.d.ts +8 -0
- package/dist/vendor/core/persistence/compiler.js +156 -0
- package/dist/vendor/core/persistence/context-handoff-store.d.ts +68 -0
- package/dist/vendor/core/persistence/context-handoff-store.js +112 -0
- package/dist/vendor/core/persistence/index.d.ts +4 -0
- package/dist/vendor/core/persistence/index.js +2 -0
- package/dist/vendor/core/persistence/ledger.d.ts +1 -1
- package/dist/vendor/core/persistence/mission-store.d.ts +56 -0
- package/dist/vendor/core/persistence/mission-store.js +281 -0
- package/dist/vendor/core/persistence/runs-reader.d.ts +2 -0
- package/dist/vendor/core/policy.d.ts +2 -0
- package/dist/vendor/core/policy.js +11 -8
- package/dist/vendor/core/red-blue/red-phase.d.ts +2 -1
- package/dist/vendor/core/red-blue/red-phase.js +3 -3
- package/dist/vendor/core/red-blue/risk-tiers.d.ts +2 -4
- package/dist/vendor/core/red-blue/risk-tiers.js +1 -3
- package/dist/vendor/core/rollback.js +15 -1
- package/dist/vendor/core/routing.d.ts +0 -42
- package/dist/vendor/core/routing.js +4 -154
- package/dist/vendor/core/savings.d.ts +13 -0
- package/dist/vendor/core/savings.js +22 -0
- package/dist/vendor/core/termination-store.d.ts +15 -0
- package/dist/vendor/core/termination-store.js +44 -0
- package/dist/vendor/core/verified-handoff.d.ts +72 -0
- package/dist/vendor/core/verified-handoff.js +238 -0
- package/package.json +4 -10
- package/server.json +3 -3
- package/dist/vendor/adapters/stub-agent-cli.d.ts +0 -8
- package/dist/vendor/adapters/stub-agent-cli.js +0 -40
- package/dist/vendor/adapters/stub-direct-provider.d.ts +0 -8
- package/dist/vendor/adapters/stub-direct-provider.js +0 -12
package/dist/resources.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
2
|
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
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,7 +19,6 @@ 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",
|
|
23
22
|
latestProofCard: "martin://runs/latest/proof-card",
|
|
24
23
|
latestBudgetStatus: "martin://runs/latest/budget-status",
|
|
25
24
|
latestVerifierEvidence: "martin://runs/latest/verifier-evidence",
|
|
@@ -35,9 +34,19 @@ export const MARTIN_STATIC_RESOURCE_URIS = {
|
|
|
35
34
|
operatingRulesGuide: "martin://guides/operating-rules",
|
|
36
35
|
publishReadinessGuide: "martin://guides/publish-readiness",
|
|
37
36
|
governanceStatus: "martin://agent/governance-status",
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
modeStatus: "martin://agent/mode-status",
|
|
38
|
+
memorySummary: "martin://agent/memory-summary"
|
|
40
39
|
};
|
|
40
|
+
function formatRecordedCost(usd, provenance) {
|
|
41
|
+
if (provenance === "unavailable")
|
|
42
|
+
return "unavailable";
|
|
43
|
+
if (provenance === "actual")
|
|
44
|
+
return `$${usd.toFixed(2)} provider-settled actual`;
|
|
45
|
+
if (provenance === "calculated") {
|
|
46
|
+
return `$${usd.toFixed(2)} calculated from observed usage`;
|
|
47
|
+
}
|
|
48
|
+
return `$${usd.toFixed(2)} estimated`;
|
|
49
|
+
}
|
|
41
50
|
export const MARTIN_RESOURCE_TEMPLATES = [
|
|
42
51
|
{
|
|
43
52
|
name: "martin_run_record",
|
|
@@ -100,18 +109,11 @@ export const MARTIN_STATIC_RESOURCES = [
|
|
|
100
109
|
description: "Compact latest-run summary for context-constrained agents.",
|
|
101
110
|
mimeType: "application/json"
|
|
102
111
|
},
|
|
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
|
-
},
|
|
110
112
|
{
|
|
111
113
|
uri: MARTIN_STATIC_RESOURCE_URIS.latestProofCard,
|
|
112
114
|
name: "martin_latest_proof_card",
|
|
113
115
|
title: "Martin Latest Proof Card",
|
|
114
|
-
description: "
|
|
116
|
+
description: "Small Markdown receipt showing what happened, what Martin prevented, and the next safe action.",
|
|
115
117
|
mimeType: "text/markdown"
|
|
116
118
|
},
|
|
117
119
|
{
|
|
@@ -212,19 +214,19 @@ export const MARTIN_STATIC_RESOURCES = [
|
|
|
212
214
|
description: "Proactive governance status: whether work is governed, budget remaining, unreceipted runs, and recommended next action. Read this before starting agent work.",
|
|
213
215
|
mimeType: "application/json"
|
|
214
216
|
},
|
|
217
|
+
{
|
|
218
|
+
uri: MARTIN_STATIC_RESOURCE_URIS.modeStatus,
|
|
219
|
+
name: "martin_mode_status",
|
|
220
|
+
title: "Martin Mode Status",
|
|
221
|
+
description: "Current MartinLoop working mode, whether it is inherited or explicitly configured, and how to switch it.",
|
|
222
|
+
mimeType: "application/json"
|
|
223
|
+
},
|
|
215
224
|
{
|
|
216
225
|
uri: MARTIN_STATIC_RESOURCE_URIS.memorySummary,
|
|
217
226
|
name: "martin_memory_summary",
|
|
218
227
|
title: "Martin Memory Summary",
|
|
219
228
|
description: "MartinLoop persistent memory: user preferences, consent signals, budget patterns, and behavioral observations aggregated over time. Read at session start to personalize recommendations.",
|
|
220
229
|
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"
|
|
228
230
|
}
|
|
229
231
|
];
|
|
230
232
|
export function listMartinResources() {
|
|
@@ -260,8 +262,6 @@ export async function readMartinResource(input) {
|
|
|
260
262
|
return jsonResource(input.uri, withDiscoveryMetadata(await martinRunDossierTool({ latest: true, runsDir: context.runsRoot }), context.runsRoot));
|
|
261
263
|
case MARTIN_STATIC_RESOURCE_URIS.latestSummary:
|
|
262
264
|
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));
|
|
265
265
|
case MARTIN_STATIC_RESOURCE_URIS.latestProofCard:
|
|
266
266
|
return textResource(input.uri, "text/markdown", await buildLatestProofCardResource(context.runsRoot));
|
|
267
267
|
case MARTIN_STATIC_RESOURCE_URIS.latestBudgetStatus:
|
|
@@ -284,7 +284,7 @@ export async function readMartinResource(input) {
|
|
|
284
284
|
case MARTIN_STATIC_RESOURCE_URIS.governanceStatus:
|
|
285
285
|
return jsonResource(input.uri, withDiscoveryMetadata(await buildGovernanceStatusResource(context.runsRoot, context.workingDirectory), context.runsRoot));
|
|
286
286
|
case MARTIN_STATIC_RESOURCE_URIS.modeStatus:
|
|
287
|
-
return jsonResource(input.uri, withDiscoveryMetadata(await buildModeStatusResource(), context.runsRoot));
|
|
287
|
+
return jsonResource(input.uri, withDiscoveryMetadata(await buildModeStatusResource(context.workingDirectory), context.runsRoot));
|
|
288
288
|
case MARTIN_STATIC_RESOURCE_URIS.agentNextStep:
|
|
289
289
|
return jsonResource(input.uri, withDiscoveryMetadata(await buildAgentNextStepResource(context.runsRoot), context.runsRoot));
|
|
290
290
|
case MARTIN_STATIC_RESOURCE_URIS.mcpUsageGuide:
|
|
@@ -386,7 +386,7 @@ async function loadLatestRunForCompactResource(runsRoot) {
|
|
|
386
386
|
empty: true,
|
|
387
387
|
warnings: [
|
|
388
388
|
"No Martin run records were found yet.",
|
|
389
|
-
"Run `npx martin-loop demo`, then
|
|
389
|
+
"Run `npx martin-loop demo`, then use `--proof --verify <command>` for explicitly non-governed verification-only evidence."
|
|
390
390
|
]
|
|
391
391
|
};
|
|
392
392
|
}
|
|
@@ -414,6 +414,7 @@ async function buildLatestSummaryResource(runsRoot) {
|
|
|
414
414
|
budget: loop.budget,
|
|
415
415
|
cost: {
|
|
416
416
|
actualUsd: loop.cost.actualUsd,
|
|
417
|
+
provenance: loop.cost.provenance ?? "unavailable",
|
|
417
418
|
avoidedUsdEstimate: loop.cost.avoidedUsd ?? 0,
|
|
418
419
|
tokensIn: loop.cost.tokensIn,
|
|
419
420
|
tokensOut: loop.cost.tokensOut,
|
|
@@ -433,44 +434,6 @@ async function buildLatestSummaryResource(runsRoot) {
|
|
|
433
434
|
warnings: [...latest.detail.warnings, ...verification.warnings]
|
|
434
435
|
};
|
|
435
436
|
}
|
|
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
|
-
}
|
|
474
437
|
async function buildLatestBudgetStatusResource(runsRoot) {
|
|
475
438
|
const latest = await loadLatestRunForCompactResource(runsRoot);
|
|
476
439
|
if (latest.empty || !latest.detail) {
|
|
@@ -487,6 +450,7 @@ async function buildLatestBudgetStatusResource(runsRoot) {
|
|
|
487
450
|
budget: loop.budget,
|
|
488
451
|
cost: {
|
|
489
452
|
actualUsd: loop.cost.actualUsd,
|
|
453
|
+
provenance: loop.cost.provenance ?? "unavailable",
|
|
490
454
|
avoidedUsdEstimate: loop.cost.avoidedUsd ?? 0,
|
|
491
455
|
tokensIn: loop.cost.tokensIn,
|
|
492
456
|
tokensOut: loop.cost.tokensOut,
|
|
@@ -601,7 +565,7 @@ async function buildLatestProofCardResource(runsRoot) {
|
|
|
601
565
|
"",
|
|
602
566
|
"What happened: Martin has not found a local run record in this runs root.",
|
|
603
567
|
"What Martin prevented: unknown until a governed run executes.",
|
|
604
|
-
"Next safe action: call `martin_doctor`, run `npx martin-loop demo`, then inspect `martin://runs/latest/
|
|
568
|
+
"Next safe action: call `martin_doctor`, run `npx martin-loop demo`, then inspect `martin://runs/latest/summary`.",
|
|
605
569
|
"",
|
|
606
570
|
"Estimate note: no cost or token savings are claimed without run evidence.",
|
|
607
571
|
""
|
|
@@ -623,7 +587,7 @@ async function buildLatestProofCardResource(runsRoot) {
|
|
|
623
587
|
`Run: \`${loop.loopId}\``,
|
|
624
588
|
`Status: ${loop.status} / ${loop.lifecycleState}`,
|
|
625
589
|
`Attempts: ${loop.attempts.length}`,
|
|
626
|
-
`Spend:
|
|
590
|
+
`Spend: ${formatRecordedCost(loop.cost.actualUsd, loop.cost.provenance ?? "unavailable")}, $${(loop.cost.avoidedUsd ?? 0).toFixed(2)} avoided estimate`,
|
|
627
591
|
`Tokens: ${loop.cost.tokensIn} in / ${loop.cost.tokensOut} out`,
|
|
628
592
|
`Verifier: ${verifierStatus}`,
|
|
629
593
|
"",
|
|
@@ -647,7 +611,7 @@ function compactEmptyState(kind, runsRoot, warnings) {
|
|
|
647
611
|
status: "empty",
|
|
648
612
|
runsRoot,
|
|
649
613
|
summary: "No Martin run records are available yet.",
|
|
650
|
-
nextStep: "Run `npx martin-loop doctor`, create the demo workspace
|
|
614
|
+
nextStep: "Run `npx martin-loop doctor`, create the demo workspace, then use `--proof --verify <command>` only for non-governed verification evidence.",
|
|
651
615
|
warnings
|
|
652
616
|
};
|
|
653
617
|
}
|
|
@@ -708,6 +672,33 @@ async function buildGovernanceStatusResource(runsRoot, workingDirectory) {
|
|
|
708
672
|
warning: governed ? undefined : "This session is NOT governed. Complete the required sequence before making changes."
|
|
709
673
|
};
|
|
710
674
|
}
|
|
675
|
+
async function buildModeStatusResource(workingDirectory) {
|
|
676
|
+
const configPath = join(homedir(), ".martin", "config.json");
|
|
677
|
+
let config = {};
|
|
678
|
+
try {
|
|
679
|
+
config = JSON.parse(await readFile(configPath, "utf8"));
|
|
680
|
+
}
|
|
681
|
+
catch {
|
|
682
|
+
// Fresh config means the implicit auto default is in effect.
|
|
683
|
+
}
|
|
684
|
+
const projectMode = config.projectOverrides?.[workingDirectory];
|
|
685
|
+
const defaultMode = config.defaultMode ?? "auto";
|
|
686
|
+
const effectiveMode = projectMode ?? defaultMode;
|
|
687
|
+
return {
|
|
688
|
+
kind: "mode-status",
|
|
689
|
+
effectiveMode,
|
|
690
|
+
defaultMode,
|
|
691
|
+
scope: projectMode ? "project" : config.defaultMode ? "global" : "implicit_default",
|
|
692
|
+
configured: Boolean(projectMode || config.defaultMode),
|
|
693
|
+
projectOverride: projectMode ?? null,
|
|
694
|
+
workingDirectory,
|
|
695
|
+
switchCommands: {
|
|
696
|
+
auto: "martin mode auto",
|
|
697
|
+
plan: "martin mode plan",
|
|
698
|
+
edits: "martin mode edits"
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
}
|
|
711
702
|
function buildCurrentPoliciesResource(workingDirectory) {
|
|
712
703
|
const signals = inspectRepoSignals(workingDirectory);
|
|
713
704
|
const recommended = buildPolicyPackDefinition(undefined, signals);
|
|
@@ -751,14 +742,14 @@ function inferAgentNextStep(loop, verification) {
|
|
|
751
742
|
return {
|
|
752
743
|
action: "triage_before_retry",
|
|
753
744
|
toolOrResource: "martin_triage_runs",
|
|
754
|
-
instruction: "Call `martin_triage_runs` and inspect the
|
|
745
|
+
instruction: "Call `martin_triage_runs` and inspect the proof card before spending another attempt."
|
|
755
746
|
};
|
|
756
747
|
}
|
|
757
748
|
if (loop.status === "completed" && verification.latestVerification?.passed === true) {
|
|
758
749
|
return {
|
|
759
750
|
action: "prove_and_share",
|
|
760
|
-
toolOrResource: MARTIN_STATIC_RESOURCE_URIS.
|
|
761
|
-
instruction: "Read the
|
|
751
|
+
toolOrResource: MARTIN_STATIC_RESOURCE_URIS.latestProofCard,
|
|
752
|
+
instruction: "Read the proof card and full dossier before sharing or promoting the result."
|
|
762
753
|
};
|
|
763
754
|
}
|
|
764
755
|
return {
|
|
@@ -783,14 +774,14 @@ Martin Loop exposes governed coding workflows over MCP. Use the server health an
|
|
|
783
774
|
2. Use the \`martin_governed_coding_kickoff\` prompt to frame a governed coding request.
|
|
784
775
|
3. Call \`martin_preflight\` before \`martin_run\` when the task or safety envelope is non-trivial.
|
|
785
776
|
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.
|
|
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.
|
|
787
778
|
6. Read \`${MARTIN_STATIC_RESOURCE_URIS.triage}\` or call \`martin_triage_runs\` to prioritize which run needs attention first.
|
|
788
779
|
7. Use \`martin_debug_failed_run\` when a loop exits failed, budget-bound, or escalated.
|
|
789
780
|
|
|
790
781
|
## Current Martin MCP Surface
|
|
791
782
|
|
|
792
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\`
|
|
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.
|
|
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}\`
|
|
794
785
|
- Resource templates: \`martin://runs/{loopId}\`, \`martin://runs/{loopId}/attempts/{attemptIndex}\`, \`martin://runs/{loopId}/verification\`
|
|
795
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\`
|
|
796
787
|
|
|
@@ -817,7 +808,7 @@ Use Martin Loop as the local governor before you spend agent tokens or retry a f
|
|
|
817
808
|
2. If no runs exist, call \`martin_doctor\`, then \`martin_preflight\`.
|
|
818
809
|
3. If a run exists, read \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\` before reading full run JSON.
|
|
819
810
|
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.
|
|
811
|
+
5. If you need a shareable receipt, read \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`.
|
|
821
812
|
|
|
822
813
|
## Install Profiles
|
|
823
814
|
|
|
@@ -855,8 +846,7 @@ Use this guide when an IDE or agent needs to know which Martin surface to call n
|
|
|
855
846
|
|
|
856
847
|
- Need the smallest next action: \`${MARTIN_STATIC_RESOURCE_URIS.agentNextStep}\`
|
|
857
848
|
- Need a quick receipt: \`${MARTIN_STATIC_RESOURCE_URIS.latestSummary}\`
|
|
858
|
-
- Need
|
|
859
|
-
- Need an optional visual proof object: \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`
|
|
849
|
+
- Need a shareable proof object: \`${MARTIN_STATIC_RESOURCE_URIS.latestProofCard}\`
|
|
860
850
|
- Need a full run review: \`martin_dossier\`
|
|
861
851
|
- Need to decide whether to retry: \`martin_triage_runs\`
|
|
862
852
|
- Need IDE setup guidance: \`${MARTIN_STATIC_RESOURCE_URIS.ideOnboardingGuide}\`
|
|
@@ -939,32 +929,6 @@ Use this guide when reviewing whether the public MCP package is ready to publish
|
|
|
939
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.
|
|
940
930
|
`;
|
|
941
931
|
}
|
|
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
|
-
}
|
|
968
932
|
function withDiscoveryMetadata(value, runsRoot) {
|
|
969
933
|
return {
|
|
970
934
|
metadata: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type ToolName = "martin_run" | "martin_inspect" | "martin_status" | "martin_doctor" | "
|
|
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";
|
|
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;
|
|
@@ -14,12 +14,12 @@ export function validateToolInput(name, args) {
|
|
|
14
14
|
return validateStatusInput(args);
|
|
15
15
|
case "martin_doctor":
|
|
16
16
|
return validateDoctorInput(args);
|
|
17
|
-
case "martin_estimate":
|
|
18
|
-
return validateEstimateInput(args);
|
|
19
17
|
case "martin_plan":
|
|
20
18
|
return validatePlanInput(args);
|
|
21
19
|
case "martin_preflight":
|
|
22
20
|
return validatePreflightInput(args);
|
|
21
|
+
case "martin_estimate":
|
|
22
|
+
return validateEstimateInput(args);
|
|
23
23
|
case "martin_logs":
|
|
24
24
|
return validateLogsInput(args);
|
|
25
25
|
case "martin_cancel":
|
|
@@ -254,22 +254,27 @@ function validateDoctorInput(args) {
|
|
|
254
254
|
...optionalEnumAsObject(record.engine, "engine", MARTIN_ENGINE_VALUES)
|
|
255
255
|
};
|
|
256
256
|
}
|
|
257
|
+
function validatePreflightInput(args) {
|
|
258
|
+
return validateRunInput(args);
|
|
259
|
+
}
|
|
260
|
+
function validatePlanInput(args) {
|
|
261
|
+
return validateRunInput(args);
|
|
262
|
+
}
|
|
257
263
|
function validateEstimateInput(args) {
|
|
258
264
|
const record = requireObject(args);
|
|
259
|
-
assertAllowedKeys(record, ["objective", "engine", "budgetUsd", "fileScope"]);
|
|
265
|
+
assertAllowedKeys(record, ["objective", "engine", "budgetUsd", "fileScope", "workingDirectory"]);
|
|
266
|
+
const engine = optionalEnum(record.engine, "engine", MARTIN_ENGINE_VALUES);
|
|
267
|
+
const fileScope = normalizeSafePathPatterns(record.fileScope, "fileScope");
|
|
260
268
|
return {
|
|
261
269
|
objective: requireString(record.objective, "objective"),
|
|
262
|
-
...
|
|
270
|
+
...(engine ? { engine } : {}),
|
|
263
271
|
...optionalPositiveNumber(record.budgetUsd, "budgetUsd"),
|
|
264
|
-
...
|
|
272
|
+
...(fileScope ? { fileScope } : {}),
|
|
273
|
+
...(record.workingDirectory !== undefined
|
|
274
|
+
? { workingDirectory: resolveSafeRepoRoot(requireString(record.workingDirectory, "workingDirectory")) }
|
|
275
|
+
: {})
|
|
265
276
|
};
|
|
266
277
|
}
|
|
267
|
-
function validatePreflightInput(args) {
|
|
268
|
-
return validateRunInput(args);
|
|
269
|
-
}
|
|
270
|
-
function validatePlanInput(args) {
|
|
271
|
-
return validateRunInput(args);
|
|
272
|
-
}
|
|
273
278
|
function validateLogsInput(args) {
|
|
274
279
|
const record = requireObject(args);
|
|
275
280
|
assertAllowedKeys(record, ["file", "loopId", "runsDir", "latest", "limit"]);
|
package/dist/server.d.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* Manual start:
|
|
17
17
|
* node dist/server.js
|
|
18
18
|
*/
|
|
19
|
+
import { type Server as NodeHttpServer } from "node:http";
|
|
19
20
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
20
21
|
export declare function createMartinMcpServer(serverInfo?: {
|
|
21
22
|
name?: string;
|
|
@@ -88,4 +89,26 @@ export declare function connectMartinMcpStdioServer(): Promise<Server<{
|
|
|
88
89
|
} | undefined;
|
|
89
90
|
} | undefined;
|
|
90
91
|
}>>;
|
|
92
|
+
export interface MartinMcpHttpServerOptions {
|
|
93
|
+
host?: string;
|
|
94
|
+
port?: number;
|
|
95
|
+
path?: string;
|
|
96
|
+
}
|
|
97
|
+
export interface MartinMcpHttpServerHandle {
|
|
98
|
+
server: NodeHttpServer;
|
|
99
|
+
host: string;
|
|
100
|
+
port: number;
|
|
101
|
+
path: string;
|
|
102
|
+
endpoint: string;
|
|
103
|
+
close: () => Promise<void>;
|
|
104
|
+
}
|
|
105
|
+
export declare function parseMartinMcpServerArgs(argv: string[]): {
|
|
106
|
+
transport: "stdio";
|
|
107
|
+
} | {
|
|
108
|
+
transport: "http";
|
|
109
|
+
host: string;
|
|
110
|
+
port: number;
|
|
111
|
+
path: string;
|
|
112
|
+
};
|
|
113
|
+
export declare function connectMartinMcpHttpServer(options?: MartinMcpHttpServerOptions): Promise<MartinMcpHttpServerHandle>;
|
|
91
114
|
export declare function isDirectExecutionEntry(entryPath: string | undefined, moduleUrl?: string): boolean;
|