@martinloop/mcp 0.7.0 → 0.8.0

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 (73) hide show
  1. package/dist/package-version.d.ts +1 -1
  2. package/dist/package-version.js +1 -1
  3. package/dist/vendor/adapters/claude-cli.d.ts +11 -1
  4. package/dist/vendor/adapters/claude-cli.js +285 -71
  5. package/dist/vendor/adapters/cli-bridge.d.ts +12 -3
  6. package/dist/vendor/adapters/cli-bridge.js +129 -149
  7. package/dist/vendor/adapters/codex-cli.d.ts +3 -3
  8. package/dist/vendor/adapters/codex-cli.js +10 -24
  9. package/dist/vendor/adapters/codex-host.js +127 -132
  10. package/dist/vendor/adapters/index.d.ts +2 -1
  11. package/dist/vendor/adapters/index.js +2 -1
  12. package/dist/vendor/adapters/openai-compatible.js +88 -6
  13. package/dist/vendor/adapters/process-supervisor.d.ts +60 -0
  14. package/dist/vendor/adapters/process-supervisor.js +541 -0
  15. package/dist/vendor/adapters/verifier-only.d.ts +10 -1
  16. package/dist/vendor/adapters/verifier-only.js +43 -1
  17. package/dist/vendor/contracts/external-outcome.d.ts +102 -0
  18. package/dist/vendor/contracts/external-outcome.js +226 -0
  19. package/dist/vendor/contracts/index.d.ts +8 -1
  20. package/dist/vendor/contracts/index.js +2 -0
  21. package/dist/vendor/contracts/swarm-hosted.d.ts +204 -0
  22. package/dist/vendor/contracts/swarm-hosted.js +629 -0
  23. package/dist/vendor/contracts/swarm.d.ts +449 -0
  24. package/dist/vendor/contracts/swarm.js +550 -0
  25. package/dist/vendor/core/external-outcome.d.ts +34 -0
  26. package/dist/vendor/core/external-outcome.js +515 -0
  27. package/dist/vendor/core/grounding.js +1 -1
  28. package/dist/vendor/core/index.d.ts +47 -1
  29. package/dist/vendor/core/index.js +53 -3
  30. package/dist/vendor/core/leash.d.ts +1 -0
  31. package/dist/vendor/core/leash.js +13 -0
  32. package/dist/vendor/core/persistence/integrity.d.ts +4 -0
  33. package/dist/vendor/core/persistence/integrity.js +19 -6
  34. package/dist/vendor/core/persistence/swarm-integrity.d.ts +63 -0
  35. package/dist/vendor/core/persistence/swarm-integrity.js +309 -0
  36. package/dist/vendor/core/swarm/candidates.d.ts +78 -0
  37. package/dist/vendor/core/swarm/candidates.js +810 -0
  38. package/dist/vendor/core/swarm/evidence-projection.d.ts +87 -0
  39. package/dist/vendor/core/swarm/evidence-projection.js +128 -0
  40. package/dist/vendor/core/swarm/evidence.d.ts +40 -0
  41. package/dist/vendor/core/swarm/evidence.js +575 -0
  42. package/dist/vendor/core/swarm/hosted-export.d.ts +48 -0
  43. package/dist/vendor/core/swarm/hosted-export.js +362 -0
  44. package/dist/vendor/core/swarm/hosted-projection.d.ts +5 -0
  45. package/dist/vendor/core/swarm/hosted-projection.js +258 -0
  46. package/dist/vendor/core/swarm/index.d.ts +110 -0
  47. package/dist/vendor/core/swarm/index.js +1060 -0
  48. package/dist/vendor/core/swarm/integration.d.ts +76 -0
  49. package/dist/vendor/core/swarm/integration.js +615 -0
  50. package/dist/vendor/core/swarm/lifecycle.d.ts +72 -0
  51. package/dist/vendor/core/swarm/lifecycle.js +252 -0
  52. package/dist/vendor/core/swarm/live-runtime.d.ts +78 -0
  53. package/dist/vendor/core/swarm/live-runtime.js +1482 -0
  54. package/dist/vendor/core/swarm/live-store.d.ts +99 -0
  55. package/dist/vendor/core/swarm/live-store.js +860 -0
  56. package/dist/vendor/core/swarm/operational-reader.d.ts +17 -0
  57. package/dist/vendor/core/swarm/operational-reader.js +96 -0
  58. package/dist/vendor/core/swarm/operations.d.ts +29 -0
  59. package/dist/vendor/core/swarm/operations.js +128 -0
  60. package/dist/vendor/core/swarm/parent-receipt.d.ts +13 -0
  61. package/dist/vendor/core/swarm/parent-receipt.js +489 -0
  62. package/dist/vendor/core/swarm/receipt-projection.d.ts +26 -0
  63. package/dist/vendor/core/swarm/receipt-projection.js +120 -0
  64. package/dist/vendor/core/swarm/scheduler.d.ts +92 -0
  65. package/dist/vendor/core/swarm/scheduler.js +555 -0
  66. package/dist/vendor/core/swarm/verification.d.ts +70 -0
  67. package/dist/vendor/core/swarm/verification.js +295 -0
  68. package/dist/vendor/core/swarm/workspaces.d.ts +77 -0
  69. package/dist/vendor/core/swarm/workspaces.js +488 -0
  70. package/dist/vendor/core/verified-handoff.d.ts +4 -0
  71. package/dist/vendor/core/verified-handoff.js +4 -0
  72. package/package.json +1 -1
  73. package/server.json +2 -2
@@ -0,0 +1,17 @@
1
+ import type { SwarmLiveEvent, SwarmLivePlan } from "../../contracts/index.js";
2
+ import { type SwarmLiveSnapshot } from "./live-store.js";
3
+ export type SwarmOperationalSelector = {
4
+ runsRoot: string;
5
+ swarmId: string;
6
+ latest?: never;
7
+ } | {
8
+ runsRoot: string;
9
+ latest: true;
10
+ swarmId?: never;
11
+ };
12
+ export interface SwarmOperationalState {
13
+ plan: SwarmLivePlan;
14
+ snapshot: SwarmLiveSnapshot;
15
+ events: SwarmLiveEvent[];
16
+ }
17
+ export declare function readSwarmOperationalState(input: SwarmOperationalSelector): Promise<SwarmOperationalState>;
@@ -0,0 +1,96 @@
1
+ import { lstat, readdir, readFile, realpath } from "node:fs/promises";
2
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
3
+ import { openSwarmLiveStoreAtDirectory, SwarmLiveStoreError, } from "./live-store.js";
4
+ import { readSwarmReceiptProjection } from "./receipt-projection.js";
5
+ import { assertSwarmPathIdentifier } from "./workspaces.js";
6
+ export async function readSwarmOperationalState(input) {
7
+ const store = await selectOperationalStore(input);
8
+ return readOperationalState(store);
9
+ }
10
+ async function readOperationalState(store) {
11
+ for (let attempt = 0; attempt < 8; attempt += 1) {
12
+ const before = await store.readSnapshot();
13
+ const events = await store.readEvents();
14
+ const snapshot = await store.readSnapshot();
15
+ if (before.revision === snapshot.revision && events.length === snapshot.eventCount) {
16
+ return { plan: structuredClone(store.plan), snapshot: await projectCommittedOutcome(store, snapshot), events };
17
+ }
18
+ }
19
+ throw new SwarmLiveStoreError("STORE_READ_CONTENTION", "Swarm state changed continuously during inspection.");
20
+ }
21
+ async function projectCommittedOutcome(store, snapshot) {
22
+ const directory = store.paths().directory;
23
+ const runsRoot = dirname(dirname(directory));
24
+ const statusPath = join(directory, "evidence", "swarm-receipt-seal-status.json");
25
+ const status = await readExactJson(statusPath).catch(() => undefined);
26
+ if (status?.schemaVersion === "martin.swarm-receipt-seal-status.v1"
27
+ && status.swarmId === store.plan.swarmId
28
+ && status.planHash === store.plan.planHash
29
+ && status.state === "needs_review") {
30
+ return {
31
+ ...snapshot,
32
+ outcome: { state: "needs_review", reason: typeof status.reason === "string" ? status.reason : "terminal_evidence_sealing_failed" }
33
+ };
34
+ }
35
+ if (snapshot.outcome.state !== "verified")
36
+ return snapshot;
37
+ try {
38
+ await readSwarmReceiptProjection({ runsRoot, swarmId: store.plan.swarmId });
39
+ return snapshot;
40
+ }
41
+ catch {
42
+ return { ...snapshot, outcome: { state: "needs_review", reason: "terminal_evidence_sealing_pending" } };
43
+ }
44
+ }
45
+ async function readExactJson(path) {
46
+ const metadata = await lstat(path);
47
+ if (metadata.isSymbolicLink() || !metadata.isFile())
48
+ throw new Error("UNSAFE_SEAL_STATUS_PATH");
49
+ const parsed = JSON.parse(await readFile(path, "utf8"));
50
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
51
+ throw new Error("INVALID_SEAL_STATUS");
52
+ return parsed;
53
+ }
54
+ async function selectOperationalStore(input) {
55
+ if ("swarmId" in input && input.swarmId !== undefined) {
56
+ assertSwarmPathIdentifier(input.swarmId, "swarm ID");
57
+ }
58
+ const runsRoot = await realpath(resolve(input.runsRoot)).catch((error) => {
59
+ throw new SwarmLiveStoreError("MISSING_SWARM_STORE", "Swarm runs root does not exist.", { cause: error });
60
+ });
61
+ const swarmsPath = join(runsRoot, "_swarms");
62
+ const swarmsRoot = await realpath(swarmsPath).catch((error) => {
63
+ throw new SwarmLiveStoreError("MISSING_SWARM_STORE", "No live swarm store exists.", { cause: error });
64
+ });
65
+ assertContained(runsRoot, swarmsRoot);
66
+ if ("swarmId" in input && input.swarmId !== undefined) {
67
+ const directory = await realpath(join(swarmsRoot, input.swarmId)).catch((error) => {
68
+ throw new SwarmLiveStoreError("MISSING_SWARM_STORE", `Swarm store not found: ${input.swarmId}.`, { cause: error });
69
+ });
70
+ assertContained(swarmsRoot, directory);
71
+ return openSwarmLiveStoreAtDirectory({ directory, swarmId: input.swarmId });
72
+ }
73
+ const entries = await readdir(swarmsRoot, { withFileTypes: true });
74
+ const candidates = [];
75
+ for (const entry of entries) {
76
+ if (!entry.isDirectory() && !entry.isSymbolicLink())
77
+ continue;
78
+ assertSwarmPathIdentifier(entry.name, "swarm ID");
79
+ const directory = await realpath(join(swarmsRoot, entry.name));
80
+ assertContained(swarmsRoot, directory);
81
+ const store = await openSwarmLiveStoreAtDirectory({ directory, swarmId: entry.name });
82
+ candidates.push({ store, snapshot: await store.readSnapshot() });
83
+ }
84
+ candidates.sort((left, right) => right.snapshot.updatedAt.localeCompare(left.snapshot.updatedAt)
85
+ || left.snapshot.swarmId.localeCompare(right.snapshot.swarmId));
86
+ const selected = candidates[0];
87
+ if (!selected)
88
+ throw new SwarmLiveStoreError("MISSING_SWARM_STORE", "No live swarm store exists.");
89
+ return selected.store;
90
+ }
91
+ function assertContained(parent, child) {
92
+ const rel = relative(parent, child);
93
+ if (!rel || (!rel.startsWith("..") && !isAbsolute(rel)))
94
+ return;
95
+ throw new SwarmLiveStoreError("STORE_PATH_ESCAPE", "Swarm store path escapes the real runs root.");
96
+ }
@@ -0,0 +1,29 @@
1
+ import type { SwarmLiveEvent, SwarmLivePlan } from "../../contracts/index.js";
2
+ import { type SwarmLiveSnapshot } from "./live-store.js";
3
+ export type SwarmOperationalSelector = {
4
+ runsRoot: string;
5
+ swarmId: string;
6
+ latest?: never;
7
+ } | {
8
+ runsRoot: string;
9
+ latest: true;
10
+ swarmId?: never;
11
+ };
12
+ export interface SwarmOperationalState {
13
+ plan: SwarmLivePlan;
14
+ snapshot: SwarmLiveSnapshot;
15
+ events: SwarmLiveEvent[];
16
+ }
17
+ export interface SwarmOperationalCancellationResult {
18
+ outcome: "created" | "already_requested" | "already_terminal";
19
+ state: SwarmOperationalState;
20
+ }
21
+ export declare function readSwarmOperationalState(input: SwarmOperationalSelector): Promise<SwarmOperationalState>;
22
+ export declare function waitForSwarmOperationalRevision(input: SwarmOperationalSelector & {
23
+ afterRevision: number;
24
+ signal?: AbortSignal;
25
+ }): Promise<SwarmOperationalState>;
26
+ export declare function requestSwarmOperationalCancellation(input: SwarmOperationalSelector & {
27
+ reason: string;
28
+ requestedBy?: string;
29
+ }): Promise<SwarmOperationalCancellationResult>;
@@ -0,0 +1,128 @@
1
+ import { lstat, readdir, readFile, realpath } from "node:fs/promises";
2
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
3
+ import { openSwarmLiveStoreAtDirectory, SwarmLiveStoreError, } from "./live-store.js";
4
+ import { assertSwarmPathIdentifier } from "./workspaces.js";
5
+ import { readSwarmReceiptProjection } from "./receipt-projection.js";
6
+ export async function readSwarmOperationalState(input) {
7
+ const store = await selectOperationalStore(input);
8
+ return readOperationalState(store);
9
+ }
10
+ export async function waitForSwarmOperationalRevision(input) {
11
+ const store = await selectOperationalStore(input);
12
+ await store.waitForRevision(input.afterRevision, input.signal);
13
+ return readOperationalState(store);
14
+ }
15
+ export async function requestSwarmOperationalCancellation(input) {
16
+ const store = await selectOperationalStore(input);
17
+ const requestedAt = new Date().toISOString();
18
+ for (let attempt = 0; attempt < 8; attempt += 1) {
19
+ const state = await readOperationalState(store);
20
+ if (state.snapshot.outcome.state !== "running")
21
+ return { outcome: "already_terminal", state };
22
+ if (state.snapshot.cancellation)
23
+ return { outcome: "already_requested", state };
24
+ try {
25
+ await store.requestCancellation({
26
+ idempotencyKey: "cancel:operator",
27
+ requestedAt,
28
+ reason: input.reason,
29
+ ...(input.requestedBy === undefined ? {} : { requestedBy: input.requestedBy }),
30
+ }, { expectedRevision: state.snapshot.revision });
31
+ return { outcome: "created", state: await readOperationalState(store) };
32
+ }
33
+ catch (error) {
34
+ const code = typeof error === "object" && error !== null && "code" in error
35
+ ? String(error.code ?? "") : "";
36
+ if (code !== "STALE_REVISION" && code !== "IDEMPOTENCY_CONFLICT")
37
+ throw error;
38
+ }
39
+ }
40
+ throw new SwarmLiveStoreError("CANCEL_CONTENTION", "Cancellation could not acquire an authoritative revision.");
41
+ }
42
+ async function readOperationalState(store) {
43
+ for (let attempt = 0; attempt < 8; attempt += 1) {
44
+ const before = await store.readSnapshot();
45
+ const events = await store.readEvents();
46
+ const snapshot = await store.readSnapshot();
47
+ if (before.revision === snapshot.revision && events.length === snapshot.eventCount) {
48
+ return { plan: structuredClone(store.plan), snapshot: await projectCommittedOutcome(store, snapshot), events };
49
+ }
50
+ }
51
+ throw new SwarmLiveStoreError("STORE_READ_CONTENTION", "Swarm state changed continuously during inspection.");
52
+ }
53
+ async function projectCommittedOutcome(store, snapshot) {
54
+ const directory = store.paths().directory;
55
+ const runsRoot = dirname(dirname(directory));
56
+ const statusPath = join(directory, "evidence", "swarm-receipt-seal-status.json");
57
+ const status = await readExactJson(statusPath).catch(() => undefined);
58
+ if (status?.schemaVersion === "martin.swarm-receipt-seal-status.v1"
59
+ && status.swarmId === store.plan.swarmId
60
+ && status.planHash === store.plan.planHash
61
+ && status.state === "needs_review") {
62
+ return {
63
+ ...snapshot,
64
+ outcome: { state: "needs_review", reason: typeof status.reason === "string" ? status.reason : "terminal_evidence_sealing_failed" }
65
+ };
66
+ }
67
+ if (snapshot.outcome.state !== "verified")
68
+ return snapshot;
69
+ try {
70
+ await readSwarmReceiptProjection({ runsRoot, swarmId: store.plan.swarmId });
71
+ return snapshot;
72
+ }
73
+ catch {
74
+ return { ...snapshot, outcome: { state: "needs_review", reason: "terminal_evidence_sealing_pending" } };
75
+ }
76
+ }
77
+ async function readExactJson(path) {
78
+ const metadata = await lstat(path);
79
+ if (metadata.isSymbolicLink() || !metadata.isFile())
80
+ throw new Error("UNSAFE_SEAL_STATUS_PATH");
81
+ const parsed = JSON.parse(await readFile(path, "utf8"));
82
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
83
+ throw new Error("INVALID_SEAL_STATUS");
84
+ return parsed;
85
+ }
86
+ async function selectOperationalStore(input) {
87
+ if ("swarmId" in input && input.swarmId !== undefined) {
88
+ assertSwarmPathIdentifier(input.swarmId, "swarm ID");
89
+ }
90
+ const runsRoot = await realpath(resolve(input.runsRoot)).catch((error) => {
91
+ throw new SwarmLiveStoreError("MISSING_SWARM_STORE", "Swarm runs root does not exist.", { cause: error });
92
+ });
93
+ const swarmsPath = join(runsRoot, "_swarms");
94
+ const swarmsRoot = await realpath(swarmsPath).catch((error) => {
95
+ throw new SwarmLiveStoreError("MISSING_SWARM_STORE", "No live swarm store exists.", { cause: error });
96
+ });
97
+ assertContained(runsRoot, swarmsRoot);
98
+ if ("swarmId" in input && input.swarmId !== undefined) {
99
+ const directory = await realpath(join(swarmsRoot, input.swarmId)).catch((error) => {
100
+ throw new SwarmLiveStoreError("MISSING_SWARM_STORE", `Swarm store not found: ${input.swarmId}.`, { cause: error });
101
+ });
102
+ assertContained(swarmsRoot, directory);
103
+ return openSwarmLiveStoreAtDirectory({ directory, swarmId: input.swarmId });
104
+ }
105
+ const entries = await readdir(swarmsRoot, { withFileTypes: true });
106
+ const candidates = [];
107
+ for (const entry of entries) {
108
+ if (!entry.isDirectory() && !entry.isSymbolicLink())
109
+ continue;
110
+ assertSwarmPathIdentifier(entry.name, "swarm ID");
111
+ const directory = await realpath(join(swarmsRoot, entry.name));
112
+ assertContained(swarmsRoot, directory);
113
+ const store = await openSwarmLiveStoreAtDirectory({ directory, swarmId: entry.name });
114
+ candidates.push({ store, snapshot: await store.readSnapshot() });
115
+ }
116
+ candidates.sort((left, right) => right.snapshot.updatedAt.localeCompare(left.snapshot.updatedAt)
117
+ || left.snapshot.swarmId.localeCompare(right.snapshot.swarmId));
118
+ const selected = candidates[0];
119
+ if (!selected)
120
+ throw new SwarmLiveStoreError("MISSING_SWARM_STORE", "No live swarm store exists.");
121
+ return selected.store;
122
+ }
123
+ function assertContained(parent, child) {
124
+ const rel = relative(parent, child);
125
+ if (!rel || (!rel.startsWith("..") && !isAbsolute(rel)))
126
+ return;
127
+ throw new SwarmLiveStoreError("STORE_PATH_ESCAPE", "Swarm store path escapes the real runs root.");
128
+ }
@@ -0,0 +1,13 @@
1
+ import { type SwarmParentReceipt } from "../../contracts/index.js";
2
+ import type { ReadAndSealSwarmEvidenceResult } from "./evidence.js";
3
+ export declare class SwarmParentReceiptError extends Error {
4
+ readonly code: string;
5
+ constructor(code: string, message: string);
6
+ }
7
+ export declare function buildParentSwarmReceipt(sealed: ReadAndSealSwarmEvidenceResult): SwarmParentReceipt;
8
+ export declare function verifyParentSwarmReceipt(receipt: SwarmParentReceipt): {
9
+ ok: true;
10
+ } | {
11
+ ok: false;
12
+ reason: string;
13
+ };