synartesis 0.1.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.
- package/LICENSE +21 -0
- package/README.md +501 -0
- package/dist/chunk-K3QIPVBY.js +85 -0
- package/dist/chunk-K3QIPVBY.js.map +1 -0
- package/dist/chunk-X4VQNEP5.js +1383 -0
- package/dist/chunk-X4VQNEP5.js.map +1 -0
- package/dist/cli.js +1708 -0
- package/dist/cli.js.map +1 -0
- package/dist/demo-agent.js +67 -0
- package/dist/demo-agent.js.map +1 -0
- package/dist/proxy.js +913 -0
- package/dist/proxy.js.map +1 -0
- package/dist/toy-crm.js +293 -0
- package/dist/toy-crm.js.map +1 -0
- package/manifests/filesystem.yaml +97 -0
- package/manifests/git.yaml +77 -0
- package/manifests/github.yaml +175 -0
- package/manifests/memory.yaml +96 -0
- package/manifests/toy-crm.yaml +66 -0
- package/package.json +67 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/invocation.ts","../src/locate.ts","../src/style.ts","../src/journal/journal.ts","../src/canonical.ts","../src/journal/schema.ts","../src/manifest/load.ts","../src/manifest/template.ts","../src/manifest/verify.ts","../src/manifest/types.ts","../src/proxy/routing.ts","../src/proxy/upstream.ts","../src/manifest/match.ts","../src/proxy/snapshot.ts"],"sourcesContent":["import { accessSync, constants } from \"node:fs\";\nimport { basename, delimiter, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * How to invoke this CLI, as the reader would have to type it.\n *\n * Printing `synartesis approve ...` is only useful advice if that command\n * exists. Until someone installs it globally it does not, and telling a person\n * to run something that is not there is worse than saying nothing.\n */\nfunction onPath(command: string): boolean {\n const dirs = (process.env[\"PATH\"] ?? \"\").split(delimiter).filter((dir) => dir !== \"\");\n return dirs.some((dir) => {\n try {\n accessSync(join(dir, command), constants.X_OK);\n return true;\n } catch {\n return false;\n }\n });\n}\n\nlet cached: string | undefined;\n\nexport function cliCommand(): string {\n if (cached !== undefined) {\n return cached;\n }\n\n // Installed globally: the shim is a file named for the command itself.\n const invokedAs = process.argv[1];\n if (invokedAs !== undefined && basename(invokedAs) === \"synartesis\") {\n cached = \"synartesis\";\n return cached;\n }\n if (onPath(\"synartesis\")) {\n cached = \"synartesis\";\n return cached;\n }\n\n // Run straight out of a checkout. Spell out what actually works.\n cached = `node ${invokedAs ?? \"dist/cli.js\"}`;\n return cached;\n}\n\n/**\n * The same, worked out from inside the proxy, which lives beside the cli in\n * whatever directory the build put them.\n */\nexport function cliCommandFrom(moduleUrl: string): string {\n if (onPath(\"synartesis\")) {\n return \"synartesis\";\n }\n return `node ${fileURLToPath(new URL(\"cli.js\", moduleUrl))}`;\n}\n\n/**\n * How to start the proxy, as the reader would have to type it.\n *\n * `synartesis proxy` where the cli is reachable: one package and one word is\n * the line people paste into a client config, and it is the same line whether\n * this was installed or is being fetched on the spot. The separate\n * synartesis-proxy binary still exists and is still what an existing config\n * points at; it is simply no longer the shortest way to say it.\n */\nexport function proxyCommand(): string {\n if (onPath(\"synartesis\")) {\n return \"synartesis proxy\";\n }\n if (onPath(\"synartesis-proxy\")) {\n return \"synartesis-proxy\";\n }\n const invokedAs = process.argv[1];\n if (invokedAs !== undefined && invokedAs.endsWith(\"cli.js\")) {\n return `node ${invokedAs} proxy`;\n }\n return `node ${fileURLToPath(new URL(\"cli.js\", import.meta.url))} proxy`;\n}\n","import { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\n\n/**\n * Where the policy and the journal are, when nobody said.\n *\n * Typing --manifest and --journal on every command is the friction people\n * actually feel. A policy that belongs to a project sits in it, so both are\n * looked for the way a version control tool looks for its root: from here,\n * upwards, until found.\n *\n * And when there is nothing above you either, there is one home. Most of what\n * anyone guards -- an agent's memory, a notes directory, an account somewhere\n * -- does not belong to a project at all, and making each one its own\n * directory with its own manifest and its own journal is how a home ends up\n * with synartesis-this and synartesis-that in it and no single place that\n * knows what an agent has done.\n */\nexport const MANIFEST_NAME = \"synartesis.yaml\";\nexport const JOURNAL_NAME = \"journal.db\";\nconst NESTED_JOURNAL = join(\".synartesis\", JOURNAL_NAME);\n\n/** Overridable, so a test never has to touch the real one. */\nexport function home(): string {\n return process.env[\"SYNARTESIS_HOME\"] ?? join(homedir(), \".synartesis\");\n}\n\nfunction walkUp(from: string, name: string): string | undefined {\n let dir = resolve(from);\n for (;;) {\n const candidate = join(dir, name);\n if (existsSync(candidate)) {\n return candidate;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n return undefined;\n }\n dir = parent;\n }\n}\n\nexport function findManifest(given?: string): string {\n if (given !== undefined) {\n return given;\n }\n return walkUp(process.cwd(), MANIFEST_NAME) ?? join(home(), MANIFEST_NAME);\n}\n\n/**\n * A journal beside the manifest, since that is where a proxy started from that\n * manifest will have been told to put one. Falls back to the nested default so\n * an existing setup keeps working.\n */\nexport function findJournal(given?: string, manifest?: string): string {\n if (given !== undefined) {\n return given;\n }\n\n const near = manifest === undefined ? undefined : dirname(resolve(manifest));\n for (const dir of [near, process.cwd()]) {\n if (dir === undefined) {\n continue;\n }\n for (const name of [JOURNAL_NAME, NESTED_JOURNAL]) {\n const candidate = join(dir, name);\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n }\n\n const found = walkUp(process.cwd(), NESTED_JOURNAL) ?? walkUp(process.cwd(), JOURNAL_NAME);\n if (found !== undefined) {\n return found;\n }\n\n // Nothing exists yet. Beside the policy, so the proxy that creates it and the\n // cli that reads it agree without either being told where to look.\n return near === undefined ? join(home(), JOURNAL_NAME) : join(near, JOURNAL_NAME);\n}\n","/**\n * The house style, translated for a terminal.\n *\n * Oxblood and a warm off-white, uppercase letterspaced labels, everything\n * quiet except the one thing that matters. A terminal has no serif and no\n * engraving, so what carries over is the palette, the capitals and the\n * restraint.\n */\nconst ESC = \"\\u001b[\";\nconst ACCENT = `${ESC}38;2;226;134;118m`;\n// Deep oxblood with a warm off-white on it, which holds on a light terminal\n// as well as a dark one.\nconst ON_ACCENT = `${ESC}48;2;94;20;32m${ESC}38;2;246;233;229m`;\nconst BRIGHT = `${ESC}38;2;246;233;229m`;\nconst DIM = `${ESC}2m`;\nconst BOLD = `${ESC}1m`;\nconst RESET = `${ESC}0m`;\n\n/**\n * Colour is for people. Piped output goes to a program that wants the text and\n * not the escape codes, and NO_COLOR is the convention for saying so outright.\n */\nconst enabled =\n process.env[\"NO_COLOR\"] === undefined &&\n process.env[\"TERM\"] !== \"dumb\" &&\n process.stdout.isTTY;\n\nfunction paint(codes: string, text: string): string {\n return enabled ? `${codes}${text}${RESET}` : text;\n}\n\n/**\n * Letterspacing, the one typographic move a terminal can actually make. Only\n * ever applied to the plain ascii labels below, so splitting by code unit is\n * safe here in a way it would not be for arbitrary text.\n */\nexport function spaced(text: string): string {\n return Array.from(text).join(\" \");\n}\n\nexport const style = {\n /** A section label: small, capital, spaced out. */\n label: (text: string): string => paint(ACCENT + DIM, spaced(text.toUpperCase())),\n heading: (text: string): string => paint(BRIGHT + BOLD, text.toUpperCase()),\n accent: (text: string): string => paint(ACCENT, text),\n strong: (text: string): string => paint(BOLD, text),\n quiet: (text: string): string => paint(DIM, text),\n /** Off-white on oxblood, the way the wordmark is set. */\n plate: (text: string): string => paint(ON_ACCENT + BOLD, ` ${text} `),\n};\n\nexport const WORDMARK = spaced(\"SYNARTESIS\");\n\n/**\n * A meander, the Greek fret. A single line that turns back on itself without\n * ever breaking, which is the same idea the name carries and the same idea the\n * product does.\n */\nexport function meander(width: number): string {\n const unit = \"\\u2517\\u2501\\u2513\\u250f\\u2501\\u251b\";\n return unit.repeat(Math.max(1, Math.ceil(width / unit.length))).slice(0, width);\n}\n\n/** A dim fret rule, for separating one region of output from the next. */\nexport function rule(width = 48): string {\n return style.quiet(meander(width));\n}\n\n/**\n * Greek sunartesis, a fastening together. The whole idea in one word: every\n * action is bound to the action that undoes it.\n */\nexport const GREEK = spaced(\"\\u03a3\\u03a5\\u039d\\u0391\\u03a1\\u03a4\\u0397\\u03a3\\u0399\\u03a3\");\nexport const MEANING = \"a fastening together\";\nexport const TAGLINE = \"an undo layer for AI agents\";\n\n/** One compact line, for a process whose real output is something else. */\nexport function mark(): string {\n return `\\n ${style.plate(WORDMARK)} ${style.quiet(MEANING)}\\n\\n`;\n}\n\nexport function banner(): string {\n return [\n \"\",\n ` ${style.plate(WORDMARK)}`,\n ` ${style.accent(meander(24))}`,\n \"\",\n ` ${style.quiet(GREEK)} ${style.quiet(\"\\u00b7\")} ${style.quiet(MEANING)}`,\n \"\",\n ` ${style.accent(spaced(TAGLINE.toUpperCase()))}`,\n ` ${style.quiet(\"Every action is bound to the action that undoes it.\")}`,\n \"\",\n ].join(\"\\n\");\n}\n","import { existsSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nimport Database from \"better-sqlite3\";\nimport { z } from \"zod\";\n\nimport { canonical } from \"../canonical.js\";\nimport { JournalError } from \"../errors.js\";\nimport { SCHEMA_SQL, SCHEMA_VERSION } from \"./schema.js\";\n\nexport type RunStatus = \"active\" | \"complete\" | \"rolled_back\" | \"partial\";\n\n/**\n * How a row says its approval was moved onto the action that ran. There is no\n * status for it -- adding one would change the schema, and an older journal\n * cannot be read under a newer schema -- so the row is denied and this is how\n * it is told apart from a person having said no.\n */\nexport const SPENT_APPROVAL = \"approval was used by action\";\n\nexport type ActionStatus =\n | \"pending\"\n | \"gated\"\n /** A person said yes; the agent has not made the call again yet. */\n | \"approved\"\n | \"denied\"\n | \"applied\"\n | \"failed\"\n | \"rolling_back\"\n | \"rolled_back\"\n | \"unrecoverable\";\n\nexport type ActionClass =\n | \"unclassified\"\n | \"readonly\"\n | \"reversible\"\n | \"compensable\"\n | \"irreversible\";\n\nexport interface RunRow {\n readonly id: string;\n readonly label: string | undefined;\n readonly startedAt: string;\n readonly endedAt: string | undefined;\n readonly status: RunStatus;\n}\n\nexport interface ActionRow {\n readonly id: string;\n readonly runId: string;\n readonly seq: number;\n readonly server: string;\n readonly tool: string;\n readonly args: unknown;\n readonly class: ActionClass;\n readonly snapshot: unknown;\n readonly postSnapshot: unknown;\n readonly result: unknown;\n readonly inverse: unknown;\n /** The read that detects drift, resolved at capture time. */\n readonly verify: unknown;\n readonly error: string | undefined;\n readonly idempotencyKey: string;\n readonly status: ActionStatus;\n readonly approvedBy: string | undefined;\n readonly approvedAt: string | undefined;\n readonly ts: string;\n}\n\nexport interface RecordPendingInput {\n readonly runId: string;\n readonly server: string;\n readonly tool: string;\n readonly args: unknown;\n readonly class: ActionClass;\n}\n\nexport interface AppliedOutcome {\n readonly result: unknown;\n /** Fully resolved at capture time (D5); absent when the class has no inverse. */\n readonly inverse?: unknown;\n /** The resolved read used to detect drift later. */\n readonly verify?: unknown;\n /** Post-state for drift detection; absent when the post-read could not run. */\n readonly postSnapshot?: unknown;\n /**\n * A non-fatal problem. `status` says what happened to the call; `error` says\n * what went wrong, and the two are independent: an applied call whose inverse\n * could not be built is both applied and no longer safely reversible.\n */\n readonly warning?: string;\n}\n\nexport interface PendingAction {\n readonly actionId: string;\n readonly seq: number;\n readonly idempotencyKey: string;\n}\n\nconst runSchema = z.object({\n id: z.string(),\n label: z.string().nullable(),\n started_at: z.string(),\n ended_at: z.string().nullable(),\n status: z.enum([\"active\", \"complete\", \"rolled_back\", \"partial\"]),\n});\n\nconst actionSchema = z.object({\n id: z.string(),\n run_id: z.string(),\n seq: z.number(),\n server: z.string(),\n tool: z.string(),\n args_json: z.string(),\n class: z.enum([\"unclassified\", \"readonly\", \"reversible\", \"compensable\", \"irreversible\"]),\n snapshot_json: z.string().nullable(),\n post_snapshot_json: z.string().nullable(),\n result_json: z.string().nullable(),\n inverse_json: z.string().nullable(),\n verify_json: z.string().nullable(),\n error: z.string().nullable(),\n idempotency_key: z.string(),\n status: z.enum([\n \"pending\",\n \"gated\",\n \"approved\",\n \"denied\",\n \"applied\",\n \"failed\",\n \"rolling_back\",\n \"rolled_back\",\n \"unrecoverable\",\n ]),\n approved_by: z.string().nullable(),\n approved_at: z.string().nullable(),\n ts: z.string(),\n});\n\nfunction decode(value: string | null): unknown {\n return value === null ? undefined : (JSON.parse(value) as unknown);\n}\n\nfunction orUndefined(value: string | null): string | undefined {\n return value === null ? undefined : value;\n}\n\nfunction toRun(raw: unknown): RunRow {\n const row = runSchema.parse(raw);\n return {\n id: row.id,\n label: orUndefined(row.label),\n startedAt: row.started_at,\n endedAt: orUndefined(row.ended_at),\n status: row.status,\n };\n}\n\nfunction toAction(raw: unknown): ActionRow {\n const row = actionSchema.parse(raw);\n return {\n id: row.id,\n runId: row.run_id,\n seq: row.seq,\n server: row.server,\n tool: row.tool,\n args: decode(row.args_json),\n class: row.class,\n snapshot: decode(row.snapshot_json),\n postSnapshot: decode(row.post_snapshot_json),\n result: decode(row.result_json),\n inverse: decode(row.inverse_json),\n verify: decode(row.verify_json),\n error: orUndefined(row.error),\n idempotencyKey: row.idempotency_key,\n status: row.status,\n approvedBy: orUndefined(row.approved_by),\n approvedAt: orUndefined(row.approved_at),\n ts: row.ts,\n };\n}\n\nexport interface Journal {\n beginRun(label: string | undefined): string;\n endRun(runId: string, status: RunStatus): void;\n /**\n * Closes a run whose proxy went away without saying so. Only a person can\n * ask for this: several proxies may share one journal, so a run left active\n * is indistinguishable from a run still being worked on, and closing one\n * that is live would make its remaining actions land in a finished run.\n *\n * Returns false when the run is already closed. Ends it at its last action\n * rather than now, since that is when anything last actually happened.\n */\n closeAbandonedRun(runId: string): boolean;\n setRunLabel(runId: string, label: string): void;\n recordPending(input: RecordPendingInput): PendingAction;\n attachSnapshot(actionId: string, snapshot: unknown): void;\n markApplied(actionId: string, outcome: AppliedOutcome): void;\n markFailed(actionId: string, error: string): void;\n markUnknown(actionId: string, error: string): void;\n /**\n * Claims an action for this rollback. Returns false when it was not this\n * call that moved it out of `applied`, which is how two undos running at\n * once are told apart from one resuming after a crash.\n */\n markRollingBack(actionId: string): boolean;\n markRolledBack(actionId: string): void;\n markUnrecoverable(actionId: string, error: string): void;\n markInverseRejected(actionId: string, error: string): void;\n markUnknownInverse(actionId: string, error: string): void;\n /**\n * `why` is kept on the row so the person deciding can see the reason\n * without the proxy running. It goes in `error`, which is already where a\n * row explains the state it is in.\n */\n markGated(actionId: string, why?: string): void;\n /** About to go out: from here on its outcome is genuinely unknown. */\n markInFlight(actionId: string): void;\n /** Returns false when the action is no longer awaiting a decision. */\n approve(actionId: string, by: string): boolean;\n deny(actionId: string, by: string | undefined, reason: string): boolean;\n /**\n * Records a refusal whatever state the row is in. `deny` is conditional\n * because an operator's decision must not overwrite one already settled; the\n * proxy needs the opposite, to record that an action it had approval for was\n * still not carried out.\n */\n settleAsDenied(actionId: string, by: string | undefined, reason: string): void;\n /**\n * Moves an approval granted in an earlier session onto the action that is\n * about to run, and spends the original so it cannot be used twice.\n */\n adoptApproval(actionId: string, granted: ActionRow): void;\n listGated(): readonly ActionRow[];\n /**\n * An approval that was granted but never carried out, for this exact call.\n * A retry after an out-of-band approval reuses that row rather than opening\n * a second one, so the approval sits on the action that actually ran.\n */\n findApproval(query: {\n server: string;\n tool: string;\n args: unknown;\n /** ISO timestamp; approvals older than this are ignored. */\n notBefore: string;\n }): ActionRow | undefined;\n /**\n * A call in this run that is already waiting for a decision. An agent told\n * to try again will often try again before anyone has answered, and a second\n * row for one decision is worse than useless: `approve` then refuses to act\n * without an id, and approving either one leaves its twin waiting for ever.\n */\n findGated(query: {\n runId: string;\n server: string;\n tool: string;\n args: unknown;\n }): ActionRow | undefined;\n getAction(actionId: string): ActionRow | undefined;\n listRuns(): readonly RunRow[];\n getRun(runId: string): RunRow | undefined;\n getActions(runId: string): readonly ActionRow[];\n /** The newest actions across every run, for watching work as it happens. */\n recentActions(limit: number): readonly ActionRow[];\n pragma(name: string): unknown;\n close(): void;\n}\n\n/**\n * Opening, with the failures named. better-sqlite3 reports \"file is not a\n * database\" and \"unable to open database file\" and leaves out which file it\n * meant, which is unhelpful precisely when the path was the mistake.\n */\nfunction openDatabase(path: string): Database.Database {\n try {\n const db = new Database(path);\n // The pragmas, not the constructor: better-sqlite3 opens lazily, so a file\n // that is not a database is only found out on the first read.\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = ON\");\n return db;\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n if (detail.includes(\"not a database\")) {\n throw new JournalError(\n \"open\",\n `${path} is not a Synartesis journal. Point --journal at a journal, or at a new file to start one.`,\n );\n }\n throw new JournalError(\"open\", `the journal at ${path} could not be opened: ${detail}`);\n }\n}\n\nclass SqliteJournal implements Journal {\n readonly #db: Database.Database;\n\n constructor(path: string) {\n if (path !== \":memory:\") {\n mkdirSync(dirname(path), { recursive: true });\n }\n // Opening is the one step a user is most likely to get wrong -- a typo in\n // --journal, a path that is a directory, a file that is something else\n // entirely -- and it was the one step whose errors went out raw, as a bare\n // \"file is not a database\" naming neither the file nor the tool.\n // WAL so a reader (the CLI) never blocks the proxy mid-run.\n this.#db = openDatabase(path);\n\n const existing = z.number().parse(this.#db.pragma(\"user_version\", { simple: true }));\n const populated =\n z\n .object({ count: z.number() })\n .parse(\n this.#db\n .prepare(\"SELECT COUNT(*) AS count FROM sqlite_master WHERE type = 'table' AND name = 'runs'\")\n .get(),\n ).count > 0;\n if (populated && existing !== SCHEMA_VERSION) {\n // Reinterpreting an older journal under a newer schema would risk\n // reading a rollback state that was never written.\n throw new JournalError(\n \"open\",\n `journal at ${path} was written by schema version ${String(existing)}, but this build expects ${String(SCHEMA_VERSION)}. ` +\n `Point --journal at a new file to carry on, and keep this one: everything an agent did is in it. Delete it only once you are sure you do not want that history.`,\n );\n }\n\n this.#db.exec(SCHEMA_SQL);\n this.#db.pragma(`user_version = ${String(SCHEMA_VERSION)}`);\n }\n\n beginRun(label: string | undefined): string {\n const id = crypto.randomUUID();\n this.#run(\"beginRun\", () => {\n this.#db\n .prepare(\"INSERT INTO runs (id, label, started_at, status) VALUES (?, ?, ?, 'active')\")\n .run(id, label ?? null, new Date().toISOString());\n });\n return id;\n }\n\n endRun(runId: string, status: RunStatus): void {\n this.#run(\"endRun\", () => {\n this.#db\n .prepare(\"UPDATE runs SET ended_at = ?, status = ? WHERE id = ?\")\n .run(new Date().toISOString(), status, runId);\n });\n }\n\n closeAbandonedRun(runId: string): boolean {\n return this.#run(\"closeAbandonedRun\", () => {\n const last = z\n .object({ ts: z.string().nullable() })\n .parse(\n this.#db\n .prepare(\"SELECT MAX(ts) AS ts FROM actions WHERE run_id = ?\")\n .get(runId) ?? { ts: null },\n ).ts;\n const result = this.#db\n .prepare(\"UPDATE runs SET ended_at = ?, status = 'complete' WHERE id = ? AND status = 'active'\")\n .run(last ?? new Date().toISOString(), runId);\n return result.changes === 1;\n });\n }\n\n setRunLabel(runId: string, label: string): void {\n this.#run(\"setRunLabel\", () => {\n this.#db.prepare(\"UPDATE runs SET label = ? WHERE id = ?\").run(label, runId);\n });\n }\n\n recordPending(input: RecordPendingInput): PendingAction {\n return this.#run(\"recordPending\", () => {\n const insert = this.#db.transaction((): PendingAction => {\n const next = this.#db\n .prepare(\"SELECT COALESCE(MAX(seq), 0) + 1 AS seq FROM actions WHERE run_id = ?\")\n .get(input.runId);\n const seq = z.object({ seq: z.number() }).parse(next).seq;\n const actionId = crypto.randomUUID();\n // Derived rather than random: a retried rollback must present the same\n // key for the same action, which is the whole point of D7.\n const idempotencyKey = `${input.runId}:${String(seq)}`;\n\n this.#db\n .prepare(\n `INSERT INTO actions\n (id, run_id, seq, server, tool, args_json, class, idempotency_key, status, ts)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?)`,\n )\n .run(\n actionId,\n input.runId,\n seq,\n input.server,\n input.tool,\n JSON.stringify(input.args ?? {}),\n input.class,\n idempotencyKey,\n new Date().toISOString(),\n );\n\n return { actionId, seq, idempotencyKey };\n });\n return insert();\n });\n }\n\n attachSnapshot(actionId: string, snapshot: unknown): void {\n this.#run(\"attachSnapshot\", () => {\n this.#db\n .prepare(\"UPDATE actions SET snapshot_json = ? WHERE id = ?\")\n .run(JSON.stringify(snapshot ?? null), actionId);\n });\n }\n\n markApplied(actionId: string, outcome: AppliedOutcome): void {\n this.#run(\"markApplied\", () => {\n this.#db\n .prepare(\n `UPDATE actions\n SET status = 'applied',\n result_json = ?,\n inverse_json = ?,\n verify_json = ?,\n post_snapshot_json = ?,\n error = ?\n WHERE id = ?`,\n )\n .run(\n JSON.stringify(outcome.result ?? null),\n outcome.inverse === undefined ? null : JSON.stringify(outcome.inverse),\n outcome.verify === undefined ? null : JSON.stringify(outcome.verify),\n outcome.postSnapshot === undefined ? null : JSON.stringify(outcome.postSnapshot),\n outcome.warning ?? null,\n actionId,\n );\n });\n }\n\n markFailed(actionId: string, error: string): void {\n this.#run(\"markFailed\", () => {\n this.#db\n .prepare(\"UPDATE actions SET status = 'failed', error = ? WHERE id = ?\")\n .run(error, actionId);\n });\n }\n\n /**\n * The call was interrupted, so whether the upstream applied it is genuinely\n * unknown. The row deliberately stays `pending`: recording it as failed\n * would assert something we cannot know, and section 3.1 wants exactly this\n * case surfaced rather than resolved by guesswork.\n */\n markUnknown(actionId: string, error: string): void {\n this.#run(\"markUnknown\", () => {\n this.#db\n .prepare(\"UPDATE actions SET status = 'pending', error = ? WHERE id = ?\")\n .run(error, actionId);\n });\n }\n\n markRollingBack(actionId: string): boolean {\n return this.#run(\"markRollingBack\", () => {\n // Conditional, so the transition is a claim rather than an announcement.\n // Two rollbacks of one run both read the action as applied and both sent\n // its inverse; for a compensating call rather than a restore, that is a\n // second real change to the world.\n const result = this.#db\n .prepare(\"UPDATE actions SET status = 'rolling_back' WHERE id = ? AND status = 'applied'\")\n .run(actionId);\n return result.changes === 1;\n });\n }\n\n markRolledBack(actionId: string): void {\n this.#run(\"markRolledBack\", () => {\n this.#db.prepare(\"UPDATE actions SET status = 'rolled_back' WHERE id = ?\").run(actionId);\n });\n }\n\n /**\n * The upstream processed the inverse and refused it, so nothing was applied\n * and the action still needs undoing. Distinct from `unrecoverable`, which\n * means a human has to look: a refused inverse may simply be a server that\n * was briefly unwell, and rollback is expected to be retried (D7).\n */\n markInverseRejected(actionId: string, error: string): void {\n this.#run(\"markInverseRejected\", () => {\n this.#db\n .prepare(\"UPDATE actions SET status = 'applied', error = ? WHERE id = ?\")\n .run(error, actionId);\n });\n }\n\n /**\n * The inverse may or may not have reached the upstream. The row stays in\n * `rolling_back` so the next attempt knows to resolve it by reading the\n * current state rather than assuming either way.\n */\n markUnknownInverse(actionId: string, error: string): void {\n this.#run(\"markUnknownInverse\", () => {\n this.#db\n .prepare(\"UPDATE actions SET status = 'rolling_back', error = ? WHERE id = ?\")\n .run(error, actionId);\n });\n }\n\n markGated(actionId: string, why?: string): void {\n this.#run(\"markGated\", () => {\n this.#db\n .prepare(\"UPDATE actions SET status = 'gated', error = ? WHERE id = ?\")\n .run(why ?? null, actionId);\n });\n }\n\n markInFlight(actionId: string): void {\n this.#run(\"markInFlight\", () => {\n this.#db.prepare(\"UPDATE actions SET status = 'pending' WHERE id = ?\").run(actionId);\n });\n }\n\n /**\n * Conditional on the row still being gated, so a decision made at the same\n * moment as a timeout resolves one way rather than both.\n */\n approve(actionId: string, by: string): boolean {\n return this.#run(\"approve\", () => {\n const result = this.#db\n .prepare(\n `UPDATE actions SET status = 'approved', approved_by = ?, approved_at = ?, error = NULL\n WHERE id = ? AND status = 'gated'`,\n )\n .run(by, new Date().toISOString(), actionId);\n return result.changes === 1;\n });\n }\n\n deny(actionId: string, by: string | undefined, reason: string): boolean {\n return this.#run(\"deny\", () => {\n const result = this.#db\n .prepare(\n `UPDATE actions SET status = 'denied', approved_by = ?, approved_at = ?, error = ?\n WHERE id = ? AND status = 'gated'`,\n )\n .run(by ?? null, new Date().toISOString(), reason, actionId);\n return result.changes === 1;\n });\n }\n\n settleAsDenied(actionId: string, by: string | undefined, reason: string): void {\n this.#run(\"settleAsDenied\", () => {\n this.#db\n .prepare(\n \"UPDATE actions SET status = 'denied', approved_by = ?, approved_at = ?, error = ? WHERE id = ?\",\n )\n .run(by ?? null, new Date().toISOString(), reason, actionId);\n });\n }\n\n adoptApproval(actionId: string, granted: ActionRow): void {\n this.#run(\"adoptApproval\", () => {\n const move = this.#db.transaction((): void => {\n this.#db\n .prepare(\"UPDATE actions SET approved_by = ?, approved_at = ? WHERE id = ?\")\n .run(granted.approvedBy ?? null, granted.approvedAt ?? null, actionId);\n this.#db\n .prepare(\"UPDATE actions SET status = 'denied', error = ? WHERE id = ?\")\n .run(`${SPENT_APPROVAL} ${actionId}`, granted.id);\n });\n move();\n });\n }\n\n listGated(): readonly ActionRow[] {\n return this.#run(\"listGated\", () =>\n this.#db.prepare(\"SELECT * FROM actions WHERE status = 'gated' ORDER BY ts\").all().map(toAction),\n );\n }\n\n findApproval(query: {\n server: string;\n tool: string;\n args: unknown;\n notBefore: string;\n }): ActionRow | undefined {\n return this.#run(\"findApproval\", () => {\n // Not scoped to one run: people restart their client, and an approval\n // stranded in a dead session is the same as no approval at all. Bounded\n // by time and by being single use instead, so a decision made this\n // morning cannot silently authorise the same call tomorrow.\n const rows = this.#db\n .prepare(\n `SELECT * FROM actions\n WHERE server = ? AND tool = ?\n AND status = 'approved'\n AND approved_at >= ?\n ORDER BY approved_at DESC`,\n )\n .all(query.server, query.tool, query.notBefore)\n .map(toAction);\n // Matched on meaning rather than on spelling: an agent that re-emits the\n // same arguments in a different key order is making the same call, and\n // sending a person back to approve what they just approved would teach\n // them to stop reading what they are approving.\n const wanted = canonical(query.args ?? {});\n return rows.find((row) => canonical(row.args) === wanted);\n });\n }\n\n findGated(query: {\n runId: string;\n server: string;\n tool: string;\n args: unknown;\n }): ActionRow | undefined {\n return this.#run(\"findGated\", () => {\n // Scoped to the run, unlike an approval: a gated row belongs to the run\n // that raised it, and adopting one from a dead session would hang the\n // decision on an action that undoing this run would never reach.\n const rows = this.#db\n .prepare(\n `SELECT * FROM actions\n WHERE run_id = ? AND server = ? AND tool = ? AND status = 'gated'\n ORDER BY seq`,\n )\n .all(query.runId, query.server, query.tool)\n .map(toAction);\n const wanted = canonical(query.args ?? {});\n return rows.find((row) => canonical(row.args) === wanted);\n });\n }\n\n getAction(actionId: string): ActionRow | undefined {\n return this.#run(\"getAction\", () => {\n const raw = this.#db.prepare(\"SELECT * FROM actions WHERE id = ?\").get(actionId);\n return raw === undefined ? undefined : toAction(raw);\n });\n }\n\n markUnrecoverable(actionId: string, error: string): void {\n this.#run(\"markUnrecoverable\", () => {\n this.#db\n .prepare(\"UPDATE actions SET status = 'unrecoverable', error = ? WHERE id = ?\")\n .run(error, actionId);\n });\n }\n\n listRuns(): readonly RunRow[] {\n return this.#run(\"listRuns\", () =>\n // Insertion order as the tiebreak, not the id. Two runs that start in\n // the same millisecond have equal timestamps, and a uuid orders them at\n // random -- which decides which one `show` and `undo` mean by \"the most\n // recent\", so the answer has to come from when they were written rather\n // than from what they happen to be called.\n this.#db.prepare(\"SELECT * FROM runs ORDER BY started_at, rowid\").all().map(toRun),\n );\n }\n\n getRun(runId: string): RunRow | undefined {\n return this.#run(\"getRun\", () => {\n const raw = this.#db.prepare(\"SELECT * FROM runs WHERE id = ?\").get(runId);\n return raw === undefined ? undefined : toRun(raw);\n });\n }\n\n getActions(runId: string): readonly ActionRow[] {\n return this.#run(\"getActions\", () =>\n this.#db\n .prepare(\"SELECT * FROM actions WHERE run_id = ? ORDER BY seq\")\n .all(runId)\n .map(toAction),\n );\n }\n\n recentActions(limit: number): readonly ActionRow[] {\n return this.#run(\"recentActions\", () =>\n this.#db\n .prepare(\"SELECT * FROM actions ORDER BY ts DESC, seq DESC LIMIT ?\")\n .all(limit)\n .map(toAction)\n .reverse(),\n );\n }\n\n pragma(name: string): unknown {\n return this.#db.pragma(name, { simple: true });\n }\n\n close(): void {\n this.#db.close();\n }\n\n /**\n * A failed journal write means the record of what the agent did is\n * incomplete. It is never swallowed and never merely logged.\n */\n #run<T>(operation: string, body: () => T): T {\n try {\n return body();\n } catch (error: unknown) {\n throw new JournalError(operation, error);\n }\n }\n}\n\nexport interface OpenOptions {\n /**\n * Refuse to create the file. Reading commands should say a journal is not\n * there rather than conjure an empty one and report that nothing happened,\n * which looks identical to a real answer and leaves a stray file behind.\n */\n readonly mustExist?: boolean;\n}\n\nexport function openJournal(path: string, options: OpenOptions = {}): Journal {\n if (options.mustExist === true && path !== \":memory:\" && !existsSync(path)) {\n throw new JournalError(\"open\", `there is no journal at ${path}`);\n }\n return new SqliteJournal(path);\n}\n\n/**\n * A row denied because its approval was spent on the call that actually ran is\n * not a refusal, and `watch` reported one as \"denied\" moments after the person\n * had said yes and the call had gone through.\n */\nexport function labelFor(action: ActionRow): string {\n return action.status === \"denied\" && (action.error ?? \"\").startsWith(SPENT_APPROVAL)\n ? \"used\"\n : action.status;\n}\n\nexport function wasRefused(action: ActionRow): boolean {\n return action.status === \"unrecoverable\" || labelFor(action) === \"denied\";\n}\n","/**\n * A stable text form of a json value.\n *\n * Key order carries no meaning in json, and nothing obliges an agent to\n * serialise the same arguments the same way twice. Anywhere two values are\n * compared for sameness -- state against recorded state, a retried call\n * against the approval that was granted for it -- the comparison has to be on\n * meaning rather than on spelling.\n */\nexport function canonical(value: unknown): string {\n if (value === undefined) {\n return \"undefined\";\n }\n if (value === null || typeof value !== \"object\") {\n return JSON.stringify(value);\n }\n if (Array.isArray(value)) {\n return `[${value.map(canonical).join(\",\")}]`;\n }\n const entries = Object.entries(value)\n .filter(([, item]) => item !== undefined)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(\",\")}}`;\n}\n","/**\n * Schema version is stored in SQLite's user_version.\n *\n * Version 2 adds `rolling_back`, written before an inverse is sent. On resume,\n * a row still in that state means the inverse may already have been applied,\n * which is the difference between a correct resume and a double-application.\n * It also adds `verify_json`, the read used to detect drift, resolved to\n * literal arguments at capture time for the same reason the inverse is (D5):\n * the manifest may have been edited by the time anyone rolls back.\n *\n * Version 3 adds `approved`: granted by a person but not yet carried out.\n * That was `pending` at first, which also means a call went out and its\n * outcome is unknown. Undo has to halt on the second and step past the first,\n * so they cannot share a name.\n *\n * There is no migration path yet, and inventing one before anything needs\n * migrating would mean shipping untested machinery. An older journal is\n * refused with instructions instead of being silently reinterpreted.\n */\nexport const SCHEMA_VERSION = 3;\n\nexport const SCHEMA_SQL = `\nCREATE TABLE IF NOT EXISTS runs (\n id TEXT PRIMARY KEY,\n label TEXT,\n started_at TEXT NOT NULL,\n ended_at TEXT,\n status TEXT NOT NULL CHECK (status IN ('active','complete','rolled_back','partial'))\n);\n\nCREATE TABLE IF NOT EXISTS actions (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL REFERENCES runs(id),\n seq INTEGER NOT NULL,\n server TEXT NOT NULL,\n tool TEXT NOT NULL,\n args_json TEXT NOT NULL,\n class TEXT NOT NULL,\n snapshot_json TEXT,\n post_snapshot_json TEXT,\n result_json TEXT,\n inverse_json TEXT,\n verify_json TEXT,\n error TEXT,\n idempotency_key TEXT NOT NULL UNIQUE,\n status TEXT NOT NULL CHECK (status IN\n ('pending','gated','approved','denied','applied','failed',\n 'rolling_back','rolled_back','unrecoverable')),\n approved_by TEXT,\n approved_at TEXT,\n ts TEXT NOT NULL,\n UNIQUE(run_id, seq)\n);\n\nCREATE INDEX IF NOT EXISTS actions_by_run ON actions(run_id, seq);\n`;\n","import { readFileSync } from \"node:fs\";\n\nimport { LineCounter, isNode, parseDocument, type Document } from \"yaml\";\nimport { z } from \"zod\";\n\nimport { ManifestError, describe as describeCause, type SourceLocation } from \"../errors.js\";\nimport { referencesIn } from \"./template.js\";\nimport type { CallTemplate, Manifest, TemplateValue, ToolPolicy } from \"./types.js\";\n\nconst templateValue: z.ZodType<TemplateValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(templateValue),\n z.record(z.string(), templateValue),\n ]),\n);\n\nconst callTemplate = z.strictObject({\n tool: z.string().min(1),\n args: z.record(z.string(), templateValue).default({}),\n});\n\nconst toolPolicy = z.strictObject({\n match: z.string().min(1),\n class: z.enum([\"readonly\", \"reversible\", \"compensable\", \"irreversible\"]),\n gate: z.enum([\"always\", \"on_write\", \"never\"]).optional(),\n snapshot: callTemplate.optional(),\n inverse: callTemplate.optional(),\n});\n\nconst serverSpec = z.strictObject({\n command: z.string().min(1),\n args: z.array(z.string()).default([]),\n env: z.record(z.string(), z.string()).optional(),\n});\n\nconst manifestSchema = z.strictObject({\n version: z.literal(1),\n servers: z.record(z.string(), serverSpec),\n tools: z.array(toolPolicy).default([]),\n});\n\ntype Path = readonly (string | number)[];\n\nclass Source {\n constructor(\n private readonly doc: Document.Parsed,\n private readonly lines: LineCounter,\n private readonly file: string,\n ) {}\n\n /** Narrows to the deepest node that still exists, so a location is always given. */\n locate(path: Path): SourceLocation {\n for (let depth = path.length; depth >= 0; depth -= 1) {\n const node: unknown =\n depth === 0 ? this.doc.contents : this.doc.getIn(path.slice(0, depth), true);\n const range = isNode(node) ? node.range : undefined;\n if (range != null) {\n const position = this.lines.linePos(range[0]);\n return { file: this.file, line: position.line, column: position.col };\n }\n }\n return { file: this.file, line: 1, column: 1 };\n }\n\n fail(path: Path, message: string): never {\n throw new ManifestError(message, this.locate(path));\n }\n}\n\n/**\n * `${VAR}` in a server's environment, taken from the shell the proxy was\n * started from.\n *\n * This is how a token stays out of a file that gets committed, which is what\n * the shipped manifests tell people to do. Without expansion the server\n * receives the reference itself and fails with an authentication error that\n * says nothing about the cause. A variable that is not set is refused at load\n * time rather than passed on empty, for the same reason: never start with a\n * policy that cannot work.\n */\nconst REFERENCE = /\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g;\n\nfunction expandEnvironment(\n source: Source,\n path: Path,\n env: Readonly<Record<string, string>>,\n): Record<string, string> {\n const expanded: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n expanded[key] = value.replace(REFERENCE, (whole, name: string) => {\n const found = process.env[name];\n if (found === undefined) {\n source.fail(\n [...path, \"env\", key],\n `${whole} is not set in this environment; export ${name} before starting, or write the value here`,\n );\n }\n return found;\n });\n }\n return expanded;\n}\n\nfunction serverSegment(pattern: string): string {\n const dot = pattern.indexOf(\".\");\n return dot === -1 ? \"\" : pattern.slice(0, dot);\n}\n\nfunction matchesAnyServer(segment: string, servers: readonly string[]): boolean {\n if (!segment.includes(\"*\")) {\n return servers.includes(segment);\n }\n const source = segment\n .split(\"*\")\n .map((literal) => literal.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"))\n .join(\"[^.]*\");\n const test = new RegExp(`^${source}$`);\n return servers.some((name) => test.test(name));\n}\n\nfunction checkCall(\n source: Source,\n path: Path,\n call: CallTemplate,\n servers: readonly string[],\n allowed: readonly string[],\n): void {\n const segment = serverSegment(call.tool);\n if (segment === \"\" || call.tool.endsWith(\".\")) {\n source.fail([...path, \"tool\"], `${call.tool} must be qualified as server.tool`);\n }\n if (segment.includes(\"*\")) {\n source.fail([...path, \"tool\"], `${call.tool} must name one server, not a pattern`);\n }\n if (!servers.includes(segment)) {\n source.fail([...path, \"tool\"], `${call.tool} names server ${segment}, which is not declared`);\n }\n\n for (const reference of referencesIn(call.args)) {\n // Matches `$ns.field`, `$ns[0]` and a bare `$ns`, so a whole-value or\n // subscripted reference is checked rather than silently treated as `$.`\n // and failing at run time.\n const namespace = /^\\$(\\w*)(?:[.[]|$)/.exec(reference)?.[1] ?? \"\";\n const label = namespace === \"\" ? \"$.\" : `$${namespace}.`;\n if (!allowed.includes(label)) {\n source.fail(\n [...path, \"args\"],\n `${reference} uses ${label}, which is not available here; allowed: ${allowed.join(\", \")}`,\n );\n }\n }\n}\n\n/**\n * Cross-field rules the shape alone cannot express. These are the difference\n * between a manifest that parses and a policy that can actually be executed,\n * and every one of them fails startup rather than surfacing mid-run.\n */\nfunction validate(source: Source, manifest: Manifest): void {\n const servers = Object.keys(manifest.servers);\n if (servers.length === 0) {\n source.fail([\"servers\"], \"at least one server must be declared\");\n }\n\n const seen = new Map<string, number>();\n manifest.tools.forEach((policy, index) => {\n const path: Path = [\"tools\", index];\n const previous = seen.get(policy.match);\n if (previous !== undefined) {\n source.fail(\n [...path, \"match\"],\n `duplicate match pattern ${policy.match}; it is already declared at tools[${String(previous)}]`,\n );\n }\n seen.set(policy.match, index);\n\n const segment = serverSegment(policy.match);\n if (segment === \"\") {\n source.fail([...path, \"match\"], `${policy.match} must be qualified as server.tool`);\n }\n if (!matchesAnyServer(segment, servers)) {\n source.fail(\n [...path, \"match\"],\n `${policy.match} names server ${segment}, which is not declared`,\n );\n }\n\n const needsInverse = policy.class === \"reversible\" || policy.class === \"compensable\";\n if (needsInverse && policy.inverse === undefined) {\n source.fail(path, `a ${policy.class} tool must declare an inverse`);\n }\n if (!needsInverse && policy.inverse !== undefined) {\n source.fail([...path, \"inverse\"], `a ${policy.class} tool must not declare an inverse`);\n }\n // A snapshot is required only when the inverse actually depends on one.\n // Some actions are reversible from their arguments alone: the inverse of\n // moving a file from A to B is moving it from B to A, and no pre-read\n // could tell you anything the arguments do not already say.\n const needsSnapshot =\n policy.inverse !== undefined &&\n referencesIn(policy.inverse.args).some(\n (reference) => reference === \"$snapshot\" || reference.startsWith(\"$snapshot.\"),\n );\n if (policy.class === \"reversible\" && needsSnapshot && policy.snapshot === undefined) {\n // Without a pre-read such a reversible action is silently irreversible.\n source.fail(path, \"this inverse reads $snapshot, so a snapshot must be declared\");\n }\n if (policy.class === \"readonly\" && policy.snapshot !== undefined) {\n source.fail([...path, \"snapshot\"], \"a readonly tool must not declare a snapshot\");\n }\n\n if (policy.snapshot !== undefined) {\n // The snapshot runs before the forward call, so neither the result nor a\n // snapshot exists yet.\n checkCall(source, [...path, \"snapshot\"], policy.snapshot, servers, [\"$.\"]);\n }\n if (policy.inverse !== undefined) {\n const allowed = [\"$.\", \"$result.\"];\n if (policy.snapshot !== undefined) {\n allowed.push(\"$snapshot.\");\n }\n checkCall(source, [...path, \"inverse\"], policy.inverse, servers, allowed);\n }\n });\n}\n\nfunction withGate(policy: z.infer<typeof toolPolicy>): ToolPolicy {\n // D4: irreversible is gated unless the manifest deliberately says otherwise.\n const gate = policy.gate ?? (policy.class === \"irreversible\" ? \"always\" : \"never\");\n return {\n match: policy.match,\n class: policy.class,\n gate,\n ...(policy.snapshot === undefined ? {} : { snapshot: policy.snapshot }),\n ...(policy.inverse === undefined ? {} : { inverse: policy.inverse }),\n };\n}\n\nexport function parseManifest(text: string, file: string): Manifest {\n const lines = new LineCounter();\n const doc = parseDocument(text, { lineCounter: lines });\n\n const syntaxError = doc.errors[0];\n if (syntaxError !== undefined) {\n const position = lines.linePos(syntaxError.pos[0]);\n throw new ManifestError(syntaxError.message, {\n file,\n line: position.line,\n column: position.col,\n });\n }\n\n const source = new Source(doc, lines, file);\n const parsed = manifestSchema.safeParse(doc.toJS());\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n if (issue === undefined) {\n throw new ManifestError(\"manifest failed validation\", source.locate([]));\n }\n const path = issue.path.filter(\n (segment): segment is string | number => typeof segment !== \"symbol\",\n );\n const where = path.length === 0 ? \"\" : `${path.join(\".\")}: `;\n throw new ManifestError(`${where}${issue.message}`, source.locate(path));\n }\n\n const manifest: Manifest = {\n version: parsed.data.version,\n servers: Object.fromEntries(\n Object.entries(parsed.data.servers).map(([name, spec]) => [\n name,\n {\n command: spec.command,\n args: spec.args,\n ...(spec.env === undefined\n ? {}\n : { env: expandEnvironment(source, [\"servers\", name], spec.env) }),\n },\n ]),\n ),\n tools: parsed.data.tools.map(withGate),\n };\n validate(source, manifest);\n return manifest;\n}\n\nexport function loadManifest(path: string): Manifest {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (error: unknown) {\n throw new ManifestError(`cannot read manifest at ${path}: ${describeCause(error)}`);\n }\n return parseManifest(text, path);\n}\n","import { ManifestError } from \"../errors.js\";\nimport type { TemplateValue } from \"./types.js\";\n\nexport interface TemplateContext {\n readonly args: unknown;\n readonly snapshot?: unknown;\n readonly result?: unknown;\n}\n\nconst NAMESPACES = [\"snapshot\", \"result\"] as const;\n\ninterface Reference {\n readonly namespace: \"args\" | \"snapshot\" | \"result\";\n readonly path: string;\n}\n\n/**\n * Three namespaces and dotted paths, nothing else. Spec 3.2 is explicit that\n * the manifest must not become a language: the moment it grows expressions,\n * it stops being writable in fifteen minutes by someone who has never seen it.\n */\nfunction parseReference(raw: string): Reference | undefined {\n if (!raw.startsWith(\"$\")) {\n return undefined;\n }\n // A bare namespace means the whole value. Writing a file back needs the\n // entire captured contents, which is not a field of anything.\n if (raw === \"$\") {\n return { namespace: \"args\", path: \"\" };\n }\n // A namespace may be followed by a dot or straight by a subscript. Servers\n // that answer with a bare list are common -- the memory server's\n // create_entities returns the entities it actually created -- and\n // $result[].name is the only safe thing for its inverse to name.\n if (raw.startsWith(\"$.\") || raw.startsWith(\"$[\")) {\n return { namespace: \"args\", path: raw.slice(raw[1] === \".\" ? 2 : 1) };\n }\n for (const namespace of NAMESPACES) {\n if (raw === `$${namespace}`) {\n return { namespace, path: \"\" };\n }\n const head = `$${namespace}`;\n const after = raw.startsWith(head) ? raw.slice(head.length) : undefined;\n if (after !== undefined && (after.startsWith(\".\") || after.startsWith(\"[\"))) {\n return { namespace, path: after.startsWith(\".\") ? after.slice(1) : after };\n }\n }\n throw new ManifestError(\n `unknown interpolation namespace in ${raw}; expected $., $snapshot. or $result.`,\n );\n}\n\ntype Segment =\n | { readonly kind: \"key\"; readonly key: string }\n | { readonly kind: \"index\"; readonly index: number }\n /** `[]`: apply the rest of the path to every element. */\n | { readonly kind: \"each\" };\n\n/** Splits `items[1].id` and `labels[].name` into their steps. */\nfunction segments(path: string, reference: string): Segment[] {\n const parts: Segment[] = [];\n for (const chunk of path.split(\".\")) {\n const match = /^([^[\\]]*)((?:\\[\\d*\\])*)$/.exec(chunk);\n if (match === null) {\n throw new ManifestError(`malformed path in ${reference}`);\n }\n const [, head = \"\", brackets = \"\"] = match;\n if (head !== \"\") {\n parts.push({ kind: \"key\", key: head });\n }\n for (const bracket of brackets.matchAll(/\\[(\\d*)\\]/g)) {\n const index = bracket[1] ?? \"\";\n parts.push(index === \"\" ? { kind: \"each\" } : { kind: \"index\", index: Number(index) });\n }\n }\n if (parts.length === 0) {\n throw new ManifestError(`empty path in ${reference}`);\n }\n return parts;\n}\n\nfunction walk(current: unknown, parts: readonly Segment[], at: number, reference: string): unknown {\n const segment = parts[at];\n if (segment === undefined) {\n return current;\n }\n if (current === null || current === undefined) {\n throw new ManifestError(`${reference} is unresolvable: nothing to read from`);\n }\n\n switch (segment.kind) {\n case \"each\": {\n if (!Array.isArray(current)) {\n throw new ManifestError(`${reference} is unresolvable: [] needs a list to walk`);\n }\n // Projection, not a transform. It reads the same field from each element\n // and nothing more, which is what an API that returns objects and\n // accepts names needs, and is still only a path.\n return current.map((item) => walk(item, parts, at + 1, reference));\n }\n case \"index\": {\n if (!Array.isArray(current) || segment.index >= current.length) {\n throw new ManifestError(\n `${reference} is unresolvable: index ${String(segment.index)} is absent`,\n );\n }\n return walk(current[segment.index], parts, at + 1, reference);\n }\n case \"key\": {\n if (typeof current !== \"object\" || !(segment.key in current)) {\n throw new ManifestError(`${reference} is unresolvable: ${segment.key} is absent`);\n }\n const next: unknown = Object.getOwnPropertyDescriptor(current, segment.key)?.value;\n return walk(next, parts, at + 1, reference);\n }\n }\n}\n\nfunction read(root: unknown, path: string, reference: string): unknown {\n return walk(root, segments(path, reference), 0, reference);\n}\n\n/**\n * A reference appearing inside a larger string, such as a commit message that\n * names the path it is reverting. Only the dotted forms are recognised here: a\n * bare `$result` in the middle of a sentence is far more likely to be prose\n * than an interpolation.\n */\nconst EMBEDDED =\n /\\$(?:snapshot|result)?\\.[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*|\\[\\d*\\])*/g;\n\nconst ESCAPE = \"\\u0000synartesis-dollar\\u0000\";\n\nfunction stringify(value: unknown): string {\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\nfunction resolveString(raw: string, context: TemplateContext): unknown {\n // A string that is nothing but a reference keeps the referenced value's\n // type. Anything else is text with references substituted into it, which is\n // what people write without being told they can.\n const whole = raw.startsWith(\"$$\") ? undefined : parseReference(raw);\n if (whole !== undefined) {\n return readNamespace(whole, raw, context);\n }\n\n const escaped = raw.split(\"$$\").join(ESCAPE);\n const substituted = escaped.replace(EMBEDDED, (token) => {\n const reference = parseReference(token);\n if (reference === undefined) {\n return token;\n }\n return stringify(readNamespace(reference, token, context));\n });\n return substituted.split(ESCAPE).join(\"$\");\n}\n\nfunction readNamespace(reference: Reference, raw: string, context: TemplateContext): unknown {\n const root = context[reference.namespace];\n if (root === undefined) {\n throw new ManifestError(\n `${raw} refers to ${reference.namespace}, which is not available at this point`,\n );\n }\n return reference.path === \"\" ? root : read(root, reference.path, raw);\n}\n\n/** Array.isArray widens a readonly union to any[]; this keeps the element type. */\nfunction isTemplateArray(value: TemplateValue): value is readonly TemplateValue[] {\n return Array.isArray(value);\n}\n\nexport function resolveTemplate(template: TemplateValue, context: TemplateContext): unknown {\n if (typeof template === \"string\") {\n return resolveString(template, context);\n }\n if (isTemplateArray(template)) {\n return template.map((item) => resolveTemplate(item, context));\n }\n if (template !== null && typeof template === \"object\") {\n return Object.fromEntries(\n Object.entries(template).map(([key, value]) => [key, resolveTemplate(value, context)]),\n );\n }\n return template;\n}\n\n/** Every reference a template contains, used for load-time validation. */\nexport function referencesIn(template: TemplateValue): string[] {\n if (typeof template === \"string\") {\n if (template.startsWith(\"$$\")) {\n return [];\n }\n if (parseReference(template) !== undefined) {\n return [template];\n }\n // Embedded references are validated too, so a namespace that is not\n // available at that point is reported when the manifest loads rather than\n // silently producing the wrong text at run time.\n return template.split(\"$$\").join(ESCAPE).match(EMBEDDED) ?? [];\n }\n if (isTemplateArray(template)) {\n return template.flatMap(referencesIn);\n }\n if (template !== null && typeof template === \"object\") {\n return Object.values(template).flatMap(referencesIn);\n }\n return [];\n}\n","import { z } from \"zod\";\n\nimport { ManifestError } from \"../errors.js\";\nimport type { Upstream } from \"../proxy/upstream.js\";\nimport { splitQualified, type Manifest } from \"./types.js\";\n\nconst listSchema = z.looseObject({\n tools: z.array(z.looseObject({ name: z.string() })),\n nextCursor: z.string().optional(),\n});\n\nasync function toolNames(upstream: Upstream): Promise<Set<string>> {\n const names = new Set<string>();\n let cursor: string | undefined;\n do {\n const page = listSchema.parse(\n await upstream.client.request(\n { method: \"tools/list\", params: cursor === undefined ? {} : { cursor } },\n z.looseObject({}),\n ),\n );\n for (const tool of page.tools) {\n names.add(tool.name);\n }\n cursor = page.nextCursor;\n } while (cursor !== undefined);\n return names;\n}\n\n/**\n * Checks that every tool a policy calls actually exists on the server it names.\n *\n * This cannot be done when the manifest is parsed, because it needs the servers\n * running. It matters because a mistyped snapshot tool is otherwise\n * indistinguishable at run time from the resource simply not being there: both\n * come back as a tool-level error. Catching it at startup keeps that inference\n * safe, and keeps a broken policy from ever serving a request.\n */\nexport async function verifyAgainstServers(\n upstreams: readonly Upstream[],\n manifest: Manifest,\n): Promise<void> {\n const available = new Map<string, Set<string>>();\n for (const upstream of upstreams) {\n available.set(upstream.name, await toolNames(upstream));\n }\n\n const problems: string[] = [];\n const check = (qualified: string, role: string, match: string): void => {\n const target = splitQualified(qualified);\n if (target === undefined) {\n return;\n }\n const names = available.get(target.server);\n if (names === undefined) {\n problems.push(`${match}: its ${role} names server ${target.server}, which is not connected`);\n return;\n }\n if (!names.has(target.tool)) {\n problems.push(\n `${match}: its ${role} calls ${qualified}, which ${target.server} does not expose`,\n );\n }\n };\n\n for (const policy of manifest.tools) {\n if (policy.snapshot !== undefined) {\n check(policy.snapshot.tool, \"snapshot\", policy.match);\n }\n if (policy.inverse !== undefined) {\n check(policy.inverse.tool, \"inverse\", policy.match);\n }\n }\n\n if (problems.length > 0) {\n throw new ManifestError(`the manifest calls tools that do not exist:\\n ${problems.join(\"\\n \")}`);\n }\n}\n","/** The four behaviours from spec 1.4. */\nexport type ToolClass = \"readonly\" | \"reversible\" | \"compensable\" | \"irreversible\";\n\n/**\n * `on_write` is a heuristic for tools whose destructiveness cannot be decided\n * statically, such as a raw SQL runner. The heuristic itself lands with the\n * gate in Phase 5; the manifest only has to carry the intent.\n */\nexport type GateMode = \"always\" | \"on_write\" | \"never\";\n\nexport interface ServerSpec {\n readonly command: string;\n readonly args: readonly string[];\n readonly env?: Readonly<Record<string, string>>;\n}\n\nexport type TemplateValue =\n | string\n | number\n | boolean\n | null\n | readonly TemplateValue[]\n | { readonly [key: string]: TemplateValue };\n\nexport interface CallTemplate {\n /** Qualified as `server.tool`. */\n readonly tool: string;\n readonly args: Readonly<Record<string, TemplateValue>>;\n}\n\nexport interface ToolPolicy {\n readonly match: string;\n readonly class: ToolClass;\n readonly gate: GateMode;\n readonly snapshot?: CallTemplate;\n readonly inverse?: CallTemplate;\n}\n\nexport interface Manifest {\n readonly version: 1;\n readonly servers: Readonly<Record<string, ServerSpec>>;\n readonly tools: readonly ToolPolicy[];\n}\n\n/** Qualified name used everywhere policy is looked up. */\nexport function qualify(server: string, tool: string): string {\n return `${server}.${tool}`;\n}\n\nexport interface QualifiedName {\n readonly server: string;\n readonly tool: string;\n}\n\n/** Splits on the first dot only; tool names may contain further dots. */\nexport function splitQualified(qualified: string): QualifiedName | undefined {\n const dot = qualified.indexOf(\".\");\n if (dot <= 0 || dot === qualified.length - 1) {\n return undefined;\n }\n return { server: qualified.slice(0, dot), tool: qualified.slice(dot + 1) };\n}\n","import { ManifestError } from \"../errors.js\";\nimport type { Manifest } from \"../manifest/types.js\";\nimport type { Upstream } from \"./upstream.js\";\n\n/**\n * A dot cannot be used to namespace tool names: many MCP clients constrain\n * tool names to [A-Za-z0-9_-], and a name the client rejects is a tool the\n * agent cannot call at all.\n */\nexport const SEPARATOR = \"__\";\n\nexport interface Route {\n readonly upstream: Upstream;\n /** The name as the upstream knows it, with any prefix removed. */\n readonly tool: string;\n}\n\nexport interface Router {\n readonly prefixed: boolean;\n readonly upstreams: readonly Upstream[];\n expose(server: string, name: string): string;\n route(exposed: string): Route | undefined;\n byName(server: string): Upstream | undefined;\n}\n\nexport function createRouter(upstreams: readonly Upstream[], manifest: Manifest): Router {\n if (upstreams.length === 0) {\n throw new ManifestError(\"no upstream servers were connected\");\n }\n\n for (const upstream of upstreams) {\n if (!(upstream.name in manifest.servers)) {\n throw new ManifestError(\n `upstream ${upstream.name} is connected but not declared in the manifest`,\n );\n }\n if (upstream.name.includes(SEPARATOR) || upstream.name.includes(\".\")) {\n throw new ManifestError(\n `server name ${upstream.name} may not contain \".\" or \"${SEPARATOR}\"; both are reserved for qualifying tool names`,\n );\n }\n }\n\n const byName = new Map(upstreams.map((upstream) => [upstream.name, upstream]));\n if (byName.size !== upstreams.length) {\n throw new ManifestError(\"two upstreams were connected under the same name\");\n }\n\n // With one server there is nothing to disambiguate, so names pass through\n // untouched and the proxy stays invisible. Adding a second server is an\n // explicit edit to the manifest, so the rename that comes with it is not a\n // surprise; what would be surprising is a name whose meaning depends on\n // which other servers happen to be configured beside it.\n const prefixed = upstreams.length > 1;\n\n // Longest first so that servers named `a` and `a_b` cannot both claim the\n // same exposed name.\n const keys = [...byName.keys()].sort((a, b) => b.length - a.length);\n\n return {\n prefixed,\n upstreams,\n expose(server: string, name: string): string {\n return prefixed ? `${server}${SEPARATOR}${name}` : name;\n },\n route(exposed: string): Route | undefined {\n if (!prefixed) {\n const only = upstreams[0];\n if (only === undefined) {\n return undefined;\n }\n // The qualified name works here too. Guarding one server advertises\n // `write_file` and guarding two advertises `fs__write_file`, so a name\n // written down against one setup was rejected by the other -- and in\n // this direction it was not even rejected: any unknown name routed to\n // the only server, missed the policy written for `fs.write_file`, and\n // was held for a human to approve as something that could not be\n // undone. A read, held for approval, because it was spelled the way\n // the other setup spells it.\n //\n // Only this server's own name is unwrapped; a tool whose real name\n // begins with it would be written `fs.fs__write_file` in the manifest.\n const prefix = `${only.name}${SEPARATOR}`;\n return exposed.startsWith(prefix)\n ? { upstream: only, tool: exposed.slice(prefix.length) }\n : { upstream: only, tool: exposed };\n }\n for (const key of keys) {\n const prefix = `${key}${SEPARATOR}`;\n if (exposed.startsWith(prefix)) {\n const upstream = byName.get(key);\n if (upstream !== undefined) {\n return { upstream, tool: exposed.slice(prefix.length) };\n }\n }\n }\n return undefined;\n },\n byName(server: string): Upstream | undefined {\n return byName.get(server);\n },\n };\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\n\nimport { UpstreamError } from \"../errors.js\";\n\nfunction describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport interface UpstreamSpec {\n /** Key the manifest uses to qualify this server's tools, e.g. `crm`. */\n readonly name: string;\n readonly command: string;\n readonly args?: readonly string[];\n readonly env?: Readonly<Record<string, string>>;\n /**\n * Where the server's own stderr goes. The proxy inherits it, so a server\n * that fails to boot says why in the client's logs. The CLI captures it, so\n * that reason can be repeated back in the error rather than shown as a\n * banner: a report for a person should not be interleaved with a server's\n * own logging, but it must not throw away the one line that explains the\n * failure either.\n */\n readonly stderr?: \"inherit\" | \"ignore\" | \"capture\";\n}\n\nexport interface Upstream {\n readonly name: string;\n readonly client: Client;\n /**\n * Start the server again after its transport has died. A single oversized\n * response is enough to close a stdio connection, and without this the\n * proxy stayed connected to nothing for the rest of the session: every call\n * after it failed with \"Not connected\", whatever it was.\n *\n * Absent on an upstream that was not spawned from a command, which has\n * nothing to respawn.\n */\n reconnect?(): Promise<void>;\n close(): Promise<void>;\n}\n\nexport const PROXY_CLIENT_INFO = { name: \"synartesis-proxy\", version: \"0.0.0\" } as const;\n\n/**\n * Whatever a stream has buffered, without asserting it into a shape. The sdk\n * types stderr as Stream, which has no read(); what it hands back is a\n * Readable, and a wrong guess here would be a crash while reporting a crash.\n */\nfunction bufferedText(stream: unknown): string {\n if (typeof stream !== \"object\" || stream === null || !(\"read\" in stream)) {\n return \"\";\n }\n const read: unknown = stream.read;\n if (typeof read !== \"function\") {\n return \"\";\n }\n const chunk: unknown = read.call(stream);\n if (typeof chunk === \"string\") {\n return chunk;\n }\n return Buffer.isBuffer(chunk) ? chunk.toString(\"utf8\") : \"\";\n}\n\n/** The tail of what a server said, tidied for repeating back in one error. */\nfunction lastWords(text: string): string | undefined {\n const lines = text\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .filter((line) => line.trim() !== \"\");\n const kept = lines.slice(-4).join(\"; \");\n return kept === \"\" ? undefined : kept;\n}\n\nexport async function connectStdioUpstream(spec: UpstreamSpec): Promise<Upstream> {\n const started = await start(spec);\n let current = started;\n return {\n name: spec.name,\n get client(): Client {\n return current.client;\n },\n async reconnect(): Promise<void> {\n // Best effort: the old one is already broken, and failing to close a\n // broken thing must not stop the new one being made.\n await current.client.close().catch(() => undefined);\n current = await start(spec);\n },\n close: async (): Promise<void> => {\n await current.client.close();\n },\n };\n}\n\nasync function start(spec: UpstreamSpec): Promise<{ client: Client }> {\n const wanted = spec.stderr ?? \"inherit\";\n const transport = new StdioClientTransport({\n command: spec.command,\n args: [...(spec.args ?? [])],\n ...(spec.env === undefined ? {} : { env: { ...spec.env } }),\n // \"pipe\" is what the sdk calls it; captured here so a failure can quote it.\n stderr: wanted === \"capture\" ? \"pipe\" : wanted,\n });\n\n const client = new Client({ ...PROXY_CLIENT_INFO });\n let said = \"\";\n try {\n await client.connect(transport);\n } catch (error: unknown) {\n // Read after the failure: the stream is only attached once the child is\n // spawned, and by the time connect rejects the server has already spoken.\n said = bufferedText(transport.stderr);\n const reason = lastWords(said);\n throw new UpstreamError(\n spec.name,\n \"connect\",\n reason === undefined ? error : `${describeError(error)} — the server said: ${reason}`,\n );\n }\n\n return { client };\n}\n","import type { Manifest, ToolPolicy } from \"./types.js\";\n\nexport interface PolicyMatch {\n readonly policy: ToolPolicy;\n /** False when the fail-closed default was synthesised instead of matched. */\n readonly matched: boolean;\n}\n\nexport interface PolicyResolver {\n resolve(qualifiedName: string): PolicyMatch;\n}\n\n/** `*` stands for any run of characters that is not a dot. */\nfunction toRegExp(pattern: string): RegExp {\n const source = pattern\n .split(\"*\")\n .map((literal) => literal.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"))\n .join(\"[^.]*\");\n return new RegExp(`^${source}$`);\n}\n\nfunction literalLength(pattern: string): number {\n return pattern.length - pattern.split(\"*\").length + 1;\n}\n\ninterface CompiledPolicy {\n readonly policy: ToolPolicy;\n readonly test: RegExp;\n readonly specificity: number;\n readonly wildcards: number;\n}\n\n/**\n * D4. An unrecognised tool is irreversible and gated. A silent passthrough on\n * an unknown destructive tool is worse than having no product at all.\n */\nfunction failClosed(qualifiedName: string): ToolPolicy {\n return { match: qualifiedName, class: \"irreversible\", gate: \"always\" };\n}\n\nexport function createPolicyResolver(manifest: Manifest): PolicyResolver {\n const compiled: CompiledPolicy[] = manifest.tools\n .map((policy) => ({\n policy,\n test: toRegExp(policy.match),\n specificity: literalLength(policy.match),\n wildcards: policy.match.split(\"*\").length - 1,\n }))\n // Longest literal wins, ties broken by fewer wildcards. Ordering is a\n // property of the patterns, never of the order they were written in.\n .sort((a, b) => b.specificity - a.specificity || a.wildcards - b.wildcards);\n\n const cache = new Map<string, PolicyMatch>();\n\n return {\n resolve(qualifiedName: string): PolicyMatch {\n const cached = cache.get(qualifiedName);\n if (cached !== undefined) {\n return cached;\n }\n const hit = compiled.find((candidate) => candidate.test.test(qualifiedName));\n const match: PolicyMatch =\n hit === undefined\n ? { policy: failClosed(qualifiedName), matched: false }\n : { policy: hit.policy, matched: true };\n cache.set(qualifiedName, match);\n return match;\n },\n };\n}\n","import { z } from \"zod\";\n\nimport { ManifestError, SnapshotError, describe } from \"../errors.js\";\nimport { resolveTemplate, type TemplateContext } from \"../manifest/template.js\";\nimport { splitQualified, type CallTemplate } from \"../manifest/types.js\";\nimport type { Router } from \"./routing.js\";\n\n/**\n * What a read saw. Absence is a real state, not a failure: after a successful\n * delete the record is gone, and that is precisely the post-state Phase 4 has\n * to compare against.\n */\nexport type StateObservation = { readonly present: true; readonly value: unknown } | { readonly present: false };\n\n/** A fully resolved call, carrying literal values only (D5). */\nexport interface InversePlan {\n readonly server: string;\n readonly tool: string;\n readonly args: Record<string, unknown>;\n}\n\nconst ToolResult = z.looseObject({\n isError: z.boolean().default(false),\n content: z.array(z.looseObject({ type: z.string() })).default([]),\n});\n\n/**\n * The message an upstream sent when it refused a call, or undefined when it\n * did not refuse.\n *\n * A tool-level error arrives as an ordinary successful response carrying\n * `isError`, so nothing on the forward path notices it unless it looks. It\n * means the server received the call, understood it, and did not do it, which\n * is the same reading `runRead` gives a refused pre-read and `executeInverse`\n * gives a refused inverse.\n */\nexport function refusal(result: unknown): string | undefined {\n const parsed = ToolResult.safeParse(result);\n if (!parsed.success || !parsed.data.isError) {\n return undefined;\n }\n const said = parsed.data.content\n .map((block) => (typeof block[\"text\"] === \"string\" ? block[\"text\"] : \"\"))\n .filter((text) => text !== \"\")\n .join(\" \");\n return said === \"\" ? JSON.stringify(result) : said;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The logical value a tool returned, rather than its MCP envelope. Manifests\n * say `$snapshot.plan`, not `$snapshot.content[0].text`, so the envelope has to\n * be unwrapped before interpolation sees it.\n */\nexport function toPayload(result: unknown): unknown {\n if (!isRecord(result)) {\n return result;\n }\n const structured = result[\"structuredContent\"];\n if (structured !== undefined) {\n return structured;\n }\n const content = result[\"content\"];\n if (Array.isArray(content) && content.length === 1) {\n const block: unknown = content[0];\n if (isRecord(block) && block[\"type\"] === \"text\" && typeof block[\"text\"] === \"string\") {\n const text = block[\"text\"];\n try {\n return JSON.parse(text) as unknown;\n } catch {\n // Not every server returns json. The raw text is still the payload.\n return text;\n }\n }\n }\n return result;\n}\n\nfunction resolveArgs(call: CallTemplate, context: TemplateContext): Record<string, unknown> {\n const resolved = resolveTemplate(call.args, context);\n if (!isRecord(resolved)) {\n throw new ManifestError(`${call.tool} resolved to arguments that are not an object`);\n }\n return resolved;\n}\n\n/**\n * Resolves the inverse while the run is still in progress (D5). At rollback\n * time the upstream may have drifted and the old value may no longer be\n * readable anywhere.\n */\nexport function planInverse(call: CallTemplate, context: TemplateContext): InversePlan {\n const target = splitQualified(call.tool);\n if (target === undefined) {\n throw new ManifestError(`inverse tool ${call.tool} is not qualified as server.tool`);\n }\n return { server: target.server, tool: target.tool, args: resolveArgs(call, context) };\n}\n\n/** The snapshot read with its arguments already reduced to literals. */\nexport interface ResolvedRead {\n readonly server: string;\n readonly tool: string;\n readonly args: Record<string, unknown>;\n}\n\n/**\n * Resolves a declared pre-read against the current context. Stored on the\n * action so that drift can be checked later without consulting a manifest\n * that may have been edited in the meantime.\n */\nexport function planRead(call: CallTemplate, context: TemplateContext): ResolvedRead {\n const target = splitQualified(call.tool);\n if (target === undefined) {\n throw new SnapshotError(call.tool, \"the snapshot tool is not qualified as server.tool\");\n }\n try {\n return { server: target.server, tool: target.tool, args: resolveArgs(call, context) };\n } catch (error: unknown) {\n throw new SnapshotError(call.tool, describe(error), { cause: error });\n }\n}\n\n/**\n * Runs a resolved pre-read. Deliberately not journalled: this is the proxy's\n * own traffic, and recording it would bury the actions an operator needs.\n */\n/**\n * Whether an error says the connection is gone rather than that the call was\n * refused. Matched on the message because the sdk reports both of these as\n * plain errors with no code to tell them apart.\n */\nexport function isDisconnected(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return message.includes(\"Not connected\") || message.includes(\"Connection closed\");\n}\n\n/**\n * Whether the call may already have arrived. The sdk says \"Not connected\" when\n * there was no transport to write to, which means it was never sent; it says\n * \"Connection closed\" when the transport went while a reply was still owed,\n * which says nothing at all about whether the far end acted on it.\n */\nexport function mayHaveArrived(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return message.includes(\"Connection closed\");\n}\n\nexport async function runRead(\n router: Router,\n read: ResolvedRead,\n signal: AbortSignal,\n): Promise<unknown> {\n const label = `${read.server}.${read.tool}`;\n const upstream = router.byName(read.server);\n if (upstream === undefined) {\n throw new SnapshotError(label, `server ${read.server} is not connected`);\n }\n const { tool, args } = read;\n\n const ask = (): Promise<unknown> =>\n upstream.client.request(\n { method: \"tools/call\", params: { name: tool, arguments: args } },\n z.looseObject({}),\n { signal },\n );\n\n let raw: unknown;\n try {\n raw = await ask();\n } catch (error: unknown) {\n // A single oversized response closes a stdio connection, and every call\n // after it -- reads, writes, anything -- then failed with \"Not connected\"\n // for the rest of the session: one large file bricked the run. Reading is\n // safe to do again, so the server is started back up and asked once more.\n if (!isDisconnected(error) || upstream.reconnect === undefined) {\n throw new SnapshotError(label, describe(error), { cause: error });\n }\n try {\n await upstream.reconnect();\n raw = await ask();\n } catch (retry: unknown) {\n // The second attempt can kill the connection the same way the first did\n // -- the response is still too large -- so leave a live one behind. The\n // call that caused it fails either way; the rest of the session should\n // not have to.\n if (isDisconnected(retry)) {\n await upstream.reconnect().catch(() => undefined);\n }\n throw new SnapshotError(\n label,\n `${describe(error)} (the connection to ${read.server} was restarted and the read failed again: ${describe(retry)})`,\n { cause: retry },\n );\n }\n }\n\n const parsed = ToolResult.safeParse(raw);\n if (parsed.success && parsed.data.isError) {\n // A tool-level error is still a failed read: whatever the write is about\n // to overwrite, we could not capture it.\n throw new SnapshotError(label, `the read reported an error: ${JSON.stringify(raw)}`, {\n absent: true,\n });\n }\n return toPayload(raw);\n}\n\n/**\n * The post-write read. Unlike the pre-read, a tool-level error here is\n * meaningful rather than fatal: the same read with the same arguments\n * succeeded moments earlier, so an error now says the resource is gone, which\n * is exactly what a delete is supposed to produce. Transport and protocol\n * failures still throw, because those say nothing about the resource.\n */\nexport async function observeState(\n router: Router,\n read: ResolvedRead,\n signal: AbortSignal,\n): Promise<StateObservation> {\n try {\n return { present: true, value: await runRead(router, read, signal) };\n } catch (error: unknown) {\n if (error instanceof SnapshotError && error.absent) {\n return { present: false };\n }\n throw error;\n }\n}\n"],"mappings":"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","names":["join","existsSync","dirname","dirname","existsSync","z","z","z","z","read","cached","z","z","read"]}
|