@martinloop/mcp 0.2.0 → 0.2.5

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 (76) hide show
  1. package/README.md +131 -158
  2. package/dist/discovery-metadata.d.ts +16 -0
  3. package/dist/discovery-metadata.js +62 -0
  4. package/dist/discovery-support.d.ts +62 -0
  5. package/dist/discovery-support.js +224 -0
  6. package/dist/package-version.d.ts +1 -0
  7. package/dist/package-version.js +3 -0
  8. package/dist/prompts.d.ts +13 -3
  9. package/dist/prompts.js +445 -74
  10. package/dist/resources.d.ts +27 -5
  11. package/dist/resources.js +557 -71
  12. package/dist/server-validation.d.ts +2 -3
  13. package/dist/server-validation.js +262 -122
  14. package/dist/server.d.ts +76 -7
  15. package/dist/server.js +1126 -400
  16. package/dist/tools/doctor.js +14 -6
  17. package/dist/tools/get-attempt.d.ts +13 -6
  18. package/dist/tools/get-attempt.js +14 -5
  19. package/dist/tools/get-run.d.ts +19 -12
  20. package/dist/tools/get-run.js +20 -11
  21. package/dist/tools/get-status.d.ts +11 -0
  22. package/dist/tools/get-status.js +12 -2
  23. package/dist/tools/get-verification-results.d.ts +10 -7
  24. package/dist/tools/get-verification-results.js +11 -6
  25. package/dist/tools/inspect-loop.d.ts +9 -0
  26. package/dist/tools/inspect-loop.js +11 -2
  27. package/dist/tools/list-runs.d.ts +25 -5
  28. package/dist/tools/list-runs.js +21 -4
  29. package/dist/tools/preflight.js +7 -2
  30. package/dist/tools/run-dossier.d.ts +37 -4
  31. package/dist/tools/run-dossier.js +40 -5
  32. package/dist/tools/run-loop.d.ts +19 -0
  33. package/dist/tools/run-loop.js +41 -3
  34. package/dist/tools/run-store.d.ts +57 -3
  35. package/dist/tools/run-store.js +404 -53
  36. package/dist/tools/tool-errors.d.ts +37 -0
  37. package/dist/tools/tool-errors.js +170 -0
  38. package/dist/tools/tool-response.d.ts +16 -0
  39. package/dist/tools/tool-response.js +34 -0
  40. package/dist/tools/tool-support.d.ts +92 -2
  41. package/dist/tools/tool-support.js +358 -63
  42. package/dist/tools/triage-runs.d.ts +33 -0
  43. package/dist/tools/triage-runs.js +138 -0
  44. package/dist/vendor/adapters/claude-cli.js +0 -1
  45. package/dist/vendor/adapters/cli-bridge.js +0 -1
  46. package/dist/vendor/adapters/direct-provider.js +0 -1
  47. package/dist/vendor/adapters/index.js +0 -1
  48. package/dist/vendor/adapters/runtime-support.js +0 -1
  49. package/dist/vendor/adapters/stub-agent-cli.js +0 -1
  50. package/dist/vendor/adapters/stub-direct-provider.js +0 -1
  51. package/dist/vendor/adapters/verifier-only.js +0 -1
  52. package/dist/vendor/contracts/governance.js +0 -1
  53. package/dist/vendor/contracts/index.d.ts +2 -0
  54. package/dist/vendor/contracts/index.js +1 -1
  55. package/dist/vendor/contracts/operator.d.ts +19 -0
  56. package/dist/vendor/contracts/operator.js +11 -0
  57. package/dist/vendor/core/compiler.js +0 -1
  58. package/dist/vendor/core/context-integrity.js +0 -1
  59. package/dist/vendor/core/grounding.js +0 -1
  60. package/dist/vendor/core/index.js +1 -2
  61. package/dist/vendor/core/leash.js +19 -12
  62. package/dist/vendor/core/persistence/compiler.js +0 -1
  63. package/dist/vendor/core/persistence/index.js +0 -1
  64. package/dist/vendor/core/persistence/ledger.js +0 -1
  65. package/dist/vendor/core/persistence/runs-reader.js +0 -1
  66. package/dist/vendor/core/persistence/store.js +0 -1
  67. package/dist/vendor/core/policy.js +0 -1
  68. package/dist/vendor/core/red-blue/red-phase.d.ts +64 -0
  69. package/dist/vendor/core/red-blue/red-phase.js +135 -0
  70. package/dist/vendor/core/red-blue/risk-tiers.d.ts +22 -0
  71. package/dist/vendor/core/red-blue/risk-tiers.js +32 -0
  72. package/dist/vendor/core/rollback.js +2 -3
  73. package/package.json +10 -5
  74. package/server.json +2 -2
  75. package/dist/tools/cockpit-support.d.ts +0 -69
  76. package/dist/tools/cockpit-support.js +0 -108
@@ -23,11 +23,12 @@ export async function martinDoctorTool(input) {
23
23
  }
24
24
  warnings.push(...runStore.warnings);
25
25
  const status = warnings.length === 0 ? "ok" : "degraded";
26
+ const summary = status === "ok"
27
+ ? `Doctor passed: ${runStore.loopCount} run(s) visible in ${runsRoot}.`
28
+ : `Doctor found ${warnings.length} issue(s); review warnings before live execution.`;
26
29
  return {
27
30
  status,
28
- summary: status === "ok"
29
- ? `Doctor passed: ${runStore.loopCount} run(s) visible in ${runsRoot}.`
30
- : `Doctor found ${warnings.length} issue(s); review warnings before live execution.`,
31
+ summary,
31
32
  server: {
32
33
  name: "martin-loop",
33
34
  nodeVersion: process.version,
@@ -41,8 +42,16 @@ export async function martinDoctorTool(input) {
41
42
  liveMode: executionMode.liveMode
42
43
  },
43
44
  engines: {
44
- claude,
45
- codex
45
+ claude: {
46
+ available: claude.available,
47
+ detail: claude.detail,
48
+ ...(claude.resolvedPath ? { resolvedPath: claude.resolvedPath } : {})
49
+ },
50
+ codex: {
51
+ available: codex.available,
52
+ detail: codex.detail,
53
+ ...(codex.resolvedPath ? { resolvedPath: codex.resolvedPath } : {})
54
+ }
46
55
  },
47
56
  ...(input.engine ? { requestedEngine: input.engine } : {}),
48
57
  runStore: {
@@ -53,4 +62,3 @@ export async function martinDoctorTool(input) {
53
62
  warnings
54
63
  };
55
64
  }
56
- //# sourceMappingURL=doctor.js.map
@@ -1,8 +1,15 @@
1
- import { getAttempt } from "./cockpit-support.js";
2
- export interface GetAttemptInput {
3
- loopId: string;
4
- attemptIndex: number;
1
+ import { buildAttemptSummary, buildLoopPreview } from "./tool-support.js";
2
+ export interface MartinGetAttemptInput {
3
+ file?: string;
4
+ loopId?: string;
5
5
  runsDir?: string;
6
+ attemptIndex?: number;
6
7
  }
7
- export type GetAttemptOutput = ReturnType<typeof getAttempt>;
8
- export declare function getAttemptTool(input: GetAttemptInput): Promise<GetAttemptOutput>;
8
+ export interface MartinGetAttemptOutput {
9
+ source: string;
10
+ sourceKind: "file" | "loop_id" | "latest" | "runs_root";
11
+ loop: ReturnType<typeof buildLoopPreview>;
12
+ attempt: ReturnType<typeof buildAttemptSummary>;
13
+ warnings: string[];
14
+ }
15
+ export declare function martinGetAttemptTool(input: MartinGetAttemptInput): Promise<MartinGetAttemptOutput>;
@@ -1,6 +1,15 @@
1
- import { getAttempt, loadSelectedRun } from "./cockpit-support.js";
2
- export async function getAttemptTool(input) {
3
- const loop = await loadSelectedRun({ loopId: input.loopId, runsDir: input.runsDir });
4
- return getAttempt(loop, input.attemptIndex);
1
+ import { buildAttemptArtifactsReference, buildAttemptSummary, buildLoopPreview } from "./tool-support.js";
2
+ import { loadAttemptFromLoop } from "./run-store.js";
3
+ export async function martinGetAttemptTool(input) {
4
+ const { detail, attempt } = await loadAttemptFromLoop(input);
5
+ const artifacts = detail.canonicalRunDirectory
6
+ ? await buildAttemptArtifactsReference(detail.runsRoot, detail.loop.loopId, attempt.index)
7
+ : undefined;
8
+ return {
9
+ source: detail.source,
10
+ sourceKind: detail.sourceKind,
11
+ loop: buildLoopPreview(detail.loop),
12
+ attempt: buildAttemptSummary(attempt, artifacts),
13
+ warnings: detail.warnings
14
+ };
5
15
  }
6
- //# sourceMappingURL=get-attempt.js.map
@@ -1,17 +1,24 @@
1
- import type { LoopRunRecord } from "../vendor/core/index.js";
2
- import { summarizeRun } from "./cockpit-support.js";
3
- export interface GetRunInput {
1
+ import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
2
+ export interface MartinGetRunInput {
3
+ file?: string;
4
4
  loopId?: string;
5
5
  runsDir?: string;
6
6
  latest?: boolean;
7
7
  }
8
- export interface GetRunOutput {
9
- summary: ReturnType<typeof summarizeRun>;
10
- task: LoopRunRecord["task"];
11
- budget: LoopRunRecord["budget"];
12
- cost: LoopRunRecord["cost"];
13
- attempts: LoopRunRecord["attempts"];
14
- createdAt: string;
15
- updatedAt: string;
8
+ export interface MartinGetRunOutput {
9
+ source: string;
10
+ sourceKind: "file" | "loop_id" | "latest" | "runs_root";
11
+ loop: ReturnType<typeof buildLoopPreview>;
12
+ budget: ReturnType<typeof buildBudgetSnapshot>;
13
+ cost: ReturnType<typeof buildCostSnapshot>;
14
+ verification: ReturnType<typeof buildVerificationSummary>;
15
+ artifacts: ReturnType<typeof buildArtifactSummary>;
16
+ inspection: {
17
+ runsRoot: string;
18
+ canonicalRunDirectory?: string;
19
+ canonicalLoopRecordPath?: string;
20
+ ledgerPath?: string;
21
+ };
22
+ warnings: string[];
16
23
  }
17
- export declare function getRunTool(input: GetRunInput): Promise<GetRunOutput>;
24
+ export declare function martinGetRunTool(input: MartinGetRunInput): Promise<MartinGetRunOutput>;
@@ -1,14 +1,23 @@
1
- import { loadSelectedRun, summarizeRun } from "./cockpit-support.js";
2
- export async function getRunTool(input) {
3
- const loop = await loadSelectedRun(input);
1
+ import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
2
+ import { loadDetailedLoopRecord, readLedgerEvents } from "./run-store.js";
3
+ export async function martinGetRunTool(input) {
4
+ const detail = await loadDetailedLoopRecord(input);
5
+ const ledgerEvents = await readLedgerEvents(detail);
6
+ const verification = buildVerificationSummary(detail.loop, ledgerEvents);
4
7
  return {
5
- summary: summarizeRun(loop),
6
- task: loop.task,
7
- budget: loop.budget,
8
- cost: loop.cost,
9
- attempts: loop.attempts,
10
- createdAt: loop.createdAt,
11
- updatedAt: loop.updatedAt
8
+ source: detail.source,
9
+ sourceKind: detail.sourceKind,
10
+ loop: buildLoopPreview(detail.loop),
11
+ budget: buildBudgetSnapshot(detail.loop.budget),
12
+ cost: buildCostSnapshot(detail.loop.cost),
13
+ verification,
14
+ artifacts: buildArtifactSummary(detail.loop),
15
+ inspection: {
16
+ runsRoot: detail.runsRoot,
17
+ ...(detail.canonicalRunDirectory ? { canonicalRunDirectory: detail.canonicalRunDirectory } : {}),
18
+ ...(detail.canonicalLoopRecordPath ? { canonicalLoopRecordPath: detail.canonicalLoopRecordPath } : {}),
19
+ ...(detail.ledgerPath ? { ledgerPath: detail.ledgerPath } : {})
20
+ },
21
+ warnings: [...detail.warnings, ...verification.warnings]
12
22
  };
13
23
  }
14
- //# sourceMappingURL=get-run.js.map
@@ -1,3 +1,4 @@
1
+ import { type LoopPreview } from "./tool-support.js";
1
2
  export interface GetStatusInput {
2
3
  /** JSON-serialized LoopRecord. */
3
4
  loopJson?: string;
@@ -11,6 +12,7 @@ export interface GetStatusInput {
11
12
  latest?: boolean;
12
13
  }
13
14
  export interface GetStatusOutput {
15
+ source: string;
14
16
  loopId: string;
15
17
  status: string;
16
18
  lifecycleState: string;
@@ -22,5 +24,14 @@ export interface GetStatusOutput {
22
24
  remainingBudgetUsd: number;
23
25
  remainingIterations: number;
24
26
  remainingTokens: number;
27
+ budget: {
28
+ maxUsd: number;
29
+ softLimitUsd: number;
30
+ maxIterations: number;
31
+ maxTokens: number;
32
+ };
33
+ inspection: {
34
+ loop: LoopPreview;
35
+ };
25
36
  }
26
37
  export declare function getStatusTool(input: GetStatusInput): Promise<GetStatusOutput>;
@@ -1,5 +1,6 @@
1
1
  import { evaluateCostGovernor } from "../vendor/core/index.js";
2
2
  import { loadLoopRecordForStatus } from "./run-store.js";
3
+ import { buildLoopPreview } from "./tool-support.js";
3
4
  export async function getStatusTool(input) {
4
5
  const resolved = await loadLoopRecordForStatus(input);
5
6
  const loop = resolved.loop;
@@ -14,6 +15,7 @@ export async function getStatusTool(input) {
14
15
  attemptsUsed: loop.attempts.length
15
16
  });
16
17
  return {
18
+ source: resolved.source,
17
19
  loopId: loop.loopId,
18
20
  status: loop.status,
19
21
  lifecycleState: loop.lifecycleState,
@@ -24,7 +26,15 @@ export async function getStatusTool(input) {
24
26
  shouldStop: costState.shouldStop,
25
27
  remainingBudgetUsd: costState.remainingBudgetUsd,
26
28
  remainingIterations: costState.remainingIterations,
27
- remainingTokens: costState.remainingTokens
29
+ remainingTokens: costState.remainingTokens,
30
+ budget: {
31
+ maxUsd: loop.budget.maxUsd,
32
+ softLimitUsd: loop.budget.softLimitUsd,
33
+ maxIterations: loop.budget.maxIterations,
34
+ maxTokens: loop.budget.maxTokens
35
+ },
36
+ inspection: {
37
+ loop: buildLoopPreview(loop)
38
+ }
28
39
  };
29
40
  }
30
- //# sourceMappingURL=get-status.js.map
@@ -1,11 +1,14 @@
1
- import { type VerificationResultSummary } from "./cockpit-support.js";
2
- export interface GetVerificationResultsInput {
1
+ import { buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
2
+ export interface MartinGetVerificationResultsInput {
3
+ file?: string;
3
4
  loopId?: string;
4
5
  runsDir?: string;
5
- latest?: boolean;
6
6
  }
7
- export interface GetVerificationResultsOutput {
8
- loopId: string;
9
- results: VerificationResultSummary[];
7
+ export interface MartinGetVerificationResultsOutput {
8
+ source: string;
9
+ sourceKind: "file" | "loop_id" | "latest" | "runs_root";
10
+ loop: ReturnType<typeof buildLoopPreview>;
11
+ verification: ReturnType<typeof buildVerificationSummary>;
12
+ warnings: string[];
10
13
  }
11
- export declare function getVerificationResultsTool(input: GetVerificationResultsInput): Promise<GetVerificationResultsOutput>;
14
+ export declare function martinGetVerificationResultsTool(input: MartinGetVerificationResultsInput): Promise<MartinGetVerificationResultsOutput>;
@@ -1,9 +1,14 @@
1
- import { extractVerificationResults, loadSelectedRun } from "./cockpit-support.js";
2
- export async function getVerificationResultsTool(input) {
3
- const loop = await loadSelectedRun(input);
1
+ import { buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
2
+ import { loadDetailedLoopRecord, readLedgerEvents } from "./run-store.js";
3
+ export async function martinGetVerificationResultsTool(input) {
4
+ const detail = await loadDetailedLoopRecord(input);
5
+ const ledgerEvents = await readLedgerEvents(detail);
6
+ const verification = buildVerificationSummary(detail.loop, ledgerEvents);
4
7
  return {
5
- loopId: loop.loopId,
6
- results: extractVerificationResults(loop)
8
+ source: detail.source,
9
+ sourceKind: detail.sourceKind,
10
+ loop: buildLoopPreview(detail.loop),
11
+ verification,
12
+ warnings: [...detail.warnings, ...verification.warnings]
7
13
  };
8
14
  }
9
- //# sourceMappingURL=get-verification-results.js.map
@@ -1,4 +1,5 @@
1
1
  import { type PortfolioSnapshot } from "../vendor/contracts/index.js";
2
+ import { type LoopPreview } from "./tool-support.js";
2
3
  export interface InspectLoopInput {
3
4
  /** Optional path to a JSON, JSONL, or run-store directory under the Martin runs root. */
4
5
  file?: string;
@@ -9,5 +10,13 @@ export interface InspectLoopOutput {
9
10
  source: string;
10
11
  loopCount: number;
11
12
  portfolio: PortfolioSnapshot;
13
+ latestRun?: LoopPreview;
14
+ recentRuns: LoopPreview[];
15
+ statusBreakdown: Record<string, number>;
16
+ lifecycleBreakdown: Record<string, number>;
17
+ inspection: {
18
+ sourceKind: "file" | "runs_root";
19
+ };
20
+ warnings: string[];
12
21
  }
13
22
  export declare function inspectLoopTool(input: InspectLoopInput): Promise<InspectLoopOutput>;
@@ -1,12 +1,21 @@
1
1
  import { buildPortfolioSnapshot } from "../vendor/contracts/index.js";
2
2
  import { loadLoopRecordsForInspect } from "./run-store.js";
3
+ import { buildLoopCollectionSummary } from "./tool-support.js";
3
4
  export async function inspectLoopTool(input) {
4
5
  const inspection = await loadLoopRecordsForInspect(input);
5
6
  const loops = inspection.loops;
7
+ const summary = buildLoopCollectionSummary(inspection.loops);
6
8
  return {
7
9
  source: inspection.source,
8
10
  loopCount: loops.length,
9
- portfolio: buildPortfolioSnapshot(loops)
11
+ portfolio: buildPortfolioSnapshot(loops),
12
+ ...(summary.latestRun ? { latestRun: summary.latestRun } : {}),
13
+ recentRuns: summary.recentRuns,
14
+ statusBreakdown: summary.statusBreakdown,
15
+ lifecycleBreakdown: summary.lifecycleBreakdown,
16
+ inspection: {
17
+ sourceKind: input.file ? "file" : "runs_root"
18
+ },
19
+ warnings: inspection.warnings
10
20
  };
11
21
  }
12
- //# sourceMappingURL=inspect-loop.js.map
@@ -1,9 +1,29 @@
1
- import { type RunSummary } from "./cockpit-support.js";
2
- export interface ListRunsInput {
1
+ import { buildLoopPreview } from "./tool-support.js";
2
+ export interface MartinListRunsInput {
3
3
  runsDir?: string;
4
4
  limit?: number;
5
+ status?: string;
6
+ lifecycleState?: string;
7
+ adapterId?: string;
8
+ model?: string;
9
+ updatedAfter?: string;
5
10
  }
6
- export interface ListRunsOutput {
7
- runs: RunSummary[];
11
+ export interface MartinListRunsOutput {
12
+ source: string;
13
+ runsRoot: string;
14
+ filters: {
15
+ limit: number;
16
+ status?: string;
17
+ lifecycleState?: string;
18
+ adapterId?: string;
19
+ model?: string;
20
+ updatedAfter?: string;
21
+ };
22
+ loopCount: number;
23
+ latestRun?: ReturnType<typeof buildLoopPreview>;
24
+ recentRuns: Array<ReturnType<typeof buildLoopPreview>>;
25
+ statusBreakdown: Record<string, number>;
26
+ lifecycleBreakdown: Record<string, number>;
27
+ warnings: string[];
8
28
  }
9
- export declare function listRunsTool(input: ListRunsInput): Promise<ListRunsOutput>;
29
+ export declare function martinListRunsTool(input: MartinListRunsInput): Promise<MartinListRunsOutput>;
@@ -1,7 +1,24 @@
1
- import { listRunSummaries } from "./cockpit-support.js";
2
- export async function listRunsTool(input) {
1
+ import { buildLoopCollectionSummary, buildLoopPreview } from "./tool-support.js";
2
+ import { listLoopRecords } from "./run-store.js";
3
+ export async function martinListRunsTool(input) {
4
+ const result = await listLoopRecords(input);
5
+ const summary = buildLoopCollectionSummary(result.loops);
3
6
  return {
4
- runs: await listRunSummaries(input)
7
+ source: result.source,
8
+ runsRoot: result.runsRoot,
9
+ filters: {
10
+ limit: input.limit ?? 20,
11
+ ...(input.status ? { status: input.status } : {}),
12
+ ...(input.lifecycleState ? { lifecycleState: input.lifecycleState } : {}),
13
+ ...(input.adapterId ? { adapterId: input.adapterId } : {}),
14
+ ...(input.model ? { model: input.model } : {}),
15
+ ...(input.updatedAfter ? { updatedAfter: input.updatedAfter } : {})
16
+ },
17
+ loopCount: result.loops.length,
18
+ ...(summary.latestRun ? { latestRun: summary.latestRun } : {}),
19
+ recentRuns: result.loops.map((loop) => buildLoopPreview(loop)),
20
+ statusBreakdown: summary.statusBreakdown,
21
+ lifecycleBreakdown: summary.lifecycleBreakdown,
22
+ warnings: result.warnings
5
23
  };
6
24
  }
7
- //# sourceMappingURL=list-runs.js.map
@@ -58,7 +58,13 @@ export async function martinPreflightTool(input) {
58
58
  },
59
59
  execution: {
60
60
  requestedEngine: engine,
61
- engineAvailability,
61
+ engineAvailability: {
62
+ available: engineAvailability.available,
63
+ detail: engineAvailability.detail,
64
+ ...(engineAvailability.resolvedPath
65
+ ? { resolvedPath: engineAvailability.resolvedPath }
66
+ : {})
67
+ },
62
68
  runsRoot: resolveRunsRoot(process.env),
63
69
  pathScope: {
64
70
  repoRoot: workingDirectory,
@@ -73,4 +79,3 @@ export async function martinPreflightTool(input) {
73
79
  }
74
80
  };
75
81
  }
76
- //# sourceMappingURL=preflight.js.map
@@ -1,8 +1,41 @@
1
- import { buildRunDossier } from "./cockpit-support.js";
2
- export interface RunDossierInput {
1
+ import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildEventSummaries, buildLoopPreview, buildVerificationSummary } from "./tool-support.js";
2
+ export interface MartinRunDossierInput {
3
+ file?: string;
3
4
  loopId?: string;
4
5
  runsDir?: string;
5
6
  latest?: boolean;
6
7
  }
7
- export type RunDossierOutput = ReturnType<typeof buildRunDossier>;
8
- export declare function runDossierTool(input: RunDossierInput): Promise<RunDossierOutput>;
8
+ export interface MartinRunDossierOutput {
9
+ source: string;
10
+ sourceKind: "file" | "loop_id" | "latest" | "runs_root";
11
+ loop: ReturnType<typeof buildLoopPreview>;
12
+ budget: ReturnType<typeof buildBudgetSnapshot>;
13
+ cost: ReturnType<typeof buildCostSnapshot>;
14
+ attempts: Array<{
15
+ index: number;
16
+ attemptId?: string;
17
+ adapterId?: string;
18
+ model?: string;
19
+ failureClass?: string;
20
+ intervention?: string;
21
+ startedAt?: string;
22
+ completedAt?: string;
23
+ summary?: string;
24
+ artifactFiles: string[];
25
+ }>;
26
+ verification: ReturnType<typeof buildVerificationSummary>;
27
+ artifacts: ReturnType<typeof buildArtifactSummary>;
28
+ recentEvents: ReturnType<typeof buildEventSummaries>;
29
+ related: {
30
+ resources: string[];
31
+ prompts: string[];
32
+ };
33
+ inspection: {
34
+ runsRoot: string;
35
+ canonicalRunDirectory?: string;
36
+ canonicalLoopRecordPath?: string;
37
+ ledgerPath?: string;
38
+ };
39
+ warnings: string[];
40
+ }
41
+ export declare function martinRunDossierTool(input: MartinRunDossierInput): Promise<MartinRunDossierOutput>;
@@ -1,6 +1,41 @@
1
- import { buildRunDossier, loadSelectedRun } from "./cockpit-support.js";
2
- export async function runDossierTool(input) {
3
- const loop = await loadSelectedRun(input);
4
- return buildRunDossier(loop);
1
+ import { buildArtifactSummary, buildBudgetSnapshot, buildCostSnapshot, buildEventSummaries, buildLoopPreview, buildSuggestedPromptNames, buildSuggestedResourceUris, buildVerificationSummary } from "./tool-support.js";
2
+ import { loadDetailedLoopRecord, readAttemptArtifactFiles, readLedgerEvents } from "./run-store.js";
3
+ export async function martinRunDossierTool(input) {
4
+ const detail = await loadDetailedLoopRecord(input);
5
+ const ledgerEvents = await readLedgerEvents(detail);
6
+ const verification = buildVerificationSummary(detail.loop, ledgerEvents);
7
+ const attempts = await Promise.all(detail.loop.attempts.map(async (attempt) => ({
8
+ index: attempt.index,
9
+ ...(attempt.attemptId ? { attemptId: attempt.attemptId } : {}),
10
+ ...(attempt.adapterId ? { adapterId: attempt.adapterId } : {}),
11
+ ...(attempt.model ? { model: attempt.model } : {}),
12
+ ...(attempt.failureClass ? { failureClass: attempt.failureClass } : {}),
13
+ ...(attempt.intervention ? { intervention: attempt.intervention } : {}),
14
+ ...(attempt.startedAt ? { startedAt: attempt.startedAt } : {}),
15
+ ...(attempt.completedAt ? { completedAt: attempt.completedAt } : {}),
16
+ ...(attempt.summary ? { summary: attempt.summary } : {}),
17
+ artifactFiles: await readAttemptArtifactFiles(detail, attempt.index)
18
+ })));
19
+ return {
20
+ source: detail.source,
21
+ sourceKind: detail.sourceKind,
22
+ loop: buildLoopPreview(detail.loop),
23
+ budget: buildBudgetSnapshot(detail.loop.budget),
24
+ cost: buildCostSnapshot(detail.loop.cost),
25
+ attempts,
26
+ verification,
27
+ artifacts: buildArtifactSummary(detail.loop),
28
+ recentEvents: buildEventSummaries(detail.loop, 8),
29
+ related: {
30
+ resources: buildSuggestedResourceUris(detail.loop.loopId),
31
+ prompts: buildSuggestedPromptNames()
32
+ },
33
+ inspection: {
34
+ runsRoot: detail.runsRoot,
35
+ ...(detail.canonicalRunDirectory ? { canonicalRunDirectory: detail.canonicalRunDirectory } : {}),
36
+ ...(detail.canonicalLoopRecordPath ? { canonicalLoopRecordPath: detail.canonicalLoopRecordPath } : {}),
37
+ ...(detail.ledgerPath ? { ledgerPath: detail.ledgerPath } : {})
38
+ },
39
+ warnings: [...detail.warnings, ...verification.warnings]
40
+ };
5
41
  }
6
- //# sourceMappingURL=run-dossier.js.map
@@ -1,3 +1,5 @@
1
+ import { type LoopBudget } from "../vendor/contracts/index.js";
2
+ import { buildArtifactSummary, buildVerificationSummary, buildLoopPreview, type MartinEngine } from "./tool-support.js";
1
3
  export interface RunLoopInput {
2
4
  objective: string;
3
5
  workingDirectory?: string;
@@ -20,5 +22,22 @@ export interface RunLoopOutput {
20
22
  costUsd: number;
21
23
  verificationPassed: boolean;
22
24
  loopId: string;
25
+ pressure: string;
26
+ shouldStop: boolean;
27
+ remainingBudgetUsd: number;
28
+ remainingIterations: number;
29
+ remainingTokens: number;
30
+ engine: MartinEngine;
31
+ workingDirectory: string;
32
+ budget: LoopBudget;
33
+ inspection: {
34
+ runsRoot: string;
35
+ runDirectory: string;
36
+ loopRecordPath: string;
37
+ ledgerPath: string;
38
+ loop: ReturnType<typeof buildLoopPreview>;
39
+ verification: ReturnType<typeof buildVerificationSummary>;
40
+ artifacts: ReturnType<typeof buildArtifactSummary>;
41
+ };
23
42
  }
24
43
  export declare function runLoopTool(input: RunLoopInput): Promise<RunLoopOutput>;
@@ -1,13 +1,24 @@
1
1
  import { createClaudeCliAdapter, createCodexCliAdapter, createStubDirectProviderAdapter } from "../vendor/adapters/index.js";
2
- import { createFileRunStore, resolveRunsRoot, runMartin } from "../vendor/core/index.js";
2
+ import { createFileRunStore, evaluateCostGovernor, resolveRunsRoot, runMartin } from "../vendor/core/index.js";
3
3
  import { DEFAULT_BUDGET } from "../vendor/contracts/index.js";
4
4
  import { normalizeSafePathPatterns, resolveSafeRepoRoot } from "../server-validation.js";
5
+ import { MartinToolError } from "./tool-errors.js";
6
+ import { buildArtifactSummary, buildVerificationSummary, buildLoopPreview, buildRunRecordPaths, getEngineAvailability, resolveExecutionMode } from "./tool-support.js";
5
7
  export async function runLoopTool(input) {
6
8
  const workingDirectory = resolveSafeRepoRoot(input.workingDirectory);
7
9
  const engine = input.engine ?? "claude";
8
10
  const model = input.model;
9
11
  const allowedPaths = normalizeSafePathPatterns(input.allowedPaths, "allowedPaths");
10
12
  const deniedPaths = normalizeSafePathPatterns(input.deniedPaths, "deniedPaths");
13
+ const executionMode = resolveExecutionMode();
14
+ const engineAvailability = getEngineAvailability(engine);
15
+ if (executionMode.liveMode && !engineAvailability.available) {
16
+ throw new MartinToolError("engine_unavailable", `Engine '${engine}' is not available on PATH.`, {
17
+ category: "environment",
18
+ suggestion: "Install the requested CLI or set MARTIN_LIVE=false for stub execution.",
19
+ retryable: false
20
+ });
21
+ }
11
22
  const adapter = process.env.MARTIN_LIVE === "false"
12
23
  ? createStubDirectProviderAdapter({ label: "Stub adapter (MARTIN_LIVE=false)", providerId: "stub", model: "stub" })
13
24
  : engine === "codex"
@@ -44,6 +55,20 @@ export async function runLoopTool(input) {
44
55
  });
45
56
  const lastAttempt = result.loop.attempts.at(-1);
46
57
  const verificationPassed = lastAttempt !== undefined && result.decision.lifecycleState === "completed";
58
+ const costState = evaluateCostGovernor({
59
+ budget: result.loop.budget,
60
+ cost: {
61
+ actualUsd: result.loop.cost.actualUsd,
62
+ avoidedUsd: result.loop.cost.avoidedUsd ?? 0,
63
+ tokensIn: result.loop.cost.tokensIn,
64
+ tokensOut: result.loop.cost.tokensOut
65
+ },
66
+ attemptsUsed: result.loop.attempts.length
67
+ });
68
+ const runsRoot = resolveRunsRoot(process.env);
69
+ const recordPaths = buildRunRecordPaths(runsRoot, result.loop.loopId);
70
+ const verification = buildVerificationSummary(result.loop);
71
+ const artifacts = buildArtifactSummary(result.loop);
47
72
  return {
48
73
  status: result.loop.status,
49
74
  lifecycleState: result.decision.lifecycleState,
@@ -51,7 +76,20 @@ export async function runLoopTool(input) {
51
76
  attempts: result.loop.attempts.length,
52
77
  costUsd: result.loop.cost.actualUsd,
53
78
  verificationPassed,
54
- loopId: result.loop.loopId
79
+ loopId: result.loop.loopId,
80
+ pressure: costState.pressure,
81
+ shouldStop: costState.shouldStop,
82
+ remainingBudgetUsd: costState.remainingBudgetUsd,
83
+ remainingIterations: costState.remainingIterations,
84
+ remainingTokens: costState.remainingTokens,
85
+ engine,
86
+ workingDirectory,
87
+ budget,
88
+ inspection: {
89
+ ...recordPaths,
90
+ loop: buildLoopPreview(result.loop),
91
+ verification,
92
+ artifacts
93
+ }
55
94
  };
56
95
  }
57
- //# sourceMappingURL=run-loop.js.map