sessionpipe 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/cli.js +962 -258
- package/dist/cli.js.map +4 -4
- package/dist/control/autoupdate.d.ts +156 -0
- package/dist/control/autoupdate.d.ts.map +1 -0
- package/dist/control/cli.d.ts +4 -0
- package/dist/control/cli.d.ts.map +1 -1
- package/dist/control/daemon.d.ts +54 -1
- package/dist/control/daemon.d.ts.map +1 -1
- package/dist/control/local.d.ts +4 -0
- package/dist/control/local.d.ts.map +1 -1
- package/dist/control/pair.d.ts +3 -0
- package/dist/control/pair.d.ts.map +1 -1
- package/dist/control/route.d.ts +6 -0
- package/dist/control/route.d.ts.map +1 -1
- package/dist/control/store.d.ts +4 -0
- package/dist/control/store.d.ts.map +1 -1
- package/dist/hook.js +5 -2
- package/dist/hook.js.map +2 -2
- package/dist/index.js +16 -15
- package/dist/index.js.map +2 -2
- package/dist/launcher.d.ts +2 -1
- package/dist/launcher.d.ts.map +1 -1
- package/dist/update.d.ts +70 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/worker.js +16 -15
- package/dist/worker.js.map +2 -2
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/cli.ts", "../../core/src/adapters/antigravity.ts", "../../core/src/paths.ts", "../../core/src/readers/files.ts", "../../core/src/readers/transcripts.ts", "../../core/src/adapters/claude-shaped.ts", "../../core/src/adapters/claude-code.ts", "../../core/src/readers/git.ts", "../../core/src/adapters/codex.ts", "../../core/src/adapters/codex-config.ts", "../../core/src/adapters/gemini-cli.ts", "../../core/src/adapters/claude-code-control.ts", "../../core/src/adapters/index.ts", "../../core/src/config.ts", "../../core/src/ulid.ts", "../../core/src/events.ts", "../../core/src/outbox.ts", "../../core/src/privacy/pii.ts", "../../core/src/privacy/secrets.ts", "../../core/src/privacy/filter.ts", "../../core/src/sinks/file.ts", "../../core/src/sinks/stdout.ts", "../src/connect.ts", "../src/control/
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n// SPDX-License-Identifier: Apache-2.0\n// sessionpipe: install once, hook everything, choose per sink what leaves.\n// connect \u00B7 install \u00B7 uninstall \u00B7 sink add|list|remove|test \u00B7 secrets \u00B7 status \u00B7\n// doctor \u00B7 tail \u00B7 backfill \u00B7 forget \u00B7 replay \u00B7 update \u00B7 hook \u00B7 worker\nimport { execFileSync, spawn, spawnSync } from \"node:child_process\";\nimport { mkdtempSync, readdirSync, readFileSync, realpathSync, rmSync, statSync, unlinkSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n ADAPTERS,\n adapterByName,\n type BackfillRow,\n type Config,\n Cursors,\n claudeControl,\n claudeDirs,\n configFile,\n type Event,\n filterEvent,\n type HookCommand,\n machineName,\n makeEvent,\n Outbox,\n readConfig,\n type SinkConfig,\n stateDir,\n type Tier,\n tilde,\n writeConfig,\n} from \"@sessionpipe/core\";\nimport { connectFolders, connectTier } from \"./connect.js\";\nimport { CONTROL_HELP, controlMain, waitMain } from \"./control/cli.js\";\nimport { moveControlSecrets, readControl } from \"./control/store.js\";\nimport { installLauncher, launcherPath, launcherState, removeLauncher, usesLauncher } from \"./launcher.js\";\nimport { buildSinks, factsState, flush, jobsDir, runJob, VERSION } from \"./run.js\";\nimport { rerunGlobally, stableNode, viaNpx } from \"./runtime.js\";\nimport { bestStore, dropSinkSecrets, moveSinkSecrets, type StoreName, sinkWithSecrets, storeLabel } from \"./secrets.js\";\n\nprocess.stdout.on(\"error\", (e: NodeJS.ErrnoException) => {\n if (e.code === \"EPIPE\") process.exit(0);\n});\nconst args = process.argv.slice(2);\nconst cmd = args[0] ?? \"help\";\nconst flag = (name: string): string | undefined => {\n const i = args.indexOf(name);\n return i >= 0 ? args[i + 1] : undefined;\n};\nconst has = (name: string): boolean => args.includes(name);\nconst out = (s = \"\"): void => {\n process.stdout.write(`${s}\\n`);\n};\nconst state = stateDir();\nconst distDir = path.dirname(fileURLToPath(import.meta.url));\n\n/** The command a hook entry runs: the launcher, which outlives node upgrades\n * (launcher.ts); on Windows, this node by a stable absolute path and hook.js by its\n * real path. */\nfunction hookCommand(): HookCommand {\n if (usesLauncher()) {\n const l = launcherPath();\n return (a) => ({ argv: [l, ...a], command: `${JSON.stringify(l)} ${a.join(\" \")}` });\n }\n const node = stableNode(process.execPath);\n let script = path.join(distDir, \"hook.js\");\n try {\n script = realpathSync(script);\n } catch {}\n return (a) => ({\n argv: [node, script, ...a],\n command: `${JSON.stringify(node)} ${JSON.stringify(script)} ${a.join(\" \")}`,\n });\n}\n\nfunction selectedAdapters(): typeof ADAPTERS {\n const named = ADAPTERS.filter((a) => has(`--${a.name}`));\n if (named.length) return named;\n return ADAPTERS.filter((a) => a.detect());\n}\n\nasync function main(): Promise<void> {\n switch (cmd) {\n case \"connect\":\n return connect();\n case \"install\":\n return install();\n case \"secrets\":\n return secrets();\n case \"uninstall\":\n return uninstall();\n case \"sink\":\n return sink();\n case \"status\":\n return status();\n case \"doctor\":\n return await doctor();\n case \"tail\":\n return tail();\n case \"backfill\":\n return backfill();\n case \"forget\":\n return forget();\n case \"replay\":\n return replay();\n case \"update\":\n return update();\n case \"worker\":\n return workerFromArgv();\n case \"control\":\n return controlMain(args, out, distDir);\n case \"wait\":\n return waitMain(args, out);\n case \"hook\":\n out(\"sessionpipe hook is dist/hook.js; harnesses run it directly\");\n return;\n case \"--version\":\n case \"-v\":\n case \"version\":\n out(VERSION);\n return;\n default:\n return help();\n }\n}\n\nfunction help(): void {\n out(`sessionpipe ${VERSION} \u2014 an open protocol for what your coding agents are doing\n\n sessionpipe connect <receiver> [--machine NAME] [--tier 0-3] [--mode safe|auto] [--folder DIR]\u2026\n (everything, in one go: hooks, a sink, signed messages, keys)\n sessionpipe install [--claude-code --codex --gemini-cli --antigravity] [--machine NAME] [--backfill DAYS] [--sink URL --tier N]\n sessionpipe uninstall [--keep-state]\n sessionpipe sink add <url|file:PATH|stdout> [--tier 0-3] [--token T] [--pii] [--name N]\n sessionpipe sink list | remove <name> | test <name>\n sessionpipe secrets [move keychain|secret-service|file] (where the machine's keys live)\n sessionpipe status | doctor [--json]\n sessionpipe tail [--session ID] [--tier N] [--harness NAME]\n sessionpipe backfill [--days 30] | forget <harness> <session> | replay --sink NAME\n sessionpipe update\n${CONTROL_HELP}\n\nDocs: https://sessionpipe.org \u00B7 nothing leaves this machine until you add a sink.`);\n}\n\nasync function install(): Promise<void> {\n if (viaNpx(distDir)) return rerunGlobally(args, out);\n const cfg = readConfig();\n const machine = flag(\"--machine\");\n if (machine) cfg.machine = machine.slice(0, 80);\n // A sink URL given here is added first, so the install knows whether it needs\n // every tool event or only the heartbeat's one.\n const sinkUrl = flag(\"--sink\");\n if (sinkUrl) await sinkAdd(sinkUrl, cfg);\n const adapters = selectedAdapters();\n if (!adapters.length) {\n out(\n \" No supported harness found on this machine (Claude Code, Codex, Gemini CLI, Antigravity). Pass --<harness> to force one.\",\n );\n return;\n }\n out(` Machine: ${machineName(cfg, os.hostname())}`);\n const lean = isLean(cfg);\n if (lean)\n out(\n \" No sink above tier 0: hooking one tool event per harness (the heartbeat's). `sink add \u2026 --tier 1` or higher hooks the rest.\",\n );\n installHarnesses(adapters, cfg, lean);\n writeConfig(cfg);\n const days = Number(flag(\"--backfill\") ?? 30);\n if (days > 0) backfillRows(adapters, days, cfg);\n out(\"\");\n const live = cfg.sinks.filter((s) => !s.paused);\n if (live.length) out(` Reporting to ${live.map((s) => `${s.name} (tier ${s.tier})`).join(\", \")}.`);\n else\n out(\n \" Nothing leaves this machine yet: events go to the local outbox. `sessionpipe tail` shows them; `sessionpipe sink add <url> --tier N` sends them.\",\n );\n out(\" Sessions already running pick up hooks on their next start (Claude Code \u2265 2.1.280 picks them up live).\");\n}\n\n/** No sink takes tier \u2265 1: the harness only needs one tool event (issue #12). */\nfunction isLean(cfg: Config): boolean {\n return !cfg.sinks.some((s) => !s.paused && Math.min(s.tier, s.max_tier ?? 3) >= 1);\n}\n\n/** Write the hooks for these harnesses; remember which files sessionpipe created. */\nfunction installHarnesses(adapters: readonly (typeof ADAPTERS)[number][], cfg: Config, lean: boolean): void {\n if (usesLauncher()) {\n const node = stableNode(process.execPath);\n const l = installLauncher({ distDir, node, version: VERSION });\n if (l.changed)\n out(` \u2713 hook launcher: ${tilde(l.launcher)} (node ${tilde(node)}, or any node on PATH once that one is gone)`);\n }\n const hc = hookCommand();\n for (const a of adapters) {\n const prev = cfg.harnesses[a.name] ?? {};\n const created = new Set(prev.created ?? []);\n const reports = a.install(hc, process.env, { lean, created: [...created] });\n for (const r of reports) {\n if (r.created) created.add(r.file);\n const mark = r.skipped ? \"!\" : r.changed ? \"\u2713\" : \"=\";\n out(\n ` ${mark} ${a.name}: ${tilde(r.file)}${r.note ? ` \u2014 ${r.note}` : r.changed ? \" written\" : \" already current\"}`,\n );\n }\n cfg.harnesses[a.name] = { enabled: true, ...(created.size ? { created: [...created] } : {}) };\n if (a.name === \"gemini-cli\")\n out(\" note: Gemini CLI's own telemetry defaults logPrompts on; that is Google's setting, not sessionpipe's.\");\n if (a.name === \"codex\" && !reports.some((r) => r.skipped))\n out(\n \" note: Codex runs non-managed hooks only after you approve them: start `codex` and accept the hook review. The notify fallback reports turn ends meanwhile.\",\n );\n }\n}\n\n/** `sessionpipe connect <receiver>`: everything a machine needs, in one command and one\n * approval \u2014 the hooks for every agent and every Claude Code account here, a sink at\n * tier 2, signed messages (the daemon, paired with open pairing), the keys moved into\n * the keychain when there is one, the daemon kept running past logout, the last 30\n * days backfilled. Run it again and it only fixes what's missing. Asks nothing: the\n * mode is --mode or safe, the folders are --folder, this one, or where your recent\n * sessions ran \u2014 never the home folder. */\nasync function connect(): Promise<void> {\n const raw = args[1];\n if (!raw || raw.startsWith(\"-\"))\n return out(\n \"usage: sessionpipe connect <receiver> [--machine NAME] [--tier 0-3] [--mode safe|auto] [--folder DIR]\u2026 [--no-service]\",\n );\n if (viaNpx(distDir)) return rerunGlobally(args, out);\n const url = (/^https?:\\/\\//.test(raw) ? raw : `https://${raw}`).replace(/\\/$/, \"\");\n const host = new URL(url).host;\n const cfg = readConfig();\n const machine = flag(\"--machine\");\n if (machine) cfg.machine = machine.slice(0, 80);\n const name = machineName(cfg, os.hostname());\n const before = cfg.sinks.find((x) => x.url.replace(/\\/$/, \"\") === url);\n const tier = connectTier(flag(\"--tier\"), before?.tier);\n out(` Connecting ${name} to ${host}.`);\n\n // 1. The hooks, for every agent on this machine (and every Claude Code account).\n const adapters = ADAPTERS.filter((a) => a.detect());\n if (!adapters.length)\n out(\n \" ! No coding agent here yet (Claude Code, Codex, Gemini CLI, Antigravity): run `sessionpipe install` once you have one.\",\n );\n else installHarnesses(adapters, cfg, tier < 1);\n writeConfig(cfg);\n await reportClaudeAccounts();\n const rows = collectRows(adapters, 30);\n\n // 2. One approval on any signed-in device: the machine's control token and its\n // sessions key together.\n const control = readControl();\n const paired = control?.receivers.find((r) => r.url === url);\n const sinkNow = readConfig().sinks.find((x) => x.url.replace(/\\/$/, \"\") === url);\n if (paired && sinkNow && (sinkNow.token || sinkNow.token_in)) {\n out(` \u2713 Already paired with ${host} as ${paired.machine}: nothing to approve.`);\n } else {\n const recent = rows\n .slice()\n .sort((a, b) => b.row.last_at - a.row.last_at)\n .map((r) => r.row.session.cwd ?? \"\");\n const choice = connectFolders({\n cwd: process.cwd(),\n home: os.homedir(),\n flags: argsAll(\"--folder\"),\n existing: control?.folders ?? [],\n recent,\n exists: (d) => {\n try {\n return statSync(d).isDirectory();\n } catch {\n return false;\n }\n },\n });\n if (choice.from === \"recent\")\n out(` Folders from your recent sessions: ${choice.folders.map((d) => tilde(d)).join(\", \")}`);\n if (choice.from === \"none\")\n out(\n \" ! No folder for sessions you message yet (this ran from your home folder, and no recent session ran anywhere else). Run `sessionpipe control pair` again from a project folder, or with --folder.\",\n );\n const mode =\n flag(\"--mode\") === \"auto\" || flag(\"--mode\") === \"safe\" ? (flag(\"--mode\") as string) : (control?.mode ?? \"safe\");\n await controlMain(\n [\n \"control\",\n \"pair\",\n url,\n \"--mode\",\n mode,\n \"--tier\",\n String(tier),\n \"--name\",\n control?.name ?? name,\n ...choice.folders.flatMap((d) => [\"--folder\", d]),\n ...(has(\"--no-service\") ? [\"--no-service\"] : []),\n ],\n out,\n distDir,\n );\n if (mode === \"safe\")\n out(\n \" Safe mode: `sessionpipe control mode auto` lets sessions you message work unattended (Claude Code's auto mode).\",\n );\n }\n\n // 3. The sink at the tier asked for, with the receiver's cap and endpoints.\n const after = readConfig();\n const sink = after.sinks.find((x) => x.url.replace(/\\/$/, \"\") === url);\n if (sink) {\n const old = sink.tier;\n sink.tier = tier;\n await learnReceiver(sink, tier);\n writeConfig(after);\n const eff = Math.min(sink.tier, sink.max_tier ?? 3) as Tier;\n out(` \u2713 Sink ${sink.name}: tier ${eff}${old !== tier ? ` (was ${old})` : \"\"} \u2014 sends ${TIER_TEXT[eff]}`);\n } else out(` ! No sink for ${host}: \\`sessionpipe sink add ${url} --token <key> --tier ${tier}\\``);\n\n // 4. Keys into the keychain, when this session has one unlocked.\n const store = bestStore();\n if (store !== \"file\") {\n const a = moveSinkSecrets(store);\n const b = moveControlSecrets(store);\n const kept = [...a.kept, ...b.kept];\n out(` \u2713 Keys: in ${storeLabel(store)}${kept.length ? ` (left in the file: ${kept.join(\", \")})` : \"\"}`);\n } else\n out(\n ` Keys: in ${tilde(path.dirname(configFile()))} at 0600 \u2014 no unlocked keychain in this session${process.env.SSH_CONNECTION ? \" (an ssh shell)\" : \"\"}`,\n );\n\n // 5. The last 30 days, now that there is somewhere to send them.\n if (rows.length) queueBackfill(rows, 30, readConfig());\n out(\"\");\n out(` Done: ${name} reports to ${host} and takes messages you sign on a device it trusts.`);\n out(\" Run this again any time; it only fixes what's missing. `sessionpipe doctor` checks everything.\");\n}\n\nfunction argsAll(name: string): string[] {\n return args.flatMap((a, i) => (a === name && args[i + 1] ? [args[i + 1] as string] : []));\n}\n\n/** Each Claude Code account on this machine, and whether Claude Code says it's signed\n * in from here (a message's headless run uses this login). */\nasync function reportClaudeAccounts(): Promise<void> {\n const bin = claudeControl.findClaude();\n if (!bin) return;\n const dirs = claudeDirs();\n const answers = await Promise.all(dirs.map((d) => claudeControl.claudeLogin(bin, d)));\n dirs.forEach((d, i) => {\n const l = answers[i] as claudeControl.Login;\n if (l.loggedIn === true)\n out(\n ` \u2713 Claude Code ${tilde(d)}: signed in${l.method ? ` (${[l.method, l.subscription].filter(Boolean).join(\", \")})` : \"\"}`,\n );\n else if (l.loggedIn === false)\n out(\n ` ! Claude Code ${tilde(d)}: not signed in as this shell sees it \u2014 ${claudeControl.loginCommand(d)}${process.platform === \"darwin\" && process.env.SSH_CONNECTION ? \" (over ssh a Mac's keychain login can't be read; log in at the screen)\" : \"\"}`,\n );\n });\n}\n\n/** `sessionpipe secrets [move <store>]`: where this machine's keys live. */\nfunction secrets(): void {\n const sub = args[1];\n if (sub === \"move\") {\n const to = args[2] as StoreName | undefined;\n if (to !== \"keychain\" && to !== \"secret-service\" && to !== \"file\") {\n out(\"usage: sessionpipe secrets move keychain|secret-service|file\");\n return;\n }\n const a = moveSinkSecrets(to);\n const b = moveControlSecrets(to);\n const moved = [...a.moved, ...b.moved];\n const kept = [...a.kept, ...b.kept];\n out(\n moved.length ? ` \u2713 moved to ${storeLabel(to)}: ${moved.join(\", \")}` : ` nothing to move to ${storeLabel(to)}`,\n );\n if (kept.length)\n out(` ! left where they are (unreadable here, or ${storeLabel(to)} refused them): ${kept.join(\", \")}`);\n return;\n }\n const cfg = readConfig();\n const where = (s: SinkConfig): string =>\n s.token_in\n ? `${storeLabel(s.token_in)}${sinkWithSecrets(s) ? \"\" : \" \u2014 can't be read from this session (locked?)\"}`\n : s.token || s.secret\n ? `${tilde(configFile())} (0600)`\n : \"no key\";\n for (const s of cfg.sinks) out(` sink ${s.name.padEnd(20)} ${where(s)}`);\n for (const r of readControl()?.receivers ?? [])\n out(\n ` control ${new URL(r.url).host.padEnd(17)} ${r.token_in ? `${storeLabel(r.token_in)}${r.token ? \"\" : \" \u2014 can't be read from this session (locked?)\"}` : \"control.json (0600)\"}`,\n );\n if (!cfg.sinks.length && !readControl()?.receivers.length) out(\" no keys on this machine\");\n out(` best store from this session: ${storeLabel(bestStore())}`);\n}\n\nfunction uninstall(): void {\n const cfg = readConfig();\n for (const a of ADAPTERS) {\n const created = cfg.harnesses[a.name]?.created ?? [];\n for (const r of a.uninstall(process.env, { created }))\n if (r.changed) out(` \u2713 ${a.name}: ${r.note ?? `hooks removed from ${tilde(r.file)}`}`);\n else if (r.skipped) out(` ! ${a.name}: ${tilde(r.file)} \u2014 ${r.note}`);\n delete cfg.harnesses[a.name];\n }\n writeConfig(cfg);\n if (usesLauncher()) removeLauncher();\n if (!has(\"--keep-state\"))\n out(\n ` Outbox and state kept under ${tilde(state)} (delete it yourself, or pass nothing: it prunes after ${readConfig().keep_days ?? 30} days).`,\n );\n out(\" Done. Every config file is byte-identical except for the entries sessionpipe wrote.\");\n}\n\nasync function sink(): Promise<void> {\n const sub = args[1];\n const cfg = readConfig();\n if (sub === \"add\" && args[2]) return sinkAdd(args[2], cfg);\n if (sub === \"list\") {\n if (!cfg.sinks.length) out(\" no sinks\");\n for (const s of cfg.sinks)\n out(\n ` ${s.name.padEnd(16)} ${s.url.padEnd(44)} tier ${s.tier}${s.max_tier !== undefined && s.max_tier < s.tier ? ` (capped ${s.max_tier})` : \"\"}${s.pii ? \" pii\" : \"\"}${s.control ? \" control\" : \"\"}${s.paused ? ` PAUSED ${s.paused}` : \"\"}`,\n );\n return;\n }\n if (sub === \"remove\" && args[2]) {\n const n = cfg.sinks.length;\n for (const s of cfg.sinks) if (s.name === args[2]) dropSinkSecrets(s);\n cfg.sinks = cfg.sinks.filter((s) => s.name !== args[2]);\n writeConfig(cfg);\n out(cfg.sinks.length < n ? ` \u2713 removed ${args[2]}` : ` no sink named ${args[2]}`);\n return;\n }\n if (sub === \"test\" && args[2]) {\n const s = cfg.sinks.find((x) => x.name === args[2]);\n if (!s) return out(` no sink named ${args[2]}`);\n const [sk] = buildSinks([s]);\n if (!sk) return out(\" sink type not supported yet\");\n // One heartbeat, then its forget: the receiver sees the round trip and keeps no row.\n const session = { id: `test-${Date.now()}`, machine: machineName(cfg, os.hostname()) };\n const mk = (type: string, seq: number) =>\n makeEvent(\n { type, harnessEvent: \"test\", data: {} },\n { harness: { name: \"sessionpipe\" }, session: { ...session, seq } },\n );\n const r = await sk.send([\n filterEvent(mk(\"session.heartbeat\", 0), sk.tier, sk.pii) as Event,\n filterEvent(mk(\"session.forgotten\", 1), sk.tier, sk.pii) as Event,\n ]);\n out(\n r.ok\n ? ` \u2713 ${s.name}: ${r.status ?? \"ok\"} accepted ${r.accepted ?? 2} (a heartbeat and its forget)`\n : ` \u2717 ${s.name}: ${r.status ?? \"\"} ${r.error ?? \"\"} (${r.action})`,\n );\n return;\n }\n out(\n \"usage: sessionpipe sink add <url|file:PATH|stdout> [--tier N] [--token T] [--pii] [--name N] | list | remove <name> | test <name>\",\n );\n}\n\nasync function sinkAdd(url: string, cfg: Config): Promise<void> {\n const tier = Math.max(0, Math.min(3, Number(flag(\"--tier\") ?? 0))) as Tier;\n const name = flag(\"--name\") ?? (url === \"stdout\" ? \"stdout\" : url.startsWith(\"file:\") ? \"file\" : new URL(url).host);\n // Control is not a property of a sink: it is set up per machine, with keys enrolled\n // at this terminal (spec/CONTROL.md \u00A72, `sessionpipe control pair`). A sink never\n // carries `control: true`.\n if (has(\"--control\"))\n out(\" --control is ignored: control is set up per machine (`sessionpipe control pair <url>`, spec/CONTROL.md)\");\n const s: SinkConfig = { name, url, tier, pii: has(\"--pii\") };\n // Changing a sink's tier keeps the key it has (pairing may have handed it over, and\n // it may live in a keychain): only --token / --secret replace one.\n const prev = cfg.sinks.find((x) => x.name === name && x.url === url);\n const token = flag(\"--token\");\n const secret = flag(\"--secret\");\n if (prev?.token_in && !token && !secret) s.token_in = prev.token_in;\n else {\n const kept = prev ? sinkWithSecrets(prev) : null;\n const t = token ?? kept?.token;\n const sec = secret ?? kept?.secret;\n if (t) s.token = t;\n if (sec) s.secret = sec;\n if (prev?.token_in) dropSinkSecrets(prev);\n }\n await learnReceiver(s, tier);\n cfg.sinks = cfg.sinks.filter((x) => x.name !== name).concat([s]);\n writeConfig(cfg);\n out(` \u2713 sink ${name}: ${url} at tier ${Math.min(tier, s.max_tier ?? 3)}${s.pii ? \", pii\" : \"\"}`);\n out(` tier ${tier} sends: ${TIER_TEXT[Math.min(tier, s.max_tier ?? 3) as Tier]}`);\n}\n/** Read the receiver's well-known file onto the sink: its tier cap and endpoints. */\nasync function learnReceiver(s: SinkConfig, tier: Tier): Promise<void> {\n if (!/^https?:\\/\\//.test(s.url)) return;\n try {\n const r = await fetch(`${s.url.replace(/\\/$/, \"\")}/.well-known/sessionpipe`, { signal: AbortSignal.timeout(8000) });\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n const wk = (await r.json()) as { max_tier?: number; endpoints?: { events?: string }; capabilities?: string[] };\n if (typeof wk.max_tier === \"number\") {\n s.max_tier = wk.max_tier as Tier;\n if (wk.max_tier < tier) out(` receiver's max_tier is ${wk.max_tier}: sending tier ${wk.max_tier}, not ${tier}`);\n }\n if (wk.endpoints) (s as SinkConfig & { endpoints?: unknown }).endpoints = wk.endpoints;\n s.well_known_at = new Date().toISOString();\n } catch (e) {\n out(\n ` ! ${s.url} has no readable /.well-known/sessionpipe (${(e as Error).message}); added anyway, at tier ${tier}`,\n );\n }\n}\n\nconst TIER_TEXT: Record<Tier, string> = {\n 0: \"session state and timing, machine, folder, repo, branch, model, title, link, the KIND of attention needed \u2014 no tool names, no words\",\n 1: \"tier 0 + tool names, durations, ok/error, file paths, the attention message, subagents, compactions \u2014 no prompts\",\n 2: \"tier 1 + your prompts and the assistant's text, secrets removed\",\n 3: \"everything, including tool input and output\",\n};\n\n/** Each harness's sessions of the last `days` days, as the backfill reads them. */\nfunction collectRows(\n adapters: readonly (typeof ADAPTERS)[number][],\n days: number,\n): { harness: string; row: BackfillRow }[] {\n const since = Date.now() - days * 86_400_000;\n const rows: { harness: string; row: BackfillRow }[] = [];\n for (const a of adapters) {\n try {\n for (const row of a.backfill(since)) rows.push({ harness: a.name, row });\n } catch {}\n }\n return rows;\n}\n\nfunction backfillRows(adapters: readonly (typeof ADAPTERS)[number][], days: number, cfg: Config): void {\n queueBackfill(collectRows(adapters, days), days, cfg);\n}\n\nfunction queueBackfill(rows: { harness: string; row: BackfillRow }[], days: number, cfg: Config): void {\n const outbox = new Outbox(state);\n let n = 0;\n const machine = machineName(cfg, os.hostname());\n for (const { harness, row } of rows) {\n const ref = { harness, session: row.session.id };\n const facts = factsState(state).get(harness, row.session.id);\n if (facts.backfilled) continue;\n const { id, ...rest } = row.session;\n const e = makeEvent(\n {\n type: \"session.backfill\",\n harnessEvent: \"backfill\",\n data: {\n started_at: new Date(row.started_at).toISOString(),\n last_at: new Date(row.last_at).toISOString(),\n ...(row.turns !== undefined ? { turns: row.turns } : {}),\n },\n },\n {\n harness: { name: harness },\n session: { ...rest, id, seq: outbox.nextSeq(ref), machine, ...(rest.cwd ? { cwd: tilde(rest.cwd) } : {}) },\n now: row.last_at,\n },\n );\n outbox.append(ref, [e]);\n factsState(state).save(harness, row.session.id, { backfilled: true });\n n++;\n }\n out(` \u2713 Backfill: ${n} session${n === 1 ? \"\" : \"s\"} from the last ${days} days queued as session.backfill`);\n void flush(state, cfg.sinks, outbox);\n}\n\nfunction backfill(): void {\n backfillRows(selectedAdapters(), Number(flag(\"--days\") ?? 30), readConfig());\n}\n\nasync function forget(): Promise<void> {\n const [, harness, session] = args;\n if (!harness || !session) return out(\"usage: sessionpipe forget <harness> <session>\");\n const cfg = readConfig();\n const outbox = new Outbox(state);\n const ref = { harness, session };\n const e = makeEvent(\n { type: \"session.forgotten\", harnessEvent: \"forget\", data: {} },\n {\n harness: { name: harness },\n session: { id: session, seq: outbox.nextSeq(ref), machine: machineName(cfg, os.hostname()) },\n },\n );\n const sinks = buildSinks(cfg.sinks);\n for (const s of sinks) {\n const r = await s.send([filterEvent(e, s.tier, s.pii) as Event]);\n out(r.ok ? ` \u2713 ${s.name}: asked to delete ${harness}:${session}` : ` \u2717 ${s.name}: ${r.error ?? r.status}`);\n }\n outbox.delete(ref);\n out(\" local outbox for the session removed\");\n}\n\nasync function replay(): Promise<void> {\n const name = flag(\"--sink\");\n const cfg = readConfig();\n const sinks = name ? cfg.sinks.filter((s) => s.name === name) : cfg.sinks;\n if (!sinks.length) return out(\" no such sink\");\n for (const s of sinks) {\n if (has(\"--from-start\")) new Cursors(state, s.name).write({});\n }\n const d = await flush(state, sinks, new Outbox(state));\n for (const [k, v] of Object.entries(d)) out(` ${k}: ${v} event${v === 1 ? \"\" : \"s\"} delivered`);\n}\n\nfunction status(): void {\n const cfg = readConfig();\n const hc = hookCommand();\n out(` machine: ${machineName(cfg, os.hostname())} sessionpipe ${VERSION} state ${tilde(state)}`);\n for (const a of ADAPTERS) {\n if (!a.detect() && !cfg.harnesses[a.name]) continue;\n for (const r of a.installed(hc, process.env, { lean: isLean(cfg) }))\n out(\n ` ${a.name.padEnd(12)} ${tilde(r.file).padEnd(44)} ${r.state}${r.state !== \"current\" && r.note ? ` \u2014 ${r.note}` : \"\"}`,\n );\n }\n if (!cfg.sinks.length) out(\" sinks: none (events stay in the local outbox)\");\n for (const s of cfg.sinks) {\n const c = new Cursors(state, s.name).read();\n const outbox = new Outbox(state);\n let pending = 0;\n for (const ref of outbox.sessions()) {\n const f = outbox.file(ref);\n try {\n pending += Math.max(0, statSync(f).size - (c[`${ref.harness}/${ref.session}`] ?? 0)) > 0 ? 1 : 0;\n } catch {}\n }\n out(\n ` sink ${s.name.padEnd(16)} tier ${Math.min(s.tier, s.max_tier ?? 3)} ${s.paused ? `PAUSED ${s.paused}` : pending ? `${pending} session file(s) with undelivered events` : \"up to date\"}`,\n );\n }\n const t = timing();\n if (t)\n out(\n ` hook: in-process p50 ${t.p50} ms over ${t.n} runs (\\`sessionpipe doctor\\` measures the wall clock the harness waits)`,\n );\n const jobs = jobsDir(state);\n try {\n const n = readdirSync(jobs).length;\n if (n) out(` jobs: ${n} waiting`);\n } catch {}\n}\n\n/** Spawn the hook the way a harness does and time the whole process (issue #12:\n * the in-process clock misses Node's startup, ~200 ms on an older Intel Mac). */\nfunction hookWall(runs = 8): { n: number; p50: number; p95: number } | null {\n const hook = path.join(distDir, \"hook.js\");\n const tmp = mkdtempSync(path.join(os.tmpdir(), \"sessionpipe-doctor-\"));\n const env = {\n ...process.env,\n SESSIONPIPE_STATE: tmp,\n SESSIONPIPE_CONFIG: path.join(tmp, \"config.json\"),\n SESSIONPIPE_NO_WORKER: \"1\",\n };\n const input = JSON.stringify({\n session_id: \"doctor\",\n hook_event_name: \"PostToolUse\",\n tool_name: \"Bash\",\n cwd: process.cwd(),\n });\n const times: number[] = [];\n try {\n for (let i = 0; i < runs; i++) {\n const t0 = process.hrtime.bigint();\n const r = spawnSync(process.execPath, [hook, \"claude-code\", \"PostToolUse\"], { input, env, encoding: \"utf8\" });\n if (r.status !== 0) return null;\n times.push(Number(process.hrtime.bigint() - t0) / 1e6);\n }\n } catch {\n return null;\n } finally {\n rmSync(tmp, { recursive: true, force: true });\n }\n times.sort((a, b) => a - b);\n const q = (p: number) => Math.round(times[Math.min(times.length - 1, Math.floor(p * times.length))] ?? 0);\n return { n: times.length, p50: q(0.5), p95: q(0.95) };\n}\n\nfunction timing(): { n: number; p50: number; p95: number } | null {\n try {\n const lines = readFileSync(path.join(state, \"timing.jsonl\"), \"utf8\").trim().split(\"\\n\").slice(-100);\n const ms = lines\n .map((l) => (JSON.parse(l) as { ms: number }).ms)\n .filter((x) => x >= 0)\n .sort((a, b) => a - b);\n if (!ms.length) return null;\n const q = (p: number) => Math.round(ms[Math.min(ms.length - 1, Math.floor(p * ms.length))] ?? 0);\n return { n: ms.length, p50: q(0.5), p95: q(0.95) };\n } catch {\n return null;\n }\n}\n\nasync function doctor(): Promise<void> {\n const cfg = readConfig();\n const hc = hookCommand();\n const report: Record<string, unknown> = {\n version: VERSION,\n node: process.version,\n node_path: stableNode(process.execPath),\n machine: machineName(cfg, os.hostname()),\n state: state,\n config: configFile(),\n harnesses: {},\n sinks: [],\n timing: timing(),\n hook_wall_ms: hookWall(),\n warnings: [] as string[],\n };\n const warnings = report.warnings as string[];\n if (usesLauncher()) {\n const l = launcherState(VERSION);\n report.launcher = { file: tilde(l.file), node: l.node, node_ok: l.nodeOk, version: l.version };\n if (Object.keys(cfg.harnesses).length) warnings.push(...l.problems);\n }\n // Where each key lives, and whether this session can read it.\n const keys: { what: string; where: string; readable: boolean }[] = [];\n for (const s of cfg.sinks)\n if (s.token_in || s.token || s.secret)\n keys.push({ what: `sink ${s.name}`, where: s.token_in ?? \"file\", readable: !!sinkWithSecrets(s) });\n const control = readControl();\n for (const r of control?.receivers ?? [])\n keys.push({ what: `control ${new URL(r.url).host}`, where: r.token_in ?? \"file\", readable: !!r.token });\n report.keys = keys;\n for (const k of keys)\n if (!k.readable)\n warnings.push(\n `${k.what}: its key is in ${storeLabel(k.where as StoreName)}, which this session can't read (locked, or an ssh shell). Events wait; the control daemon sends them from your own session.`,\n );\n // Each Claude Code account: a message's headless run needs its login.\n const claudeBin = claudeControl.findClaude();\n if (claudeBin) {\n const dirs = claudeDirs();\n const logins = await Promise.all(dirs.map((d) => claudeControl.claudeLogin(claudeBin, d)));\n report.claude_accounts = dirs.map((d, i) => ({ dir: tilde(d), signed_in: logins[i]?.loggedIn ?? null }));\n dirs.forEach((d, i) => {\n if (logins[i]?.loggedIn === false && control?.receivers.length)\n warnings.push(`Claude Code ${tilde(d)} isn't signed in from here: ${claudeControl.loginCommand(d)}`);\n });\n }\n // A systemd user service stops at logout unless the user lingers.\n if (process.platform === \"linux\" && control?.receivers.length) {\n let linger: boolean | null = null;\n try {\n linger = /^Linger=yes/m.test(\n execFileSync(\"loginctl\", [\"show-user\", os.userInfo().username, \"--property=Linger\"], {\n encoding: \"utf8\",\n timeout: 5000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }),\n );\n } catch {}\n report.linger = linger;\n if (linger === false)\n warnings.push(\n `the control daemon stops when you log out: \\`loginctl enable-linger ${os.userInfo().username}\\` (with sudo if refused) keeps it running`,\n );\n }\n if (/\\/Cellar\\/node(?:@\\d+)?\\/[^/]+\\//.test(distDir))\n warnings.push(\n \"sessionpipe is installed inside Homebrew's versioned node folder; `brew upgrade node` will delete it. Install with `npm install -g --prefix ~/.local sessionpipe`.\",\n );\n for (const a of ADAPTERS) {\n if (!a.detect()) continue;\n const st = a.installed(hc, process.env, { lean: isLean(cfg) });\n (report.harnesses as Record<string, unknown>)[a.name] = st.map((r) => ({\n file: tilde(r.file),\n state: r.state,\n ...(r.note ? { note: r.note } : {}),\n }));\n for (const r of st)\n if (r.state === \"inactive\")\n warnings.push(`${a.name}: hooks are written but the harness will not run them \u2014 ${r.note ?? \"\"}`);\n for (const r of st)\n if (r.state === \"stale\")\n warnings.push(\n `${a.name}: the hook in ${tilde(r.file)} points at an old node or script path; run \\`sessionpipe install\\` again.`,\n );\n for (const r of st)\n if (r.state === \"misplaced\")\n warnings.push(\n `${a.name}: the notify line in ${tilde(r.file)} sits inside a [table], where Codex never reads it; run \\`sessionpipe install\\` again.`,\n );\n }\n for (const s of cfg.sinks)\n (report.sinks as unknown[]).push({\n name: s.name,\n url: s.url,\n tier: s.tier,\n max_tier: s.max_tier ?? null,\n pii: !!s.pii,\n control: !!s.control,\n paused: s.paused ?? null,\n token: s.token_in ? `in ${s.token_in}` : s.token ? `${s.token.slice(0, 4)}\u2026` : null,\n });\n const w = report.hook_wall_ms as { p50: number; p95: number; n: number } | null;\n if (w && w.p50 > 150)\n warnings.push(\n `the harness waits ${w.p50} ms per hook (p50, target < 150): that is Node's own startup on this machine. A lean install (no sink above tier 0) hooks fewer events.`,\n );\n if (has(\"--json\")) {\n out(JSON.stringify(report, null, 2));\n return;\n }\n out(` sessionpipe ${VERSION} \u00B7 node ${process.version} at ${report.node_path}`);\n out(` config ${tilde(configFile())} \u00B7 state ${tilde(state)}`);\n for (const [h, st] of Object.entries(report.harnesses as Record<string, { file: string; state: string }[]>))\n for (const r of st) out(` ${h.padEnd(12)} ${r.file.padEnd(44)} ${r.state}`);\n for (const s of report.sinks as { name: string; tier: number; max_tier: number | null; paused: string | null }[])\n out(\n ` sink ${s.name.padEnd(16)} tier ${s.tier}${s.max_tier !== null ? ` (receiver max ${s.max_tier})` : \"\"}${s.paused ? ` PAUSED ${s.paused}` : \"\"}`,\n );\n const lr = report.launcher as { file: string; node: string | null; node_ok: boolean } | undefined;\n if (lr)\n out(` hooks run ${lr.file} \u2192 node ${lr.node ? tilde(lr.node) : \"?\"}${lr.node_ok ? \"\" : \" (gone: PATH's node)\"}`);\n for (const k of keys)\n out(` key ${k.what.padEnd(28)} ${storeLabel(k.where as StoreName)}${k.readable ? \"\" : \" (unreadable here)\"}`);\n for (const a of (report.claude_accounts as { dir: string; signed_in: boolean | null }[] | undefined) ?? [])\n out(\n ` claude ${a.dir.padEnd(26)} ${a.signed_in === true ? \"signed in\" : a.signed_in === false ? \"NOT signed in from here\" : \"can't tell\"}`,\n );\n const t = report.timing as { p50: number; p95: number; n: number } | null;\n out(\n w\n ? ` hook wall clock (what the harness waits): p50 ${w.p50} ms \u00B7 p95 ${w.p95} ms over ${w.n} spawns`\n : \" hook wall clock: could not spawn dist/hook.js\",\n );\n out(\n t\n ? ` hook in-process: p50 ${t.p50} ms \u00B7 p95 ${t.p95} ms over the last ${t.n} runs`\n : \" hook in-process: no runs yet\",\n );\n for (const w of warnings) out(` ! ${w}`);\n if (!warnings.length) out(\" no warnings\");\n}\n\n/** Follow the local outbox: one event per line, filtered to a tier. The zero-server demo. */\nasync function tail(): Promise<void> {\n const tier = Math.max(0, Math.min(3, Number(flag(\"--tier\") ?? 1))) as Tier;\n const onlySession = flag(\"--session\");\n const onlyHarness = flag(\"--harness\");\n const outbox = new Outbox(state);\n const offsets = new Map<string, number>();\n const fmt = (e: Event): string => {\n const t = e.time.slice(11, 19);\n const d = e.data as Record<string, unknown>;\n let detail = \"\";\n switch (e.type) {\n case \"session.started\":\n detail = `source=${d.source} ${e.session.cwd ?? \"\"} ${e.session.branch ?? \"\"}`;\n break;\n case \"turn.started\":\n detail = d.prompt_chars !== undefined ? `prompt_chars=${d.prompt_chars}` : \"\";\n break;\n case \"tool.started\":\n detail = String(d.tool ?? \"\");\n break;\n case \"tool.ended\":\n detail = `${d.tool} ${d.ok ? \"ok\" : \"error\"}${d.ms !== undefined ? ` ${d.ms}ms` : \"\"}`;\n break;\n case \"attention.needed\":\n detail = `${d.kind}${d.tool ? ` ${d.tool}` : \"\"}${d.message ? ` \"${String(d.message).slice(0, 60)}\"` : \"\"}`;\n break;\n case \"turn.ended\":\n detail = String(d.reason ?? \"\");\n break;\n case \"session.ended\":\n detail = `reason=${d.reason}`;\n break;\n case \"turn.transcript\":\n detail = `#${d.turn} \"${String(d.user).slice(0, 50).replace(/\\s+/g, \" \")}\"`;\n break;\n case \"session.backfill\":\n detail = `${e.session.title ?? \"\"}`;\n break;\n default:\n detail = JSON.stringify(d).slice(0, 80);\n }\n return `${t} ${e.harness.name.padEnd(11)} ${e.session.id.slice(0, 4)}\u2026 ${e.type.padEnd(17)} ${detail}`;\n };\n out(`sessionpipe tail \u00B7 tier ${tier} \u00B7 ${tilde(state)}/outbox (Ctrl-C to stop)`);\n // Start at the end of each file unless --all.\n for (const ref of outbox.sessions()) {\n try {\n offsets.set(`${ref.harness}/${ref.session}`, has(\"--all\") ? 0 : statSync(outbox.file(ref)).size);\n } catch {}\n }\n for (;;) {\n for (const ref of outbox.sessions()) {\n if (onlyHarness && ref.harness !== onlyHarness) continue;\n if (onlySession && !ref.session.startsWith(onlySession)) continue;\n const k = `${ref.harness}/${ref.session}`;\n const from = offsets.get(k) ?? 0;\n const { events, offset } = outbox.read(ref, from, 200);\n offsets.set(k, offset);\n for (const e of events) {\n const f = filterEvent(e, tier, false);\n if (f) out(has(\"--json\") ? JSON.stringify(f) : fmt(f));\n }\n }\n await new Promise((r) => setTimeout(r, 500));\n }\n}\n\nasync function workerFromArgv(): Promise<void> {\n const f = args[1];\n if (!f) return;\n const job = JSON.parse(readFileSync(f, \"utf8\"));\n try {\n unlinkSync(f);\n } catch {}\n await runJob(job);\n}\n\nasync function update(): Promise<void> {\n if (process.env.SESSIONPIPE_NO_UPDATE_CHECK) return out(\" update check is off (SESSIONPIPE_NO_UPDATE_CHECK)\");\n try {\n const r = await fetch(\"https://registry.npmjs.org/sessionpipe/latest\", { signal: AbortSignal.timeout(8000) });\n const j = (await r.json()) as { version?: string };\n if (!j.version) throw new Error(\"no version\");\n if (j.version === VERSION) return out(` sessionpipe ${VERSION} is current`);\n out(` ${j.version} is available (you run ${VERSION}); installing into this copy's prefix\u2026`);\n const prefix = prefixOf(distDir);\n execFileSync(\"npm\", [\"install\", \"-g\", `sessionpipe@${j.version}`, ...(prefix ? [\"--prefix\", prefix] : [])], {\n stdio: \"inherit\",\n });\n out(\" re-arming hooks\u2026\");\n const bin = prefix ? path.join(prefix, \"bin\", \"sessionpipe\") : \"sessionpipe\";\n const p = spawn(bin, [\"install\", \"--backfill\", \"0\"], { stdio: \"inherit\" });\n await new Promise((r) => p.on(\"exit\", r));\n } catch (e) {\n out(` couldn't check npm: ${(e as Error).message}`);\n }\n}\nfunction prefixOf(p: string): string | null {\n const re =\n process.platform === \"win32\"\n ? /^(.*?)[\\\\/]node_modules[\\\\/]sessionpipe[\\\\/]/\n : /^(.*)\\/lib\\/node_modules\\/sessionpipe\\//;\n const m = re.exec(p);\n return m?.[1] ?? null;\n}\n\nmain().catch((e) => {\n process.stderr.write(`sessionpipe: ${(e as Error).message}\\n`);\n process.exit(1);\n});\n", "// SPDX-License-Identifier: Apache-2.0\n// Antigravity (Google) \u2014 docs: https://antigravity.google/docs/hooks\n// Config: ~/.gemini/config/hooks.json \u2014 top-level keys are hook NAMES, ours is\n// \"sessionpipe\". stdin is camelCase with NO event name (it rides in argv). Every\n// hook must print `{}`; non-JSON is a deny. Timeouts in seconds. No session end\n// exists. Ported from spacesheep-cli lib/sessions.js (facts, remote url, projects).\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport path from \"node:path\";\nimport { HOME } from \"../paths.js\";\nimport { ends, parseLines } from \"../readers/files.js\";\nimport { readAntigravity } from \"../readers/transcripts.js\";\nimport { formatJson, readJsonFile } from \"./claude-shaped.js\";\nimport type {\n Adapter,\n BackfillRow,\n FactsState,\n HookCommand,\n HookInput,\n HookResult,\n InstallOptions,\n InstallReport,\n SessionFacts,\n} from \"./types.js\";\n\nconst NAME = \"antigravity\";\nconst HOOK_NAME = \"sessionpipe\";\nexport const AG_EVENTS = [\"PreInvocation\", \"PostInvocation\", \"PreToolUse\", \"PostToolUse\", \"Stop\"] as const;\nconst gemini = (env: NodeJS.ProcessEnv) => env.GEMINI_CLI_HOME || path.join(HOME, \".gemini\");\nconst hooksFile = (env: NodeJS.ProcessEnv) => path.join(gemini(env), \"config\", \"hooks.json\");\nconst projectsDir = (env: NodeJS.ProcessEnv) => path.join(gemini(env), \"config\", \"projects\");\nconst dataDirs = (env: NodeJS.ProcessEnv) =>\n [\"antigravity\", \"antigravity-cli\", \"antigravity-ide\"].map((d) => path.join(gemini(env), d));\nconst ID_RE = /^[A-Za-z0-9_-]{1,128}$/;\nconst validTool = (n: unknown): n is string => typeof n === \"string\" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);\n\nfunction entry(cmd: HookCommand, lean?: boolean) {\n const handler = (e: string) => ({ type: \"command\", command: cmd([NAME, e]).command, timeout: 5 });\n const out: Record<string, unknown> = { enabled: true };\n for (const e of AG_EVENTS) {\n if (lean && e === \"PreToolUse\") continue;\n out[e] = /Tool/.test(e) ? [{ matcher: \"*\", hooks: [handler(e)] }] : [handler(e)];\n }\n return out;\n}\n\nexport const antigravity: Adapter = {\n name: NAME,\n events: AG_EVENTS,\n detect: (env = process.env) =>\n existsSync(path.join(gemini(env), \"config\")) || dataDirs(env).some((d) => existsSync(d)),\n configFiles: (env = process.env) => [hooksFile(env)],\n install(cmd, env = process.env, opts: InstallOptions = {}): InstallReport[] {\n const file = hooksFile(env);\n const f = readJsonFile(file);\n if (!f.ok) return [{ file, changed: false, skipped: true, note: `${f.reason}; not touched` }];\n const hooks = f.value;\n const e = entry(cmd, opts.lean);\n if (JSON.stringify(hooks[HOOK_NAME]) === JSON.stringify(e)) return [{ file, changed: false }];\n hooks[HOOK_NAME] = e;\n mkdirSync(path.dirname(file), { recursive: true });\n writeFileSync(file, formatJson(hooks, f));\n return [\n {\n file,\n changed: true,\n created: !f.existed,\n note: \"hooks.json is read when a conversation starts; open ones report after a restart\",\n },\n ];\n },\n uninstall(env = process.env, opts: InstallOptions = {}): InstallReport[] {\n const file = hooksFile(env);\n if (!existsSync(file)) return [{ file, changed: false }];\n const f = readJsonFile(file);\n if (!f.ok) return [{ file, changed: false, skipped: true, note: `${f.reason}; not touched` }];\n const hooks = f.value;\n if (!(HOOK_NAME in hooks)) return [{ file, changed: false }];\n delete hooks[HOOK_NAME];\n if (opts.created?.includes(file) && !Object.keys(hooks).length) {\n unlinkSync(file);\n return [{ file, changed: true, note: \"removed (sessionpipe created it)\" }];\n }\n writeFileSync(file, formatJson(hooks, f));\n return [{ file, changed: true }];\n },\n installed(cmd, env = process.env, opts: InstallOptions = {}) {\n const file = hooksFile(env);\n const f = readJsonFile(file);\n const have = f.ok ? f.value[HOOK_NAME] : undefined;\n return [\n {\n file,\n state: !have ? \"missing\" : JSON.stringify(have) === JSON.stringify(entry(cmd, opts.lean)) ? \"current\" : \"stale\",\n },\n ];\n },\n\n fromHook(input: HookInput): HookResult | null {\n const event = input.argv[1] ?? \"\";\n let s: Record<string, unknown> = {};\n try {\n s = input.stdin ? (JSON.parse(input.stdin) as Record<string, unknown>) : {};\n } catch {}\n const id = (s.conversationId ?? s.session_id ?? s.sessionId) as string | undefined;\n // Antigravity parses stdout as the hook's answer; `{}` is \"carry on\" for every event.\n if (!id) return { session: { id: \"\" }, events: [], stdout: \"{}\\n\" };\n const workspaces = agWorkspaces(s.workspacePaths);\n const session: HookResult[\"session\"] = { id: String(id), cwd: workspaces[0] ?? input.cwd };\n if (typeof s.modelName === \"string\" && s.modelName !== \"auto\") session.model = s.modelName;\n const toolCall = s.toolCall as { name?: unknown; args?: unknown } | undefined;\n const tool = validTool(toolCall?.name) ? toolCall?.name : validTool(s.toolName) ? s.toolName : undefined;\n const ev = (type: string, data: Record<string, unknown>) => ({ type, data: prune(data), harnessEvent: event });\n const events: HookResult[\"events\"] = [];\n switch (event) {\n case \"PreInvocation\":\n // Fires before every model call of an execution; only the first is the person's ask.\n if (Number(s.invocationNum) === 0 || s.invocationNum === undefined) {\n events.push(ev(\"session.started\", { source: \"unknown\" }));\n events.push(ev(\"turn.started\", {}));\n } else events.push(ev(\"session.heartbeat\", {}));\n break;\n case \"PostInvocation\":\n break;\n case \"PreToolUse\":\n if (tool) events.push(ev(\"tool.started\", { tool, input: toolCall?.args }));\n break;\n case \"PostToolUse\":\n if (tool)\n events.push(\n ev(\"tool.ended\", {\n tool,\n ok: !s.error,\n error: typeof s.error === \"string\" ? s.error.slice(0, 2000) : undefined,\n input: toolCall?.args,\n }),\n );\n break;\n case \"Stop\":\n events.push(ev(\"turn.ended\", { reason: s.error ? \"error\" : \"stop\" }));\n break;\n default:\n return { session, events: [], stdout: \"{}\\n\" };\n }\n const r: HookResult = { session, events, stdout: \"{}\\n\", hints: { workspaces } };\n if (typeof s.transcriptPath === \"string\") r.transcript = s.transcriptPath;\n return r;\n },\n\n readTranscript(file, fromLine) {\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { turns: [], line: fromLine };\n }\n return readAntigravity(text.split(\"\\n\"), fromLine);\n },\n\n facts(session, transcript, hints, state): SessionFacts {\n if (!transcript) return {};\n return antigravityFacts(transcript, {\n conversation: session.id,\n workspaces: (hints.workspaces as string[] | undefined) ?? (session.cwd ? [session.cwd] : []),\n state,\n env: process.env,\n });\n },\n\n backfill(sinceMs, env = process.env): BackfillRow[] {\n const rows: BackfillRow[] = [];\n const noState: FactsState = { get: () => ({}), save: () => {} };\n for (const data of dataDirs(env)) {\n let ids: string[] = [];\n try {\n ids = readdirSync(path.join(data, \"brain\")).filter((n) => /^[0-9a-f-]{36}$/i.test(n));\n } catch {}\n for (const id of ids) {\n const f = path.join(data, \"brain\", id, \".system_generated\", \"logs\", \"transcript.jsonl\");\n try {\n if (statSync(f).mtimeMs < sinceMs) continue;\n } catch {\n continue;\n }\n const facts = antigravityFacts(f, { conversation: id, workspaces: [], state: noState, env });\n if (!facts.started_at || !facts.last_at) continue;\n const { started_at, last_at, first_ask: _fa, harness_version: _hv, ...rest } = facts;\n rows.push({ session: { id, ...rest }, started_at, last_at });\n }\n }\n return rows;\n },\n};\n\nfunction prune<T extends Record<string, unknown>>(o: T): T {\n for (const k of Object.keys(o)) if (o[k] === undefined) delete o[k];\n return o;\n}\n\n/** A folder as Antigravity writes it (a file:// URI or a path) \u2192 an absolute path, or null. */\nexport function agPath(p: unknown): string | null {\n if (typeof p !== \"string\" || !p) return null;\n let s = p;\n if (/^file:/i.test(s)) {\n try {\n s = decodeURIComponent(new URL(s).pathname);\n } catch {\n return null;\n }\n if (process.platform === \"win32\" && /^\\/[A-Za-z]:/.test(s)) s = s.slice(1);\n } else if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(s)) return null;\n if (!path.isAbsolute(s)) return null;\n return path.resolve(s);\n}\nexport const agWorkspaces = (paths: unknown): string[] =>\n (Array.isArray(paths) ? paths : [])\n .map(agPath)\n .filter((p): p is string => !!p)\n .filter((p, i, a) => a.indexOf(p) === i);\n\nfunction agVariants(p: string): string[] {\n const out = [p];\n try {\n const r = realpathSync.native(p);\n if (r !== p) out.push(r);\n } catch {}\n return out;\n}\nfunction agProjects(dir: string): { id: string; folders: string[] }[] {\n const out: { id: string; folders: string[] }[] = [];\n let names: string[] = [];\n try {\n names = readdirSync(dir).filter((n) => n.endsWith(\".json\"));\n } catch {\n return out;\n }\n for (const n of names) {\n const id = n.slice(0, -5);\n if (!ID_RE.test(id)) continue;\n let j: { projectResources?: { resources?: { folderUri?: unknown }[] } };\n try {\n j = JSON.parse(readFileSync(path.join(dir, n), \"utf8\"));\n } catch {\n continue;\n }\n const folders: string[] = [];\n for (const r of j?.projectResources?.resources ?? []) {\n const f = agPath(r?.folderUri);\n if (f) folders.push(...agVariants(f));\n }\n if (folders.length) out.push({ id, folders });\n }\n return out;\n}\n/** The project whose folder is the workspace or contains it; the deepest wins. */\nexport function agMatchProject(projects: { id: string; folders: string[] }[], workspaces: string[]): string | null {\n const ws: string[] = [];\n for (const w of workspaces) {\n const p = agPath(w);\n if (p) ws.push(...agVariants(p));\n }\n let best: string | null = null;\n let bestLen = -1;\n for (const pr of projects)\n for (const f of pr.folders) {\n const within = ws.some((w) => w === f || w.startsWith(f.endsWith(path.sep) ? f : f + path.sep));\n if (within && f.length > bestLen) {\n best = pr.id;\n bestLen = f.length;\n }\n }\n return best;\n}\n\n/** Antigravity's web remote: https://antigravity.google.com/r/<installation uuid>-v2, with\n * ?p=c/<conversation>?section=<project> when the project is known. */\nexport function antigravityRemoteUrl(\n transcript: string,\n opts: { conversation?: string; workspaces?: string[]; env: NodeJS.ProcessEnv; projectsDir?: string },\n): string | null {\n const i = transcript.indexOf(`${path.sep}brain${path.sep}`);\n const dirs = (i > 0 ? [transcript.slice(0, i)] : []).concat(dataDirs(opts.env));\n for (const d of dirs) {\n try {\n const m = /installation_uuid:\\s*\"([0-9a-f-]{36})\"/i.exec(\n readFileSync(path.join(d, \"antigravity_state.pbtxt\"), \"utf8\"),\n );\n if (!m) continue;\n const base = `https://antigravity.google.com/r/${m[1]}-v2`;\n const conv = opts.conversation ?? \"\";\n if (!ID_RE.test(conv) || !opts.workspaces?.length) return base;\n const project = agMatchProject(agProjects(opts.projectsDir ?? projectsDir(opts.env)), opts.workspaces);\n return project ? `${base}?p=${encodeURIComponent(`c/${conv}?section=${project}`)}` : base;\n } catch {}\n }\n return null;\n}\n\nexport function antigravityFacts(\n file: string,\n opts: { conversation: string; workspaces: string[]; state: FactsState; env: NodeJS.ProcessEnv },\n): SessionFacts {\n const { head, tail } = ends(file, 128 * 1024, 64 * 1024);\n const H = parseLines(head);\n const T = parseLines(tail);\n const out: SessionFacts = {};\n const url = antigravityRemoteUrl(file, opts);\n if (url) out.url = url;\n for (const j of H) {\n if (j.type !== \"USER_INPUT\" || typeof j.content !== \"string\") continue;\n const m = /<USER_REQUEST>([\\s\\S]*?)(?:<\\/USER_REQUEST>|$)/.exec(j.content);\n const text = (m ? (m[1] ?? \"\") : j.content).trim();\n const line = (text.split(\"\\n\").find((l) => l.trim()) ?? \"\").trim();\n if (!line || /^<[a-z_-]+>/i.test(line)) continue;\n out.title = line.length > 80 ? `${line.slice(0, 80).replace(/\\s+\\S*$/, \"\")}\u2026` : line;\n out.title_source = \"first-ask\";\n break;\n }\n const times = H.concat(T)\n .map((j) => Date.parse(String(j.created_at ?? j.timestamp ?? \"\")))\n .filter((n) => n > 0);\n if (times.length) {\n out.started_at = Math.min(...times);\n out.last_at = Math.max(...times);\n }\n return out;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Where sessionpipe keeps its files (spec: the client's Files section).\n// config ~/.config/sessionpipe/config.json SESSIONPIPE_CONFIG\n// state ~/.local/state/sessionpipe/ SESSIONPIPE_STATE\n// Windows %APPDATA%\\sessionpipe\\ and %LOCALAPPDATA%\\sessionpipe\\\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport const HOME = os.homedir();\n\nexport function configFile(env: NodeJS.ProcessEnv = process.env): string {\n if (env.SESSIONPIPE_CONFIG) return path.resolve(env.SESSIONPIPE_CONFIG);\n if (process.platform === \"win32\")\n return path.join(env.APPDATA || path.join(HOME, \"AppData\", \"Roaming\"), \"sessionpipe\", \"config.json\");\n return path.join(env.XDG_CONFIG_HOME || path.join(HOME, \".config\"), \"sessionpipe\", \"config.json\");\n}\n\nexport function stateDir(env: NodeJS.ProcessEnv = process.env): string {\n if (env.SESSIONPIPE_STATE) return path.resolve(env.SESSIONPIPE_STATE);\n if (process.platform === \"win32\")\n return path.join(env.LOCALAPPDATA || path.join(HOME, \"AppData\", \"Local\"), \"sessionpipe\");\n return path.join(env.XDG_STATE_HOME || path.join(HOME, \".local\", \"state\"), \"sessionpipe\");\n}\n\n/** `~` for the home directory, as the session block writes paths. */\nexport function tilde(p: string, home: string = HOME): string {\n if (!p) return p;\n if (p === home) return \"~\";\n return p.startsWith(home + path.sep) || p.startsWith(`${home}/`) ? `~${p.slice(home.length)}` : p;\n}\n\n/** A file-name-safe id. */\nexport const safeId = (s: string): string =>\n String(s)\n .replace(/[^A-Za-z0-9_.-]/g, \"_\")\n .slice(0, 160);\n", "// SPDX-License-Identifier: Apache-2.0\n// Reading the ends of large files, JSON lines, and recent files under a root.\nimport { closeSync, fstatSync, openSync, readdirSync, readSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\n\n/** The first and last bytes of a file, as lines \u2014 a transcript can be tens of MB. */\nexport function ends(file: string, headBytes: number, tailBytes: number): { head: string[]; tail: string[] } {\n let fd: number | undefined;\n try {\n fd = openSync(file, \"r\");\n const size = fstatSync(fd).size;\n const read = (pos: number, len: number) => {\n const b = Buffer.alloc(len);\n const n = readSync(fd as number, b, 0, len, pos);\n return b.subarray(0, n).toString(\"utf8\");\n };\n const head = read(0, Math.min(size, headBytes));\n const tail = size > headBytes ? read(Math.max(0, size - tailBytes), Math.min(size, tailBytes)) : head;\n return { head: head.split(\"\\n\").slice(0, -1), tail: tail.split(\"\\n\").slice(size > headBytes ? 1 : 0) };\n } catch {\n return { head: [], tail: [] };\n } finally {\n if (fd !== undefined)\n try {\n closeSync(fd);\n } catch {}\n }\n}\n\nexport const parseLines = (lines: string[]): Record<string, unknown>[] =>\n lines\n .map((l) => {\n try {\n return JSON.parse(l) as Record<string, unknown>;\n } catch {\n return null;\n }\n })\n .filter((x): x is Record<string, unknown> => !!x);\n\n/** Read line by line up to `cap` bytes, stopping when `visit` returns a value. */\nexport function scanLines<T>(file: string, visit: (line: string) => T | null, cap = 16 * 1024 * 1024): T | null {\n let fd: number | undefined;\n try {\n fd = openSync(file, \"r\");\n const buf = Buffer.alloc(1024 * 1024);\n let pos = 0;\n let rest: Buffer = Buffer.alloc(0);\n while (pos < cap) {\n const n = readSync(fd, buf, 0, buf.length, pos);\n if (!n) break;\n pos += n;\n let chunk = Buffer.concat([rest, buf.subarray(0, n)]);\n let nl = chunk.indexOf(10);\n while (nl >= 0) {\n const r = visit(chunk.subarray(0, nl).toString(\"utf8\"));\n if (r !== null) return r;\n chunk = chunk.subarray(nl + 1);\n nl = chunk.indexOf(10);\n }\n rest = chunk;\n }\n } catch {\n } finally {\n if (fd !== undefined)\n try {\n closeSync(fd);\n } catch {}\n }\n return null;\n}\n\nexport function recentFiles(root: string, depth: number, sinceMs: number, match: (name: string) => boolean): string[] {\n const out: string[] = [];\n const walk = (dir: string, d: number) => {\n let names: import(\"node:fs\").Dirent[] = [];\n try {\n names = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of names) {\n const p = path.join(dir, e.name);\n if (e.isDirectory()) {\n if (d < depth) walk(p, d + 1);\n continue;\n }\n if (!match(e.name)) continue;\n try {\n if (statSync(p).mtimeMs >= sinceMs) out.push(p);\n } catch {}\n }\n };\n walk(root, 0);\n return out;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Transcript readers: complete turns (a person's message + everything the assistant\n// said before the next one), each with the line it ends on, and the line the\n// cursor may advance to once every turn is delivered. Ported from spacesheep-cli\n// lib/memory.js. One reader per harness file format; nothing else is vendor code.\nimport type { TranscriptRead } from \"../adapters/types.js\";\n\ninterface Msg {\n role: \"user\" | \"assistant\";\n text: string;\n at: number;\n line: number;\n}\n\nexport function pairTurns(msgs: Msg[], endLine: number): TranscriptRead {\n const turns: { user: string; assistant: string; at: number; startLine: number; endLine: number }[] = [];\n let cur: (typeof turns)[number] | null = null;\n for (const m of msgs) {\n if (m.role === \"user\") {\n // Never overwrite a prompt that has no reply yet: in an agentic turn the reply\n // comes after tool calls, and a second user record is not a new question.\n if (cur && !cur.assistant) {\n cur.user += `\\n\\n${m.text}`;\n continue;\n }\n if (cur) turns.push(cur);\n cur = { user: m.text, assistant: \"\", at: m.at, startLine: m.line, endLine: m.line };\n } else {\n if (!cur) cur = { user: \"\", assistant: \"\", at: m.at, startLine: m.line, endLine: m.line };\n cur.assistant += (cur.assistant ? \"\\n\\n\" : \"\") + m.text;\n cur.endLine = m.line;\n }\n }\n if (cur?.assistant) turns.push(cur);\n // A user message with no reply yet stays unsent: the cursor stops before it.\n const line = cur && !cur.assistant ? cur.startLine : endLine;\n return { turns: turns.map((t) => ({ user: t.user, assistant: t.assistant, at: t.at, endLine: t.endLine })), line };\n}\n\n/** Injected context the person never typed: <tag>\u2026</tag> wrappers, HTML comments, slash-command expansions. */\nexport const isInjected = (text: string): boolean =>\n (/^<[a-z_-]+>/i.test(text) && /<\\/[a-z_-]+>\\s*$/i.test(text)) || /^<!--\\s/.test(text) || /^<command-/.test(text);\n\nconst endOf = (lines: string[]) => (lines[lines.length - 1] === \"\" ? lines.length - 1 : lines.length);\nconst parse = (raw: string): Record<string, unknown> | null => {\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return null;\n }\n};\nconst textParts = (c: unknown, kinds: string[]): string => {\n if (typeof c === \"string\") return c;\n if (!Array.isArray(c)) return \"\";\n return c\n .filter(\n (b) =>\n b &&\n typeof b === \"object\" &&\n kinds.includes((b as { type?: string }).type ?? \"\") &&\n typeof (b as { text?: unknown }).text === \"string\",\n )\n .map((b) => (b as { text: string }).text)\n .join(\"\\n\");\n};\n\n/** Claude Code / Droid: {type:\"user\"|\"assistant\", message:{content}, timestamp, isMeta, isSidechain, origin}. */\nexport function readClaude(lines: string[], from: number): TranscriptRead {\n const msgs: Msg[] = [];\n for (let i = from; i < lines.length; i++) {\n const j = lines[i] ? parse(lines[i] as string) : null;\n if (!j || j.isSidechain) continue;\n const origin = j.origin as { kind?: string } | undefined;\n if (j.type === \"user\" && (j.isMeta || (origin?.kind && origin.kind !== \"human\"))) continue;\n const at = Date.parse(String(j.timestamp ?? \"\")) || Date.now();\n const c = (j.message as { content?: unknown } | undefined)?.content;\n if (j.type === \"user\") {\n const text = textParts(c, [\"text\"]).trim();\n if (!text || isInjected(text)) continue;\n msgs.push({ role: \"user\", text, at, line: i });\n } else if (j.type === \"assistant\" && Array.isArray(c)) {\n const text = textParts(c, [\"text\"]).trim();\n if (text) msgs.push({ role: \"assistant\", text, at, line: i });\n }\n }\n return pairTurns(msgs, endOf(lines));\n}\n\n/** Codex rollout: {type:\"response_item\", payload:{type:\"message\", role, content:[{type:\"input_text\"|\"output_text\", text}]}}. */\nexport function readCodex(lines: string[], from: number): TranscriptRead {\n const msgs: Msg[] = [];\n for (let i = from; i < lines.length; i++) {\n const j = lines[i] ? parse(lines[i] as string) : null;\n if (!j || j.type !== \"response_item\") continue;\n const p = j.payload as { type?: string; role?: string; content?: unknown } | undefined;\n if (!p || p.type !== \"message\") continue;\n const at = Date.parse(String(j.timestamp ?? \"\")) || Date.now();\n const text = textParts(p.content, [\"input_text\", \"output_text\"]).trim();\n if (!text) continue;\n if (p.role === \"user\") {\n if (/^<[a-z_-]+>/i.test(text)) continue; // <environment_context>: Codex's own injections\n msgs.push({ role: \"user\", text, at, line: i });\n } else if (p.role === \"assistant\") msgs.push({ role: \"assistant\", text, at, line: i });\n }\n return pairTurns(msgs, endOf(lines));\n}\n\n/** Gemini CLI chat log: {type:\"user\"|\"gemini\", content|message|text, timestamp}. */\nexport function readGemini(lines: string[], from: number): TranscriptRead {\n const msgs: Msg[] = [];\n for (let i = from; i < lines.length; i++) {\n const j = lines[i] ? parse(lines[i] as string) : null;\n if (!j) continue;\n const role = j.type === \"user\" ? \"user\" : j.type === \"gemini\" || j.type === \"model\" ? \"assistant\" : null;\n if (!role) continue;\n const raw = j.content ?? j.message ?? j.text;\n const text = (typeof raw === \"string\" ? raw : textParts(raw, [\"text\"])).trim();\n if (!text) continue;\n const at = Date.parse(String(j.timestamp ?? \"\")) || Date.now();\n msgs.push({ role, text, at, line: i });\n }\n return pairTurns(msgs, endOf(lines));\n}\n\n/** Antigravity: one step per line, type USER_INPUT | PLANNER_RESPONSE, content with <USER_REQUEST> wrapping. */\nexport function readAntigravity(lines: string[], from: number): TranscriptRead {\n const msgs: Msg[] = [];\n for (let i = from; i < lines.length; i++) {\n const j = lines[i] ? parse(lines[i] as string) : null;\n if (!j || typeof j.content !== \"string\") continue;\n const at = Date.parse(String(j.created_at ?? j.timestamp ?? \"\")) || Date.now();\n if (j.type === \"USER_INPUT\") {\n const m = /<USER_REQUEST>([\\s\\S]*?)(?:<\\/USER_REQUEST>|$)/.exec(j.content);\n const text = (m ? (m[1] ?? \"\") : j.content).trim();\n if (text) msgs.push({ role: \"user\", text, at, line: i });\n } else if (j.type === \"PLANNER_RESPONSE\") {\n const text = j.content.trim();\n if (text) msgs.push({ role: \"assistant\", text, at, line: i });\n }\n }\n return pairTurns(msgs, endOf(lines));\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The hooks file shape Claude Code introduced and Codex, Droid and (with\n// `version: 1`) Cursor and Copilot reuse: {\"hooks\":{\"<Event>\":[{\"matcher\"?,\n// \"hooks\":[{\"type\":\"command\",\"command\",\"timeout\"}]}]}}. Ours is one entry per\n// event; a re-install replaces a stale entry of ours (an old node path) and never\n// touches anyone else's.\n//\n// Two rules from issue #8: a file that is not plain JSON (a comment, a trailing\n// comma, a write in progress) is never written back \u2014 the harness is skipped and\n// the report says why; and a file is written back in its own shape (indent, final\n// newline) so uninstall leaves it byte-identical. A file that did not exist before\n// install is reported `created`, and uninstall deletes it once it is empty again.\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HookCommand, InstallReport } from \"./types.js\";\n\nexport interface ClaudeShapedOptions {\n /** Which events take a `matcher` (tool and permission events). */\n matcherFor: (event: string) => string | undefined;\n /** Seconds (milliseconds for Gemini CLI). */\n timeout: number;\n /** A longer timeout for one event (Claude Code's PermissionRequest, which may wait\n * for a verified control answer: spec/CONTROL.md \u00A76). */\n timeoutFor?: (event: string) => number | undefined;\n /** Extra top-level keys the file must carry (Cursor/Copilot: version: 1). */\n top?: Record<string, unknown>;\n}\n\n/** A command of ours: a path that contains \"sessionpipe\" and ends in hook.js (or in\n * sessionpipe-hook, the launcher that outlives a node upgrade), then a harness and an event. */\nexport const OURS = /(?:sessionpipe[^\"\\n]*[\\\\/]hook\\.js|[\\\\/]sessionpipe-hook)\"?\\s+[a-z][a-z-]*\\s+[A-Za-z]+\\s*$/;\nexport const isOurs = (h: { hooks?: { command?: string }[] }): boolean =>\n Array.isArray(h?.hooks) && h.hooks.some((x) => typeof x.command === \"string\" && OURS.test(x.command));\n\nexport type JsonFile =\n | {\n ok: true;\n existed: true;\n value: Record<string, unknown>;\n raw: string;\n indent: string;\n eol: string;\n finalNewline: boolean;\n }\n | { ok: true; existed: false; value: Record<string, unknown>; raw: \"\"; indent: \" \"; eol: \"\\n\"; finalNewline: true }\n | { ok: false; existed: true; reason: string };\n\n/** Read a JSON config file with its shape. Never guesses: a parse failure is a\n * refusal to touch the file, not an empty object. */\nexport function readJsonFile(file: string): JsonFile {\n let raw: string;\n try {\n raw = readFileSync(file, \"utf8\");\n } catch {\n return { ok: true, existed: false, value: {}, raw: \"\", indent: \" \", eol: \"\\n\", finalNewline: true };\n }\n let value: unknown;\n try {\n value = JSON.parse(raw);\n } catch {\n const hint = /^\\s*\\/\\/|\\/\\*/m.test(raw) ? \"not plain JSON (it has comments)\" : \"not plain JSON\";\n return { ok: false, existed: true, reason: hint };\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n return { ok: false, existed: true, reason: \"not a JSON object\" };\n const eol = raw.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const m = /^( +|\\t+)\\S/m.exec(raw);\n const indent = m?.[1] ?? \" \";\n return {\n ok: true,\n existed: true,\n value: value as Record<string, unknown>,\n raw,\n indent,\n eol,\n finalNewline: /\\r?\\n$/.test(raw),\n };\n}\n\n/** Serialise in the file's own shape. */\nexport function formatJson(value: unknown, f: { indent: string; eol: string; finalNewline: boolean }): string {\n const text = JSON.stringify(value, null, f.indent).replace(/\\n/g, f.eol);\n return f.finalNewline ? text + f.eol : text;\n}\n\n/** Back-compat helper for callers that only read. */\nexport function readJson(file: string): Record<string, unknown> {\n const f = readJsonFile(file);\n return f.ok ? f.value : {};\n}\n\nfunction entryFor(event: string, harness: string, cmd: HookCommand, o: ClaudeShapedOptions) {\n const matcher = o.matcherFor(event);\n return {\n ...(matcher !== undefined ? { matcher } : {}),\n hooks: [{ type: \"command\", command: cmd([harness, event]).command, timeout: o.timeoutFor?.(event) ?? o.timeout }],\n };\n}\n\nexport function installClaudeShaped(\n file: string,\n harness: string,\n events: readonly string[],\n cmd: HookCommand,\n o: ClaudeShapedOptions,\n): InstallReport {\n const f = readJsonFile(file);\n if (!f.ok) return { file, changed: false, skipped: true, note: `${f.reason}; not touched` };\n const settings = f.value;\n const hooks = (settings.hooks && typeof settings.hooks === \"object\" ? settings.hooks : {}) as Record<\n string,\n unknown[]\n >;\n let changed = false;\n const want = new Set(events);\n // Events we no longer hook (a lean install) lose their entry of ours.\n for (const ev of Object.keys(hooks)) {\n if (want.has(ev)) continue;\n const list = Array.isArray(hooks[ev]) ? hooks[ev] : [];\n const kept = list.filter((h) => !isOurs(h as never));\n if (kept.length !== list.length) {\n changed = true;\n if (kept.length) hooks[ev] = kept;\n else delete hooks[ev];\n }\n }\n for (const ev of events) {\n const list = Array.isArray(hooks[ev]) ? hooks[ev] : [];\n const entry = entryFor(ev, harness, cmd, o);\n const mine = list.filter((h) => isOurs(h as never));\n if (mine.length === 1 && JSON.stringify(mine[0]) === JSON.stringify(entry)) continue;\n hooks[ev] = list.filter((h) => !isOurs(h as never)).concat([entry]);\n changed = true;\n }\n if (o.top)\n for (const [k, v] of Object.entries(o.top))\n if (settings[k] !== v) {\n settings[k] = v;\n changed = true;\n }\n if (changed) {\n settings.hooks = hooks;\n mkdirSync(path.dirname(file), { recursive: true });\n writeFileSync(file, formatJson(settings, f));\n }\n return { file, changed, created: !f.existed && changed };\n}\n\nexport function uninstallClaudeShaped(\n file: string,\n events: readonly string[],\n opts: { created?: boolean | undefined } = {},\n): InstallReport {\n if (!existsSync(file)) return { file, changed: false };\n const f = readJsonFile(file);\n if (!f.ok) return { file, changed: false, skipped: true, note: `${f.reason}; not touched` };\n const settings = f.value;\n const hooks = settings.hooks as Record<string, unknown[]> | undefined;\n if (!hooks || typeof hooks !== \"object\") return { file, changed: false };\n let changed = false;\n for (const ev of [...events, ...Object.keys(hooks)]) {\n const list = Array.isArray(hooks[ev]) ? hooks[ev] : [];\n const kept = list.filter((h) => !isOurs(h as never));\n if (kept.length !== list.length) {\n changed = true;\n if (kept.length) hooks[ev] = kept;\n else delete hooks[ev];\n }\n }\n if (!changed) return { file, changed: false };\n if (!Object.keys(hooks).length) delete settings.hooks;\n if (opts.created && !Object.keys(settings).length) {\n unlinkSync(file);\n return { file, changed: true, note: \"removed (sessionpipe created it)\" };\n }\n const next = formatJson(settings, f);\n if (next !== f.raw) writeFileSync(file, next);\n return { file, changed: true };\n}\n\nexport function installedClaudeShaped(\n file: string,\n harness: string,\n events: readonly string[],\n cmd: HookCommand,\n o: ClaudeShapedOptions,\n): \"current\" | \"stale\" | \"missing\" {\n const f = readJsonFile(file);\n const hooks = (f.ok ? (f.value.hooks ?? {}) : {}) as Record<string, unknown[]>;\n let present = 0;\n let current = 0;\n for (const ev of events) {\n const list = Array.isArray(hooks[ev]) ? hooks[ev] : [];\n const mine = list.filter((h) => isOurs(h as never));\n if (mine.length) present++;\n if (mine.length === 1 && JSON.stringify(mine[0]) === JSON.stringify(entryFor(ev, harness, cmd, o))) current++;\n }\n // An entry of ours on an event outside the wanted set (a lean install after a full one) is stale.\n for (const ev of Object.keys(hooks))\n if (!events.includes(ev) && (Array.isArray(hooks[ev]) ? hooks[ev] : []).some((h) => isOurs(h as never)))\n return \"stale\";\n if (!present) return \"missing\";\n return current === events.length ? \"current\" : \"stale\";\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Claude Code (Anthropic) \u2014 docs: https://code.claude.com/docs/en/hooks\n// Config: settings.json in EVERY config dir (~/.claude, $CLAUDE_CONFIG_DIR, ~/.claude-*):\n// one per account; hooks written to one never fire for the others. Reads only the\n// hook's stdin, the transcript it names, the per-pid session registry and the config\n// dir's .claude.json account id. Ported from spacesheep-cli lib/sessions.js.\n\nimport { execFileSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { HOME } from \"../paths.js\";\nimport { ends, parseLines, recentFiles, scanLines } from \"../readers/files.js\";\nimport { gitFacts } from \"../readers/git.js\";\nimport { isInjected, readClaude } from \"../readers/transcripts.js\";\nimport { installClaudeShaped, installedClaudeShaped, uninstallClaudeShaped } from \"./claude-shaped.js\";\nimport type {\n Adapter,\n BackfillRow,\n FactsState,\n HookCommand,\n HookInput,\n HookResult,\n InstallOptions,\n SessionFacts,\n} from \"./types.js\";\n\nconst NAME = \"claude-code\";\nexport const CLAUDE_EVENTS = [\n \"SessionStart\",\n \"UserPromptSubmit\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PostToolUseFailure\",\n \"PermissionRequest\",\n \"Notification\",\n \"Stop\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PreCompact\",\n \"PostCompact\",\n \"SessionEnd\",\n \"StopFailure\",\n] as const;\n/** With no sink above tier 0 only the heartbeat needs a tool event: one, not three (issue #12). */\nconst LEAN_SKIP = new Set([\"PreToolUse\", \"PostToolUseFailure\"]);\nconst eventsFor = (lean?: boolean) => (lean ? CLAUDE_EVENTS.filter((e) => !LEAN_SKIP.has(e)) : [...CLAUDE_EVENTS]);\nconst OPTS = {\n matcherFor: (e: string) => (/Tool|Permission/.test(e) ? \"\" : undefined),\n timeout: 5,\n // The hook waits up to 125 s for a verified control answer, and only when control\n // is paired on this machine; everywhere else it exits in milliseconds as before.\n timeoutFor: (e: string) => (e === \"PermissionRequest\" ? 130 : undefined),\n};\nconst DESKTOP_ID = /^local_[A-Za-z0-9-]{1,64}$/;\n\n/** Every Claude Code config dir on this machine. `home` follows the env's HOME, so a\n * caller with its own env (a test) never reaches the real ~/.claude: the install test\n * once rewrote a real settings.json with its fake hook paths on every run. */\nexport function claudeDirs(env: NodeJS.ProcessEnv = process.env, home = env.HOME || HOME): string[] {\n const out: string[] = [];\n const add = (d?: string) => {\n if (!d) return;\n const r = path.resolve(d);\n if (!out.includes(r)) out.push(r);\n };\n add(path.join(home, \".claude\"));\n add(env.CLAUDE_CONFIG_DIR);\n try {\n for (const e of readdirSync(home, { withFileTypes: true })) {\n if (!e.isDirectory() || !/^\\.claude[-_.]/.test(e.name)) continue;\n const d = path.join(home, e.name);\n if (existsSync(path.join(d, \"projects\")) || existsSync(path.join(d, \"settings.json\"))) add(d);\n }\n } catch {}\n return out.filter((d, i) => i === 0 || existsSync(d));\n}\nconst settingsIn = (dir: string) => path.join(dir, \"settings.json\");\nconst configDirOf = (transcript: string) => path.dirname(path.dirname(path.dirname(transcript)));\n\nconst validTool = (n: unknown): n is string => typeof n === \"string\" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);\nconst endReason = (r: unknown): \"clear\" | \"logout\" | \"exit\" | \"other\" =>\n r === \"clear\" || r === \"logout\" || r === \"exit\" ? r : r === \"prompt_input_exit\" ? \"exit\" : \"other\";\nconst notifKind = (t: unknown): \"permission\" | \"question\" | \"elicitation\" | \"idle\" | \"error\" =>\n t === \"permission_prompt\"\n ? \"permission\"\n : t === \"idle_prompt\"\n ? \"idle\"\n : t === \"elicitation_dialog\"\n ? \"elicitation\"\n : \"question\";\n\nexport const claudeCode: Adapter = {\n name: NAME,\n events: CLAUDE_EVENTS,\n detect: (env = process.env) => claudeDirs(env).some((d) => existsSync(d)),\n configFiles: (env = process.env) => claudeDirs(env).map(settingsIn),\n install: (cmd, env = process.env, opts: InstallOptions = {}) =>\n claudeDirs(env).map((d) => installClaudeShaped(settingsIn(d), NAME, eventsFor(opts.lean), cmd, OPTS)),\n uninstall: (env = process.env, opts: InstallOptions = {}) =>\n claudeDirs(env).map((d) =>\n uninstallClaudeShaped(settingsIn(d), CLAUDE_EVENTS, { created: opts.created?.includes(settingsIn(d)) }),\n ),\n installed: (cmd, env = process.env, opts: InstallOptions = {}) =>\n claudeDirs(env).map((d) => ({\n file: settingsIn(d),\n state: installedClaudeShaped(settingsIn(d), NAME, eventsFor(opts.lean), cmd, OPTS),\n })),\n\n fromHook(input: HookInput): HookResult | null {\n const event = input.argv[1] ?? \"\";\n let s: Record<string, unknown> = {};\n try {\n s = input.stdin ? (JSON.parse(input.stdin) as Record<string, unknown>) : {};\n } catch {}\n const id = (s.session_id ?? s.sessionId) as string | undefined;\n if (!id) return null;\n const session: HookResult[\"session\"] = { id: String(id), cwd: typeof s.cwd === \"string\" ? s.cwd : input.cwd };\n if (typeof s.model === \"string\") session.model = s.model;\n if (typeof s.agent_id === \"string\" && event.startsWith(\"Subagent\") === false && s.agent_id)\n session.parent_id = null;\n const turn_id = typeof s.prompt_id === \"string\" ? s.prompt_id : undefined;\n const tool = validTool(s.tool_name) ? s.tool_name : undefined;\n const call_id = typeof s.tool_use_id === \"string\" ? s.tool_use_id : undefined;\n const ms = typeof s.duration_ms === \"number\" ? Math.round(s.duration_ms) : undefined;\n const agent_id = typeof s.agent_id === \"string\" ? s.agent_id : undefined;\n // PermissionRequest carries no tool_use_id (recorded 2026-09-28): the id is a hash\n // of the prompt, the tool and its input, so the same prompt yields the same id and\n // a later control answer can name it.\n const permissionId = () =>\n `perm-${createHash(\"sha256\")\n .update(`${turn_id ?? \"\"}|${tool ?? \"\"}|${JSON.stringify(s.tool_input ?? null)}`)\n .digest(\"hex\")\n .slice(0, 16)}`;\n const ev = (type: string, data: Record<string, unknown>) => ({ type, data: prune(data), harnessEvent: event });\n const events: HookResult[\"events\"] = [];\n switch (event) {\n case \"SessionStart\":\n events.push(ev(\"session.started\", { source: pickSource(s.source ?? s.trigger) }));\n break;\n case \"UserPromptSubmit\":\n events.push(\n ev(\"turn.started\", {\n turn_id,\n prompt_chars: typeof s.prompt === \"string\" ? [...s.prompt].length : undefined,\n }),\n );\n break;\n case \"PreToolUse\":\n if (tool) events.push(ev(\"tool.started\", { tool, call_id, turn_id, agent_id, input: s.tool_input }));\n break;\n case \"PostToolUse\":\n if (tool)\n events.push(\n ev(\"tool.ended\", {\n tool,\n call_id,\n turn_id,\n agent_id,\n ms,\n ok: true,\n input: s.tool_input,\n output: s.tool_response,\n }),\n );\n break;\n case \"PostToolUseFailure\":\n if (tool)\n events.push(\n ev(\"tool.ended\", {\n tool,\n call_id,\n turn_id,\n agent_id,\n ms,\n ok: false,\n error: errText(s.error ?? s.tool_response),\n input: s.tool_input,\n output: s.tool_response,\n }),\n );\n break;\n case \"PermissionRequest\":\n events.push(\n ev(\"attention.needed\", {\n attention_id: call_id ?? permissionId(),\n kind: \"permission\",\n tool,\n message: tool ? `${tool}${describe(s.tool_input)}` : undefined,\n }),\n );\n break;\n case \"Notification\":\n events.push(\n ev(\"attention.needed\", {\n attention_id: `notif-${Date.now()}`,\n kind: notifKind(s.notification_type),\n message: typeof s.message === \"string\" ? s.message.slice(0, 200) : undefined,\n }),\n );\n break;\n case \"Stop\":\n events.push(ev(\"turn.ended\", { turn_id, reason: \"stop\" }));\n break;\n case \"StopFailure\":\n // The turn ended on an API error (rate_limit, overloaded, authentication_failed,\n // server_error \u2026); the payload key is `error` (issue #10, recorded 2026-09-28).\n events.push(\n ev(\"turn.ended\", {\n turn_id,\n reason: \"error\",\n error: typeof s.error === \"string\" ? s.error.slice(0, 200) : undefined,\n }),\n );\n break;\n case \"SubagentStart\":\n events.push(\n ev(\"subagent.started\", {\n agent_id: String(s.agent_id ?? \"\"),\n agent_type: typeof s.agent_type === \"string\" ? s.agent_type : undefined,\n }),\n );\n break;\n case \"SubagentStop\":\n events.push(\n ev(\"subagent.ended\", {\n agent_id: String(s.agent_id ?? \"\"),\n agent_type: typeof s.agent_type === \"string\" ? s.agent_type : undefined,\n }),\n );\n break;\n case \"PreCompact\":\n events.push(ev(\"context.compacted\", { trigger: s.trigger === \"manual\" ? \"manual\" : \"auto\" }));\n break;\n case \"PostCompact\":\n break; // PreCompact already said it; a second event would double-count\n case \"SessionEnd\":\n events.push(ev(\"session.ended\", { reason: endReason(s.reason) }));\n break;\n default:\n return null;\n }\n const hints: Record<string, unknown> = {};\n const host = input.env.CLAUDE_CODE_HOST_SESSION_ID;\n if (host && DESKTOP_ID.test(host)) hints.desktop_id = host;\n // The registry file is found while the process tree stands (the detached\n // worker's parent is gone by the time it runs). Heartbeat-class events skip it.\n if (event !== \"PreToolUse\" && event !== \"PostToolUse\") hints.claude_pid = claudePid(input.env);\n const r: HookResult = { session, events, hints };\n if (typeof s.transcript_path === \"string\") r.transcript = s.transcript_path;\n return r;\n },\n\n readTranscript(file, fromLine) {\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { turns: [], line: fromLine };\n }\n return readClaude(text.split(\"\\n\"), fromLine);\n },\n\n facts(session, transcript, hints, state): SessionFacts {\n const out: SessionFacts = {};\n if (transcript) Object.assign(out, claudeFacts(transcript, session.id, hints, state));\n const cwd = out.cwd ?? session.cwd;\n Object.assign(out, gitFacts(cwd), out.branch ? { branch: out.branch } : {});\n if (!out.url && typeof hints.desktop_id === \"string\") out.url = `claude://code/continue/${hints.desktop_id}`;\n return out;\n },\n\n backfill(sinceMs, env = process.env): BackfillRow[] {\n const rows: BackfillRow[] = [];\n const files: string[] = [];\n for (const d of claudeDirs(env))\n files.push(...recentFiles(path.join(d, \"projects\"), 1, sinceMs, (n) => /^[0-9a-f-]{36}\\.jsonl$/.test(n)));\n const noState: FactsState = { get: () => ({}), save: () => {} };\n for (const f of files) {\n const id = path.basename(f, \".jsonl\");\n const facts = claudeFacts(f, id, {}, noState);\n if (!facts.started_at || !facts.last_at) continue;\n const { started_at, last_at, first_ask: _fa, harness_version: _hv, ...rest } = facts;\n const cwd = rest.cwd;\n rows.push({\n session: { id, ...rest, ...gitFacts(cwd), ...(rest.branch ? { branch: rest.branch } : {}) },\n started_at,\n last_at,\n });\n }\n return rows;\n },\n};\n\nfunction prune<T extends Record<string, unknown>>(o: T): T {\n for (const k of Object.keys(o)) if (o[k] === undefined) delete o[k];\n return o;\n}\nfunction pickSource(v: unknown): string {\n return typeof v === \"string\" && [\"startup\", \"resume\", \"clear\", \"compact\", \"fork\"].includes(v) ? v : \"unknown\";\n}\nfunction errText(v: unknown): string | undefined {\n if (typeof v === \"string\") return v.slice(0, 2000);\n if (v && typeof v === \"object\") {\n const e = v as { error?: unknown; message?: unknown };\n if (typeof e.error === \"string\") return e.error.slice(0, 2000);\n if (typeof e.message === \"string\") return e.message.slice(0, 2000);\n }\n return undefined;\n}\nfunction describe(input: unknown): string {\n if (!input || typeof input !== \"object\") return \"\";\n const i = input as Record<string, unknown>;\n const v = i.command ?? i.file_path ?? i.path ?? i.url ?? i.pattern;\n return typeof v === \"string\" ? ` ${v.slice(0, 120)}` : \"\";\n}\n\n// --- facts: title, url, model, account, from Claude Code's own files ------------------\n\nconst NAME_RANK: Record<string, \"custom\" | \"harness\"> = {\n user: \"custom\",\n auto: \"harness\",\n hook: \"harness\",\n peer: \"harness\",\n};\ninterface Registry {\n sessionId: string | null;\n name: string | null;\n name_source: \"custom\" | \"harness\" | null;\n bridge: string | null;\n}\nfunction registryEntry(j: unknown): Registry | null {\n if (!j || typeof j !== \"object\") return null;\n const r = j as { sessionId?: unknown; name?: unknown; nameSource?: string; bridgeSessionId?: unknown };\n const source = r.nameSource ? NAME_RANK[r.nameSource] : undefined;\n return {\n sessionId: r.sessionId ? String(r.sessionId) : null,\n name: source && typeof r.name === \"string\" && r.name.trim() ? r.name.trim() : null,\n name_source: source ?? null,\n bridge: typeof r.bridgeSessionId === \"string\" ? r.bridgeSessionId : null,\n };\n}\nconst liveCache = new Map<string, Map<string, Registry>>();\nfunction claudeLive(dir: string): Map<string, Registry> {\n const hit = liveCache.get(dir);\n if (hit) return hit;\n const map = new Map<string, Registry>();\n let names: string[] = [];\n try {\n names = readdirSync(path.join(dir, \"sessions\")).filter((n) => n.endsWith(\".json\"));\n } catch {}\n for (const n of names) {\n try {\n const e = registryEntry(JSON.parse(readFileSync(path.join(dir, \"sessions\", n), \"utf8\")));\n if (e?.sessionId) map.set(e.sessionId, e);\n } catch {}\n }\n liveCache.set(dir, map);\n return map;\n}\nfunction claudeLiveByPid(dir: string, pid: unknown): Registry | null {\n if (!pid) return null;\n try {\n return registryEntry(JSON.parse(readFileSync(path.join(dir, \"sessions\", `${pid}.json`), \"utf8\")));\n } catch {\n return null;\n }\n}\n/** The Claude Code process that ran this hook: the nearest ancestor with a registry\n * file (hooks run under a shell, so usually the parent's parent). */\nexport function claudePid(env: NodeJS.ProcessEnv = process.env): number | null {\n try {\n const dirs = claudeDirs(env);\n const has = (pid: number) => dirs.some((d) => existsSync(path.join(d, \"sessions\", `${pid}.json`)));\n let pid = process.ppid;\n if (has(pid)) return pid;\n const parent = parentOf();\n for (let hop = 0; hop < 6 && pid > 1; hop++) {\n pid = parent(pid);\n if (pid > 1 && has(pid)) return pid;\n }\n } catch {}\n return null;\n}\nfunction parentOf(): (pid: number) => number {\n if (process.platform === \"linux\") {\n return (pid) => {\n try {\n const st = readFileSync(`/proc/${pid}/stat`, \"utf8\");\n return Number(st.slice(st.lastIndexOf(\")\") + 2).split(\" \")[1]) || 0;\n } catch {\n return 0;\n }\n };\n }\n const table = new Map<number, number>();\n try {\n const out = execFileSync(\"ps\", [\"-axo\", \"pid=,ppid=\"], {\n encoding: \"utf8\",\n timeout: 2000,\n maxBuffer: 8 * 1024 * 1024,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n for (const l of out.split(\"\\n\")) {\n const m = /^\\s*(\\d+)\\s+(\\d+)/.exec(l);\n if (m) table.set(Number(m[1]), Number(m[2]));\n }\n } catch {}\n return (pid) => table.get(pid) || 0;\n}\nconst accountCache = new Map<string, string | null>();\n/** The account id (never the email) from the config dir's .claude.json. */\nfunction claudeAccount(dir: string): string | null {\n const hit = accountCache.get(dir);\n if (hit !== undefined) return hit;\n const files = [path.join(dir, \".claude.json\")];\n if (path.resolve(dir) === path.join(HOME, \".claude\")) files.unshift(path.join(HOME, \".claude.json\"));\n let acct: string | null = null;\n for (const f of files) {\n try {\n const a = (JSON.parse(readFileSync(f, \"utf8\")) as { oauthAccount?: { accountUuid?: string } }).oauthAccount;\n if (a?.accountUuid) {\n acct = String(a.accountUuid);\n break;\n }\n } catch {}\n }\n accountCache.set(dir, acct);\n return acct;\n}\nconst LINK_RE = /^https:\\/\\/claude\\.ai\\/code\\/session_[A-Za-z0-9]+$/;\nfunction transcriptLink(records: Record<string, unknown>[]): string | null {\n for (let i = records.length - 1; i >= 0; i--) {\n const j = records[i] as { type?: string; subtype?: string; url?: unknown; bridgeSessionId?: unknown };\n if (j.type === \"system\" && j.subtype === \"bridge_status\" && typeof j.url === \"string\" && LINK_RE.test(j.url))\n return j.url;\n if (j.type === \"bridge-session\" && typeof j.bridgeSessionId === \"string\") {\n const m = /^(?:cse|session)_([A-Za-z0-9]+)$/.exec(j.bridgeSessionId);\n if (m) return `https://claude.ai/code/session_${m[1]}`;\n }\n }\n return null;\n}\n/** A first ask as the Claude Code app titles an untitled session: whitespace\n * collapsed, whole up to 50 characters, else its first 50 and \"...\". */\nexport function appTitle(text: string): string {\n const t = String(text).replace(/\\s+/g, \" \").trim();\n return t.length > 50 ? `${t.slice(0, 50)}...` : t;\n}\nfunction askText(j: Record<string, unknown> | null): string | null {\n if (!j || j.type !== \"user\" || j.isMeta || j.isSidechain) return null;\n const origin = j.origin as { kind?: string } | undefined;\n if (origin?.kind && origin.kind !== \"human\") return null;\n const c = (j.message as { content?: unknown } | undefined)?.content;\n const text = (\n typeof c === \"string\"\n ? c\n : Array.isArray(c)\n ? c\n .filter((b) => b && b.type === \"text\" && typeof b.text === \"string\")\n .map((b) => b.text as string)\n .join(\"\\n\")\n : \"\"\n ).trim();\n if (!text || isInjected(text)) return null;\n return text;\n}\nfunction firstAsk(records: Record<string, unknown>[]): string | null {\n for (const j of records) {\n const t = askText(j);\n if (t) return appTitle(t);\n }\n return null;\n}\nfunction scanTitles(file: string, from: number, found: { custom?: string | null; ai?: string | null }) {\n const out = { custom: found.custom ?? null, ai: found.ai ?? null, upto: from };\n let size = 0;\n try {\n size = statSync(file).size;\n } catch {\n return out;\n }\n if (size < from) {\n out.upto = 0;\n out.custom = out.ai = null;\n from = 0;\n }\n // Only lines carrying a title record are parsed; the rest of the new bytes are skipped.\n let pos = 0;\n scanLines<null>(\n file,\n (l) => {\n pos += Buffer.byteLength(l, \"utf8\") + 1;\n if (pos <= from || l.indexOf('-title\"') < 0) return null;\n try {\n const j = JSON.parse(l) as { type?: string; customTitle?: string; aiTitle?: string };\n if (j.type === \"custom-title\" && j.customTitle) out.custom = j.customTitle;\n if (j.type === \"ai-title\" && j.aiTitle) out.ai = j.aiTitle;\n } catch {}\n return null;\n },\n 512 * 1024 * 1024,\n );\n out.upto = size;\n return out;\n}\n\n/** A session's title and where it came from, best first: /rename (registry \"user\"\n * name or custom-title) \u2192 Claude Code's own title (registry \"auto\" name or\n * ai-title) \u2192 the first ask, marked first-ask so a real title later replaces it. */\nexport function claudeFacts(\n file: string,\n sessionId: string,\n hints: Record<string, unknown>,\n state: FactsState,\n): SessionFacts {\n const { head, tail } = ends(file, 64 * 1024, 256 * 1024);\n const H = parseLines(head);\n const T = parseLines(tail);\n const out: SessionFacts = {};\n const id = sessionId || path.basename(file, \".jsonl\");\n const mem = state.get(NAME, id);\n let custom: string | null = null;\n let ai: string | null = null;\n for (const j of H.concat(T)) {\n if (j.type === \"custom-title\" && typeof j.customTitle === \"string\") custom = j.customTitle;\n if (j.type === \"ai-title\" && typeof j.aiTitle === \"string\") ai = j.aiTitle;\n }\n let size = 0;\n try {\n size = statSync(file).size;\n } catch {}\n if (!custom && !ai && size > 64 * 1024 + 256 * 1024) {\n const s = scanTitles(file, Number(mem.scan_upto) || 0, {\n custom: mem.scan_custom as string | null,\n ai: mem.scan_ai as string | null,\n });\n custom = s.custom;\n ai = s.ai;\n state.save(NAME, id, { scan_upto: s.upto, scan_custom: s.custom, scan_ai: s.ai });\n }\n const dir = configDirOf(file);\n const live = claudeLive(dir).get(id) ?? claudeLiveByPid(dir, hints.claude_pid);\n if (live?.name) state.save(NAME, id, { name: live.name, name_source: live.name_source });\n const bridge =\n live?.bridge && /^session_[A-Za-z0-9]+$/.test(live.bridge) ? `https://claude.ai/code/${live.bridge}` : null;\n const url = bridge ?? transcriptLink(T) ?? transcriptLink(H) ?? (typeof mem.url === \"string\" ? mem.url : null);\n if (url) {\n out.url = url;\n state.save(NAME, id, { url });\n }\n const name = live?.name\n ? { title: live.name, source: live.name_source as \"custom\" | \"harness\" }\n : typeof mem.name === \"string\"\n ? { title: mem.name, source: mem.name_source as \"custom\" | \"harness\" }\n : null;\n const pick =\n (name && name.source === \"custom\" && name) ||\n (custom && { title: custom, source: \"custom\" as const }) ||\n name ||\n (ai && { title: ai, source: \"harness\" as const });\n let ask = typeof mem.first_ask === \"string\" ? mem.first_ask : firstAsk(H);\n if (!ask && size > 64 * 1024 && !mem.first_ask_none) {\n ask = scanLines<string>(file, (l) => {\n try {\n const t = askText(JSON.parse(l) as Record<string, unknown>);\n return t ? appTitle(t) : null;\n } catch {\n return null;\n }\n });\n if (!ask && size > 16 * 1024 * 1024) state.save(NAME, id, { first_ask_none: true });\n }\n if (ask) {\n out.first_ask = ask;\n if (!mem.first_ask) state.save(NAME, id, { first_ask: ask });\n }\n if (pick) {\n out.title = String(pick.title).slice(0, 120);\n out.title_source = pick.source;\n } else if (ask) {\n out.title = ask;\n out.title_source = \"first-ask\";\n }\n const acct = claudeAccount(dir);\n if (acct) out.account_id = acct;\n for (let i = T.length - 1; i >= 0; i--) {\n const m = (T[i] as { message?: { model?: string } }).message?.model;\n if (T[i]?.type === \"assistant\" && m && m !== \"<synthetic>\") {\n out.model = m;\n break;\n }\n }\n const meta = [...T].reverse().find((j) => j.version) ?? H.find((j) => j.version);\n if (meta?.version) out.harness_version = String(meta.version);\n const times = H.concat(T)\n .map((j) => Date.parse(String(j.timestamp ?? \"\")))\n .filter((n) => n > 0);\n if (times.length) {\n out.started_at = Math.min(...times);\n out.last_at = Math.max(...times);\n }\n const withCwd = H.find((j) => typeof j.cwd === \"string\");\n if (withCwd) {\n out.cwd = withCwd.cwd as string;\n if (typeof withCwd.gitBranch === \"string\" && withCwd.gitBranch !== \"HEAD\") out.branch = withCwd.gitBranch;\n }\n return out;\n}\n\n/** For tests: each hook runs in a fresh process; a test that edits the registry mid-run clears the cache. */\nexport const _resetClaudeCaches = (): void => {\n liveCache.clear();\n accountCache.clear();\n};\n", "// SPDX-License-Identifier: Apache-2.0\n// The repo and branch of a folder, from git itself; credentials stripped from the\n// remote. Cached per folder for the life of the process (a worker run).\nimport { execFileSync } from \"node:child_process\";\n\nconst cache = new Map<string, { repo?: string; branch?: string }>();\n\nexport function gitFacts(cwd: string | undefined): { repo?: string; branch?: string } {\n if (!cwd) return {};\n const hit = cache.get(cwd);\n if (hit) return hit;\n const run = (args: string[]) => {\n try {\n return execFileSync(\"git\", [\"-C\", cwd, ...args], {\n encoding: \"utf8\",\n timeout: 1500,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n } catch {\n return \"\";\n }\n };\n const out: { repo?: string; branch?: string } = {};\n const repo = run([\"remote\", \"get-url\", \"origin\"]);\n if (repo) out.repo = stripCredentials(repo);\n const branch = run([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"]);\n if (branch && branch !== \"HEAD\") out.branch = branch;\n cache.set(cwd, out);\n return out;\n}\n\n/** `https://user:token@host/x` \u2192 `https://host/x`; `git@github.com:a/b.git` \u2192 `github.com/a/b`. */\nexport function stripCredentials(url: string): string {\n let u = url.replace(/\\/\\/[^/@]*@/, \"//\");\n const ssh = /^(?:ssh:\\/\\/)?git@([^:/]+)[:/](.+?)(?:\\.git)?$/.exec(u);\n if (ssh) u = `${ssh[1]}/${ssh[2]}`;\n return u.replace(/^https?:\\/\\//, \"\").replace(/\\.git$/, \"\");\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Codex CLI (OpenAI) \u2014 docs: https://learn.chatgpt.com/docs/hooks\n// Config: ~/.codex/hooks.json (Claude-shaped, 12 events, timeouts in seconds) AND\n// `notify` at the top level of config.toml as the fallback when hooks are off or\n// not yet trusted (non-managed hooks need a /hooks review in the CLI). An existing\n// notify (Codex Computer Use) is chained through --previous-notify, never replaced.\nimport { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { HOME } from \"../paths.js\";\nimport { ends, parseLines, recentFiles } from \"../readers/files.js\";\nimport { readCodex } from \"../readers/transcripts.js\";\nimport { installClaudeShaped, installedClaudeShaped, uninstallClaudeShaped } from \"./claude-shaped.js\";\nimport * as toml from \"./codex-config.js\";\nimport type {\n Adapter,\n BackfillRow,\n HookCommand,\n HookInput,\n HookResult,\n InstalledReport,\n InstallOptions,\n SessionFacts,\n} from \"./types.js\";\n\nconst NAME = \"codex\";\nexport const CODEX_EVENTS = [\n \"SessionStart\",\n \"UserPromptSubmit\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PermissionRequest\",\n \"Stop\",\n \"Interrupt\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PreCompact\",\n \"PostCompact\",\n \"SessionEnd\",\n] as const;\nconst OPTS = { matcherFor: (e: string) => (/Tool|Permission/.test(e) ? \"\" : undefined), timeout: 5 };\nconst eventsFor = (lean?: boolean) => (lean ? CODEX_EVENTS.filter((e) => e !== \"PreToolUse\") : [...CODEX_EVENTS]);\n\nconst codexHome = (env: NodeJS.ProcessEnv) => env.CODEX_HOME || path.join(HOME, \".codex\");\nconst hooksFile = (env: NodeJS.ProcessEnv) => path.join(codexHome(env), \"hooks.json\");\nconst configFile = (env: NodeJS.ProcessEnv) => path.join(codexHome(env), \"config.toml\");\nconst sessionsDir = (env: NodeJS.ProcessEnv) => path.join(codexHome(env), \"sessions\");\n\nconst validTool = (n: unknown): n is string => typeof n === \"string\" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);\nconst endReason = (r: unknown): \"clear\" | \"logout\" | \"exit\" | \"other\" =>\n r === \"clear\" || r === \"logout\" || r === \"exit\" ? r : \"other\";\n\nfunction installNotify(cmd: HookCommand, env: NodeJS.ProcessEnv) {\n const file = configFile(env);\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {}\n const argv = cmd([NAME, \"notify\"]).argv;\n const line = `notify = ${JSON.stringify(argv)}`;\n const n = toml.readNotify(text);\n const write = (next: string) => {\n mkdirSync(path.dirname(file), { recursive: true });\n writeFileSync(file, next);\n };\n if (n && !n.other) {\n if (!n.misplaced && JSON.stringify(n.argv) === JSON.stringify(argv))\n return { file, changed: false, note: \"notify current\" };\n write(toml.withNotify(text, line));\n return {\n file,\n changed: true,\n note: n.misplaced\n ? \"notify moved to the top level (it sat inside a [table], where Codex never reads it)\"\n : \"notify updated\",\n };\n }\n if (n?.other) {\n const prev = toml.previousNotify(n.argv);\n if (toml.isComputerUse(n.argv)) {\n if (prev && toml.OURS.test(JSON.stringify(prev))) {\n if (JSON.stringify(prev) === JSON.stringify(argv))\n return { file, changed: false, note: \"notify current (after Codex Computer Use)\" };\n }\n if (!prev || toml.OURS.test(JSON.stringify(prev))) {\n const next = toml.replaceNotify(text, `notify = ${toml.withPreviousRaw(n.raw, argv)}`);\n if (next) {\n write(next);\n return { file, changed: true, note: \"chained after Codex Computer Use (--previous-notify)\" };\n }\n }\n }\n return {\n file,\n changed: false,\n skipped: true,\n note: `notify belongs to ${(n.argv?.[0] ?? n.raw).replace(/^.*\\//, \"\").slice(0, 40)}; left alone. Codex will report nothing until you approve the hooks: start \\`codex\\` and accept the hook review`,\n };\n }\n write(toml.withNotify(text, line));\n return { file, changed: true, note: \"notify set at the top level\" };\n}\n\nfunction uninstallNotify(env: NodeJS.ProcessEnv) {\n const file = configFile(env);\n let text: string;\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { file, changed: false };\n }\n const n = toml.readNotify(text);\n if (!n) return { file, changed: false };\n if (!n.other) {\n writeFileSync(file, toml.withoutNotify(text));\n return { file, changed: true };\n }\n const prev = toml.previousNotify(n.argv);\n if (toml.isComputerUse(n.argv) && prev && toml.OURS.test(JSON.stringify(prev))) {\n const next = toml.replaceNotify(text, `notify = ${toml.stripPreviousRaw(n.raw)}`);\n if (next) writeFileSync(file, next);\n return { file, changed: true };\n }\n return { file, changed: false };\n}\n\nfunction findRollout(threadId: string, env: NodeJS.ProcessEnv): string | null {\n let best: string | null = null;\n const walk = (dir: string, depth: number) => {\n let names: string[] = [];\n try {\n names = readdirSync(dir);\n } catch {\n return;\n }\n for (const n of names.sort().reverse()) {\n const p = path.join(dir, n);\n if (n.endsWith(\".jsonl\") && n.includes(threadId)) {\n best = p;\n return;\n }\n if (depth < 3) {\n walk(p, depth + 1);\n if (best) return;\n }\n }\n };\n walk(sessionsDir(env), 0);\n return best;\n}\n\nexport const codex: Adapter = {\n name: NAME,\n events: CODEX_EVENTS,\n detect: (env = process.env) => existsSync(codexHome(env)),\n configFiles: (env = process.env) => [hooksFile(env), configFile(env)],\n install: (cmd, env = process.env, opts: InstallOptions = {}) => [\n installClaudeShaped(hooksFile(env), NAME, eventsFor(opts.lean), cmd, OPTS),\n installNotify(cmd, env),\n ],\n uninstall: (env = process.env, opts: InstallOptions = {}) => [\n uninstallClaudeShaped(hooksFile(env), CODEX_EVENTS, { created: opts.created?.includes(hooksFile(env)) }),\n uninstallNotify(env),\n ],\n installed: (cmd, env = process.env, opts: InstallOptions = {}) => {\n const out: InstalledReport[] = [\n {\n file: hooksFile(env),\n state: installedClaudeShaped(hooksFile(env), NAME, eventsFor(opts.lean), cmd, OPTS),\n note: \"Codex runs non-managed hooks only after the review in `codex` (/hooks); until then nothing is reported unless the notify fallback is ours\",\n },\n ];\n let text = \"\";\n try {\n text = readFileSync(configFile(env), \"utf8\");\n } catch {}\n const n = toml.readNotify(text);\n const argv = cmd([NAME, \"notify\"]).argv;\n const prev = n ? toml.previousNotify(n.argv) : null;\n const ours = n && (!n.other || (prev && JSON.stringify(prev) === JSON.stringify(argv)));\n out.push({\n file: configFile(env),\n state:\n !n || (n.other && !ours)\n ? \"missing\"\n : n.misplaced\n ? \"misplaced\"\n : JSON.stringify(n.argv) === JSON.stringify(argv) || (prev && JSON.stringify(prev) === JSON.stringify(argv))\n ? \"current\"\n : \"stale\",\n });\n return out;\n },\n\n fromHook(input: HookInput): HookResult | null {\n const event = input.argv[1] ?? \"\";\n let s: Record<string, unknown> = {};\n if (event === \"notify\") {\n // Codex's notify passes one JSON argument: {\"type\":\"agent-turn-complete\",\"thread-id\":\u2026,\"turn-id\":\u2026,\"cwd\":\u2026}\n const raw = input.argv.find((a) => a.startsWith(\"{\")) ?? input.stdin;\n try {\n s = raw ? (JSON.parse(raw) as Record<string, unknown>) : {};\n } catch {}\n const id = (s[\"thread-id\"] ?? s.thread_id ?? s[\"session-id\"] ?? s.session_id) as string | undefined;\n if (!id) return null;\n const r: HookResult = {\n session: { id: String(id), cwd: typeof s.cwd === \"string\" ? s.cwd : input.cwd },\n events: [\n {\n type: \"turn.ended\",\n data: { reason: \"stop\", ...(typeof s[\"turn-id\"] === \"string\" ? { turn_id: s[\"turn-id\"] } : {}) },\n harnessEvent: \"notify\",\n },\n ],\n hints: {},\n };\n const file = findRollout(String(id), input.env as NodeJS.ProcessEnv);\n if (file) r.transcript = file;\n return r;\n }\n try {\n s = input.stdin ? (JSON.parse(input.stdin) as Record<string, unknown>) : {};\n } catch {}\n const id = s.session_id as string | undefined;\n if (!id) return null;\n const session: HookResult[\"session\"] = { id: String(id), cwd: typeof s.cwd === \"string\" ? s.cwd : input.cwd };\n if (typeof s.model === \"string\") session.model = s.model;\n const turn_id = typeof s.turn_id === \"string\" ? s.turn_id : undefined;\n const tool = validTool(s.tool_name) ? s.tool_name : undefined;\n const call_id = typeof s.tool_use_id === \"string\" ? s.tool_use_id : undefined;\n const ev = (type: string, data: Record<string, unknown>) => ({ type, data: prune(data), harnessEvent: event });\n const events: HookResult[\"events\"] = [];\n switch (event) {\n case \"SessionStart\":\n events.push(\n ev(\"session.started\", {\n source:\n typeof s.source === \"string\" && [\"startup\", \"resume\", \"clear\", \"compact\", \"fork\"].includes(s.source)\n ? s.source\n : \"unknown\",\n }),\n );\n break;\n case \"UserPromptSubmit\":\n events.push(\n ev(\"turn.started\", {\n turn_id,\n prompt_chars: typeof s.prompt === \"string\" ? [...s.prompt].length : undefined,\n }),\n );\n break;\n case \"PreToolUse\":\n if (tool) events.push(ev(\"tool.started\", { tool, call_id, turn_id, input: s.tool_input }));\n break;\n case \"PostToolUse\":\n if (tool)\n events.push(\n ev(\"tool.ended\", { tool, call_id, turn_id, ok: true, input: s.tool_input, output: s.tool_response }),\n );\n break;\n case \"PermissionRequest\":\n events.push(\n ev(\"attention.needed\", { attention_id: call_id ?? `perm-${Date.now()}`, kind: \"permission\", tool }),\n );\n break;\n case \"Stop\":\n events.push(ev(\"turn.ended\", { turn_id, reason: \"stop\" }));\n break;\n case \"Interrupt\":\n events.push(ev(\"turn.ended\", { turn_id, reason: \"interrupt\" }));\n break;\n case \"SubagentStart\":\n events.push(\n ev(\"subagent.started\", {\n agent_id: String(s.agent_id ?? s.subagent_id ?? \"\"),\n agent_type: typeof s.agent_type === \"string\" ? s.agent_type : undefined,\n }),\n );\n break;\n case \"SubagentStop\":\n events.push(\n ev(\"subagent.ended\", {\n agent_id: String(s.agent_id ?? s.subagent_id ?? \"\"),\n agent_type: typeof s.agent_type === \"string\" ? s.agent_type : undefined,\n }),\n );\n break;\n case \"PreCompact\":\n events.push(ev(\"context.compacted\", { trigger: s.trigger === \"manual\" ? \"manual\" : \"auto\" }));\n break;\n case \"PostCompact\":\n break;\n case \"SessionEnd\":\n events.push(ev(\"session.ended\", { reason: endReason(s.reason) }));\n break;\n default:\n return null;\n }\n const r: HookResult = { session, events, hints: {} };\n if (typeof s.transcript_path === \"string\") r.transcript = s.transcript_path;\n return r;\n },\n\n readTranscript(file, fromLine) {\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { turns: [], line: fromLine };\n }\n return readCodex(text.split(\"\\n\"), fromLine);\n },\n\n facts(session, transcript): SessionFacts {\n const out: SessionFacts = {};\n if (transcript) Object.assign(out, codexFacts(transcript));\n return out;\n },\n\n backfill(sinceMs, env = process.env): BackfillRow[] {\n const rows: BackfillRow[] = [];\n for (const f of recentFiles(sessionsDir(env), 3, sinceMs, (n) => /^rollout-.*\\.jsonl$/.test(n))) {\n const m = /([0-9a-f]{8}-[0-9a-f-]{27,})\\.jsonl$/i.exec(path.basename(f));\n if (!m?.[1]) continue;\n const facts = codexFacts(f);\n if (!facts.started_at || !facts.last_at) continue;\n const { started_at, last_at, first_ask: _fa, harness_version: _hv, ...rest } = facts;\n rows.push({ session: { id: m[1], ...rest }, started_at, last_at });\n }\n return rows;\n },\n};\n\nfunction prune<T extends Record<string, unknown>>(o: T): T {\n for (const k of Object.keys(o)) if (o[k] === undefined) delete o[k];\n return o;\n}\n\n/** Codex keeps no title; its first real ask stands in. */\nexport function codexFacts(file: string): SessionFacts {\n const { head, tail } = ends(file, 128 * 1024, 64 * 1024);\n const H = parseLines(head);\n const T = parseLines(tail);\n const out: SessionFacts = {};\n const meta = H.find((j) => j.type === \"session_meta\" && j.payload) as\n | { payload?: { cwd?: string; cli_version?: string; git?: { branch?: string; repository_url?: string } } }\n | undefined;\n if (meta?.payload) {\n const p = meta.payload;\n if (p.cwd) out.cwd = p.cwd;\n if (p.cli_version) out.harness_version = String(p.cli_version);\n if (p.git?.branch) out.branch = p.git.branch;\n if (p.git?.repository_url) out.repo = String(p.git.repository_url).replace(/\\/\\/[^/@]*@/, \"//\");\n }\n const ctx = H.concat(T)\n .reverse()\n .find((j) => j.type === \"turn_context\" && (j.payload as { model?: string } | undefined)?.model) as\n | { payload?: { model?: string } }\n | undefined;\n if (ctx?.payload?.model) out.model = ctx.payload.model;\n for (const j of H) {\n const p = j.payload as { type?: string; role?: string; content?: { type?: string; text?: string }[] } | undefined;\n if (j.type !== \"response_item\" || !p || p.type !== \"message\" || p.role !== \"user\") continue;\n const text = (p.content ?? [])\n .filter((b) => b && b.type === \"input_text\" && typeof b.text === \"string\")\n .map((b) => b.text as string)\n .join(\"\\n\")\n .trim();\n if (!text || /^<[a-z_-]+>/i.test(text)) continue;\n const line = text.split(\"\\n\").find((l) => l.trim()) ?? \"\";\n out.title = line.length > 80 ? `${line.slice(0, 80).replace(/\\s+\\S*$/, \"\")}\u2026` : line;\n out.title_source = \"first-ask\";\n break;\n }\n const times = H.concat(T)\n .map((j) => Date.parse(String(j.timestamp ?? \"\")))\n .filter((n) => n > 0);\n if (times.length) {\n out.started_at = Math.min(...times);\n out.last_at = Math.max(...times);\n }\n return out;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Codex's ~/.codex/config.toml, as far as the notify fallback needs it: its one\n// top-level `notify` command. Codex reads `notify` only at the top level \u2014 before\n// the first [table] \u2014 and Codex itself appends a [projects.\"<path>\"] table for every\n// folder it trusts, so a line appended at the end lands inside one and never runs.\n// Ported from spacesheep-cli lib/codex-config.js. Pure text in, text out.\n\nconst NOTIFY_LINE = /^[ \\t]*notify[ \\t]*=[ \\t]*(\\[.*\\])[ \\t]*(?:#.*)?$/m;\nconst NOTIFY_KEY = /^[ \\t]*notify[ \\t]*=/m;\n/** A notify that runs sessionpipe's hook directly (or through its launcher). */\nexport const OURS = /(?:hook\\.js|sessionpipe-hook)\",\\s*\"codex\",\\s*\"notify\"/;\n\nfunction scan(line: string, st: { depth: number; str: string | null }): void {\n let i = 0;\n while (i < line.length) {\n if (st.str) {\n const j = line.indexOf(st.str, i);\n if (j < 0) return;\n i = j + 3;\n st.str = null;\n continue;\n }\n const ch = line[i];\n if (ch === \"#\") return;\n if (line.startsWith('\"\"\"', i) || line.startsWith(\"'''\", i)) {\n st.str = line.slice(i, i + 3);\n i += 3;\n continue;\n }\n if (ch === '\"') {\n i++;\n while (i < line.length && line[i] !== '\"') i += line[i] === \"\\\\\" ? 2 : 1;\n i++;\n continue;\n }\n if (ch === \"'\") {\n const j = line.indexOf(\"'\", i + 1);\n i = j < 0 ? line.length : j + 1;\n continue;\n }\n if (ch === \"[\") st.depth++;\n else if (ch === \"]\") st.depth = Math.max(0, st.depth - 1);\n i++;\n }\n}\n\n/** Offset of the first table header, or -1. */\nexport function firstTableAt(text: string): number {\n const st = { depth: 0, str: null as string | null };\n let pos = 0;\n for (const line of text.split(\"\\n\")) {\n if (!st.str && st.depth === 0 && /^[ \\t]*\\[/.test(line)) return pos;\n scan(line, st);\n pos += line.length + 1;\n }\n return -1;\n}\n\nfunction split(text: string) {\n const at = firstTableAt(text);\n return at < 0 ? { head: text, tail: \"\", at: text.length } : { head: text.slice(0, at), tail: text.slice(at), at };\n}\n\nexport function parseArgv(raw: string): string[] | null {\n try {\n const a = JSON.parse(raw) as unknown;\n return Array.isArray(a) && a.every((x) => typeof x === \"string\") ? (a as string[]) : null;\n } catch {\n return null;\n }\n}\n\nexport interface Notify {\n raw: string;\n argv: string[] | null;\n index: number;\n length: number;\n misplaced: boolean;\n other: boolean;\n}\n\n/** notify as Codex sees it; `misplaced` for a line of ours inside a table. */\nexport function readNotify(text: string): Notify | null {\n const { head, tail, at } = split(text);\n const m = NOTIFY_LINE.exec(head);\n if (m)\n return {\n raw: m[1] ?? \"\",\n argv: parseArgv(m[1] ?? \"\"),\n index: m.index,\n length: m[0].length,\n misplaced: false,\n other: !OURS.test(m[1] ?? \"\"),\n };\n const k = NOTIFY_KEY.exec(head);\n if (k) {\n const rest = head.slice(k.index).split(\"\\n\")[0] ?? \"\";\n return {\n raw: rest.replace(NOTIFY_KEY, \"\").trim(),\n argv: null,\n index: k.index,\n length: 0,\n misplaced: false,\n other: true,\n };\n }\n const t = NOTIFY_LINE.exec(tail);\n if (t && OURS.test(t[1] ?? \"\"))\n return {\n raw: t[1] ?? \"\",\n argv: parseArgv(t[1] ?? \"\"),\n index: at + t.index,\n length: t[0].length,\n misplaced: true,\n other: false,\n };\n return null;\n}\n\nfunction dropLine(text: string, index: number, length: number): string {\n return text.slice(0, index) + text.slice(index + length).replace(/^\\r?\\n/, \"\");\n}\n\n/** Put `line` at the top level: before the first table, or at the end of a file that has none. */\nexport function insertTopLevel(text: string, line: string): string {\n const { head, tail } = split(text);\n if (!tail) return (head.trim() ? head.replace(/\\s*$/, \"\\n\") : \"\") + line + \"\\n\";\n return `${(head.trim() ? head.replace(/\\s*$/, \"\\n\") : \"\") + line}\\n\\n${tail}`;\n}\n\n/** The config with `line` as its notify, for a config whose notify is ours or absent. */\nexport function withNotify(text: string, line: string): string {\n const n = readNotify(text);\n if (n && !n.misplaced && !n.other) return text.slice(0, n.index) + line + text.slice(n.index + n.length);\n if (n?.misplaced) return insertTopLevel(dropLine(text, n.index, n.length), line);\n return insertTopLevel(text, line);\n}\n\n/** The config with its top-level notify line replaced by `line`. */\nexport function replaceNotify(text: string, line: string): string | null {\n const n = readNotify(text);\n if (!n || n.misplaced || !n.length) return null;\n return text.slice(0, n.index) + line + text.slice(n.index + n.length);\n}\n\n/** The config with our top-level or misplaced notify removed. */\nexport function withoutNotify(text: string): string {\n const n = readNotify(text);\n if (!n || n.other || !n.length) return text;\n return dropLine(text, n.index, n.length);\n}\n\n// Codex Computer Use takes the notify slot itself and keeps the command it found in\n// its own argv: [client, \"turn-ended\", \"--previous-notify\", \"<that command as JSON>\"].\nconst PREVIOUS = \"--previous-notify\";\nexport function previousNotify(argv: string[] | null): string[] | null {\n if (!Array.isArray(argv)) return null;\n const i = argv.indexOf(PREVIOUS);\n return i >= 0 && typeof argv[i + 1] === \"string\" ? parseArgv(argv[i + 1] as string) : null;\n}\nexport function withPrevious(argv: string[], prev: string[] | null): string[] {\n const out = argv.slice();\n const i = out.indexOf(PREVIOUS);\n if (i >= 0) out.splice(i, 2);\n if (prev) out.push(PREVIOUS, JSON.stringify(prev));\n return out;\n}\n/** The raw notify value with its --previous-notify pair removed, formatting kept. */\nexport function stripPreviousRaw(raw: string): string {\n return raw.replace(/,\\s*\"--previous-notify\",\\s*\"(?:[^\"\\\\]|\\\\.)*\"\\s*(?=\\])/, \"\");\n}\n/** The raw notify value with `prev` as its --previous-notify, formatting of the rest kept. */\nexport function withPreviousRaw(raw: string, prev: string[]): string {\n const base = stripPreviousRaw(raw).replace(/\\s*\\]\\s*$/, \"\");\n return `${base}, \"--previous-notify\", ${JSON.stringify(JSON.stringify(prev))}]`;\n}\nexport const isComputerUse = (argv: string[] | null): boolean =>\n Array.isArray(argv) && typeof argv[0] === \"string\" && /(^|\\/)SkyComputerUseClient$/.test(argv[0]);\n", "// SPDX-License-Identifier: Apache-2.0\n// Gemini CLI (Google) \u2014 docs: https://geminicli.com/docs/hooks/reference\n// Config: ~/.gemini/settings.json `hooks` key, same array-of-groups shape as Claude\n// Code but timeouts in MILLISECONDS and a `name` per handler. stdout must be JSON or\n// empty. Its own telemetry defaults logPrompts on; the installer says so once.\nimport { execFileSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { HOME } from \"../paths.js\";\nimport { ends, parseLines } from \"../readers/files.js\";\nimport { readGemini } from \"../readers/transcripts.js\";\nimport { installClaudeShaped, installedClaudeShaped, uninstallClaudeShaped } from \"./claude-shaped.js\";\nimport type { Adapter, HookInput, HookResult, InstallOptions, SessionFacts } from \"./types.js\";\n\nconst NAME = \"gemini-cli\";\nexport const GEMINI_EVENTS = [\n \"SessionStart\",\n \"BeforeAgent\",\n \"BeforeTool\",\n \"AfterTool\",\n \"Notification\",\n \"AfterAgent\",\n \"PreCompress\",\n \"SessionEnd\",\n] as const;\nconst OPTS = { matcherFor: (e: string) => (/Tool/.test(e) ? \".*\" : undefined), timeout: 5000 };\nconst geminiDir = (env: NodeJS.ProcessEnv) => env.GEMINI_CLI_HOME || path.join(HOME, \".gemini\");\nconst settings = (env: NodeJS.ProcessEnv) => path.join(geminiDir(env), \"settings.json\");\nconst validTool = (n: unknown): n is string => typeof n === \"string\" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);\nconst eventsFor = (lean?: boolean) => (lean ? GEMINI_EVENTS.filter((e) => e !== \"BeforeTool\") : [...GEMINI_EVENTS]);\n\n/** Before 0.46 the hooks system is off unless tools.enableHooks is true (issue #11). */\nexport function geminiHooksActive(settingsFile: string): { active: boolean; note?: string } {\n let tools: { enableHooks?: unknown } | undefined;\n try {\n tools = (JSON.parse(readFileSync(settingsFile, \"utf8\")) as { tools?: { enableHooks?: unknown } }).tools;\n } catch {}\n if (tools?.enableHooks === true) return { active: true };\n if (tools?.enableHooks === false)\n return { active: false, note: \"inactive: tools.enableHooks is false in settings.json\" };\n let version = \"\";\n try {\n version = execFileSync(\"gemini\", [\"--version\"], {\n encoding: \"utf8\",\n timeout: 4000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n } catch {\n return {\n active: true,\n note: \"could not run `gemini --version`; hooks need tools.enableHooks on versions before 0.46\",\n };\n }\n const m = /(\\d+)\\.(\\d+)/.exec(version);\n if (m && (Number(m[1]) > 0 || Number(m[2]) >= 46)) return { active: true };\n return {\n active: false,\n note: `inactive: Gemini CLI ${version || \"?\"} runs hooks only with \"tools\": {\"enableHooks\": true} in settings.json`,\n };\n}\n\nexport const geminiCli: Adapter = {\n name: NAME,\n events: GEMINI_EVENTS,\n // ~/.gemini also belongs to Antigravity; Gemini CLI is here when its settings or its chat logs exist.\n detect: (env = process.env) => existsSync(settings(env)) || existsSync(path.join(geminiDir(env), \"tmp\")),\n configFiles: (env = process.env) => [settings(env)],\n install: (cmd, env = process.env, opts: InstallOptions = {}) => {\n const r = installClaudeShaped(settings(env), NAME, eventsFor(opts.lean), cmd, OPTS);\n const a = geminiHooksActive(settings(env));\n return [a.note && !r.skipped ? { ...r, note: [r.note, a.note].filter(Boolean).join(\"; \") } : r];\n },\n uninstall: (env = process.env, opts: InstallOptions = {}) => [\n uninstallClaudeShaped(settings(env), GEMINI_EVENTS, { created: opts.created?.includes(settings(env)) }),\n ],\n installed: (cmd, env = process.env, opts: InstallOptions = {}) => {\n const state = installedClaudeShaped(settings(env), NAME, eventsFor(opts.lean), cmd, OPTS);\n const a = geminiHooksActive(settings(env));\n return [\n {\n file: settings(env),\n state: state === \"current\" && !a.active ? \"inactive\" : state,\n ...(a.note ? { note: a.note } : {}),\n },\n ];\n },\n\n fromHook(input: HookInput): HookResult | null {\n const event = input.argv[1] ?? \"\";\n let s: Record<string, unknown> = {};\n try {\n s = input.stdin ? (JSON.parse(input.stdin) as Record<string, unknown>) : {};\n } catch {}\n const id = s.session_id as string | undefined;\n if (!id) return null;\n const session: HookResult[\"session\"] = { id: String(id), cwd: typeof s.cwd === \"string\" ? s.cwd : input.cwd };\n const tool = validTool(s.tool_name) ? s.tool_name : undefined;\n const ev = (type: string, data: Record<string, unknown>) => ({ type, data: prune(data), harnessEvent: event });\n const events: HookResult[\"events\"] = [];\n switch (event) {\n case \"SessionStart\":\n events.push(\n ev(\"session.started\", {\n source:\n typeof s.source === \"string\" && [\"startup\", \"resume\", \"clear\"].includes(s.source) ? s.source : \"unknown\",\n }),\n );\n break;\n case \"BeforeAgent\":\n events.push(\n ev(\"turn.started\", { prompt_chars: typeof s.prompt === \"string\" ? [...s.prompt].length : undefined }),\n );\n break;\n case \"BeforeTool\":\n if (tool) events.push(ev(\"tool.started\", { tool, input: s.tool_input }));\n break;\n case \"AfterTool\": {\n const resp = s.tool_response as { error?: unknown; llmContent?: unknown } | undefined;\n const err =\n resp && typeof resp === \"object\" && resp.error\n ? String(typeof resp.error === \"string\" ? resp.error : JSON.stringify(resp.error)).slice(0, 2000)\n : undefined;\n if (tool)\n events.push(\n ev(\"tool.ended\", {\n tool,\n ok: !err,\n error: err,\n input: s.tool_input,\n output: resp?.llmContent ?? s.tool_response,\n }),\n );\n break;\n }\n case \"Notification\":\n events.push(\n ev(\"attention.needed\", {\n attention_id: `notif-${Date.now()}`,\n kind: s.notification_type === \"ToolPermission\" ? \"permission\" : \"question\",\n message: typeof s.message === \"string\" ? s.message.slice(0, 200) : undefined,\n }),\n );\n break;\n case \"AfterAgent\":\n events.push(ev(\"turn.ended\", { reason: \"stop\" }));\n break;\n case \"PreCompress\":\n events.push(ev(\"context.compacted\", { trigger: s.trigger === \"manual\" ? \"manual\" : \"auto\" }));\n break;\n case \"SessionEnd\":\n events.push(\n ev(\"session.ended\", {\n reason:\n s.reason === \"clear\" || s.reason === \"logout\" || s.reason === \"exit\"\n ? s.reason\n : s.reason === \"prompt_input_exit\"\n ? \"exit\"\n : \"other\",\n }),\n );\n break;\n default:\n return null;\n }\n const r: HookResult = { session, events, hints: {} };\n if (typeof s.transcript_path === \"string\") r.transcript = s.transcript_path;\n return r;\n },\n\n readTranscript(file, fromLine) {\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { turns: [], line: fromLine };\n }\n return readGemini(text.split(\"\\n\"), fromLine);\n },\n\n facts(_session, transcript): SessionFacts {\n const out: SessionFacts = {};\n if (!transcript) return out;\n const { head, tail } = ends(transcript, 64 * 1024, 64 * 1024);\n const H = parseLines(head);\n const T = parseLines(tail);\n const first = H.find((j) => j.type === \"user\");\n const raw = first ? (first.content ?? first.message ?? first.text) : undefined;\n const text = typeof raw === \"string\" ? raw.trim() : \"\";\n if (text) {\n const line = text.split(\"\\n\").find((l) => l.trim()) ?? \"\";\n out.title = line.length > 80 ? `${line.slice(0, 80).replace(/\\s+\\S*$/, \"\")}\u2026` : line;\n out.title_source = \"first-ask\";\n }\n const times = H.concat(T)\n .map((j) => Date.parse(String(j.timestamp ?? \"\")))\n .filter((n) => n > 0);\n if (times.length) {\n out.started_at = Math.min(...times);\n out.last_at = Math.max(...times);\n }\n return out;\n },\n\n backfill: () => [], // chat logs are keyed by a project hash, not a session id we can name; the first hook of a resumed session reports it\n};\n\nfunction prune<T extends Record<string, unknown>>(o: T): T {\n for (const k of Object.keys(o)) if (o[k] === undefined) delete o[k];\n return o;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Claude Code (Anthropic) \u2014 control delivery (spec/CONTROL.md \u00A76). Claude Code on\n// this machine, as the control daemon needs it: which `claude` to\n// run and with which permission flags, where a session's transcript is and which\n// folder it runs in, whether a live process holds it, and running one headless\n// turn (`claude -p --resume`, `--fork-session`, `--session-id`). Ported from the\n// spacesheep CLI's machine listener (lib/machine.js, 1.22), which ran it in\n// production first.\nimport { execFile, execFileSync, spawn } from \"node:child_process\";\nimport { accessSync, closeSync, constants, openSync, readdirSync, readFileSync, readSync, statSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nexport const JOB_TIMEOUT_MS = 30 * 60_000;\nconst OUT_CAP = 1024 * 1024;\n/** A transcript someone else wrote this recently is in use. */\nconst LIVE_WRITE_MS = 90_000;\n\nexport type Mode = \"safe\" | \"auto\";\n\nfunction isExe(p: string): boolean {\n try {\n if (!statSync(p).isFile()) return false;\n accessSync(p, constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nconst cmpVersion = (a: string, b: string) => {\n const pa = a.split(\".\").map(Number);\n const pb = b.split(\".\").map(Number);\n for (let i = 0; i < Math.max(pa.length, pb.length); i++)\n if ((pa[i] ?? 0) !== (pb[i] ?? 0)) return (pa[i] ?? 0) - (pb[i] ?? 0);\n return 0;\n};\n\n/** The `claude` to run: on PATH, else where the installers put it, else the newest\n * copy the desktop app ships. Null when this machine has none. */\nexport function findClaude(env: NodeJS.ProcessEnv = process.env, home = os.homedir()): string | null {\n if (env.SESSIONPIPE_CLAUDE && isExe(env.SESSIONPIPE_CLAUDE)) return env.SESSIONPIPE_CLAUDE;\n const names = process.platform === \"win32\" ? [\"claude.exe\", \"claude.cmd\"] : [\"claude\"];\n for (const d of String(env.PATH || \"\").split(path.delimiter)) {\n if (!d || !path.isAbsolute(d)) continue;\n for (const n of names) if (isExe(path.join(d, n))) return path.join(d, n);\n }\n for (const p of [\n path.join(home, \".claude\", \"local\", \"claude\"),\n path.join(home, \".local\", \"bin\", \"claude\"),\n \"/opt/homebrew/bin/claude\",\n \"/usr/local/bin/claude\",\n ])\n if (isExe(p)) return p;\n const app = path.join(home, \"Library\", \"Application Support\", \"Claude\", \"claude-code\");\n let versions: string[] = [];\n try {\n versions = readdirSync(app)\n .filter((n) => /^\\d+(\\.\\d+)*$/.test(n))\n .sort(cmpVersion)\n .reverse();\n } catch {}\n for (const v of versions) {\n const p = path.join(app, v, \"claude.app\", \"Contents\", \"MacOS\", \"claude\");\n if (isExe(p)) return p;\n }\n return null;\n}\n\n/** One option's text in `claude --help`: its line and the deeper-indented lines under it. */\nfunction optionBlock(help: string, flag: string): string | null {\n const lines = help.split(\"\\n\");\n const re = new RegExp(`^\\\\s{0,4}(?:-\\\\w, )?${flag.replace(/-/g, \"\\\\-\")}(?![\\\\w-])`);\n const start = lines.findIndex((l) => re.test(l));\n if (start < 0) return null;\n const out = [lines[start] as string];\n for (let i = start + 1; i < lines.length && lines[i]?.trim() && !/^\\s{0,4}-/.test(lines[i] as string); i++)\n out.push(lines[i] as string);\n return out.join(\" \");\n}\n\nexport interface Caps {\n hasMode: boolean;\n modes: string[];\n promptsNone: boolean;\n fork: boolean;\n /** `--output-format stream-json` with `--include-partial-messages`: the answer can be\n * forwarded as it is written. Optional so older callers' literals still type. */\n stream?: boolean;\n}\n\nexport function parseCaps(help: string): Caps {\n const pm = optionBlock(help, \"--permission-mode\");\n const pp = optionBlock(help, \"--permission-prompts\");\n return {\n hasMode: !!pm,\n modes: pm ? [...pm.matchAll(/\"([A-Za-z]+)\"/g)].map((m) => m[1] as string) : [],\n promptsNone: !!pp && /\"none\"/.test(pp),\n fork: !!optionBlock(help, \"--fork-session\"),\n stream: !!optionBlock(help, \"--include-partial-messages\"),\n };\n}\n\n/** Permission flags for the machine's mode. Safe: `dontAsk` (nothing that needs\n * approval runs). Auto: Claude Code's own auto mode, or a refusal. Never\n * bypassPermissions \u2014 no path here writes it. */\nexport function modeFlags(mode: Mode, caps: Caps): { args: string[] } | { error: string } {\n if (mode === \"auto\") {\n if (!caps.modes.includes(\"auto\"))\n return { error: \"this machine is in auto mode, but its Claude Code has no auto permission mode\" };\n return { args: [\"--permission-mode\", \"auto\"] };\n }\n if (caps.modes.includes(\"dontAsk\")) return { args: [\"--permission-mode\", \"dontAsk\"] };\n const args: string[] = [];\n if (caps.hasMode)\n args.push(\n \"--permission-mode\",\n caps.modes.includes(\"manual\") && !caps.modes.includes(\"default\") ? \"manual\" : \"default\",\n );\n if (caps.promptsNone) args.push(\"--permission-prompts\", \"none\");\n return { args };\n}\n\n/** The env a headless turn runs with: ours, minus the markers that make Claude Code\n * think it runs inside another session, with CLAUDE_CONFIG_DIR naming the account. */\nexport function claudeEnv(configDir?: string, env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {\n const e = { ...env };\n for (const k of [\n \"CLAUDECODE\",\n \"CLAUDE_CODE_SESSION_ID\",\n \"CLAUDE_CODE_HOST_SESSION_ID\",\n \"CLAUDE_CODE_ENTRYPOINT\",\n \"CLAUDE_CODE_SESSION_ATTENDED\",\n \"CLAUDE_CODE_SSE_PORT\",\n ])\n delete e[k];\n e.SESSIONPIPE_CONTROL_JOB = \"1\";\n if (configDir !== undefined) {\n if (path.resolve(configDir) === path.resolve(os.homedir(), \".claude\")) delete e.CLAUDE_CONFIG_DIR;\n else e.CLAUDE_CONFIG_DIR = configDir;\n }\n return e;\n}\n\n/** Whether Claude Code is signed in for one account, in Claude Code's own words\n * (`claude auth status --json`). `loggedIn: null` means this Claude Code can't say\n * (too old for `auth status`, or it didn't answer): never a reason to refuse. */\nexport interface Login {\n loggedIn: boolean | null;\n /** claude.ai, an API key, a long-lived token\u2026 as Claude Code names it. */\n method?: string;\n subscription?: string;\n}\n\nexport function parseAuthStatus(stdout: string | null | undefined): Login {\n const text = String(stdout || \"\").trim();\n const start = text.indexOf(\"{\");\n if (start < 0) return { loggedIn: null };\n try {\n const j = JSON.parse(text.slice(start)) as Record<string, unknown>;\n if (typeof j.loggedIn !== \"boolean\") return { loggedIn: null };\n return {\n loggedIn: j.loggedIn,\n ...(typeof j.authMethod === \"string\" ? { method: j.authMethod } : {}),\n ...(typeof j.subscriptionType === \"string\" ? { subscription: j.subscriptionType } : {}),\n };\n } catch {\n return { loggedIn: null };\n }\n}\n\n/** Ask Claude Code whether the account in `configDir` (the default one when omitted)\n * is signed in, from this process \u2014 which is the point: a login kept in the macOS\n * keychain is readable from the screen's own session and not from a background\n * service on a Mac nobody is logged in to, or from an ssh shell, so a headless turn\n * started there dies with \"please run /login\". */\nexport function claudeLogin(bin: string, configDir?: string, env: NodeJS.ProcessEnv = process.env): Promise<Login> {\n return new Promise((resolve) => {\n execFile(\n bin,\n [\"auth\", \"status\", \"--json\"],\n { encoding: \"utf8\", timeout: 20_000, env: claudeEnv(configDir, env), maxBuffer: 256 * 1024 },\n // `auth status` may exit non-zero when signed out; its JSON still says so.\n (_err, stdout) => resolve(parseAuthStatus(stdout)),\n );\n });\n}\n\n/** The command that signs one account in, quoted for a sentence. */\nexport function loginCommand(configDir: string | undefined): string {\n const home = os.homedir();\n const isDefault = !configDir || path.resolve(configDir) === path.resolve(home, \".claude\");\n return isDefault ? \"`claude auth login`\" : `\\`CLAUDE_CONFIG_DIR=${configDir.replace(home, \"~\")} claude auth login\\``;\n}\n\n/** What to tell the person when an account isn't signed in for the daemon. */\nexport function loginHint(configDir: string | undefined, platform: NodeJS.Platform = process.platform): string {\n const shown = configDir ? configDir.replace(os.homedir(), \"~\") : \"~/.claude\";\n const login = loginCommand(configDir);\n if (platform === \"darwin\")\n return `Claude Code (${shown}) isn't signed in as this machine's background service sees it. On a Mac its login lives in the login keychain, which a background service can read only while someone is logged in at the screen: log in at the Mac, or run ${login} there.`;\n return `Claude Code (${shown}) isn't signed in on this machine: run ${login} there.`;\n}\n\nexport function detectCaps(bin: string): Caps {\n let help = \"\";\n try {\n help = execFileSync(bin, [\"--help\"], {\n encoding: \"utf8\",\n timeout: 30_000,\n env: claudeEnv(),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n maxBuffer: 4 * 1024 * 1024,\n });\n } catch (e) {\n help = String((e as { stdout?: string })?.stdout || \"\");\n }\n return parseCaps(help);\n}\n\nexport interface Transcript {\n file: string;\n configDir: string;\n project: string;\n}\n\n/** <config dir>/projects/<folder>/<session>.jsonl in any Claude Code config dir. */\nexport function findTranscript(session: string, dirs: string[]): Transcript | null {\n if (!UUID_RE.test(session)) return null;\n for (const dir of dirs) {\n let projects: import(\"node:fs\").Dirent[] = [];\n try {\n projects = readdirSync(path.join(dir, \"projects\"), { withFileTypes: true });\n } catch {\n continue;\n }\n for (const p of projects) {\n if (!p.isDirectory()) continue;\n const file = path.join(dir, \"projects\", p.name, `${session}.jsonl`);\n try {\n if (statSync(file).isFile()) return { file, configDir: dir, project: p.name };\n } catch {}\n }\n }\n return null;\n}\n\nconst projectName = (cwd: string) => cwd.replace(/[^a-zA-Z0-9]/g, \"-\");\n\n/** The folder a session runs in, from its transcript's own records (never from a\n * command): the `cwd` whose project name is the folder the transcript is filed\n * under, else the first `cwd`. Streams; a line over 2 MB is skipped. */\nexport function sessionFolder(t: Transcript, cap = 8 * 1024 * 1024): string | null {\n let first: string | null = null;\n let count = 0;\n let fd: number | undefined;\n const look = (line: Buffer): string | null => {\n if (line.indexOf('\"cwd\"') < 0) return null;\n let j: { cwd?: unknown };\n try {\n j = JSON.parse(line.toString(\"utf8\"));\n } catch {\n return null;\n }\n if (!j || typeof j.cwd !== \"string\" || !path.isAbsolute(j.cwd)) return null;\n if (projectName(j.cwd) === t.project) return j.cwd;\n first ??= j.cwd;\n count++;\n return null;\n };\n try {\n fd = openSync(t.file, \"r\");\n const buf = Buffer.alloc(256 * 1024);\n let pos = 0;\n let rest = Buffer.alloc(0);\n let skipping = false;\n while (pos < cap && count < 50) {\n const n = readSync(fd, buf, 0, buf.length, pos);\n if (!n) {\n if (!skipping && rest.length) {\n const hit = look(rest);\n if (hit) return hit;\n }\n break;\n }\n pos += n;\n let chunk = rest.length ? Buffer.concat([rest, buf.subarray(0, n)]) : buf.subarray(0, n);\n let nl = chunk.indexOf(10);\n while (nl >= 0) {\n const line = chunk.subarray(0, nl);\n chunk = chunk.subarray(nl + 1);\n if (skipping) skipping = false;\n else {\n const hit = look(line);\n if (hit) return hit;\n }\n nl = chunk.indexOf(10);\n }\n if (chunk.length > 2 * 1024 * 1024) {\n skipping = true;\n rest = Buffer.alloc(0);\n } else rest = skipping ? Buffer.alloc(0) : Buffer.from(chunk);\n }\n } catch {\n } finally {\n if (fd !== undefined)\n try {\n closeSync(fd);\n } catch {}\n }\n return first;\n}\n\nfunction pidAlive(pid: number): boolean {\n if (!Number.isSafeInteger(pid) || pid <= 1) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n return (e as { code?: string }).code === \"EPERM\";\n }\n}\n\n/** A Claude Code process holds this session right now: its registry file,\n * <config>/sessions/<pid>.json, names it and the pid is alive (interactive and\n * Agent SDK sessions both file one). */\nexport function liveProcess(session: string, configDir: string): boolean {\n let names: string[] = [];\n try {\n names = readdirSync(path.join(configDir, \"sessions\")).filter((n) => /^\\d+\\.json$/.test(n));\n } catch {\n return false;\n }\n for (const n of names) {\n try {\n const j = JSON.parse(readFileSync(path.join(configDir, \"sessions\", n), \"utf8\")) as {\n sessionId?: unknown;\n pid?: unknown;\n };\n if (String(j.sessionId) !== session) continue;\n if (pidAlive(Number(j.pid ?? n.slice(0, -5)))) return true;\n } catch {}\n }\n return false;\n}\n\n/** Written in the last 90 s, and not by a job of ours. */\nexport function recentlyWritten(file: string, ourLastEnd?: number, now = Date.now()): boolean {\n let m: number;\n try {\n m = statSync(file).mtimeMs;\n } catch {\n return false;\n }\n if (now - m > LIVE_WRITE_MS) return false;\n return !(ourLastEnd && m <= ourLastEnd + 2000);\n}\n\nexport interface RunResult {\n error?: string;\n code?: number | null;\n signal?: NodeJS.Signals | null;\n stdout?: string | null;\n tooBig?: boolean;\n stderr?: string;\n timedOut?: boolean;\n}\n\n/** Run one headless turn in its own process group, holding at most 1 MB of stdout. */\nexport function runClaude(\n bin: string,\n args: string[],\n o: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeoutMs?: number;\n /** Streaming (`--output-format stream-json`): each stdout line as it arrives. Only\n * the `result` line is kept for the RunResult, so a long stream never hits the cap. */\n onLine?: (line: string) => void;\n },\n): Promise<RunResult> {\n return new Promise((resolve) => {\n let out: Buffer[] = [];\n let outLen = 0;\n let tooBig = false;\n let errTail = \"\";\n let timedOut = false;\n let settled = false;\n let child: import(\"node:child_process\").ChildProcess;\n try {\n child = spawn(bin, args, {\n cwd: o.cwd,\n env: o.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: process.platform !== \"win32\",\n windowsHide: true,\n });\n } catch (e) {\n resolve({ error: (e as Error).message });\n return;\n }\n const kill = (sig: NodeJS.Signals) => {\n try {\n if (process.platform !== \"win32\" && child.pid) process.kill(-child.pid, sig);\n else child.kill(sig);\n } catch {\n try {\n child.kill(sig);\n } catch {}\n }\n };\n let partial = \"\";\n child.stdout?.on(\"data\", (b: Buffer) => {\n if (o.onLine) {\n const chunk = partial + b.toString(\"utf8\");\n const lines = chunk.split(\"\\n\");\n partial = lines.pop() ?? \"\";\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n o.onLine(line);\n } catch {}\n if (line.includes('\"type\":\"result\"')) {\n out = [Buffer.from(line)];\n outLen = line.length;\n }\n }\n if (partial.length > OUT_CAP) partial = \"\";\n return;\n }\n if (tooBig) return;\n if (outLen + b.length > OUT_CAP) {\n tooBig = true;\n out = [];\n return;\n }\n out.push(b);\n outLen += b.length;\n });\n child.stderr?.on(\"data\", (b: Buffer) => {\n errTail = (errTail + b.toString(\"utf8\")).slice(-4000);\n });\n const timer = setTimeout(() => {\n timedOut = true;\n kill(\"SIGTERM\");\n setTimeout(() => kill(\"SIGKILL\"), 10_000).unref();\n }, o.timeoutMs ?? JOB_TIMEOUT_MS);\n const result = (code: number | null, signal: NodeJS.Signals | null): RunResult => ({\n code,\n signal,\n stdout: tooBig ? null : Buffer.concat(out).toString(\"utf8\"),\n tooBig,\n stderr: errTail,\n timedOut,\n });\n const finish = (r: RunResult) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(r);\n };\n child.on(\"error\", (e) => finish({ error: e.message }));\n // A tool the agent left running can hold stdout open after Claude Code exits.\n child.on(\"exit\", (code, signal) => setTimeout(() => finish(result(code, signal)), 2000).unref());\n child.on(\"close\", (code, signal) => {\n // The last line may end without a newline: it is often the result itself.\n if (o.onLine && partial.trim()) {\n try {\n o.onLine(partial);\n } catch {}\n if (partial.includes('\"type\":\"result\"')) {\n out = [Buffer.from(partial)];\n outLen = partial.length;\n }\n partial = \"\";\n }\n finish(result(code, signal));\n });\n });\n}\n\nexport interface ClaudeResult {\n type?: string;\n result?: unknown;\n is_error?: boolean;\n subtype?: string;\n session_id?: unknown;\n permission_denials?: { tool_name?: unknown }[];\n}\n\n/** `--output-format json`: one result object, or an array whose last `result` entry it is. */\nexport function parseResult(stdout: string | null | undefined): ClaudeResult | null {\n const s = String(stdout || \"\").trim();\n if (!s) return null;\n const pick = (j: unknown): ClaudeResult | null => {\n if (Array.isArray(j)) {\n for (let i = j.length - 1; i >= 0; i--) if (j[i]?.type === \"result\") return j[i];\n return null;\n }\n return j && typeof j === \"object\" ? (j as ClaudeResult) : null;\n };\n try {\n return pick(JSON.parse(s));\n } catch {}\n const lines = s.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n try {\n const j = pick(JSON.parse(lines[i] as string));\n if (j && (j.type === \"result\" || \"result\" in j)) return j;\n } catch {}\n }\n return null;\n}\n\nexport const isUuid = (s: unknown): s is string => typeof s === \"string\" && UUID_RE.test(s);\n", "// SPDX-License-Identifier: Apache-2.0\n// The registry: the only place that lists vendors. A new harness is one file here\n// plus its fixtures and its row in spec/ADAPTERS.md.\nimport { antigravity } from \"./antigravity.js\";\nimport { claudeCode } from \"./claude-code.js\";\nimport { codex } from \"./codex.js\";\nimport { geminiCli } from \"./gemini-cli.js\";\nimport type { Adapter } from \"./types.js\";\n\nexport const ADAPTERS: readonly Adapter[] = [claudeCode, codex, geminiCli, antigravity];\nexport const adapterByName = (name: string): Adapter | undefined => ADAPTERS.find((a) => a.name === name);\nexport { claudeDirs } from \"./claude-code.js\";\nexport * as claudeControl from \"./claude-code-control.js\";\nexport type {\n Adapter,\n AdapterEvent,\n BackfillRow,\n FactsState,\n HookCommand,\n HookInput,\n HookResult,\n InstallReport,\n SessionFacts,\n TranscriptRead,\n Turn,\n} from \"./types.js\";\nexport { antigravity, claudeCode, codex, geminiCli };\n", "// SPDX-License-Identifier: Apache-2.0\n// ~/.config/sessionpipe/config.json, mode 0600: the machine's name, the sinks with\n// their tier and token, per-harness switches, the update check.\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { configFile } from \"./paths.js\";\nimport type { Tier } from \"./types.js\";\n\nexport interface SinkConfig {\n name: string;\n /** https://\u2026, file:PATH, stdout, otlp:URL */\n url: string;\n tier: Tier;\n pii?: boolean;\n /** @deprecated Never set: control is per machine (spec/CONTROL.md \u00A72). Kept so an\n * older config still reads. */\n control?: boolean;\n token?: string;\n /** whsec_\u2026 for Standard Webhooks signatures. */\n secret?: string;\n /** The token (and secret) live in this store instead of in this file; the client\n * reads them from it when it sends. */\n token_in?: \"keychain\" | \"secret-service\";\n /** Learned from the receiver's well-known file; re-read daily. */\n max_tier?: Tier;\n well_known_at?: string;\n paused?: string;\n}\n\nexport interface Config {\n machine?: string;\n sinks: SinkConfig[];\n harnesses: Record<string, { enabled?: boolean; created?: string[] }>;\n update_check?: boolean;\n keep_days?: number;\n}\n\nexport const DEFAULT_CONFIG: Config = { sinks: [], harnesses: {}, update_check: true, keep_days: 30 };\n\nexport function readConfig(file: string = configFile()): Config {\n try {\n const j = JSON.parse(readFileSync(file, \"utf8\")) as Partial<Config>;\n return {\n ...DEFAULT_CONFIG,\n ...j,\n sinks: Array.isArray(j.sinks) ? j.sinks : [],\n harnesses: j.harnesses && typeof j.harnesses === \"object\" ? j.harnesses : {},\n };\n } catch {\n return { ...DEFAULT_CONFIG, sinks: [], harnesses: {} };\n }\n}\n\nexport function writeConfig(c: Config, file: string = configFile()): void {\n mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });\n writeFileSync(file, `${JSON.stringify(c, null, 2)}\\n`, { mode: 0o600 });\n if (process.platform !== \"win32\" && existsSync(file)) {\n try {\n chmodSync(file, 0o600);\n } catch {}\n }\n}\n\n/** The machine's name: what the person configured, else the hostname without a\n * local suffix. Never guessed from anything else (a hand-typed name once linked 64\n * versions to nothing). */\nexport function machineName(c: Config, hostname: string): string {\n if (c.machine) return String(c.machine).slice(0, 80);\n return hostname.replace(/\\.(local|lan|home)$/i, \"\");\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// ULID: 48-bit ms timestamp + 80 random bits, Crockford base32. Monotonic within a\n// process so two events in the same millisecond still sort in emit order.\nimport { randomBytes } from \"node:crypto\";\n\nconst ALPHABET = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\nlet lastTime = 0;\nlet lastRand: number[] = [];\n\nfunction encodeTime(t: number): string {\n let out = \"\";\n let n = t;\n for (let i = 0; i < 10; i++) {\n out = ALPHABET[n % 32] + out;\n n = Math.floor(n / 32);\n }\n return out;\n}\n\nexport function ulid(now: number = Date.now()): string {\n if (now === lastTime) {\n // increment the random part\n for (let i = lastRand.length - 1; i >= 0; i--) {\n const v = (lastRand[i] ?? 0) + 1;\n if (v < 32) {\n lastRand[i] = v;\n break;\n }\n lastRand[i] = 0;\n }\n } else {\n lastTime = now;\n const b = randomBytes(16);\n lastRand = Array.from({ length: 16 }, (_, i) => (b[i] ?? 0) % 32);\n }\n return encodeTime(now) + lastRand.map((v) => ALPHABET[v]).join(\"\");\n}\n\nexport const isUlid = (s: string): boolean => /^[0-9A-HJKMNP-TV-Z]{26}$/.test(s);\n", "// SPDX-License-Identifier: Apache-2.0\n// From an adapter's output to a protocol event: id, time, the full session block\n// as known now, and the raw (tier 3) data. Filtering per sink happens later.\nimport type { AdapterEvent } from \"./adapters/types.js\";\nimport type { Event, Session } from \"./types.js\";\nimport { ulid } from \"./ulid.js\";\n\nexport interface EventContext {\n harness: { name: string; version?: string };\n session: Session;\n now?: number;\n}\n\nexport function makeEvent(a: AdapterEvent, ctx: EventContext): Event {\n const now = ctx.now ?? Date.now();\n const harness: Event[\"harness\"] = { name: ctx.harness.name, event: a.harnessEvent };\n if (ctx.harness.version) harness.version = ctx.harness.version;\n return {\n protocol: 1,\n id: ulid(now),\n type: a.type,\n time: new Date(now).toISOString(),\n tier: 3,\n harness,\n session: ctx.session,\n privacy: { rulesets: [], pii: false },\n data: a.data,\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The outbox: append-only JSONL per (harness, session) under\n// <state>/outbox/<harness>/<session>.jsonl, a per-session seq counter, a per-sink\n// cursor that moves only when the sink acknowledged, and a per-session lock so two\n// workers never interleave. Never lose, never duplicate.\nimport {\n appendFileSync,\n closeSync,\n existsSync,\n mkdirSync,\n openSync,\n readdirSync,\n readFileSync,\n readSync,\n renameSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport path from \"node:path\";\nimport { safeId } from \"./paths.js\";\nimport type { Event } from \"./types.js\";\n\nexport interface OutboxRef {\n harness: string;\n session: string;\n}\n\nexport class Outbox {\n constructor(readonly root: string) {}\n\n dir(harness: string): string {\n return path.join(this.root, \"outbox\", safeId(harness));\n }\n file(ref: OutboxRef): string {\n return path.join(this.dir(ref.harness), `${safeId(ref.session)}.jsonl`);\n }\n private seqFile(ref: OutboxRef): string {\n return path.join(this.dir(ref.harness), `${safeId(ref.session)}.seq`);\n }\n\n /** The next seq for a session, persisted (survives a hibernating machine and a\n * restart; an in-memory counter would restart at 0 and collide). */\n nextSeq(ref: OutboxRef): number {\n const f = this.seqFile(ref);\n let n = 0;\n try {\n n = Number(readFileSync(f, \"utf8\")) || 0;\n } catch {\n // A missing counter with an existing outbox: recover from the file's last line.\n n = this.lastSeqInFile(ref) + 1;\n }\n mkdirSync(path.dirname(f), { recursive: true, mode: 0o700 });\n writeFileSync(f, String(n + 1), { mode: 0o600 });\n return n;\n }\n\n private lastSeqInFile(ref: OutboxRef): number {\n const f = this.file(ref);\n if (!existsSync(f)) return -1;\n const lines = readFileSync(f, \"utf8\").trim().split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n try {\n const j = JSON.parse(lines[i] ?? \"\") as Event;\n if (typeof j.session?.seq === \"number\") return j.session.seq;\n } catch {}\n }\n return -1;\n }\n\n append(ref: OutboxRef, events: Event[]): void {\n if (!events.length) return;\n mkdirSync(this.dir(ref.harness), { recursive: true, mode: 0o700 });\n appendFileSync(this.file(ref), `${events.map((e) => JSON.stringify(e)).join(\"\\n\")}\\n`, { mode: 0o600 });\n }\n\n /** Every session file, newest first. */\n sessions(): OutboxRef[] {\n const out: { ref: OutboxRef; mtime: number }[] = [];\n const base = path.join(this.root, \"outbox\");\n if (!existsSync(base)) return [];\n for (const h of readdirSync(base)) {\n const d = path.join(base, h);\n let names: string[] = [];\n try {\n names = readdirSync(d).filter((n) => n.endsWith(\".jsonl\"));\n } catch {\n continue;\n }\n for (const n of names) {\n try {\n out.push({ ref: { harness: h, session: n.slice(0, -6) }, mtime: statSync(path.join(d, n)).mtimeMs });\n } catch {}\n }\n }\n return out.sort((a, b) => b.mtime - a.mtime).map((x) => x.ref);\n }\n\n /** Read events after byte offset `from`; returns them and the new offset. Lines\n * are read whole; a partial trailing line (a write in progress) is left. */\n read(ref: OutboxRef, from: number, maxEvents = 500): { events: Event[]; offset: number } {\n const f = this.file(ref);\n if (!existsSync(f)) return { events: [], offset: from };\n const size = statSync(f).size;\n if (from >= size) return { events: [], offset: from };\n const fd = openSync(f, \"r\");\n try {\n const buf = Buffer.alloc(Math.min(size - from, 8 * 1024 * 1024));\n const n = readSync(fd, buf, 0, buf.length, from);\n const text = buf.subarray(0, n).toString(\"utf8\");\n const events: Event[] = [];\n let offset = from;\n let pos = 0;\n while (events.length < maxEvents) {\n const nl = text.indexOf(\"\\n\", pos);\n if (nl < 0) break;\n const line = text.slice(pos, nl);\n pos = nl + 1;\n offset = from + Buffer.byteLength(text.slice(0, pos), \"utf8\");\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as Event);\n } catch {}\n }\n return { events, offset };\n } finally {\n closeSync(fd);\n }\n }\n\n /** Files older than `days` are pruned; the cursor files with them. */\n prune(days: number, now = Date.now()): number {\n let n = 0;\n const cutoff = now - days * 86_400_000;\n for (const ref of this.sessions()) {\n const f = this.file(ref);\n try {\n if (statSync(f).mtimeMs < cutoff) {\n unlinkSync(f);\n try {\n unlinkSync(this.seqFile(ref));\n } catch {}\n n++;\n }\n } catch {}\n }\n return n;\n }\n\n delete(ref: OutboxRef): void {\n for (const f of [this.file(ref), this.seqFile(ref)]) {\n try {\n unlinkSync(f);\n } catch {}\n }\n }\n}\n\n/** Per-sink cursor: byte offset per session file, moved only on a 2xx. */\nexport class Cursors {\n constructor(\n readonly root: string,\n readonly sink: string,\n ) {}\n private file(): string {\n return path.join(this.root, \"cursors\", `${safeId(this.sink)}.json`);\n }\n read(): Record<string, number> {\n try {\n return JSON.parse(readFileSync(this.file(), \"utf8\")) as Record<string, number>;\n } catch {\n return {};\n }\n }\n write(c: Record<string, number>): void {\n const f = this.file();\n mkdirSync(path.dirname(f), { recursive: true, mode: 0o700 });\n const tmp = `${f}.${process.pid}.tmp`;\n writeFileSync(tmp, JSON.stringify(c), { mode: 0o600 });\n renameSync(tmp, f);\n }\n key(ref: OutboxRef): string {\n return `${ref.harness}/${ref.session}`;\n }\n}\n\n/** A lock per session so two workers never interleave. Stale after 5 min. */\nexport function takeLock(root: string, ref: OutboxRef, staleMs = 5 * 60_000): (() => void) | null {\n const dir = path.join(root, \"locks\");\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n const f = path.join(dir, `${safeId(ref.harness)}-${safeId(ref.session)}.lock`);\n try {\n if (Date.now() - statSync(f).mtimeMs > staleMs) unlinkSync(f);\n else return null;\n } catch {}\n try {\n writeFileSync(f, String(process.pid), { flag: \"wx\" });\n } catch {\n return null;\n }\n return () => {\n try {\n unlinkSync(f);\n } catch {}\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// pii@1 \u2014 an opt-in second pass that reduces identifiers (spec/PRIVACY.md \u00A72). It\n// does not promise anonymity; it removes the obvious.\nimport { createHash } from \"node:crypto\";\n\nexport const RULESET_PII = \"pii@1\";\n\nconst EMAIL = /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/g;\n/** E.164 and common national forms: an optional +, 7\u201315 digits with separators,\n * optional area-code parentheses. A version number (22.23.1) or an IP never matches:\n * the run must not sit between dots, and needs \u2265 7 digits. */\nconst PHONE = /(?<![\\w.])(?:\\+\\d{1,3}[ .-]?)?(?:\\(\\d{2,4}\\)[ .-]?)?\\d{2,4}(?:[ .-]?\\d{2,4}){1,3}(?!\\w)/g;\n\nfunction looksPhone(s: string): boolean {\n const digits = s.replace(/\\D/g, \"\");\n if (digits.length < 7 || digits.length > 15) return false;\n // \"port 8891, pr 12345\": a bare run with no separator or + is a number, not a phone.\n if (!/[+() .-]/.test(s)) return false;\n // \"22.23.1\", \"185.199.108.153\": dots alone are a version or an address.\n if (!/[+() -]/.test(s)) return false;\n return true;\n}\n\n/** Replace emails and phone numbers, and write `home` as `~`. */\nexport function reducePii(text: string, home?: string): string {\n if (!text) return text;\n let out = text.replace(EMAIL, \"[email]\");\n out = out.replace(PHONE, (m) => (looksPhone(m) ? \"[phone]\" : m));\n if (home) {\n const h = home.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n out = out.replace(new RegExp(`(?<![A-Za-z0-9_])${h}(?=/|$|\\\\s|[\"'\\`])`, \"g\"), \"~\");\n }\n return out;\n}\n\n/** The machine's name under pii@1: the first 8 hex of its SHA-256. */\nexport function hashMachine(name: string): string {\n return createHash(\"sha256\").update(name).digest(\"hex\").slice(0, 8);\n}\n\n/** Apply pii@1 to every string in a value; `home` becomes `~`. */\nexport function reducePiiDeep<T>(v: T, home?: string): T {\n if (typeof v === \"string\") return reducePii(v, home) as T;\n if (Array.isArray(v)) return v.map((x) => reducePiiDeep(x, home)) as T;\n if (v && typeof v === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, x] of Object.entries(v as Record<string, unknown>)) out[k] = reducePiiDeep(x, home);\n return out as T;\n }\n return v;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// secrets@1 \u2014 credentials out of every string, on the person's machine, before an\n// event reaches the outbox. Ported from spacesheep-cli lib/redact.js (Michael\n// Makarov, MIT \u2192 Apache-2.0, see NOTICE). The ruleset is defined in\n// spec/PRIVACY.md \u00A72 and pinned by conformance/redaction/secrets.json.\n//\n// Every pattern is linear: bounded repetition, no nested quantifiers. The\n// adversarial vectors (password_ \u00D7 5000, a 50 000-space run) pin that.\n\nexport const RULESET_SECRETS = \"secrets@1\";\nexport const REDACTED = \"[redacted]\";\n\n/** Token formats that are a credential by their shape alone. Each is anchored on a\n * vendor prefix, so a commit sha or a UUID never matches. */\nconst TOKEN_PATTERNS: RegExp[] = [\n /-----BEGIN [A-Z0-9 ]*PRIVATE KEY(?: BLOCK)?-----[\\s\\S]*?(?:-----END [A-Z0-9 ]*PRIVATE KEY(?: BLOCK)?-----|$)/g,\n /\\b(?:AKIA|ASIA|ABIA|ACCA)[0-9A-Z]{16}\\b/g, // AWS access key id\n /\\bgh[pousr]_[A-Za-z0-9]{30,}\\b/g, // GitHub\n /\\bgithub_pat_[A-Za-z0-9_]{30,}\\b/g,\n /\\bglpat-[A-Za-z0-9_-]{20,}\\b/g, // GitLab\n /\\bxox[abposre]-[A-Za-z0-9-]{10,}\\b/g, // Slack\n /\\bhttps:\\/\\/hooks\\.slack\\.com\\/services\\/[A-Za-z0-9/_-]+/g,\n /\\bhttps:\\/\\/(?:ptb\\.|canary\\.)?discord(?:app)?\\.com\\/api\\/webhooks\\/[0-9]+\\/[A-Za-z0-9_-]+/g,\n /\\bsk-(?:ant-|proj-|svcacct-|admin-|or-v1-)?[A-Za-z0-9_-]{20,}\\b/g, // Anthropic, OpenAI, DeepSeek, OpenRouter\n /\\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\\b/g, // Stripe secret / restricted\n /\\bwhsec_[A-Za-z0-9+/=]{20,}/g, // Stripe / Svix / Standard Webhooks secret\n /\\bAIza[0-9A-Za-z_-]{35}\\b/g, // Google API key\n /\\bya29\\.[0-9A-Za-z_-]{20,}/g, // Google OAuth access token\n /\\b1\\/\\/0[0-9A-Za-z_-]{30,}/g, // Google OAuth refresh token\n /\\bGOCSPX-[0-9A-Za-z_-]{20,}/g, // Google OAuth client secret\n /\\bxai-[A-Za-z0-9]{30,}\\b/g,\n /\\bgsk_[A-Za-z0-9]{30,}\\b/g, // Groq\n /\\bpplx-[A-Za-z0-9]{30,}\\b/g, // Perplexity\n /\\bhf_[A-Za-z0-9]{30,}\\b/g, // Hugging Face\n /\\bpcsk_[A-Za-z0-9_]{30,}\\b/g, // Pinecone\n /\\bnpm_[A-Za-z0-9]{30,}\\b/g,\n /\\bpypi-[A-Za-z0-9_-]{50,}/g,\n /\\bSG\\.[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}/g, // SendGrid\n /\\bshp(?:at|ss|ca|pa)_[a-fA-F0-9]{32}\\b/g, // Shopify\n /\\bdop_v1_[a-f0-9]{64}\\b/g, // DigitalOcean\n /\\b(?:lin_api|lin_oauth)_[A-Za-z0-9]{30,}\\b/g, // Linear\n /\\b(?:ntn|secret)_[A-Za-z0-9]{40,}\\b/g, // Notion\n /\\bsbp_[a-f0-9]{40}\\b/g, // Supabase\n /\\bfigd_[A-Za-z0-9_-]{30,}/g, // Figma\n /\\bdp\\.(?:pt|st|sa|ct)\\.[A-Za-z0-9]{30,}/g, // Doppler\n /\\bgrn_[A-Za-z0-9_-]{20,}/g, // Granola\n /\\bss_[a-f0-9]{32,}\\b/g, // spacesheep API keys\n /\\b[0-9]{8,10}:AA[A-Za-z0-9_-]{33}\\b/g, // Telegram bot token\n /\\beyJ[A-Za-z0-9_-]{10,}\\.eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}/g, // JWT\n];\n/** `scheme://user:password@host` \u2014 the password goes, the user and host stay. */\nconst URL_CREDENTIALS = /\\b([a-z][a-z0-9+.-]{1,20}:\\/\\/[^\\s:/@'\"`<>]{1,100}:)([^\\s@/'\"`<>]{1,200})(@)/gi;\n/** `Authorization: Bearer \u2026` / `Basic \u2026`, and a bare `Bearer <token>` in a curl line. */\nconst AUTH_HEADER = /\\b((?:Bearer|Basic|Token)\\s+)([A-Za-z0-9._~+/=-]{16,})/g;\n// The words that name a secret, in prose. `key` alone is too common (\"the key\n// point\"), so it only counts with a qualifier.\nconst SECRET_WORD =\n \"(?:pass(?:word|wd|phrase|code)?s?|pwd|secret(?:[ _-]?key)?s?|client[ _-]?secret|api[ _-]?keys?|apikeys?|access[ _-]?keys?|access[ _-]?tokens?|auth[ _-]?tokens?|refresh[ _-]?tokens?|private[ _-]?keys?|tokens?|credentials?|creds)\";\n/** Strict form: a NAME, an explicit separator (`=`, `:`, `=>`), a value. The name is\n * one flat run of identifier characters judged in code (isSecretName), never by a\n * nested pattern. Only a secret name goes on to consume its value \u2014 otherwise\n * `https:` would swallow the `?token=\u2026` behind it. */\nconst NAME_SEP = /(?<![A-Za-z0-9_])([A-Za-z][A-Za-z0-9_-]{1,79})([\"']?\\s{0,3}(?::=|=>|=|:)\\s{0,3})/g;\nconst VALUE = /\"([^\"\\n]{1,300})\"|'([^'\\n]{1,300})'|`([^`\\n]{1,300})`|([^\\s\"'`,;&)}\\]]{1,300})/y;\n\nfunction redactAssignments(text: string): string {\n let out = \"\";\n let last = 0;\n NAME_SEP.lastIndex = 0;\n for (let m = NAME_SEP.exec(text); m; m = NAME_SEP.exec(text)) {\n const name = m[1] ?? \"\";\n if (!isSecretName(name)) continue;\n VALUE.lastIndex = NAME_SEP.lastIndex;\n const v = VALUE.exec(text);\n if (!v) continue;\n const value = v[1] ?? v[2] ?? v[3] ?? v[4] ?? \"\";\n NAME_SEP.lastIndex = VALUE.lastIndex;\n if (isPlaceholder(value) || value.includes(REDACTED)) continue;\n // `max_tokens: 4096`, `input_tokens=12k` \u2014 a token COUNT, not a token.\n if (/tokens?$/i.test(name) && /^\\d+(?:[.,]\\d+)*[km]?$/i.test(value)) continue;\n const q = v[1] != null ? '\"' : v[2] != null ? \"'\" : v[3] != null ? \"`\" : \"\";\n out += text.slice(last, v.index) + q + REDACTED + q;\n last = VALUE.lastIndex;\n }\n return last ? out + text.slice(last) : text;\n}\n\n/** Is this identifier the name of a secret? `DB_PASSWORD`, `apiKey`, `client-secret`,\n * `AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`; an env-style `STRIPE_KEY` too. Not\n * `password_hash`, `tokenizer`, `sort_key`. */\nexport function isSecretName(name: string): boolean {\n if (/^[A-Z0-9_]+_KEY$/.test(name)) return true;\n const flat = name.toLowerCase().replace(/[_-]/g, \"\");\n return /(?:pass(?:word|wd|phrase|code)|pwd|secret|secretkey|secretaccesskey|clientsecret|apikey|accesskey|accesstoken|authtoken|refreshtoken|privatekey|token|credential|creds)s?$/.test(\n flat,\n );\n}\n\n/** Loose form: prose. \"password is Hunter2!\", \"the token was ghx\u2026\". Only a value\n * that looks generated counts, so \"the password is wrong\" passes untouched.\n * Whitespace runs are bounded so a long run can't make the match quadratic. */\nconst PROSE = new RegExp(\n `(\\\\b${SECRET_WORD}(?:[ \\\\t]{1,3}(?:is|was|=|:|to|as|of|for[ \\\\t]{1,3}\\\\S{1,40}[ \\\\t]{1,3}is))?[ \\\\t]{1,3})([\"'\\`]?)([^\\\\s\"'\\`]{6,200})\\\\2`,\n \"gi\",\n);\n\n/** A value that is plainly not the secret itself: a type, a variable, a template, an\n * already-redacted marker, an env lookup. */\nfunction isPlaceholder(v: string): boolean {\n const s = v.replace(/[.,;:!?]+$/, \"\");\n if (!s) return true;\n if (\n /^(?:string|number|boolean|bool|str|int|any|unknown|null|undefined|none|nil|true|false|optional|required|text|varchar|password|secret|token|env|string\\[\\]|object|bytes)$/i.test(\n s,\n )\n )\n return true;\n if (/^\\[?redacted\\]?$/i.test(s) || /^\\*+$/.test(s) || /^x{3,}$/i.test(s) || /^\\.{3}$|^\u2026$/.test(s)) return true;\n if (/^[<{$%]/.test(s)) return true; // <your-key>, ${VAR}, {{var}}, $VAR, %VAR%\n if (\n /^(?:process\\.env|env|os\\.environ|c\\.env|this\\.env|import\\.meta\\.env|getenv|config|settings|secrets|args|opts|options|req|request|body|params|input|data|user|self|this)\\b/i.test(\n s,\n )\n )\n return true;\n if (/^[A-Za-z_$][\\w$]*(?:\\.[A-Za-z_$][\\w$]*)+$/.test(s)) return true; // a member path: form.password\n if (/[(]/.test(s)) return true; // a call: hash(pw), getSecret()\n if (/^(?:your|my|the|a|an|some|new|old)[-_ ]/i.test(s)) return true; // your-api-key\n return false;\n}\n\n/** Does a prose value look like something generated, rather than an English word? */\nfunction looksSecret(v: string): boolean {\n const s = v.replace(/[.,;:!?)]+$/, \"\");\n if (s.length < 6) return false;\n if (isPlaceholder(s)) return false;\n if (/^https?:\\/\\//i.test(s)) return false; // a link, handled by URL_CREDENTIALS if it carries one\n if (/^[a-z]+(?:[-'][a-z]+)*$/.test(s)) return false; // a lowercase word\n if (/^[A-Z][a-z]+$/.test(s)) return false; // a capitalised word\n if (/^\\d+(?:[.,]\\d+)*[a-z%]*$/i.test(s)) return false; // a count: 4096, 128k, 3.5, 50%\n if (/^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/.test(s)) return false; // an env var's NAME\n const kinds = [/[a-z]/, /[A-Z]/, /[0-9]/, /[^A-Za-z0-9]/].filter((r) => r.test(s)).length;\n return kinds >= 3 || (/[0-9]/.test(s) && /[A-Za-z]/.test(s));\n}\n\n/** Redact every credential in `text`. Returns the same string when there is none. */\nexport function redactSecrets(text: string): string {\n if (!text) return text;\n let out = text;\n for (const re of TOKEN_PATTERNS) out = out.replace(re, REDACTED);\n out = out.replace(URL_CREDENTIALS, (_m, head: string, _pw: string, at: string) => `${head}${REDACTED}${at}`);\n out = out.replace(AUTH_HEADER, (m, head: string, v: string) => (v.includes(REDACTED) ? m : `${head}${REDACTED}`));\n out = redactAssignments(out);\n out = out.replace(PROSE, (m, head: string, q: string, v: string) =>\n !looksSecret(v) || v.includes(REDACTED) ? m : `${head}${q}${REDACTED}${q}`,\n );\n return out;\n}\n\n/** Did redaction change anything? */\nexport function hasSecret(text: string): boolean {\n return !!text && redactSecrets(text) !== text;\n}\n\n/** Redact every string in a JSON-able value (keys are left alone). */\nexport function redactDeep<T>(v: T): T {\n if (typeof v === \"string\") return redactSecrets(v) as T;\n if (Array.isArray(v)) return v.map(redactDeep) as T;\n if (v && typeof v === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, x] of Object.entries(v as Record<string, unknown>)) out[k] = redactDeep(x);\n return out as T;\n }\n return v;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// filter(event, tier, pii): the pure function every sink runs an event through.\n// Removes by ALLOWLIST per type and tier (spec/PRIVACY.md \u00A71), redacts every string\n// above tier 0 with secrets@1, and runs pii@1 when asked. Returns null when the\n// type is not carried at the tier. The conformance runner runs the same function.\nimport type { Event, Tier } from \"../types.js\";\nimport { hashMachine, RULESET_PII, reducePiiDeep } from \"./pii.js\";\nimport { RULESET_SECRETS, redactDeep } from \"./secrets.js\";\n\n/** The lowest tier that carries each known type (kept in step with schema/v1.ts). */\nexport const TYPE_TIER: Record<string, Tier> = {\n \"session.started\": 0,\n \"session.heartbeat\": 0,\n \"session.ended\": 0,\n \"session.backfill\": 0,\n \"session.forgotten\": 0,\n \"turn.started\": 0,\n \"turn.ended\": 0,\n \"turn.transcript\": 2,\n \"tool.started\": 1,\n \"tool.ended\": 1,\n \"files.changed\": 1,\n \"attention.needed\": 0,\n \"attention.cleared\": 0,\n \"subagent.started\": 1,\n \"subagent.ended\": 1,\n \"context.compacted\": 1,\n native: 3,\n};\n\n/** data keys allowed per type at tier N (cumulative: tier 1 includes tier 0's). */\nconst DATA_ALLOW: Record<string, Partial<Record<Tier, string[]>>> = {\n \"session.started\": { 0: [\"source\"] },\n \"session.heartbeat\": { 0: [] },\n \"session.ended\": { 0: [\"reason\"] },\n \"session.backfill\": { 0: [\"started_at\", \"last_at\", \"turns\"] },\n \"session.forgotten\": { 0: [] },\n \"turn.started\": { 0: [\"turn_id\"], 1: [\"prompt_chars\"] },\n \"turn.ended\": { 0: [\"turn_id\", \"reason\", \"ms\"], 1: [\"error\"] },\n \"turn.transcript\": { 2: [\"turn\", \"user\", \"assistant\", \"at\"] },\n \"tool.started\": { 1: [\"tool\", \"call_id\", \"turn_id\", \"agent_id\"], 3: [\"input\"] },\n \"tool.ended\": { 1: [\"tool\", \"call_id\", \"turn_id\", \"agent_id\", \"ms\", \"ok\", \"error\"], 3: [\"input\", \"output\"] },\n \"files.changed\": { 1: [\"paths\"] },\n \"attention.needed\": { 0: [\"attention_id\", \"kind\"], 1: [\"tool\", \"message\"] },\n \"attention.cleared\": { 0: [\"attention_id\", \"how\"] },\n \"subagent.started\": { 1: [\"agent_id\", \"agent_type\"] },\n \"subagent.ended\": { 1: [\"agent_id\", \"agent_type\"] },\n \"context.compacted\": { 1: [\"trigger\"] },\n};\n\nconst SESSION_ALLOW = [\n \"id\",\n \"seq\",\n \"machine\",\n \"cwd\",\n \"repo\",\n \"branch\",\n \"model\",\n \"title\",\n \"title_source\",\n \"url\",\n \"account_id\",\n \"parent_id\",\n];\nconst MAX_SIDE = 20_000;\nconst MAX_IO = 64 * 1024;\n\nfunction allowedKeys(type: string, tier: Tier): string[] | null {\n const table = DATA_ALLOW[type];\n if (!table) return null; // unknown type: kept whole (receivers keep extra keys), redacted\n const out: string[] = [];\n for (let t = 0; t <= tier; t++) for (const k of table[t as Tier] ?? []) out.push(k);\n return out;\n}\n\nfunction cap(v: unknown, max: number): unknown {\n if (typeof v === \"string\") return v.length > max ? `${v.slice(0, max)}\u2026` : v;\n if (v && typeof v === \"object\") {\n const s = JSON.stringify(v);\n return s.length > max ? `${s.slice(0, max)}\u2026` : v;\n }\n return v;\n}\n\nexport interface FilterOptions {\n /** The person's home directory, for pii@1's `~` rewrite. */\n home?: string;\n}\n\n/** The event as a sink at `tier` may see it, or null when the type is above the tier. */\nexport function filterEvent(event: Event, tier: Tier, pii: boolean, opts: FilterOptions = {}): Event | null {\n const minTier = TYPE_TIER[event.type];\n if (minTier !== undefined && minTier > tier) return null;\n if (event.type === \"native\" && tier < 3) return null;\n\n const session: Record<string, unknown> = {};\n for (const k of SESSION_ALLOW)\n if (event.session[k as keyof typeof event.session] !== undefined)\n session[k] = event.session[k as keyof typeof event.session];\n\n let data: Record<string, unknown> = {};\n const keys = allowedKeys(event.type, tier);\n if (keys === null) data = { ...event.data };\n else for (const k of keys) if (event.data[k] !== undefined) data[k] = event.data[k];\n if (typeof data.user === \"string\") data.user = cap(data.user, MAX_SIDE);\n if (typeof data.assistant === \"string\") data.assistant = cap(data.assistant, MAX_SIDE);\n if (data.input !== undefined) data.input = cap(data.input, MAX_IO);\n if (data.output !== undefined) data.output = cap(data.output, MAX_IO);\n if (typeof data.message === \"string\") data.message = cap(data.message, 200);\n\n const rulesets: string[] = [];\n let out: Event = { ...event, tier, session: session as Event[\"session\"], data, privacy: { rulesets, pii } };\n if (tier > 0) {\n // Redact, then the caps above already applied: a cut before redaction could leave half a key.\n out = { ...out, session: redactDeep(out.session), data: redactDeep(out.data) };\n rulesets.push(RULESET_SECRETS);\n }\n if (pii) {\n const s = reducePiiDeep(out.session, opts.home) as Record<string, unknown>;\n if (typeof s.machine === \"string\") s.machine = hashMachine(s.machine);\n delete s.account_id;\n out = { ...out, session: s as Event[\"session\"], data: reducePiiDeep(out.data, opts.home) };\n rulesets.push(RULESET_PII);\n }\n out.privacy = { rulesets, pii };\n return out;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// file:PATH \u2014 append filtered events as JSONL. The zero-server sink.\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Event, Tier } from \"../types.js\";\nimport type { DeliveryResult, Sink } from \"./types.js\";\n\nexport class FileSink implements Sink {\n constructor(\n readonly name: string,\n readonly file: string,\n readonly tier: Tier,\n readonly pii: boolean,\n ) {}\n async send(events: Event[]): Promise<DeliveryResult> {\n try {\n mkdirSync(path.dirname(this.file), { recursive: true });\n appendFileSync(this.file, `${events.map((e) => JSON.stringify(e)).join(\"\\n\")}\\n`);\n return { ok: true, acknowledged: events.length, accepted: events.length, duplicates: 0, rejected: [] };\n } catch (e) {\n return { ok: false, acknowledged: 0, error: String((e as Error).message), action: \"retry\" };\n }\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// stdout \u2014 one JSON line per event to a writable (the worker's stdout is ignored\n// when spawned by a hook, so this sink is for `sessionpipe tail` and tests).\nimport type { Event, Tier } from \"../types.js\";\nimport type { DeliveryResult, Sink } from \"./types.js\";\n\nexport class StdoutSink implements Sink {\n constructor(\n readonly name: string,\n readonly tier: Tier,\n readonly pii: boolean,\n private readonly write: (line: string) => void = (l) => process.stdout.write(`${l}\\n`),\n ) {}\n async send(events: Event[]): Promise<DeliveryResult> {\n for (const e of events) this.write(JSON.stringify(e));\n return { ok: true, acknowledged: events.length, accepted: events.length, duplicates: 0, rejected: [] };\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The pure half of `sessionpipe connect`: which folders a machine allows sessions you\n// message to run in, when nobody said. Never the home folder or anything above it:\n// \"allow everything I own\" is not a default anyone should find out about later.\nimport path from \"node:path\";\n\n/** The home folder, or a folder that contains it (/, /Users), or the filesystem root. */\nexport function isBroad(dir: string, home: string): boolean {\n const d = path.resolve(dir);\n const h = path.resolve(home);\n if (d === path.parse(d).root) return true;\n return d === h || h.startsWith(d.endsWith(path.sep) ? d : d + path.sep);\n}\n\nconst inside = (child: string, parent: string): boolean =>\n child !== parent && child.startsWith(parent.endsWith(path.sep) ? parent : parent + path.sep);\n\nexport interface FolderChoice {\n folders: string[];\n /** Where they came from: the flags, the machine's own list, the folder this ran in,\n * the folders recent sessions ran in, or nowhere. */\n from: \"flags\" | \"existing\" | \"here\" | \"recent\" | \"none\";\n}\n\n/** `recent`: the folders this machine's sessions ran in, newest first. */\nexport function connectFolders(o: {\n cwd: string;\n home: string;\n flags: string[];\n existing: string[];\n recent: string[];\n exists?: (dir: string) => boolean;\n max?: number;\n}): FolderChoice {\n if (o.flags.length) return { folders: o.flags.map((d) => path.resolve(d)), from: \"flags\" };\n if (o.existing.length) return { folders: [], from: \"existing\" };\n if (!isBroad(o.cwd, o.home)) return { folders: [path.resolve(o.cwd)], from: \"here\" };\n const exists = o.exists ?? (() => true);\n const picked: string[] = [];\n for (const raw of o.recent) {\n if (!raw || !path.isAbsolute(raw)) continue;\n const d = path.resolve(raw);\n if (isBroad(d, o.home) || picked.includes(d) || !exists(d)) continue;\n if (picked.some((p) => inside(d, p))) continue;\n // A wider folder replaces the narrower ones already picked under it.\n for (let i = picked.length - 1; i >= 0; i--) if (inside(picked[i] as string, d)) picked.splice(i, 1);\n picked.push(d);\n if (picked.length >= (o.max ?? 8)) break;\n }\n return picked.length ? { folders: picked, from: \"recent\" } : { folders: [], from: \"none\" };\n}\n\n/** The tier `connect` reports at: --tier when given; otherwise 2 (what a session board\n * needs: the asks and the answers, secrets removed), never lowering a sink set higher. */\nexport function connectTier(flag: string | undefined, current: number | undefined): 0 | 1 | 2 | 3 {\n if (flag !== undefined && flag !== \"\")\n return Math.max(0, Math.min(3, Math.trunc(Number(flag)) || 0)) as 0 | 1 | 2 | 3;\n return Math.max(2, Math.min(3, current ?? 0)) as 2 | 3;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// `sessionpipe control pair | keys | off | run | status` and `sessionpipe wait`.\nimport { existsSync, realpathSync, watchFile } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { claudeControl, claudeDirs, Outbox, readConfig, stateDir, type Tier, writeConfig } from \"@sessionpipe/core\";\n\nconst { claudeLogin, detectCaps, findClaude, runClaude } = claudeControl;\n\nimport { isBroad } from \"../connect.js\";\nimport { flush } from \"../run.js\";\nimport { rerunGlobally, stableNode, viaNpx } from \"../runtime.js\";\nimport { controlAccount, secretGet, sinkWithSecrets } from \"../secrets.js\";\nimport { ControlDaemon } from \"./daemon.js\";\nimport { ask, socketPath } from \"./local.js\";\nimport { installService, off, pair, removeKey, uninstallService } from \"./pair.js\";\nimport { loadSdk } from \"./sdk.js\";\nimport { controlFile, controlState, readControl, writeControl } from \"./store.js\";\nimport { waitForMessage, waitSession } from \"./wait.js\";\n\nexport const CONTROL_HELP = ` sessionpipe control pair <receiver> [--folder DIR]\u2026 [--mode safe|auto] [--tier 0-3] [--token T] [--name N] [--no-service]\n sessionpipe control mode auto|safe (how sessions run when you message them)\n sessionpipe control status | keys [remove <id>] | off [<receiver>] | run\n sessionpipe wait [--session <harness>:<id>] (a session runs this in the background)`;\n\nconst MODE_TEXT = ` auto Claude Code's auto mode: the session reads, edits and runs commands, and Claude Code's\n own safety check stops what looks dangerous. Pick this to get work done from your phone.\n safe Only what each folder's Claude Code settings already allow: with no allow rules, a\n session can't even read a file. Pick this if this machine holds things no agent\n should touch unattended.`;\n\n/** Ask the person at this machine, once: auto or safe. Not a terminal (an agent ran the\n * pair command): safe, and say how to change it. */\nasync function askMode(out: (s?: string) => void): Promise<\"safe\" | \"auto\"> {\n if (!process.stdin.isTTY) {\n out(\" Mode: safe for now. Run `sessionpipe control mode auto` to let sessions you message work unattended.\");\n return \"safe\";\n }\n out(\"\");\n out(\" When you message a session on this machine from your phone, how may it run?\");\n out(MODE_TEXT);\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n for (;;) {\n const a = (await rl.question(\" auto or safe? [auto] \")).trim().toLowerCase();\n if (a === \"\" || a === \"a\" || a === \"auto\") return \"auto\";\n if (a === \"s\" || a === \"safe\") return \"safe\";\n }\n } finally {\n rl.close();\n }\n}\n\nexport async function controlMain(argv: string[], out: (s?: string) => void, distDir: string): Promise<void> {\n const flag = (n: string) => {\n const i = argv.indexOf(n);\n return i >= 0 ? argv[i + 1] : undefined;\n };\n const flags = (n: string) => argv.flatMap((a, i) => (a === n && argv[i + 1] ? [argv[i + 1] as string] : []));\n const sub = argv[1];\n switch (sub) {\n case \"pair\": {\n // `spacesheep.dev` is enough: a bare host means https.\n const raw = argv[2];\n if (!raw || raw.startsWith(\"-\")) return out(`usage:\\n${CONTROL_HELP}`);\n if (viaNpx(distDir)) return rerunGlobally(argv, out);\n const url = (/^https?:\\/\\//.test(raw) ? raw : `https://${raw}`).replace(/\\/$/, \"\");\n const cfg = readConfig();\n const sink = cfg.sinks.find((s) => s.url.replace(/\\/$/, \"\") === url);\n // No token is fine where the receiver offers open pairing: the person approves the\n // link signed in, and that is the whole setup.\n const token = flag(\"--token\") ?? (sink ? sinkWithSecrets(sink)?.token : undefined) ?? null;\n if (token !== null && !/^[\\x21-\\x7e]+$/.test(token))\n return out(\n \" That token has a character a key never has (a placeholder like ss_\u2026 pasted as is?). Leave --token out to pair with a link instead.\",\n );\n const folders = flags(\"--folder\");\n const existing = readControl();\n // The folder this ran in \u2014 unless that is the home folder or above it, which\n // would let a message start a session anywhere you own.\n if (!folders.length && !existing?.folders.length) {\n if (!isBroad(process.cwd(), os.homedir())) folders.push(process.cwd());\n else\n out(\n ` ! Not allowing all of ${process.cwd()}: sessions you message may run only in folders you name. Pass --folder <project>, or run this from inside one.`,\n );\n }\n // How sessions run when a message arrives is the person's call, asked once here at\n // the machine \u2014 never a default they find out about when a session can't read a file.\n const mode: \"safe\" | \"auto\" =\n flag(\"--mode\") === \"auto\" || flag(\"--mode\") === \"safe\"\n ? (flag(\"--mode\") as \"safe\" | \"auto\")\n : existing?.mode && existing.receivers.length\n ? existing.mode\n : await askMode(out);\n const tier = argv.includes(\"--tier\") ? (Math.max(0, Math.min(3, Number(flag(\"--tier\")) || 0)) as Tier) : 0;\n await pair({\n url,\n token,\n // The key the receiver handed over at pairing becomes this machine's sink for it,\n // at --tier (0 \u2014 session state only \u2014 unless given), unless one is configured.\n addSink: (t) => {\n const r = adoptSinkToken(url, t, tier);\n if (r === \"kept\") return;\n out(\n r === \"filled\"\n ? ` \u2713 Sink ${new URL(url).host} now carries the key the receiver handed over.`\n : tier >= 2\n ? ` \u2713 Sink ${new URL(url).host} added at tier ${tier}.`\n : ` \u2713 Sink ${new URL(url).host} added (tier ${tier}: ${tier ? \"tool activity\" : \"session state\"}, no conversation text). \\`sessionpipe sink add ${url} --tier 2\\` sends transcripts too.`,\n );\n },\n folders,\n mode,\n name: flag(\"--name\") ?? existing?.name ?? cfg.machine ?? os.hostname(),\n out,\n });\n const c = readControl()!;\n out(` Folders sessions may run in: ${c.folders.join(\", \")}`);\n out(\n ` Mode: ${c.mode} (${c.mode === \"safe\" ? \"nothing that needs approval runs unattended\" : \"Claude Code's auto mode\"})`,\n );\n let cli = path.join(distDir, \"cli.js\");\n try {\n cli = realpathSync(cli);\n } catch {}\n if (argv.includes(\"--no-service\"))\n out(\" Daemon: not installed as a service (--no-service); run `sessionpipe control run` yourself\");\n else out(` Daemon: ${installService({ node: stableNode(process.execPath), cli })}`);\n return;\n }\n case \"mode\": {\n const want = argv[2];\n if (want !== \"auto\" && want !== \"safe\") {\n const c = readControl();\n return out(` mode: ${c?.mode ?? \"not set up\"}\\n usage: sessionpipe control mode auto|safe\\n${MODE_TEXT}`);\n }\n const c = readControl();\n if (!c) return out(\" control isn't set up on this machine: run `sessionpipe control pair <receiver>` first\");\n c.mode = want;\n writeControl(c);\n // The running daemon reads control.json again within seconds; the next run uses it.\n return out(\n ` \u2713 Sessions you message now run in ${want} mode${want === \"auto\" ? \" (Claude Code's auto mode decides what's safe)\" : \" (only what each folder's settings already allow)\"}.`,\n );\n }\n case \"keys\": {\n const c = readControl();\n if (argv[2] === \"remove\" && argv[3]) {\n const n = removeKey(argv[3]);\n return out(n ? ` removed ${n} key(s)` : \" no such key\");\n }\n if (!c?.receivers.length)\n return out(\" control isn't paired on this machine (`sessionpipe control pair <receiver>`)\");\n for (const r of c.receivers) {\n out(` ${r.url} \u00B7 machine ${r.machine}`);\n for (const k of r.keys)\n out(` ${k.id.slice(0, 16)}\u2026 ${k.alg === -7 ? \"ES256\" : \"RS256\"} added ${k.added_at.slice(0, 10)}`);\n }\n return;\n }\n case \"off\": {\n const c = await off({ out, ...(argv[2] ? { url: argv[2] } : {}) });\n if (c && !c.receivers.length) uninstallService();\n return;\n }\n case \"status\": {\n const r = await ask(socketPath(stateDir()), { op: \"status\" }, 2000);\n if (r?.op !== \"status\") return out(\" the control daemon isn't running\");\n return out(JSON.stringify(r.status, null, 2));\n }\n case \"run\":\n return runDaemon(out);\n default:\n return out(CONTROL_HELP);\n }\n}\n\nasync function runDaemon(out: (s?: string) => void): Promise<void> {\n const cfg = readControl();\n if (!cfg?.receivers.length) {\n out(\"control isn't paired on this machine; nothing to do (`sessionpipe control pair <receiver>`)\");\n return;\n }\n const log = (s: string) => out(`${new Date().toISOString()} ${s}`);\n let claude: { bin: string; caps: ReturnType<typeof detectCaps>; sig: string } | null = null;\n const claudeNow = () => {\n const bin = findClaude();\n if (!bin) return null;\n const sig = `${bin}:${existsSync(bin) ? realpathSync(bin) : \"\"}`;\n if (claude?.sig !== sig) claude = { bin, caps: detectCaps(bin), sig };\n return claude;\n };\n const sdk = await loadSdk({ claudeBin: findClaude(), env: process.env, log });\n const d = new ControlDaemon(cfg, controlState(), socketPath(stateDir()), {\n now: Date.now,\n fetch,\n log,\n claudeDirs: () => claudeDirs(),\n claude: claudeNow,\n run: runClaude,\n sdk,\n login: async (configDir) => {\n const c = claudeNow();\n return c ? claudeLogin(c.bin, configDir) : { loggedIn: null };\n },\n token: (r) => (r.token_in ? secretGet(r.token_in, controlAccount(r.machine)) : null),\n });\n await d.start();\n // A sink whose token lives in a keychain can't send from a hook's worker that runs\n // where the keychain is locked (a session started over ssh). This daemon runs in the\n // person's own session, so it drains what those workers left, once a minute.\n const drain = setInterval(() => {\n const sinks = readConfig().sinks.filter((s) => s.token_in && !s.paused);\n if (sinks.length) void flush(stateDir(), sinks, new Outbox(stateDir())).catch(() => {});\n }, 60_000);\n drain.unref();\n watchFile(controlFile(), { interval: 5000 }, () => {\n const next = readControl();\n if (next) d.reload(next);\n });\n const bye = async () => {\n await d.stop();\n process.exit(0);\n };\n process.on(\"SIGTERM\", bye);\n process.on(\"SIGINT\", bye);\n}\n\nexport async function waitMain(argv: string[], out: (s?: string) => void): Promise<void> {\n const i = argv.indexOf(\"--session\");\n const session = waitSession(i >= 0 ? argv[i + 1] : undefined);\n if (!session) {\n out(\"sessionpipe wait: which session? Pass --session <harness>:<id> (Claude Code sets CLAUDE_CODE_SESSION_ID).\");\n process.exitCode = 2;\n return;\n }\n out(await waitForMessage(session));\n}\n\n/** Give a sink the key a receiver handed over at pairing. A sink for the receiver that\n * has a key keeps it (\"kept\"); one without a key gets this one (\"filled\"); otherwise a\n * new sink at `tier` (\"added\"). */\nexport function adoptSinkToken(url: string, token: string, tier: Tier, file?: string): \"kept\" | \"filled\" | \"added\" {\n const now = file ? readConfig(file) : readConfig();\n const same = now.sinks.find((x) => x.url.replace(/\\/$/, \"\") === url);\n if (same && (same.token || same.token_in)) return \"kept\";\n if (same) same.token = token;\n else now.sinks.push({ name: new URL(url).host, url, tier, pii: false, token });\n if (file) writeConfig(now, file);\n else writeConfig(now);\n return same ? \"filled\" : \"added\";\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// What a worker run does, as a function so tests and `sessionpipe replay` share it.\nimport {\n appendFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport {\n adapterByName,\n Cursors,\n type Event,\n type FactsState,\n FileSink,\n filterEvent,\n gitFacts,\n machineName,\n makeEvent,\n Outbox,\n readConfig,\n redactDeep,\n type Session,\n type Sink,\n type SinkConfig,\n StdoutSink,\n safeId,\n stateDir,\n takeLock,\n tilde,\n writeConfig,\n} from \"@sessionpipe/core\";\nimport { ask, socketPath } from \"./control/local.js\";\nimport { HttpSink } from \"./http-sink.js\";\nimport { sinkWithSecrets } from \"./secrets.js\";\n\nasync function tellDaemon(state: string, job: Job, session: string, transcript?: string): Promise<void> {\n const sock = socketPath(state);\n if (process.platform !== \"win32\" && !existsSync(sock)) return;\n await ask(\n sock,\n {\n op: \"event\",\n session: `claude-code:${session}`,\n event: job.event,\n cwd: job.cwd,\n ...(transcript ? { transcript } : {}),\n },\n 300,\n );\n}\n\ndeclare const __SESSIONPIPE_VERSION__: string;\nconst VERSION = typeof __SESSIONPIPE_VERSION__ === \"string\" ? __SESSIONPIPE_VERSION__ : \"0.0.0\";\n\nexport interface Job {\n harness: string;\n event: string;\n argv: string[];\n stdin: string;\n cwd: string;\n env: Record<string, string>;\n ppid?: number;\n at: number;\n}\n\n/** A job file the worker will pick up: random suffix, 0600, in a 0700 dir. */\nexport function enqueueJob(state: string, job: Job): string {\n const jobs = jobsDir(state);\n mkdirSync(jobs, { recursive: true, mode: 0o700 });\n const f = path.join(jobs, `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}.json`);\n writeFileSync(f, JSON.stringify(job), { mode: 0o600 });\n return f;\n}\n\n/** Jobs another worker left behind (a lost lock race, a killed worker): every\n * worker sweeps the ones older than `olderThanMs` before it exits, so no event\n * is lost (ground rule 4). Each is removed before it runs, so two sweepers\n * never run one twice. */\nexport async function sweepJobs(state: string, olderThanMs = 3000, limit = 20): Promise<number> {\n const jobs = jobsDir(state);\n let names: string[] = [];\n try {\n names = readdirSync(jobs).filter((n) => n.endsWith(\".json\"));\n } catch {\n return 0;\n }\n let ran = 0;\n for (const n of names.sort().slice(0, limit)) {\n const f = path.join(jobs, n);\n let job: Job | null = null;\n try {\n if (Date.now() - statSync(f).mtimeMs < olderThanMs) continue;\n job = JSON.parse(readFileSync(f, \"utf8\")) as Job;\n unlinkSync(f);\n } catch {\n continue;\n }\n await runJob(job, { state }).catch(() => {});\n ran++;\n }\n return ran;\n}\n\nexport function log(state: string, line: string): void {\n try {\n mkdirSync(state, { recursive: true, mode: 0o700 });\n const f = path.join(state, \"log\");\n try {\n if (statSync(f).size > 1024 * 1024) renameSync(f, `${f}.1`);\n } catch {}\n appendFileSync(f, `${new Date().toISOString()} ${line}\\n`);\n } catch {}\n}\n\n/** <state>/facts/<harness>/<session>.json \u2014 what the machine learned about a session. */\nexport function factsState(state: string): FactsState {\n const file = (h: string, s: string) => path.join(state, \"facts\", safeId(h), `${safeId(s)}.json`);\n return {\n get(h, s) {\n try {\n return JSON.parse(readFileSync(file(h, s), \"utf8\")) as Record<string, unknown>;\n } catch {\n return {};\n }\n },\n save(h, s, patch) {\n const cur = this.get(h, s);\n const next = { ...cur, ...patch };\n if (JSON.stringify(next) === JSON.stringify(cur)) return;\n mkdirSync(path.dirname(file(h, s)), { recursive: true, mode: 0o700 });\n writeFileSync(file(h, s), JSON.stringify(next), { mode: 0o600 });\n },\n };\n}\n\nexport function buildSinks(sinks: SinkConfig[], o: { locked?: (name: string) => void } = {}): Sink[] {\n const out: Sink[] = [];\n for (const raw of sinks) {\n if (raw.paused) continue;\n // A token kept in a keychain is read now; one this process can't read (a keychain\n // locked in an ssh session) leaves the sink's events waiting, never sent unsigned.\n const s = sinkWithSecrets(raw);\n if (!s) {\n o.locked?.(raw.name);\n continue;\n }\n const tier = Math.min(s.tier, s.max_tier ?? 3) as 0 | 1 | 2 | 3;\n if (s.url === \"stdout\") out.push(new StdoutSink(s.name, tier, !!s.pii));\n else if (s.url.startsWith(\"file:\"))\n out.push(new FileSink(s.name, s.url.slice(5).replace(/^~(?=\\/|$)/, os.homedir()), tier, !!s.pii));\n else if (/^https?:\\/\\//.test(s.url)) out.push(new HttpSink(s, tier));\n }\n return out;\n}\n\n/** Run one hook job end to end: events \u2192 outbox \u2192 sinks. Returns what happened. */\nexport async function runJob(\n job: Job,\n opts: { state?: string; now?: number } = {},\n): Promise<{ events: Event[]; delivered: Record<string, number> }> {\n const state = opts.state ?? stateDir();\n const cfg = readConfig();\n const adapter = adapterByName(job.harness);\n if (!adapter) return { events: [], delivered: {} };\n const r = adapter.fromHook({ argv: job.argv, stdin: job.stdin, env: { ...process.env, ...job.env }, cwd: job.cwd });\n if (!r || !r.session.id) return { events: [], delivered: {} };\n // The control daemon learns each Claude Code session's turn state from its events\n // (a message for a session mid-turn waits for its Stop; a pending permission prompt\n // closes when the tool runs). A local round trip, and nothing when no daemon runs.\n if (job.harness === \"claude-code\") await tellDaemon(state, job, r.session.id, r.transcript);\n const outbox = new Outbox(state);\n const ref = { harness: job.harness, session: r.session.id };\n // Hooks of one session fire close together (parallel subagents, issue #9): wait\n // for the lock with a short backoff before giving the job back to the queue.\n let release = takeLock(state, ref);\n for (let wait = 50; !release && wait <= 3200; wait *= 2) {\n await new Promise((res) => setTimeout(res, wait));\n release = takeLock(state, ref);\n }\n if (!release) {\n log(state, `${job.harness} ${job.event}: session ${r.session.id} locked for 6 s, re-queued`);\n enqueueJob(state, job);\n return { events: [], delivered: {} };\n }\n try {\n const facts = factsState(state);\n const mem = facts.get(job.harness, r.session.id);\n // Heartbeat-class events read no facts (they fire every tool call); the rest refresh them.\n const heavy = !/^(PreToolUse|PostToolUse|PostToolUseFailure|BeforeTool|AfterTool|PostInvocation)$/.test(job.event);\n let learned: Partial<Session> = {};\n if (heavy) {\n const f = adapter.facts(r.session, r.transcript, r.hints ?? {}, facts);\n const { started_at: _s, last_at: _l, first_ask: _fa, harness_version, ...rest } = f;\n learned = rest;\n if (harness_version) facts.save(job.harness, r.session.id, { harness_version });\n facts.save(job.harness, r.session.id, { session: { ...(mem.session as object), ...learned } });\n }\n const known = (mem.session as Partial<Session> | undefined) ?? {};\n const cwdRaw = learned.cwd ?? r.session.cwd ?? known.cwd;\n const git = heavy ? gitFacts(cwdRaw) : {};\n const session: Session = {\n ...known,\n ...learned,\n ...git,\n ...(learned.branch ? { branch: learned.branch } : {}),\n id: r.session.id,\n seq: 0,\n machine: machineName(cfg, os.hostname()),\n ...(cwdRaw ? { cwd: tilde(cwdRaw) } : {}),\n ...(r.session.model ? { model: r.session.model } : {}),\n };\n const version = (facts.get(job.harness, r.session.id).harness_version as string | undefined) ?? undefined;\n const events: Event[] = [];\n for (const a of r.events) {\n const e = makeEvent(a, {\n harness: { name: job.harness, ...(version ? { version } : {}) },\n session: { ...session, seq: outbox.nextSeq(ref) },\n now: opts.now ?? job.at,\n });\n events.push(e);\n }\n // Tier 2: after a turn ends, the transcript's new turns become turn.transcript events.\n const wantsTranscript = cfg.sinks.some((s) => !s.paused && Math.min(s.tier, s.max_tier ?? 3) >= 2);\n if (\n wantsTranscript &&\n r.transcript &&\n r.events.some((e) => e.type === \"turn.ended\" || e.type === \"session.ended\")\n ) {\n const cur = facts.get(job.harness, r.session.id);\n const fromLine = Number(cur.transcript_line) || 0;\n let turnNo = Number(cur.transcript_turns) || 0;\n const read = adapter.readTranscript(r.transcript, fromLine);\n for (const t of read.turns) {\n events.push(\n makeEvent(\n {\n type: \"turn.transcript\",\n harnessEvent: job.event,\n data: { turn: turnNo++, user: t.user, assistant: t.assistant, at: new Date(t.at).toISOString() },\n },\n {\n harness: { name: job.harness, ...(version ? { version } : {}) },\n session: { ...session, seq: outbox.nextSeq(ref) },\n now: opts.now ?? job.at,\n },\n ),\n );\n }\n if (read.turns.length)\n facts.save(job.harness, r.session.id, { transcript_line: read.line, transcript_turns: turnNo });\n }\n // At rest the outbox holds redacted strings (advisory GHSA-8f6f-c3c9-j5p6): the\n // tier-3 fields stay, with their secrets already gone; filterEvent runs the same\n // idempotent pass again per sink.\n outbox.append(\n ref,\n events.map((e) => ({ ...e, session: redactDeep(e.session), data: redactDeep(e.data) })),\n );\n log(\n state,\n `${job.harness} ${job.event}: ${events.map((e) => e.type).join(\",\") || \"nothing\"} (${r.session.id.slice(0, 8)})`,\n );\n const delivered = await flush(state, cfg.sinks, outbox, ref);\n if (Math.random() < 0.02) outbox.prune(cfg.keep_days ?? 30);\n return { events, delivered };\n } finally {\n release();\n }\n}\n\nconst BATCH = 50;\nconst MAX_PER_RUN = 500;\n\n/** Drain every sink from its cursor: this session first, then any backlog. Events\n * from many sessions are packed into one batch of up to BATCH, so a first\n * install's 400-session backfill is nine POSTs, not four hundred (the receiver's\n * write limit ended the first replay at 278 events, 2026-09-28). A cursor moves\n * only after its batch was acknowledged; a refused batch stops the sink for this\n * run and the next worker starts from the same cursors. */\nexport async function flush(\n state: string,\n sinkConfigs: SinkConfig[],\n outbox: Outbox,\n first?: { harness: string; session: string },\n): Promise<Record<string, number>> {\n const delivered: Record<string, number> = {};\n const sinks = buildSinks(sinkConfigs, {\n locked: (name) => log(state, `sink ${name}: its token is in a keychain this process can't read; left for later`),\n });\n const refs = outbox.sessions();\n if (first) {\n const k = `${first.harness}/${safeId(first.session)}`;\n refs.sort((a, b) => (`${a.harness}/${a.session}` === k ? -1 : `${b.harness}/${b.session}` === k ? 1 : 0));\n }\n for (const sink of sinks) {\n const cursors = new Cursors(state, sink.name);\n const c = cursors.read();\n let sent = 0;\n let stalled = false;\n // Pull filtered events session by session into one batch; remember where each\n // session's offset would land if the batch goes through.\n let batch: Event[] = [];\n let pending: Record<string, number> = {};\n const send = async (): Promise<boolean> => {\n if (!batch.length) {\n Object.assign(c, pending);\n pending = {};\n cursors.write(c);\n return true;\n }\n const res = await sink.send(batch);\n if (!res.ok) {\n log(state, `sink ${sink.name}: ${res.status ?? \"\"} ${res.error ?? \"\"} \u2192 ${res.action ?? \"retry\"}`);\n if (res.action === \"pause\" || res.action === \"lower-tier\") applySinkVerdict(sink.name, res);\n if (res.action !== \"drop\") {\n batch = [];\n pending = {};\n return false;\n }\n }\n sent += batch.length;\n Object.assign(c, pending);\n cursors.write(c);\n batch = [];\n pending = {};\n return true;\n };\n for (const ref of refs) {\n if (stalled || sent >= MAX_PER_RUN) break;\n let offset = pending[cursors.key(ref)] ?? c[cursors.key(ref)] ?? 0;\n for (;;) {\n const room = BATCH - batch.length;\n const { events, offset: next } = outbox.read(ref, offset, room);\n if (!events.length) break;\n for (const e of events) {\n const f = filterEvent(e, sink.tier, sink.pii, { home: os.homedir() });\n if (f) batch.push(f);\n }\n offset = next;\n pending[cursors.key(ref)] = offset;\n if (batch.length >= BATCH) {\n if (!(await send())) {\n stalled = true;\n break;\n }\n if (sent >= MAX_PER_RUN) break;\n }\n }\n }\n if (!stalled && (batch.length || Object.keys(pending).length)) if (!(await send())) stalled = true;\n delivered[sink.name] = sent;\n }\n return delivered;\n}\n\nfunction applySinkVerdict(name: string, res: { action?: string; max_tier?: number; error?: string }): void {\n try {\n const cfg = readConfig();\n const s = cfg.sinks.find((x) => x.name === name);\n if (!s) return;\n if (res.action === \"pause\") s.paused = `${new Date().toISOString()} ${res.error ?? \"unauthorized\"}`;\n if (res.action === \"lower-tier\" && typeof res.max_tier === \"number\") s.max_tier = res.max_tier as 0 | 1 | 2 | 3;\n writeConfig(cfg);\n } catch {}\n}\n\nexport { VERSION };\nexport const versionLine = (): string => `sessionpipe ${VERSION}`;\nexport const jobsDir = (state: string): string => path.join(state, \"jobs\");\nexport const hasJobs = (state: string): boolean => existsSync(jobsDir(state));\n", "// SPDX-License-Identifier: Apache-2.0\n// The daemon's local socket (spec/CONTROL.md \u00A78): how the waiter, the Stop and\n// PermissionRequest hooks and the worker talk to the one daemon on this machine.\n// Line-delimited JSON, one request per connection. A Unix socket in the state\n// directory (0600, in a 0700 dir); a per-user named pipe on Windows. Only node:\n// builtins \u2014 the hook bundle imports this.\nimport net from \"node:net\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport type LocalRequest =\n /** A waiter parks until a message for its session arrives. */\n | { op: \"wait\"; session: string; pid?: number }\n /** A Stop hook asks for a queued message (turn mode). */\n | { op: \"stop\"; session: string; active: boolean }\n /** A PermissionRequest hook parks until a verified answer, or until it's released. */\n | { op: \"permission\"; session: string; attention: string; tool?: string }\n /** The worker reports a hook event: turn state and attention closure. */\n | { op: \"event\"; session: string; event: string; transcript?: string; cwd?: string }\n /** `sessionpipe control status`. */\n | { op: \"status\" };\n\nexport type LocalReply =\n | { op: \"message\"; text: string; id: string }\n | { op: \"block\"; reason: string; id: string }\n | { op: \"decision\"; behavior: \"allow\" | \"deny\"; message?: string; id: string }\n | { op: \"none\" }\n /** A newer waiter for the same session took over; this one stops. */\n | { op: \"replaced\" }\n | { op: \"ok\" }\n | { op: \"status\"; status: unknown };\n\n/** Where the daemon listens. `SESSIONPIPE_SOCKET` overrides (tests). */\nexport function socketPath(state: string, env: NodeJS.ProcessEnv = process.env): string {\n if (env.SESSIONPIPE_SOCKET) return env.SESSIONPIPE_SOCKET;\n if (process.platform === \"win32\") return `\\\\\\\\.\\\\pipe\\\\sessionpipe-control-${os.userInfo().username}`;\n return path.join(state, \"control.sock\");\n}\n\n/** One request, one reply. `timeoutMs` bounds the whole exchange; null on any\n * failure (no daemon, a timeout, a garbled reply) \u2014 callers treat that as \"none\". */\nexport function ask(sock: string, req: LocalRequest, timeoutMs: number): Promise<LocalReply | null> {\n return new Promise((resolve) => {\n let buf = \"\";\n let done = false;\n const s = net.connect(sock);\n const finish = (r: LocalReply | null) => {\n if (done) return;\n done = true;\n clearTimeout(t);\n s.destroy();\n resolve(r);\n };\n const t = setTimeout(() => finish(null), timeoutMs);\n s.on(\"connect\", () => s.write(`${JSON.stringify(req)}\\n`));\n s.on(\"data\", (d) => {\n buf += d.toString(\"utf8\");\n const i = buf.indexOf(\"\\n\");\n if (i < 0) return;\n try {\n finish(JSON.parse(buf.slice(0, i)) as LocalReply);\n } catch {\n finish(null);\n }\n });\n s.on(\"error\", () => finish(null));\n s.on(\"close\", () => finish(null));\n });\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The HTTP sink (spec/HTTP.md \u00A72): POST {events} with the protocol header, a bearer\n// token and optional Standard Webhooks signature; errors map to what the sender\n// does next. The cursor moves only on 202. Retry/backoff is the worker's cadence\n// (each hook run drains the backlog); this class reports, it does not sleep.\nimport { createHash, createHmac } from \"node:crypto\";\nimport type { DeliveryResult, Event, Sink, SinkConfig, Tier } from \"@sessionpipe/core\";\n\nconst TIMEOUT_MS = 15_000;\n\n/** The Standard Webhooks message id (HTTP.md \u00A72): the same batch sent again carries\n * the same id, so a receiver that dedupes on webhook-id sees a retry as one message.\n * Derived from the events' own ids, which the outbox keeps across retries. */\nexport function webhookId(events: Pick<Event, \"id\">[]): string {\n return `msg_${createHash(\"sha256\")\n .update(events.map((e) => e.id).join(\",\"))\n .digest(\"base64url\")\n .slice(0, 32)}`;\n}\n\nexport class HttpSink implements Sink {\n readonly name: string;\n readonly pii: boolean;\n private readonly url: string;\n constructor(\n private readonly cfg: SinkConfig,\n readonly tier: Tier,\n ) {\n this.name = cfg.name;\n this.pii = !!cfg.pii;\n this.url = cfg.url.replace(/\\/$/, \"\");\n }\n\n private eventsUrl(): string {\n // The endpoint from the well-known file is stored beside the url at `sink add`;\n // until then the spec's default path.\n const ep = (this.cfg as { endpoints?: { events?: string } }).endpoints?.events ?? \"/api/sessionpipe/v1/events\";\n return /^https?:\\/\\//.test(ep) ? ep : this.url + ep;\n }\n\n async send(events: Event[]): Promise<DeliveryResult> {\n const body = JSON.stringify({ events });\n const headers: Record<string, string> = { \"content-type\": \"application/json\", \"sessionpipe-protocol\": \"1\" };\n if (this.cfg.token) headers.authorization = `Bearer ${this.cfg.token}`;\n if (this.cfg.secret?.startsWith(\"whsec_\")) {\n const id = webhookId(events);\n const ts = Math.floor(Date.now() / 1000);\n const key = Buffer.from(this.cfg.secret.slice(6), \"base64\");\n const sig = createHmac(\"sha256\", key).update(`${id}.${ts}.${body}`).digest(\"base64\");\n headers[\"webhook-id\"] = id;\n headers[\"webhook-timestamp\"] = String(ts);\n headers[\"webhook-signature\"] = `v1,${sig}`;\n }\n const ctl = new AbortController();\n const t = setTimeout(() => ctl.abort(), TIMEOUT_MS);\n try {\n const r = await fetch(this.eventsUrl(), { method: \"POST\", headers, body, signal: ctl.signal });\n const text = await r.text();\n let j: Record<string, unknown> = {};\n try {\n j = text ? (JSON.parse(text) as Record<string, unknown>) : {};\n } catch {}\n if (r.status === 202 || r.status === 200) {\n return {\n ok: true,\n acknowledged: events.length,\n accepted: Number(j.accepted ?? events.length),\n duplicates: Number(j.duplicates ?? 0),\n rejected: Array.isArray(j.rejected) ? (j.rejected as { id: string; reason: string }[]) : [],\n ...(typeof j.max_tier === \"number\" ? { max_tier: j.max_tier as Tier } : {}),\n status: r.status,\n };\n }\n const err = typeof j.reason === \"string\" ? j.reason : text.slice(0, 200);\n if (r.status === 400) return { ok: false, acknowledged: 0, status: 400, error: err, action: \"drop\" };\n if (r.status === 401) return { ok: false, acknowledged: 0, status: 401, error: err, action: \"pause\" };\n if (r.status === 403)\n return {\n ok: false,\n acknowledged: 0,\n status: 403,\n error: err,\n action: \"lower-tier\",\n ...(typeof j.max_tier === \"number\" ? { max_tier: j.max_tier as Tier } : {}),\n };\n if (r.status === 413) return { ok: false, acknowledged: 0, status: 413, error: err, action: \"split\" };\n if (r.status === 429)\n return {\n ok: false,\n acknowledged: 0,\n status: 429,\n error: err,\n action: \"retry\",\n retryAfterMs: Number(r.headers.get(\"retry-after\") ?? 60) * 1000,\n };\n return { ok: false, acknowledged: 0, status: r.status, error: err, action: \"retry\" };\n } catch (e) {\n return { ok: false, acknowledged: 0, error: String((e as Error).message ?? e), action: \"retry\" };\n } finally {\n clearTimeout(t);\n }\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Where this machine's secrets live: each sink's token (and Webhooks secret) and each\n// paired receiver's machine token. In the operating system's keychain when this person\n// has one unlocked \u2014 the macOS Keychain, or the Secret Service (GNOME Keyring, KWallet)\n// in a Linux desktop session \u2014 and otherwise in config.json / control.json at mode\n// 0600, which is all a headless server has (the same as ~/.ssh). A secret in a store\n// leaves `token_in` in the file and no token.\n//\n// What a store protects against, plainly: a dotfiles repo, a backup, a synced\n// ~/.config, a `cat` over a shoulder. Not a program running as you: `security` hands an\n// item it wrote back without asking, which is also how the hook's worker reads it.\n\nimport { spawnSync } from \"node:child_process\";\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { configFile, readConfig, type SinkConfig, writeConfig } from \"@sessionpipe/core\";\n\nexport type SecretStore = \"keychain\" | \"secret-service\";\nexport type StoreName = SecretStore | \"file\";\n\nconst SERVICE = \"sessionpipe\";\n\nexport type Runner = (cmd: string, args: string[], input?: string) => { status: number | null; stdout: string };\nexport const defaultRunner: Runner = (cmd, args, input) => {\n const r = spawnSync(cmd, args, {\n input: input ?? \"\",\n encoding: \"utf8\",\n timeout: 8000,\n stdio: [\"pipe\", \"pipe\", \"ignore\"],\n });\n return { status: r.error ? null : r.status, stdout: r.stdout ?? \"\" };\n};\n\n/** A sink's item. The machine has one config, so a sink's name is enough \u2014 except\n * where SESSIONPIPE_CONFIG points at another (a second profile, a test): then the\n * item names that config too, so two configs' sinks of one name never share a key. */\nexport const sinkAccount = (name: string, what: \"token\" | \"secret\" = \"token\"): string => {\n const scope = process.env.SESSIONPIPE_CONFIG\n ? `@${createHash(\"sha256\").update(configFile()).digest(\"hex\").slice(0, 8)}`\n : \"\";\n return `sink:${name}:${what}${scope}`;\n};\nexport const controlAccount = (machine: string): string => `control:${machine}`;\n\n/** `security -i` reads its commands from stdin, so the value never sits in argv (and in\n * `ps`). Its parser takes double-quoted words: a value with a quote, a backslash or a\n * space isn't stored there and stays in the file. */\nconst KC_SAFE = /^[\\x21\\x23-\\x5b\\x5d-\\x7e]{1,4096}$/;\nconst NAME_SAFE = /^[\\x20\\x21\\x23-\\x5b\\x5d-\\x7e]{1,200}$/;\n\nexport function secretGet(store: SecretStore, account: string, run: Runner = defaultRunner): string | null {\n const r =\n store === \"keychain\"\n ? run(\"security\", [\"find-generic-password\", \"-s\", SERVICE, \"-a\", account, \"-w\"])\n : run(\"secret-tool\", [\"lookup\", \"service\", SERVICE, \"account\", account]);\n if (r.status !== 0) return null;\n const v = r.stdout.replace(/\\r?\\n$/, \"\");\n return v || null;\n}\n\nexport function secretSet(store: SecretStore, account: string, value: string, run: Runner = defaultRunner): boolean {\n if (store === \"keychain\") {\n if (!KC_SAFE.test(value) || !NAME_SAFE.test(account)) return false;\n run(\n \"security\",\n [\"-i\"],\n `add-generic-password -U -s ${SERVICE} -a \"${account}\" -l \"${SERVICE} ${account}\" -w \"${value}\"\\n`,\n );\n } else {\n run(\"secret-tool\", [\"store\", \"--label\", `${SERVICE} ${account}`, \"service\", SERVICE, \"account\", account], value);\n }\n // Trust only a read-back: `security -i` exits 0 whatever its commands did.\n return secretGet(store, account, run) === value;\n}\n\nexport function secretDel(store: SecretStore, account: string, run: Runner = defaultRunner): void {\n if (store === \"keychain\") run(\"security\", [\"delete-generic-password\", \"-s\", SERVICE, \"-a\", account]);\n else run(\"secret-tool\", [\"clear\", \"service\", SERVICE, \"account\", account]);\n}\n\n/** Can this process write, read back and delete an item in the store right now? */\nexport function probe(store: SecretStore, run: Runner = defaultRunner): boolean {\n const account = `probe:${randomBytes(6).toString(\"hex\")}`;\n const ok = secretSet(store, account, randomBytes(12).toString(\"base64url\"), run);\n secretDel(store, account, run);\n return ok;\n}\n\n/** The best place for secrets on this machine, from this session. SESSIONPIPE_SECRETS\n * (file | keychain | secret-service) overrides. The Secret Service is used only in a\n * desktop session: on a server its keyring is locked whenever nobody is logged in,\n * which is exactly when the daemon needs its token. */\nexport function bestStore(\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n run: Runner = defaultRunner,\n): StoreName {\n const want = env.SESSIONPIPE_SECRETS;\n if (want === \"file\") return \"file\";\n const candidates: SecretStore[] =\n want === \"keychain\" || want === \"secret-service\"\n ? [want]\n : platform === \"darwin\"\n ? [\"keychain\"]\n : platform === \"linux\" && env.DBUS_SESSION_BUS_ADDRESS && (env.DISPLAY || env.WAYLAND_DISPLAY)\n ? [\"secret-service\"]\n : [];\n for (const s of candidates) if (probe(s, run)) return s;\n return \"file\";\n}\n\nexport const storeLabel = (s: StoreName | undefined): string =>\n s === \"keychain\" ? \"the macOS Keychain\" : s === \"secret-service\" ? \"the Secret Service keyring\" : \"a 0600 file\";\n\n/** The sink with its token and secret filled in from its store. Null when they live in\n * a store this process can't read right now (a keychain locked in an ssh session):\n * the caller leaves the events in the outbox rather than sending them unsigned. */\nexport function sinkWithSecrets(s: SinkConfig, run: Runner = defaultRunner): SinkConfig | null {\n if (!s.token_in) return s;\n const token = secretGet(s.token_in, sinkAccount(s.name), run);\n if (!token) return null;\n const secret = secretGet(s.token_in, sinkAccount(s.name, \"secret\"), run);\n return { ...s, token, ...(secret ? { secret } : {}) };\n}\n\n/** Store a sink's secrets in `to` (or back in the file) and save the config. */\nexport function moveSinkSecrets(\n to: StoreName,\n o: { run?: Runner; file?: string } = {},\n): { moved: string[]; kept: string[] } {\n const run = o.run ?? defaultRunner;\n const cfg = o.file ? readConfig(o.file) : readConfig();\n const moved: string[] = [];\n const kept: string[] = [];\n for (const s of cfg.sinks) {\n const from = s.token_in;\n if ((from ?? \"file\") === to) continue;\n const full = sinkWithSecrets(s, run);\n if (!full) {\n kept.push(s.name);\n continue;\n }\n if (!full.token && !full.secret) continue;\n if (to === \"file\") {\n if (full.token) s.token = full.token;\n if (full.secret) s.secret = full.secret;\n delete s.token_in;\n } else {\n const ok =\n (!full.token || secretSet(to, sinkAccount(s.name), full.token, run)) &&\n (!full.secret || secretSet(to, sinkAccount(s.name, \"secret\"), full.secret, run));\n if (!ok) {\n secretDel(to, sinkAccount(s.name), run);\n secretDel(to, sinkAccount(s.name, \"secret\"), run);\n kept.push(s.name);\n continue;\n }\n delete s.token;\n delete s.secret;\n s.token_in = to;\n }\n moved.push(s.name);\n if (from) {\n // Written first, then the file says where; only then is the old copy dropped.\n if (o.file) writeConfig(cfg, o.file);\n else writeConfig(cfg);\n secretDel(from, sinkAccount(s.name), run);\n secretDel(from, sinkAccount(s.name, \"secret\"), run);\n }\n }\n if (o.file) writeConfig(cfg, o.file);\n else writeConfig(cfg);\n return { moved, kept };\n}\n\n/** Forget a sink's secrets wherever they are (sink remove, uninstall). */\nexport function dropSinkSecrets(s: SinkConfig, run: Runner = defaultRunner): void {\n if (!s.token_in) return;\n secretDel(s.token_in, sinkAccount(s.name), run);\n secretDel(s.token_in, sinkAccount(s.name, \"secret\"), run);\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Persistent paths shared by hook installation and control pairing.\nimport { execFileSync } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { VERSION } from \"./run.js\";\n\n/** Homebrew's versioned Cellar path dies on `brew upgrade node`; its stable links survive. */\nexport function stableNode(exe: string): string {\n const m = /^(.*)\\/Cellar\\/(node(?:@\\d+)?)\\/[^/]+\\/bin\\/node$/.exec(exe);\n if (!m) return exe;\n let real: string;\n try {\n real = realpathSync(exe);\n } catch {\n return exe;\n }\n for (const c of [`${m[1]}/opt/${m[2]}/bin/node`, `${m[1]}/bin/node`]) {\n try {\n if (realpathSync(c) === real) return c;\n } catch {}\n }\n return exe;\n}\n\nexport function viaNpx(distDir: string): boolean {\n return /[\\\\/]_npx[\\\\/]/.test(distDir) || /[\\\\/]\\.npm[\\\\/]/.test(distDir);\n}\n\n/** Install the running version persistently and hand off the original command before side effects. */\nexport function rerunGlobally(argv: string[], out: (s: string) => void): void {\n out(` Installing sessionpipe@${VERSION} globally, so hooks and services use a persistent copy\u2026`);\n let bin: string;\n try {\n // Homebrew's default prefix is the versioned Cellar folder that `brew upgrade\n // node` deletes, and its bin is not on PATH (issue #13): install into ~/.local\n // there, and run the copy from the prefix we installed into.\n let prefix = \"\";\n try {\n prefix = execFileSync(\"npm\", [\"prefix\", \"-g\"], {\n encoding: \"utf8\",\n timeout: 15000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n } catch {}\n const target = /\\/Cellar\\/node(?:@\\d+)?\\/[^/]+/.test(prefix) ? path.join(os.homedir(), \".local\") : prefix;\n execFileSync(\"npm\", [\"install\", \"-g\", `sessionpipe@${VERSION}`, ...(target ? [\"--prefix\", target] : [])], {\n stdio: [\"ignore\", \"ignore\", \"inherit\"],\n });\n bin =\n process.platform === \"win32\"\n ? path.join(target, \"sessionpipe.cmd\")\n : target\n ? path.join(target, \"bin\", \"sessionpipe\")\n : \"sessionpipe\";\n if (target && target !== prefix)\n out(` Installed into ${target}; make sure ${path.join(target, \"bin\")} is on your PATH.`);\n } catch {\n out(\n \" ! couldn't install globally (`npm install -g sessionpipe` failed). Run it yourself, then retry this command.\",\n );\n process.exit(1);\n }\n // The command's own failure (a pairing that expired) is its own to report, not an\n // install that failed: it has said why; pass its exit status on.\n try {\n execFileSync(bin, argv, { stdio: \"inherit\", shell: process.platform === \"win32\" });\n } catch (e) {\n process.exit(typeof (e as { status?: unknown }).status === \"number\" ? (e as { status: number }).status : 1);\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The control daemon (spec/CONTROL.md): one process per computer. It holds one\n// long-poll per paired receiver, verifies every command itself against the keys\n// enrolled at this terminal, and delivers each one the cheapest way the session\n// allows \u2014 to a parked waiter, at the session's next Stop, to a session it holds\n// through the Agent SDK, or by a headless resume or fork \u2014 then acks how.\n//\n// A receiver can queue a message; it can never make this process run one.\nimport { existsSync, mkdirSync, realpathSync, statSync, unlinkSync } from \"node:fs\";\nimport net from \"node:net\";\nimport path from \"node:path\";\nimport { claudeControl, redactSecrets } from \"@sessionpipe/core\";\nimport { type ControlCommand, parseSessionRef, verifyCommand } from \"@sessionpipe/core/control\";\nimport type { LocalReply, LocalRequest } from \"./local.js\";\nimport { awaitAnswer, transcriptEnd } from \"./reply.js\";\nimport { type DeliveryMode, frame, IN_PLACE_ANSWER, kindPath, routePrompt } from \"./route.js\";\nimport {\n type Ack,\n AckOutbox,\n type ControlConfig,\n type DaemonState,\n NonceStore,\n type PairedReceiver,\n readState,\n writeControl,\n writeState,\n} from \"./store.js\";\nimport { AnswerStream } from \"./stream.js\";\n\nconst {\n claudeEnv,\n findTranscript,\n isUuid,\n JOB_TIMEOUT_MS,\n liveProcess,\n loginHint,\n modeFlags,\n parseResult,\n recentlyWritten,\n sessionFolder,\n} = claudeControl;\ntype Caps = claudeControl.Caps;\ntype RunResult = claudeControl.RunResult;\ntype Login = claudeControl.Login;\n\ndeclare const __SESSIONPIPE_VERSION__: string;\nconst VERSION = typeof __SESSIONPIPE_VERSION__ === \"string\" ? __SESSIONPIPE_VERSION__ : \"0.0.0\";\n\nconst MAX_REPLY = 20_000;\nconst HELLO_EVERY_MS = 10 * 60_000;\n/** A message waiting for a Stop that never comes goes another way after this. */\nconst TURN_FALLBACK_MS = 30 * 60_000;\n/** How long the daemon follows a session's turn for the answer to an in-place\n * message before acking it delivered without one. */\nconst ANSWER_WAIT_MS = 30 * 60_000;\n/** How long a Stop hook may take to be answered. */\nconst RECENT_ACKS_MS = 25 * 3600_000;\n/** Events that prove a pending permission prompt was resolved some other way. */\nconst CLOSES_ATTENTION = new Set([\n \"PostToolUse\",\n \"PostToolUseFailure\",\n \"Stop\",\n \"StopFailure\",\n \"UserPromptSubmit\",\n \"SessionEnd\",\n]);\n\n/** The message as the receiver carried it (control.json). */\nexport interface Carried {\n id: string;\n cmd: string;\n csig?: string | null;\n grant?: { str: string; cred: string; ad: string; cd: string; sig: string } | null;\n confirm?: { cred: string; ad: string; cd: string; sig: string } | null;\n at: string;\n expires_at: string;\n}\n\n/** A session the Agent SDK holds for the daemon (sdk.ts; a fake in tests). */\nexport interface SdkSession {\n /** Deliver one message; resolves with the agent's reply when the turn ends. */\n send(text: string): Promise<{ reply: string; error?: string }>;\n interrupt(): Promise<void>;\n close(): void;\n readonly busy: boolean;\n readonly lastUsed: number;\n}\nexport interface SdkHost {\n start(o: {\n session: string;\n cwd: string;\n mode: \"safe\" | \"auto\";\n configDir?: string;\n allowedTools?: string[];\n }): SdkSession;\n}\n\nexport interface DaemonDeps {\n now: () => number;\n fetch: typeof fetch;\n log: (line: string) => void;\n claudeDirs: () => string[];\n claude: () => { bin: string; caps: Caps } | null;\n run: (\n bin: string,\n args: string[],\n o: { cwd: string; env: NodeJS.ProcessEnv; timeoutMs?: number; onLine?: (line: string) => void },\n ) => Promise<RunResult>;\n sdk?: SdkHost | null;\n /** How long to follow a live session's turn for an in-place answer (tests shorten it). */\n answerWaitMs?: number;\n /** Close an SDK session idle this long (a held session costs ~300 MB). */\n sdkIdleMs?: number;\n env?: NodeJS.ProcessEnv;\n /** Is Claude Code signed in for this account, as this process sees it? Asked before\n * a headless run, so a login the daemon can't read (a macOS keychain with nobody at\n * the screen) fails with what to do, not with Claude Code's \"please run /login\". */\n login?: (configDir?: string) => Promise<Login>;\n /** Read a receiver's machine token again: it may live in a keychain that was\n * locked when the daemon started and has unlocked since. */\n token?: (r: PairedReceiver) => string | null;\n platform?: NodeJS.Platform;\n}\n\ninterface TurnPending {\n receiver: PairedReceiver;\n msgId: string;\n text: string;\n session: string;\n queuedAt: number;\n}\n\ninterface Live {\n midTurn: boolean;\n /** The Stop hook just delivered a block: the next Stop event continues the turn. */\n continued: boolean;\n waiter: net.Socket | null;\n turnQueue: TurnPending[];\n attentions: Map<string, net.Socket>;\n cwd?: string;\n transcript?: string;\n lastEvent: number;\n}\n\nexport interface Status {\n version: string;\n name: string;\n receivers: {\n url: string;\n machine: string;\n keys: number;\n polling: boolean;\n last_poll: number | null;\n last_error: string | null;\n }[];\n waiting: string[];\n mid_turn: string[];\n attentions: { session: string; id: string }[];\n sdk: string[];\n nonces: number;\n acks_pending: number;\n delivered: Record<string, number>;\n}\n\n/** The machine's own caps (CONTROL.md \u00A76 `start`): every command is the owner's,\n * signed, but a burst of them must not start a crowd of agents. A start beyond the\n * caps is refused `start_limit`; a headless run beyond `headless` waits its turn. */\n/** What a receiver may let its sessions use without asking (CONTROL.md \u00A76): its own MCP\n * servers, by name \u2014 never a built-in tool. The receiver is where the message came\n * from, so answering it there (publishing a page, replying) is the job; anything else\n * still needs the person's approval rule. */\nexport function sessionToolsFrom(v: unknown): string[] {\n if (!Array.isArray(v)) return [];\n return [\n ...new Set(v.filter((t): t is string => typeof t === \"string\" && /^mcp__[A-Za-z0-9_-]{1,64}$/.test(t))),\n ].slice(0, 8);\n}\n\nexport const LIMITS = { startConcurrent: 2, startPerHour: 10, headless: 3 } as const;\n\nexport class ControlDaemon {\n private server: net.Server | null = null;\n private readonly live = new Map<string, Live>();\n private readonly sdkSessions = new Map<string, SdkSession>();\n private readonly nonces: NonceStore;\n private readonly acks: AckOutbox;\n private readonly recentAcks = new Map<string, { ack: Ack; at: number }>();\n private readonly inflight = new Set<string>();\n private readonly queues = new Map<string, Promise<unknown>>();\n private readonly lastEnd = new Map<string, number>();\n private state: DaemonState;\n private running = false;\n private readonly polling = new Map<string, { last: number | null; error: string | null; on: boolean }>();\n private readonly delivered: Record<string, number> = {};\n private helloTimer: NodeJS.Timeout | null = null;\n private helloSoon: NodeJS.Timeout | null = null;\n private readonly aborts = new Set<AbortController>();\n /** Per receiver: the MCP servers its sessions may use unattended (its well-known). */\n private readonly sessionTools = new Map<string, string[]>();\n /** Sessions a run of the daemon's own is working on right now (a start, a resume):\n * a message for one waits for that run and resumes it \u2014 never a copy, which would\n * set two agents on one task (2026-10-02: a \"just merge when ready\" sent while the\n * start still ran forked a second agent that raced the first toward main). */\n private readonly ownRuns = new Map<string, number>();\n private startsRunning = 0;\n private startTimes: number[] = [];\n private procs = 0;\n private readonly procWaiters: (() => void)[] = [];\n /** configDir \u2192 the last login answer and when (a yes is kept 10 minutes, a no 30 s). */\n private readonly logins = new Map<string, { at: number; login: Login }>();\n\n constructor(\n private cfg: ControlConfig,\n private readonly dir: string,\n private readonly sock: string,\n private readonly deps: DaemonDeps,\n ) {\n this.nonces = new NonceStore(path.join(dir, \"nonces.jsonl\"), deps.now);\n this.acks = new AckOutbox(path.join(dir, \"acks.jsonl\"));\n this.state = readState(path.join(dir, \"state.json\"));\n }\n\n // --- lifecycle ------------------------------------------------------------------\n\n async start(): Promise<void> {\n this.running = true;\n mkdirSync(this.dir, { recursive: true, mode: 0o700 });\n await this.listen();\n for (const r of this.cfg.receivers) void this.pollLoop(r);\n this.helloTimer = setInterval(() => void this.helloAll(), HELLO_EVERY_MS);\n this.helloTimer.unref();\n void this.helloAll();\n void this.flushAcks();\n const idle = setInterval(() => this.closeIdleSdk(), 60_000);\n idle.unref();\n this.deps.log(`control daemon ${VERSION} up \u00B7 ${this.cfg.receivers.length} receiver(s) \u00B7 socket ${this.sock}`);\n }\n\n async stop(): Promise<void> {\n this.running = false;\n for (const a of this.aborts) a.abort();\n if (this.helloTimer) clearInterval(this.helloTimer);\n if (this.helloSoon) clearTimeout(this.helloSoon);\n for (const s of this.sdkSessions.values()) s.close();\n for (const l of this.live.values()) {\n l.waiter?.destroy();\n for (const a of l.attentions.values()) a.destroy();\n }\n await new Promise<void>((r) => (this.server ? this.server.close(() => r()) : r()));\n if (process.platform !== \"win32\")\n try {\n unlinkSync(this.sock);\n } catch {}\n }\n\n reload(cfg: ControlConfig): void {\n const known = new Set(this.cfg.receivers.map((r) => r.control + r.machine));\n this.cfg = cfg;\n for (const r of cfg.receivers) if (!known.has(r.control + r.machine)) void this.pollLoop(r);\n }\n\n status(): Status {\n return {\n version: VERSION,\n name: this.cfg.name,\n receivers: this.cfg.receivers.map((r) => {\n const p = this.polling.get(r.control + r.machine);\n return {\n url: r.url,\n machine: r.machine,\n keys: r.keys.length,\n polling: !!p?.on,\n last_poll: p?.last ?? null,\n last_error: p?.error ?? null,\n };\n }),\n waiting: [...this.live].filter(([, l]) => l.waiter).map(([k]) => k),\n mid_turn: [...this.live].filter(([, l]) => l.midTurn).map(([k]) => k),\n attentions: [...this.live].flatMap(([k, l]) => [...l.attentions.keys()].map((id) => ({ session: k, id }))),\n sdk: [...this.sdkSessions.keys()],\n nonces: this.nonces.size,\n acks_pending: this.acks.all().length,\n delivered: { ...this.delivered },\n };\n }\n\n // --- the local socket -----------------------------------------------------------\n\n private listen(): Promise<void> {\n if (process.platform !== \"win32\") {\n try {\n if (existsSync(this.sock)) unlinkSync(this.sock);\n } catch {}\n }\n this.server = net.createServer((s) => this.onConn(s));\n return new Promise((resolve, reject) => {\n this.server!.once(\"error\", reject);\n this.server!.listen(this.sock, () => resolve());\n });\n }\n\n private onConn(s: net.Socket): void {\n let buf = \"\";\n let handled = false;\n s.on(\"error\", () => {});\n s.on(\"data\", (d) => {\n if (handled) return;\n buf += d.toString(\"utf8\");\n if (buf.length > 64 * 1024) return s.destroy();\n const i = buf.indexOf(\"\\n\");\n if (i < 0) return;\n handled = true;\n let req: LocalRequest;\n try {\n req = JSON.parse(buf.slice(0, i)) as LocalRequest;\n } catch {\n return s.destroy();\n }\n this.onRequest(req, s);\n });\n }\n\n private reply(s: net.Socket, r: LocalReply): void {\n try {\n s.end(`${JSON.stringify(r)}\\n`);\n } catch {}\n }\n\n private liveOf(session: string): Live {\n let l = this.live.get(session);\n if (!l) {\n l = {\n midTurn: false,\n continued: false,\n waiter: null,\n turnQueue: [],\n attentions: new Map(),\n lastEvent: this.deps.now(),\n };\n this.live.set(session, l);\n }\n return l;\n }\n\n private onRequest(req: LocalRequest, s: net.Socket): void {\n switch (req.op) {\n case \"status\":\n this.reply(s, { op: \"status\", status: this.status() });\n return;\n case \"wait\": {\n if (!parseSessionRef(req.session)) {\n this.reply(s, { op: \"none\" });\n return;\n }\n const l = this.liveOf(req.session);\n if (l.waiter && l.waiter !== s) this.reply(l.waiter, { op: \"replaced\" });\n l.waiter = s;\n s.on(\"close\", () => {\n if (l.waiter === s) {\n l.waiter = null;\n this.scheduleHello();\n }\n });\n this.scheduleHello();\n return;\n }\n case \"stop\": {\n const l = this.liveOf(req.session);\n l.lastEvent = this.deps.now();\n const p = this.takeTurn(l);\n if (!p) {\n this.reply(s, { op: \"none\" });\n return;\n }\n l.continued = true;\n const from = this.answerFrom(req.session);\n this.reply(s, { op: \"block\", reason: `${frame(p.text, p.receiver.url)}\\n\\n${IN_PLACE_ANSWER}`, id: p.msgId });\n this.followAnswer(p.receiver, p.msgId, \"turn\", req.session, from, p.queuedAt);\n return;\n }\n case \"permission\": {\n const l = this.liveOf(req.session);\n const prev = l.attentions.get(req.attention);\n if (prev && prev !== s) this.reply(prev, { op: \"none\" });\n l.attentions.set(req.attention, s);\n s.on(\"close\", () => {\n if (l.attentions.get(req.attention) === s) l.attentions.delete(req.attention);\n });\n return;\n }\n case \"event\":\n this.onEvent(req);\n this.reply(s, { op: \"ok\" });\n return;\n }\n }\n\n /** A queued turn message that hasn't expired. */\n private takeTurn(l: Live): TurnPending | null {\n while (l.turnQueue.length) {\n const p = l.turnQueue.shift()!;\n if (!this.inflight.has(p.msgId)) continue;\n return p;\n }\n return null;\n }\n\n private onEvent(e: Extract<LocalRequest, { op: \"event\" }>): void {\n const l = this.liveOf(e.session);\n l.lastEvent = this.deps.now();\n if (e.cwd) l.cwd = e.cwd;\n if (e.transcript) l.transcript = e.transcript;\n if (CLOSES_ATTENTION.has(e.event) && l.attentions.size) {\n for (const s of l.attentions.values()) this.reply(s, { op: \"none\" });\n l.attentions.clear();\n }\n if (e.event === \"UserPromptSubmit\" || e.event === \"SessionStart\") {\n if (e.event === \"UserPromptSubmit\") l.midTurn = true;\n return;\n }\n if (e.event === \"Stop\" && l.continued) {\n l.continued = false;\n return;\n }\n if (e.event === \"Stop\" || e.event === \"StopFailure\" || e.event === \"SessionEnd\") {\n l.midTurn = false;\n l.continued = false;\n // A message queued for a Stop that came and went without taking it (it\n // arrived after the hook asked, or the turn failed) goes another way.\n const left = l.turnQueue.splice(0);\n for (const p of left) if (this.inflight.has(p.msgId)) void this.reroute(p);\n }\n }\n\n // --- receivers ------------------------------------------------------------------\n\n private async pollLoop(first: PairedReceiver): Promise<void> {\n const key = first.control + first.machine;\n const st = { last: null as number | null, error: null as string | null, on: true };\n this.polling.set(key, st);\n let backoff = 0;\n let downSince = 0;\n // A deploy takes the receiver away for seconds, not minutes: retry soon, capped at\n // 15 s (one request per machine), with jitter so every machine a deploy dropped\n // doesn't come back in the same instant. The old 60 s / 5 min steps left a\n // machine blind for minutes after a 30-second outage.\n const steps = [1000, 2000, 5000, 10_000, 15_000];\n const pause = (n: number) => (steps[Math.min(n, steps.length - 1)] as number) * (0.75 + Math.random() * 0.5);\n for (;;) {\n // The current record every round: `control pair` may have added a key since.\n const r = this.cfg.receivers.find((x) => x.control + x.machine === key);\n if (!this.running || !r) break;\n if (!r.token) {\n // Its token lives in a keychain this process can't read yet (locked, or nobody\n // logged in): ask again every 30 s rather than poll with no bearer.\n const t = this.deps.token?.(r) ?? null;\n if (t) {\n r.token = t;\n this.deps.log(`${r.url}: machine token readable again`);\n } else {\n if (!st.error?.startsWith(\"can't read\"))\n this.deps.log(`${r.url}: can't read this machine's token from ${r.token_in ?? \"its store\"}; retrying`);\n st.error = `can't read this machine's token from ${r.token_in ?? \"its store\"} (locked?); retrying every 30 s`;\n await new Promise((res) => setTimeout(res, 30_000));\n continue;\n }\n }\n const ctl = new AbortController();\n this.aborts.add(ctl);\n // A poll held past wait + 10 s is a dead connection (a laptop that slept, a\n // network that changed): give up on it and ask again.\n const t = setTimeout(() => ctl.abort(), 35_000);\n try {\n const u = new URL(r.control);\n u.searchParams.set(\"machine\", r.machine);\n u.searchParams.set(\"wait\", \"25\");\n const asked = this.deps.now();\n const res = await this.deps.fetch(u, { headers: { authorization: `Bearer ${r.token}` }, signal: ctl.signal });\n st.last = this.deps.now();\n if (downSince && res.status < 500) {\n // Timed to when this poll was sent: a long-poll that reconnected is then held\n // up to `wait` before it answers.\n this.deps.log(`${r.url}: back after ${Math.round((asked - downSince) / 1000)} s (${backoff} failed tries)`);\n downSince = 0;\n }\n if (res.status === 401) {\n st.error = \"the receiver no longer knows this machine (401); run `sessionpipe control pair` again\";\n this.deps.log(`${r.url}: ${st.error}`);\n break;\n }\n if (res.status === 200) {\n const body = (await res.json()) as { messages?: Carried[] };\n // Looked up again: a key may have been added while this poll was parked.\n const cur = this.cfg.receivers.find((x) => x.control + x.machine === key) ?? r;\n let fresh = 0;\n // Not awaited: a headless turn can run for half an hour, and the next\n // message (for another session, or a permission answer) must not wait\n // behind it. handle() orders what must be ordered (one session's prompts).\n for (const m of body.messages ?? []) {\n if (m && !this.inflight.has(m.id)) fresh++;\n void this.handle(cur, m).catch((e) =>\n this.deps.log(`handle ${String(m?.id).slice(-8)}: ${String((e as Error)?.message || e)}`),\n );\n }\n // Only messages already in hand (a receiver that ignores `taken`): don't\n // turn the long-poll into a spin.\n if (!fresh) await sleep(2000);\n st.error = null;\n backoff = 0;\n } else if (res.status === 204) {\n st.error = null;\n backoff = 0;\n } else {\n st.error = `HTTP ${res.status}`;\n downSince ||= this.deps.now();\n await sleep(pause(backoff++));\n }\n } catch (e) {\n if (!this.running) break;\n st.error = String((e as Error)?.message || e).slice(0, 120);\n downSince ||= this.deps.now();\n await sleep(pause(backoff++));\n } finally {\n clearTimeout(t);\n this.aborts.delete(ctl);\n }\n }\n st.on = false;\n }\n\n private scheduleHello(): void {\n if (this.helloSoon) return;\n this.helloSoon = setTimeout(() => {\n this.helloSoon = null;\n void this.helloAll();\n }, 1500);\n this.helloSoon.unref();\n }\n\n /** Read each receiver's well-known for its session tools (at start, then with every hello). */\n private async refreshSessionTools(): Promise<void> {\n for (const r of this.cfg.receivers) {\n try {\n const res = await this.deps.fetch(`${r.url.replace(/\\/$/, \"\")}/.well-known/sessionpipe`, {\n signal: AbortSignal.timeout(8000),\n });\n if (!res.ok) continue;\n const wk = (await res.json()) as { control?: { session_tools?: unknown } };\n const tools = sessionToolsFrom(wk.control?.session_tools);\n const key = r.control + r.machine;\n if (JSON.stringify(tools) !== JSON.stringify(this.sessionTools.get(key) ?? []))\n this.deps.log(\n `${r.url}: sessions it messages may use ${tools.length ? tools.join(\", \") : \"nothing extra\"} without asking`,\n );\n this.sessionTools.set(key, tools);\n } catch {}\n }\n }\n\n private allowedFor(r: PairedReceiver): string[] {\n return this.sessionTools.get(r.control + r.machine) ?? [];\n }\n\n private async helloAll(): Promise<void> {\n void this.refreshSessionTools();\n const waiting = [...this.live].filter(([, l]) => l.waiter).map(([k]) => k);\n const modes: DeliveryMode[] = [\"waiter\", \"turn\", \"resume\", \"fork\", ...(this.deps.sdk ? ([\"sdk\"] as const) : [])];\n for (const r of this.cfg.receivers) {\n const body = {\n name: this.cfg.name,\n harnesses: [\"claude-code\"],\n modes,\n keys: r.keys.map((k) => k.id),\n version: VERSION,\n waiting,\n folders: this.cfg.folders,\n mode: this.cfg.mode,\n };\n await this.post(r, \"/hello\", body).catch(() => {});\n }\n }\n\n private async post(r: PairedReceiver, sub: string, body: unknown): Promise<Response> {\n const ctl = new AbortController();\n const t = setTimeout(() => ctl.abort(), 15_000);\n try {\n return await this.deps.fetch(`${r.control.replace(/\\/$/, \"\")}${sub}`, {\n method: \"POST\",\n headers: { authorization: `Bearer ${r.token}`, \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: ctl.signal,\n });\n } finally {\n clearTimeout(t);\n }\n }\n\n // --- acks -----------------------------------------------------------------------\n\n private finish(r: PairedReceiver, id: string, a: Omit<Ack, \"receiver\" | \"id\" | \"at\">, since?: number): void {\n const ack: Ack = { receiver: r.control + r.machine, id, at: new Date(this.deps.now()).toISOString(), ...a };\n if (ack.reply) ack.reply = redactSecrets(ack.reply).slice(0, MAX_REPLY);\n if (ack.detail) ack.detail = redactSecrets(ack.detail).slice(0, 500);\n if (a.outcome !== \"taken\") {\n this.inflight.delete(id);\n this.recentAcks.set(id, { ack, at: this.deps.now() });\n this.delivered[a.mode ?? a.outcome] = (this.delivered[a.mode ?? a.outcome] ?? 0) + 1;\n this.deps.log(\n `ack ${id.slice(-8)} ${a.outcome}${a.mode ? ` via ${a.mode}` : \"\"}${a.code ? ` (${a.code})` : \"\"}${since ? ` send\u2192${a.outcome} ${this.deps.now() - since} ms` : \"\"}`,\n );\n }\n this.acks.add(ack);\n void this.flushAcks();\n }\n\n private flushing = false;\n private async flushAcks(): Promise<void> {\n if (this.flushing) return;\n this.flushing = true;\n try {\n for (let round = 0; round < 5; round++) {\n const all = this.acks.all();\n if (!all.length) return;\n const left: Ack[] = [];\n for (const r of this.cfg.receivers) {\n const mine = all.filter((a) => a.receiver === r.control + r.machine);\n if (!mine.length) continue;\n const acks = mine.map(({ receiver: _r, ...a }) => a);\n const ok = await this.post(r, \"/ack\", { acks })\n .then((res) => res.status >= 200 && res.status < 300)\n .catch(() => false);\n if (!ok) left.push(...mine);\n }\n // Acks for a receiver no longer paired are dropped.\n const now = this.acks.all();\n const added = now.slice(all.length);\n this.acks.keep([...left, ...added]);\n if (!left.length && !added.length) return;\n if (left.length) await sleep(2000 * (round + 1));\n }\n } finally {\n this.flushing = false;\n }\n }\n\n // --- one message ----------------------------------------------------------------\n\n async handle(r: PairedReceiver, m: Carried): Promise<void> {\n if (!m || typeof m.id !== \"string\") return;\n if (this.inflight.has(m.id)) return; // redelivered while we work on it\n const prior = this.recentAcks.get(m.id);\n if (prior && this.deps.now() - prior.at < RECENT_ACKS_MS) {\n this.acks.add(prior.ack);\n void this.flushAcks();\n return;\n }\n // In hand from here, before anything is awaited: a redelivery that arrives while\n // this one verifies must not verify too and come back `replay`. Every path below\n // ends in finish(), which lets go of it.\n this.inflight.add(m.id);\n const sent = Date.parse(m.at) || this.deps.now();\n if (Date.parse(m.expires_at) <= this.deps.now()) return this.finish(r, m.id, { outcome: \"expired\" });\n const v = await verifyCommand(\n { cmd: m.cmd, csig: m.csig ?? null, grant: m.grant ?? null, confirm: m.confirm ?? null },\n { machine: r.machine, rpId: r.rpId, trusted: r.keys, now: this.deps.now(), seenNonce: this.nonces.seen },\n );\n if (!v.ok) {\n this.deps.log(`refused ${m.id.slice(-8)}: ${v.code} \u2014 ${v.why}`);\n return this.finish(r, m.id, { outcome: \"refused\", code: v.code, detail: v.why });\n }\n const cmd = v.cmd;\n // A device this machine already trusts vouched for a new one (CONTROL.md \u00A72): the\n // signature just verified against an enrolled key, so the new key joins the store.\n if (cmd.kind === \"key.add\") return this.addKey(r, m.id, cmd, sent);\n const ref = parseSessionRef(cmd.session)!;\n const kp = kindPath(cmd.kind, ref.harness);\n if (typeof kp === \"object\") return this.finish(r, m.id, { outcome: \"unsupported\", detail: kp.unsupported });\n try {\n if (kp === \"start\") return await this.startSession(r, m.id, cmd, sent);\n let place = this.place(cmd.session);\n // A session the daemon is still starting may have no transcript yet: wait for\n // that run on the session's queue, then place it again.\n if (\"refused\" in place && this.ownRuns.has(ref.id)) {\n this.finish(r, m.id, { outcome: \"taken\" });\n await this.serial(ref.id, async () => {});\n place = this.place(cmd.session);\n }\n if (\"refused\" in place)\n return this.finish(r, m.id, { outcome: \"refused\", code: place.refused, detail: place.why });\n if (kp === \"permission\") return this.permission(r, m.id, cmd, sent);\n if (kp === \"cancel\") return await this.cancel(r, m.id, cmd, sent);\n // One session's prompts in the order they came, each routed only once the one\n // before it has landed (a second message to a session the first one forked\n // goes to the copy). Other sessions don't wait.\n return await this.serial(`deliver:${cmd.session}`, async () => {\n // Read again: the message before this one may have moved the session (a fork).\n const now = this.place(cmd.session);\n if (\"refused\" in now) return this.finish(r, m.id, { outcome: \"refused\", code: now.refused, detail: now.why });\n return this.prompt(r, m.id, cmd, now, sent);\n });\n } catch (e) {\n this.finish(r, m.id, { outcome: \"failed\", detail: String((e as Error)?.message || e) });\n }\n }\n\n /** Where the session lives, and whether its folder is allowed \u2014 read from the\n * session's own transcript (Claude Code) or the hooks' cwd, never the command. */\n private place(\n session: string,\n ): { refused: string; why: string } | { folder: string; transcript: ReturnType<typeof findTranscript> } {\n const ref = parseSessionRef(session)!;\n if (ref.harness === \"claude-code\") {\n const target = this.state.copies[ref.id] ?? ref.id;\n const t = findTranscript(target, this.deps.claudeDirs()) ?? findTranscript(ref.id, this.deps.claudeDirs());\n if (!t) return { refused: \"no_session\", why: `no Claude Code session ${ref.id.slice(0, 8)} on this machine` };\n const folder = sessionFolder(t);\n const ok = folder && this.allowed(folder);\n if (!ok) return { refused: \"folder\", why: \"that session's folder isn't one this machine allows\" };\n return { folder: ok, transcript: t };\n }\n const cwd = this.live.get(session)?.cwd;\n const ok = cwd && this.allowed(cwd);\n if (!ok) return { refused: cwd ? \"folder\" : \"no_session\", why: \"no allowed folder known for that session\" };\n return { folder: ok, transcript: null };\n }\n\n private allowed(dir: string): string | null {\n if (!path.isAbsolute(dir)) return null;\n let r: string;\n try {\n r = realpathSync.native(dir);\n if (!statSync(r).isDirectory()) return null;\n } catch {\n return null;\n }\n for (const f of this.cfg.folders) {\n let rf = f;\n try {\n rf = realpathSync.native(f);\n } catch {}\n if (r === rf || r.startsWith(rf.endsWith(path.sep) ? rf : rf + path.sep)) return r;\n }\n return null;\n }\n\n private permission(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number) {\n const l = this.live.get(cmd.session);\n const hook = l?.attentions.get(cmd.for as string);\n if (!hook) {\n // Nothing is ever auto-allowed: an allow needs a prompt open right now.\n if (cmd.decision === \"allow\")\n return this.finish(r, id, {\n outcome: \"refused\",\n code: \"no_attention\",\n detail: \"no permission prompt open for that id\",\n });\n this.finish(r, id, { outcome: \"expired\", detail: \"the prompt was already answered or closed\" });\n return;\n }\n l!.attentions.delete(cmd.for as string);\n this.reply(hook, {\n op: \"decision\",\n behavior: cmd.decision as \"allow\" | \"deny\",\n ...(cmd.note ? { message: cmd.note } : {}),\n id,\n });\n this.finish(r, id, { outcome: \"delivered\", mode: \"turn\" }, sent);\n }\n\n private async cancel(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number): Promise<void> {\n const ref = parseSessionRef(cmd.session)!;\n const held = this.sdkSessions.get(ref.id);\n if (!held)\n return this.finish(r, id, {\n outcome: \"unsupported\",\n detail: \"no cancel path for a session the daemon doesn't hold\",\n });\n await held.interrupt();\n this.finish(r, id, { outcome: \"delivered\", mode: \"sdk\" }, sent);\n }\n\n private view(session: string, transcript: ReturnType<typeof findTranscript>) {\n const ref = parseSessionRef(session)!;\n const l = this.live.get(session);\n const claude = ref.harness === \"claude-code\" ? this.deps.claude() : null;\n const target = this.state.copies[ref.id] ?? ref.id;\n const t = transcript;\n // The daemon's own run holding it is not \"someone else's live process\": the message\n // queues behind that run (serial per session) and resumes it.\n const live =\n !this.ownRuns.has(target) &&\n !!t &&\n (liveProcess(target, t.configDir) || recentlyWritten(t.file, this.lastEnd.get(target), this.deps.now()));\n return {\n harness: ref.harness,\n sdk: this.sdkSessions.has(ref.id),\n waiter: !!l?.waiter && !l.waiter.destroyed,\n midTurn: !!l?.midTurn,\n live,\n known: !!t,\n canFork: !!claude?.caps.fork,\n api: false,\n };\n }\n\n private async prompt(\n r: PairedReceiver,\n id: string,\n cmd: ControlCommand,\n place: { folder: string; transcript: ReturnType<typeof findTranscript> },\n sent: number,\n ): Promise<void> {\n const route = routePrompt(this.view(cmd.session, place.transcript));\n if (\"unsupported\" in route) return this.finish(r, id, { outcome: \"unsupported\", detail: route.unsupported });\n if (\"refused\" in route) return this.finish(r, id, { outcome: \"refused\", code: route.refused });\n const ref = parseSessionRef(cmd.session)!;\n const text = cmd.text as string;\n switch (route.mode) {\n case \"waiter\": {\n const l = this.live.get(cmd.session)!;\n const w = l.waiter!;\n l.waiter = null;\n const from = this.answerFrom(cmd.session);\n this.reply(w, { op: \"message\", text: frame(text, r.url), id });\n this.scheduleHello();\n return this.followAnswer(r, id, \"waiter\", cmd.session, from, sent);\n }\n case \"turn\": {\n const l = this.liveOf(cmd.session);\n const p: TurnPending = { receiver: r, msgId: id, text, session: cmd.session, queuedAt: sent };\n l.turnQueue.push(p);\n // It waits for the session's Stop: the receiver must not keep handing it back.\n this.finish(r, id, { outcome: \"taken\" });\n const t = setTimeout(() => {\n if (this.inflight.has(id) && l.turnQueue.includes(p)) {\n l.turnQueue.splice(l.turnQueue.indexOf(p), 1);\n void this.reroute(p);\n }\n }, TURN_FALLBACK_MS);\n t.unref();\n return;\n }\n case \"sdk\": {\n const s = this.sdkSessions.get(ref.id)!;\n this.finish(r, id, { outcome: \"taken\" });\n const out = await s.send(frame(text, r.url));\n return this.finish(\n r,\n id,\n out.error\n ? { outcome: \"failed\", detail: out.error }\n : { outcome: \"delivered\", mode: \"sdk\", reply: out.reply },\n sent,\n );\n }\n case \"resume\":\n case \"fork\":\n return this.headless(r, id, cmd, place, route.mode, sent);\n case \"api\":\n return this.finish(r, id, { outcome: \"unsupported\", detail: \"no input API wired for this harness\" });\n }\n }\n\n /** A turn message whose Stop never took it: route again, now that it isn't mid-turn. */\n private async reroute(p: TurnPending): Promise<void> {\n const l = this.liveOf(p.session);\n l.midTurn = false;\n const place = this.place(p.session);\n if (\"refused\" in place) return this.finish(p.receiver, p.msgId, { outcome: \"refused\", code: place.refused });\n const cmd = { kind: \"prompt\", session: p.session, text: p.text } as ControlCommand;\n this.inflight.delete(p.msgId);\n this.inflight.add(p.msgId);\n await this.prompt(p.receiver, p.msgId, cmd, place, p.queuedAt).catch((e) =>\n this.finish(p.receiver, p.msgId, { outcome: \"failed\", detail: String((e as Error)?.message || e) }),\n );\n }\n\n /** Jobs for one session (and its copy) run one at a time, in order. */\n private serial<T>(key: string, task: () => Promise<T>): Promise<T> {\n const prev = this.queues.get(key) ?? Promise.resolve();\n const next = prev.then(task, task);\n this.queues.set(\n key,\n next.catch(() => {}),\n );\n return next;\n }\n\n /** Null when Claude Code is signed in for this account (or can't say); otherwise what\n * to tell the person. */\n private async loginProblem(configDir?: string): Promise<string | null> {\n if (!this.deps.login) return null;\n const key = configDir ?? \"\";\n const now = this.deps.now();\n const hit = this.logins.get(key);\n let login = hit && now - hit.at < (hit.login.loggedIn === false ? 30_000 : 600_000) ? hit.login : null;\n if (!login) {\n login = await this.deps.login(configDir).catch((): Login => ({ loggedIn: null }));\n this.logins.set(key, { at: now, login });\n }\n if (login.loggedIn !== false) return null;\n this.deps.log(`claude isn't signed in for ${configDir ?? \"the default account\"} as the daemon sees it`);\n return loginHint(configDir, this.deps.platform ?? process.platform);\n }\n\n private async headless(\n r: PairedReceiver,\n id: string,\n cmd: ControlCommand,\n place: { folder: string; transcript: ReturnType<typeof findTranscript> },\n mode: \"resume\" | \"fork\",\n sent: number,\n ): Promise<void> {\n const claude = this.deps.claude();\n if (!claude)\n return this.finish(r, id, { outcome: \"failed\", detail: \"Claude Code isn't installed on this machine\" });\n const mf = modeFlags(this.cfg.mode, claude.caps);\n if (\"error\" in mf) return this.finish(r, id, { outcome: \"refused\", code: \"mode\", detail: mf.error });\n const signedOut = await this.loginProblem(place.transcript?.configDir);\n if (signedOut) return this.finish(r, id, { outcome: \"failed\", detail: signedOut });\n const ref = parseSessionRef(cmd.session)!;\n this.finish(r, id, { outcome: \"taken\" });\n await this.serial(ref.id, async () => {\n const target = this.state.copies[ref.id] ?? ref.id;\n const resume = mode === \"fork\" ? [\"--resume\", target, \"--fork-session\"] : [\"--resume\", target];\n const allow = this.allowedFor(r);\n const args = [\n \"-p\",\n ...this.outputArgs(claude.caps),\n ...mf.args,\n ...(allow.length ? [`--allowedTools=${allow.join(\",\")}`] : []),\n ...resume,\n frame(cmd.text as string, r.url),\n ];\n this.deps.log(`${id.slice(-8)}: claude -p ${[...mf.args, ...resume].join(\" \")} in ${place.folder}`);\n const stream = this.answerStream(r, id);\n const res = await this.owning(target, () =>\n this.slot(() =>\n this.deps.run(claude.bin, args, {\n cwd: place.folder,\n env: claudeEnv(place.transcript?.configDir, this.deps.env),\n timeoutMs: JOB_TIMEOUT_MS,\n ...(claude.caps.stream ? { onLine: (l: string) => stream.feed(l) } : {}),\n }),\n ),\n );\n stream.close();\n this.lastEnd.set(target, this.deps.now());\n const out = this.outcome(res);\n if (\"failed\" in out) return this.finish(r, id, { outcome: \"failed\", detail: out.failed });\n const ran = isUuid(out.session) ? out.session : target;\n if (mode === \"fork\" && ran !== target) {\n this.state.copies[ref.id] = ran;\n writeState(path.join(this.dir, \"state.json\"), this.state);\n this.lastEnd.set(ran, this.deps.now());\n }\n this.finish(\n r,\n id,\n { outcome: \"delivered\", mode, reply: out.reply, ...(ran !== ref.id ? { session: `claude-code:${ran}` } : {}) },\n sent,\n );\n });\n }\n\n private outcome(res: RunResult): { failed: string } | { reply: string; session?: string } {\n if (res.error) return { failed: `couldn't start Claude Code: ${res.error}` };\n if (res.timedOut) return { failed: \"Claude Code was still working after 30 minutes, so it was stopped\" };\n if (res.tooBig) return { failed: \"Claude Code's answer was too large to read\" };\n const j = parseResult(res.stdout);\n if (!j) {\n const why = String(res.stderr || \"\")\n .trim()\n .split(\"\\n\")\n .slice(-3)\n .join(\" \");\n return {\n failed: `Claude Code exited (${res.signal || `code ${res.code}`}) without an answer${why ? `: ${why}` : \"\"}`,\n };\n }\n if (j.is_error) return { failed: String(j.result || j.subtype || \"Claude Code reported an error\") };\n const denials = Array.isArray(j.permission_denials) ? j.permission_denials : [];\n const names = [...new Set(denials.map((d) => d?.tool_name).filter((n): n is string => typeof n === \"string\"))];\n const tail = denials.length\n ? `\\n\\n(Not allowed on this machine, since nobody was there to approve: ${names.join(\", \") || `${denials.length} action(s)`}.)`\n : \"\";\n const text =\n typeof j.result === \"string\" && j.result.trim() ? j.result : \"(Claude Code finished without a written reply.)\";\n return { reply: text + tail, ...(typeof j.session_id === \"string\" ? { session: j.session_id } : {}) };\n }\n\n private addKey(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number) {\n const k = cmd.key!;\n const name = typeof cmd.name === \"string\" ? cmd.name.trim().slice(0, 80) : undefined;\n const rec = this.cfg.receivers.find((x) => x.control === r.control && x.machine === r.machine) ?? r;\n if (rec.keys.some((x) => x.id === k.id))\n return this.finish(r, id, { outcome: \"delivered\", detail: \"that device was already trusted\" }, sent);\n rec.keys.push({\n id: k.id,\n alg: k.alg,\n spki: k.spki,\n ...(name ? { name } : {}),\n added_at: new Date(this.deps.now()).toISOString(),\n });\n try {\n writeControl(this.cfg, this.deps.env);\n } catch (e) {\n rec.keys = rec.keys.filter((x) => x.id !== k.id);\n return this.finish(r, id, {\n outcome: \"failed\",\n detail: `couldn't save the key: ${String((e as Error)?.message || e)}`,\n });\n }\n this.deps.log(\n `trusted a new device${name ? ` (${name})` : \"\"} on ${r.url}: ${k.id.slice(0, 12)}\u2026, vouched for by a key it already trusted`,\n );\n this.finish(r, id, { outcome: \"delivered\", detail: `trusted ${name || \"a new device\"}` }, sent);\n }\n\n /** Where the session's transcript ends right now: its answer starts after this. */\n private answerFrom(session: string): { file: string; offset: number } | null {\n const ref = parseSessionRef(session);\n if (!ref || ref.harness !== \"claude-code\") return null;\n const t = findTranscript(this.state.copies[ref.id] ?? ref.id, this.deps.claudeDirs());\n return t ? { file: t.file, offset: transcriptEnd(t.file) } : null;\n }\n\n /** A message handed to a live session (a waiter, a Stop block) is `taken` now; the\n * session answers in its own turn, which the daemon reads from the transcript and\n * sends back as the final ack's `reply` \u2014 so the person sees the answer where they\n * asked. A turn that doesn't end within ANSWER_WAIT_MS is acked delivered without. */\n private followAnswer(\n r: PairedReceiver,\n id: string,\n mode: \"waiter\" | \"turn\",\n session: string,\n from: { file: string; offset: number } | null,\n sent: number,\n ): void {\n this.deps.log(`${id.slice(-8)}: in ${session.slice(0, 24)} via ${mode} ${this.deps.now() - sent} ms after send`);\n this.finish(r, id, { outcome: \"taken\" });\n const stream = this.answerStream(r, id);\n void (async () => {\n const answer = from\n ? await awaitAnswer(from.file, from.offset, {\n timeoutMs: this.deps.answerWaitMs ?? ANSWER_WAIT_MS,\n now: this.deps.now,\n onText: (t) => stream.set(t),\n })\n : null;\n stream.close();\n this.finish(r, id, { outcome: \"delivered\", mode, ...(answer ? { reply: answer } : {}) }, sent);\n })().catch((e) => this.finish(r, id, { outcome: \"delivered\", mode, detail: String((e as Error)?.message || e) }));\n }\n\n /** The answer so far, sent as a `progress` ack: whole, with a rising seq, at most\n * one in flight. Fire-and-forget \u2014 the final ack carries everything. */\n private answerStream(r: PairedReceiver, id: string): AnswerStream {\n return new AnswerStream(async (text, seq) => {\n await this.post(r, \"/ack\", {\n acks: [\n {\n id,\n outcome: \"progress\",\n at: new Date(this.deps.now()).toISOString(),\n seq,\n reply: redactSecrets(text).slice(0, MAX_REPLY),\n },\n ],\n });\n });\n }\n\n /** How a headless run prints: streamed where this Claude Code can, else one JSON at the end. */\n private outputArgs(caps: { stream?: boolean }): string[] {\n return caps.stream\n ? [\"--output-format\", \"stream-json\", \"--verbose\", \"--include-partial-messages\"]\n : [\"--output-format\", \"json\"];\n }\n\n /** Mark a session as held by one of the daemon's runs while `fn` runs. */\n private async owning<T>(session: string, fn: () => Promise<T>): Promise<T> {\n this.ownRuns.set(session, (this.ownRuns.get(session) ?? 0) + 1);\n try {\n return await fn();\n } finally {\n const n = (this.ownRuns.get(session) ?? 1) - 1;\n if (n > 0) this.ownRuns.set(session, n);\n else this.ownRuns.delete(session);\n }\n }\n\n private limits() {\n const l = this.cfg.limits ?? {};\n const n = (v: unknown, d: number) => (typeof v === \"number\" && Number.isInteger(v) && v >= 0 ? v : d);\n return {\n startConcurrent: n(l.start_concurrent, LIMITS.startConcurrent),\n startPerHour: n(l.start_per_hour, LIMITS.startPerHour),\n headless: Math.max(1, n(l.headless, LIMITS.headless)),\n };\n }\n\n /** One headless Claude Code process at a time per slot; the rest wait in order. */\n private async slot<T>(fn: () => Promise<T>): Promise<T> {\n while (this.procs >= this.limits().headless) await new Promise<void>((r) => this.procWaiters.push(r));\n this.procs++;\n try {\n return await fn();\n } finally {\n this.procs--;\n this.procWaiters.shift()?.();\n }\n }\n\n private async startSession(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number): Promise<void> {\n const lim = this.limits();\n const now = this.deps.now();\n this.startTimes = this.startTimes.filter((t) => now - t < 3_600_000);\n if (this.startsRunning >= lim.startConcurrent || this.startTimes.length >= lim.startPerHour) {\n const detail =\n this.startsRunning >= lim.startConcurrent\n ? `this machine is already starting ${this.startsRunning} new session(s); it starts at most ${lim.startConcurrent} at once`\n : `this machine started ${this.startTimes.length} new sessions in the last hour, its limit`;\n this.deps.log(`refused ${id.slice(-8)}: start_limit \u2014 ${detail}`);\n return this.finish(r, id, { outcome: \"refused\", code: \"start_limit\", detail });\n }\n this.startsRunning++;\n this.startTimes.push(now);\n const sid = parseSessionRef(cmd.session)!.id;\n try {\n // On the session's own queue, and held as the daemon's own: a message sent while\n // the start still runs waits for it and resumes the session, never forks it.\n await this.serial(sid, () => this.owning(sid, () => this.startOne(r, id, cmd, sent)));\n } finally {\n this.startsRunning--;\n }\n }\n\n private async startOne(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number): Promise<void> {\n const ref = parseSessionRef(cmd.session)!;\n const cwd = this.allowed(cmd.cwd as string);\n if (!cwd)\n return this.finish(r, id, {\n outcome: \"refused\",\n code: \"folder\",\n detail: \"that folder isn't one this machine allows\",\n });\n if (findTranscript(ref.id, this.deps.claudeDirs()) || this.sdkSessions.has(ref.id))\n return this.finish(r, id, {\n outcome: \"refused\",\n code: \"bad_session\",\n detail: \"that new session's id is already taken\",\n });\n const signedOut = await this.loginProblem(this.deps.env?.CLAUDE_CONFIG_DIR);\n if (signedOut) return this.finish(r, id, { outcome: \"failed\", detail: signedOut });\n this.finish(r, id, { outcome: \"taken\" });\n if (this.deps.sdk) {\n const sdk = this.deps.sdk;\n const out = await this.slot(async () => {\n const s = sdk.start({ session: ref.id, cwd, mode: this.cfg.mode, allowedTools: this.allowedFor(r) });\n this.sdkSessions.set(ref.id, s);\n return s.send(frame(cmd.text as string, r.url));\n });\n return this.finish(\n r,\n id,\n out.error ? { outcome: \"failed\", detail: out.error } : { outcome: \"delivered\", mode: \"sdk\", reply: out.reply },\n sent,\n );\n }\n const claude = this.deps.claude();\n if (!claude)\n return this.finish(r, id, { outcome: \"failed\", detail: \"Claude Code isn't installed on this machine\" });\n const mf = modeFlags(this.cfg.mode, claude.caps);\n if (\"error\" in mf) return this.finish(r, id, { outcome: \"refused\", code: \"mode\", detail: mf.error });\n const stream = this.answerStream(r, id);\n const res = await this.slot(() =>\n this.deps.run(\n claude.bin,\n [\n \"-p\",\n ...this.outputArgs(claude.caps),\n ...mf.args,\n ...(this.allowedFor(r).length ? [`--allowedTools=${this.allowedFor(r).join(\",\")}`] : []),\n \"--session-id\",\n ref.id,\n frame(cmd.text as string, r.url),\n ],\n {\n cwd,\n env: claudeEnv(undefined, this.deps.env),\n timeoutMs: JOB_TIMEOUT_MS,\n ...(claude.caps.stream ? { onLine: (l: string) => stream.feed(l) } : {}),\n },\n ),\n );\n stream.close();\n // The transcript this run just wrote is ours: the next message must not read it as a\n // live session (a fork instead of a resume).\n this.lastEnd.set(ref.id, this.deps.now());\n const out = this.outcome(res);\n if (\"failed\" in out) return this.finish(r, id, { outcome: \"failed\", detail: out.failed });\n this.finish(r, id, { outcome: \"delivered\", mode: \"resume\", reply: out.reply }, sent);\n }\n\n private closeIdleSdk(): void {\n const idle = this.deps.sdkIdleMs ?? 10 * 60_000;\n for (const [id, s] of this.sdkSessions)\n if (!s.busy && this.deps.now() - s.lastUsed > idle) {\n s.close();\n this.sdkSessions.delete(id);\n this.deps.log(\n `sdk session ${id.slice(0, 8)} closed after ${Math.round(idle / 60_000)} min idle (it resumes on the next message)`,\n );\n }\n }\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms).unref?.());\n", "// SPDX-License-Identifier: Apache-2.0\n// The one verifier for signed control commands (spec/CONTROL.md \u00A74\u2013\u00A75). A machine\n// runs a command only when this says yes; a receiver MAY run it too, as an early\n// word, so a bad command is refused where the person can see why.\n//\n// WebCrypto only (globalThis.crypto.subtle), no node: imports, no clock of its own\n// (`now` is passed in): the same file runs in a Cloudflare Worker, in a browser and\n// in Node \u2265 20, and conformance/control-vectors/ pins its answers.\n//\n// Every signature covers the EXACT bytes as transmitted (`cmd`, `grant.str`): the\n// strings are parsed to read their fields and never re-serialized to verify.\n\n/** One passkey tap vouches for a day key for at most this long. */\nexport const GRANT_MAX_MS = 24 * 3600_000;\n/** Clock slack between the signing device, the receiver and the machine. */\nexport const SKEW_MS = 5 * 60_000;\n/** The machine judges a command by when it was SIGNED: a message sent while the lid\n * was shut still runs when the machine wakes, up to a day later. */\nexport const MACHINE_MAX_AGE_MS = 24 * 3600_000;\n/** A receiver's early check is stricter: a command is carried within ten minutes of\n * being signed, or not at all. */\nexport const RECEIVER_MAX_AGE_MS = 10 * 60_000;\n/** How long a machine remembers a nonce: longer than MACHINE_MAX_AGE_MS + SKEW_MS. */\nexport const NONCE_TTL_MS = 25 * 3600_000;\n/** The whole command string, in UTF-16 code units (what JSON.parse sees). */\nexport const CMD_MAX = 48_000;\n/** A prompt's text, in characters. */\nexport const TEXT_MAX = 20_000;\n/** A permission answer's note. */\nexport const NOTE_MAX = 2_000;\n/** A grant string. */\nexport const GRANT_STR_MAX = 2_000;\n\nexport const COMMAND_TYPE = \"sessionpipe.control\";\nexport const GRANT_TYPE = \"sessionpipe.grant\";\nexport const CONTROL_KINDS = [\"prompt\", \"permission.answer\", \"cancel\", \"start\", \"key.add\"] as const;\n/** The session a `key.add` names: the machine's own key store, not a coding session. */\nexport const KEY_STORE_SESSION = \"sessionpipe:keys\";\nexport type ControlKind = (typeof CONTROL_KINDS)[number];\n\n/** COSE algorithm ids a trusted key may use. */\nexport const ES256 = -7;\nexport const RS256 = -257;\n\n/** A key enrolled on the machine: a passkey's credential id, COSE alg and SPKI (base64url). */\nexport interface TrustedKey {\n id: string;\n alg: number;\n spki: string;\n}\n/** A WebAuthn assertion: credential id, authenticatorData, clientDataJSON, signature (base64url). */\nexport interface Assertion {\n cred: string;\n ad: string;\n cd: string;\n sig: string;\n}\n/** The day's grant: a passkey's assertion over sha256(str), where str names the day key. */\nexport interface GrantBundle extends Assertion {\n str: string;\n}\n/** What a receiver carries for one command (control.json minus the receiver's envelope). */\nexport interface SignedCommand {\n cmd: string;\n csig?: string | null;\n grant?: GrantBundle | null;\n confirm?: Assertion | null;\n}\nexport interface Grant {\n v: 1;\n t: typeof GRANT_TYPE;\n pub: string;\n iat: number;\n exp: number;\n rp: string;\n}\nexport interface ControlCommand {\n v: 1;\n t: typeof COMMAND_TYPE;\n machine: string;\n kind: ControlKind;\n /** `<harness>:<id>`, e.g. `claude-code:8c132906-\u2026`. */\n session: string;\n text?: string;\n for?: string;\n decision?: \"allow\" | \"deny\";\n note?: string;\n cwd?: string;\n /** key.add only: the passkey to trust from now on, as the receiver holds it. */\n key?: { id: string; alg: -7 | -257; spki: string };\n /** key.add only: what the person calls the device (\"iPhone\"), for `control keys`. */\n name?: string;\n nonce: string;\n iat: number;\n}\n\n/** Why a command was refused. Stable: conformance vectors and acks name these. */\nexport type RefusalCode =\n | \"malformed\"\n | \"not_a_command\"\n | \"wrong_machine\"\n | \"unknown_kind\"\n | \"bad_session\"\n | \"bad_fields\"\n | \"bad_nonce\"\n | \"too_old\"\n | \"future\"\n | \"unsigned\"\n | \"untrusted_key\"\n | \"bad_assertion\"\n | \"bad_grant\"\n | \"outside_grant\"\n | \"bad_csig\"\n | \"replay\"\n | \"nonce_store\";\n\nexport type Verdict =\n | { ok: true; cmd: ControlCommand; via: \"grant\" | \"confirm\"; key: string }\n | { ok: false; code: RefusalCode; why: string };\n\nexport interface VerifyOptions {\n /** This machine's id; a command for another machine is refused. */\n machine: string;\n /** The receiver's WebAuthn rp id the keys were enrolled for (well-known control.signing.rp_id). */\n rpId: string;\n /** The keys enrolled on this machine (or, for a receiver's early check, the account's). */\n trusted: TrustedKey[];\n /** Epoch ms. */\n now: number;\n /** MACHINE_MAX_AGE_MS on a machine (default), RECEIVER_MAX_AGE_MS on a receiver. */\n maxAgeMs?: number;\n /** Called once, last, only for a command whose signatures all verified: answer\n * true when the nonce was seen before, otherwise record it (durably) and answer\n * false. A throw refuses the command (`nonce_store`): never run what could not\n * be remembered. Omit it on a receiver's early check. */\n seenNonce?: (nonce: string) => boolean | Promise<boolean>;\n}\n\nconst NONCE_RE = /^[A-Za-z0-9_-]{22,64}$/;\nconst MACHINE_RE = /^m_[A-Za-z0-9_-]{16,40}$/;\nconst HARNESS_RE = /^[a-z][a-z0-9-]{0,39}$/;\nconst SESSION_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/;\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst B64URL_RE = /^[A-Za-z0-9_-]*$/;\nconst UP = 0x01;\nconst UV = 0x04;\n\n// --- encodings ------------------------------------------------------------------\n\nconst enc = new TextEncoder();\nconst dec = new TextDecoder();\n\nexport function b64url(bytes: Uint8Array | ArrayBuffer): string {\n const u = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);\n let s = \"\";\n for (const b of u) s += String.fromCharCode(b);\n return btoa(s).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/** base64url without padding, strictly; null for anything else. */\nexport function fromB64url(s: unknown): Uint8Array | null {\n if (typeof s !== \"string\" || !B64URL_RE.test(s) || s.length % 4 === 1) return null;\n try {\n const bin = atob(s.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((s.length + 3) % 4));\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n } catch {\n return null;\n }\n}\n\nexport async function sha256(data: string | Uint8Array): Promise<Uint8Array> {\n const bytes = typeof data === \"string\" ? enc.encode(data) : data;\n return new Uint8Array(await crypto.subtle.digest(\"SHA-256\", bytes as Uint8Array<ArrayBuffer>));\n}\n\nfunction concat(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(a.length + b.length);\n out.set(a, 0);\n out.set(b, a.length);\n return out;\n}\n\nfunction sameBytes(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let d = 0;\n for (let i = 0; i < a.length; i++) d |= (a[i] as number) ^ (b[i] as number);\n return d === 0;\n}\n\n/** A DER ECDSA signature (what WebAuthn returns) as the 64-byte r\u2016s WebCrypto verifies.\n * Strict: every length must match the bytes, so one signature has one encoding (a\n * P-256 signature is at most 72 bytes, so the short length form is the only one). */\nexport function derToRaw(der: Uint8Array): Uint8Array | null {\n if (der[0] !== 0x30 || der.length < 8 || der[1] !== der.length - 2) return null;\n let i = 2;\n const part = (): Uint8Array | null => {\n if (der[i] !== 0x02) return null;\n const len = der[i + 1] as number;\n if (len < 1 || len > 33) return null;\n let v = der.slice(i + 2, i + 2 + len);\n if (v.length !== len) return null;\n // Minimal integers only: no needless leading zero, and never negative.\n if ((v[0] as number) & 0x80) return null;\n if (len > 1 && v[0] === 0 && !((v[1] as number) & 0x80)) return null;\n i += 2 + len;\n while (v.length > 32 && v[0] === 0) v = v.slice(1);\n if (v.length > 32) return null;\n const out = new Uint8Array(32);\n out.set(v, 32 - v.length);\n return out;\n };\n const r = part();\n const s = part();\n return r && s && i === der.length ? concat(r, s) : null;\n}\n\nconst u8 = (b: Uint8Array) => b as Uint8Array<ArrayBuffer>;\n/** WebCrypto's key type, named without the DOM lib (Workers, Node and browsers all have it). */\ntype CryptoKey = Awaited<ReturnType<typeof crypto.subtle.importKey>>;\n\nasync function importKey(key: TrustedKey): Promise<CryptoKey | null> {\n const spki = fromB64url(key.spki);\n if (!spki?.length) return null;\n try {\n if (key.alg === ES256)\n return await crypto.subtle.importKey(\"spki\", u8(spki), { name: \"ECDSA\", namedCurve: \"P-256\" }, false, [\"verify\"]);\n if (key.alg === RS256) {\n const k = await crypto.subtle.importKey(\"spki\", u8(spki), { name: \"RSASSA-PKCS1-v1_5\", hash: \"SHA-256\" }, false, [\n \"verify\",\n ]);\n const bits = (k.algorithm as { modulusLength?: number }).modulusLength ?? 0;\n return bits >= 2048 ? k : null;\n }\n } catch {}\n return null;\n}\n\n/** Can this key be enrolled at all? A machine refuses to trust a key it could never verify with. */\nexport async function keyUsable(key: TrustedKey): Promise<boolean> {\n return (\n !!key &&\n typeof key.id === \"string\" &&\n /^[A-Za-z0-9_-]{16,1400}$/.test(key.id) &&\n (key.alg === ES256 || key.alg === RS256) &&\n !!(await importKey(key))\n );\n}\n\n// --- WebAuthn -------------------------------------------------------------------\n\n/** A WebAuthn origin a key may have been used from: https on the rp id or a subdomain;\n * for rp id `localhost`, plain http on any port too. A bare origin, as a browser writes it. */\nexport function originAllowed(origin: unknown, rpId: string): boolean {\n if (typeof origin !== \"string\" || !rpId) return false;\n let u: URL;\n try {\n u = new URL(origin);\n } catch {\n return false;\n }\n if (u.origin !== origin) return false;\n if (u.hostname !== rpId && !u.hostname.endsWith(`.${rpId}`)) return false;\n if (u.protocol === \"https:\") return true;\n return u.protocol === \"http:\" && rpId === \"localhost\";\n}\n\ntype Check = { ok: true } | { ok: false; why: string };\nconst no = (why: string): Check => ({ ok: false, why });\n\n/** One passkey assertion over `challenge`, made with `key`, by a verified person. */\nexport async function verifyAssertion(\n challenge: Uint8Array,\n a: Assertion | null | undefined,\n key: TrustedKey,\n rpId: string,\n): Promise<Check> {\n if (!a || typeof a !== \"object\") return no(\"no passkey signature\");\n if (a.cred !== key.id) return no(\"signed with a key this machine doesn't trust\");\n const cdBytes = fromB64url(a.cd);\n const ad = fromB64url(a.ad);\n const sig = fromB64url(a.sig);\n if (!cdBytes || !ad || !sig?.length) return no(\"the passkey signature is malformed\");\n let cd: { type?: unknown; challenge?: unknown; origin?: unknown; crossOrigin?: unknown };\n try {\n cd = JSON.parse(dec.decode(cdBytes));\n } catch {\n return no(\"the passkey signature is malformed\");\n }\n if (!cd || typeof cd !== \"object\") return no(\"the passkey signature is malformed\");\n if (cd.type !== \"webauthn.get\") return no(\"the passkey answered a different question\");\n if (cd.challenge !== b64url(challenge)) return no(\"the passkey signed something else\");\n if (!originAllowed(cd.origin, rpId)) return no(`the passkey was used on another site, not ${rpId}`);\n if (cd.crossOrigin === true) return no(\"the passkey was used inside another site's frame\");\n if (ad.length < 37) return no(\"the passkey signature is malformed\");\n if (!sameBytes(ad.slice(0, 32), await sha256(rpId))) return no(`the passkey belongs to another site, not ${rpId}`);\n const flags = ad[32] as number;\n if (!(flags & UP) || !(flags & UV)) return no(\"the passkey signed without verifying the person\");\n const pub = await importKey(key);\n if (!pub) return no(\"a trusted key is unusable\");\n const signed = concat(ad, await sha256(cdBytes));\n let good = false;\n try {\n if (key.alg === ES256) {\n const raw = derToRaw(sig);\n good = !!raw && (await crypto.subtle.verify({ name: \"ECDSA\", hash: \"SHA-256\" }, pub, u8(raw), u8(signed)));\n } else {\n good = await crypto.subtle.verify({ name: \"RSASSA-PKCS1-v1_5\" }, pub, u8(sig), u8(signed));\n }\n } catch {\n good = false;\n }\n return good ? { ok: true } : no(\"the passkey signature doesn't verify\");\n}\n\n/** What a passkey signs to enroll on a machine: bound to that machine and that pairing code. */\nexport function pairChallenge(machine: string, code: string): Promise<Uint8Array> {\n return sha256(`sessionpipe.pair:${machine}:${code}`);\n}\n\n/** The enrollment proof: the new key's assertion over pairChallenge(machine, code).\n * Only after this verifies does the key go into the machine's trust store. */\nexport async function verifyEnrollment(o: {\n machine: string;\n code: string;\n key: TrustedKey;\n proof: Assertion;\n rpId: string;\n}): Promise<Check> {\n if (!(await keyUsable(o.key))) return no(\"the key is in a shape this machine can't use\");\n return verifyAssertion(await pairChallenge(o.machine, o.code), o.proof, o.key, o.rpId);\n}\n\n// --- the command ------------------------------------------------------------------\n\ntype Parsed = { ok: true; cmd: ControlCommand } | { ok: false; code: RefusalCode; why: string };\nconst bad = (code: RefusalCode, why: string): { ok: false; code: RefusalCode; why: string } => ({\n ok: false,\n code,\n why,\n});\nconst isNum = (n: unknown): n is number => typeof n === \"number\" && Number.isFinite(n);\n\n/** The session id rule per harness (ADAPTERS.md): Claude Code ids are UUIDs. */\nexport function sessionIdOk(harness: string, id: string): boolean {\n if (!SESSION_ID_RE.test(id)) return false;\n if (harness === \"claude-code\") return UUID_RE.test(id);\n return true;\n}\n\n/** Split `<harness>:<id>`; null when either half breaks its rule. */\nexport function parseSessionRef(ref: unknown): { harness: string; id: string } | null {\n if (typeof ref !== \"string\") return null;\n const i = ref.indexOf(\":\");\n if (i <= 0) return null;\n const harness = ref.slice(0, i);\n const id = ref.slice(i + 1);\n return HARNESS_RE.test(harness) && sessionIdOk(harness, id) ? { harness, id } : null;\n}\n\n/** Read the command's fields from the exact string. Structure only; no clock, no keys. */\nexport function parseCommand(str: unknown): Parsed {\n if (typeof str !== \"string\" || !str || str.length > CMD_MAX)\n return bad(\"malformed\", \"the command is missing or too long\");\n let c: Record<string, unknown>;\n try {\n c = JSON.parse(str);\n } catch {\n return bad(\"malformed\", \"the command is not JSON\");\n }\n if (!c || typeof c !== \"object\" || Array.isArray(c)) return bad(\"malformed\", \"the command is not an object\");\n if (c.v !== 1 || c.t !== COMMAND_TYPE) return bad(\"not_a_command\", \"not a sessionpipe control command\");\n if (typeof c.machine !== \"string\" || !MACHINE_RE.test(c.machine)) return bad(\"malformed\", \"which machine?\");\n if (!CONTROL_KINDS.includes(c.kind as ControlKind))\n return bad(\"unknown_kind\", \"the command asks for something unknown\");\n const ref = parseSessionRef(c.session);\n if (!ref) return bad(\"bad_session\", \"which session?\");\n if (typeof c.nonce !== \"string\" || !NONCE_RE.test(c.nonce))\n return bad(\"bad_nonce\", \"the nonce is missing or malformed\");\n if (!isNum(c.iat) || !Number.isInteger(c.iat) || c.iat <= 0)\n return bad(\"malformed\", \"the command has no signing time\");\n const has = (k: string) => c[k] !== undefined;\n const text = () => typeof c.text === \"string\" && c.text.trim().length > 0 && c.text.length <= TEXT_MAX;\n switch (c.kind as ControlKind) {\n case \"prompt\":\n if (!text()) return bad(\"bad_fields\", `a prompt needs text, at most ${TEXT_MAX} characters`);\n if (has(\"for\") || has(\"decision\") || has(\"cwd\")) return bad(\"bad_fields\", \"a prompt carries only text\");\n break;\n case \"start\":\n if (!text()) return bad(\"bad_fields\", `a new session needs text, at most ${TEXT_MAX} characters`);\n if (ref.harness !== \"claude-code\") return bad(\"bad_fields\", \"only Claude Code sessions can be started\");\n if (typeof c.cwd !== \"string\" || !isAbsolute(c.cwd) || c.cwd.length > 1024)\n return bad(\"bad_fields\", \"a new session needs an absolute folder\");\n if (has(\"for\") || has(\"decision\")) return bad(\"bad_fields\", \"a start carries text and cwd\");\n break;\n case \"permission.answer\":\n if (typeof c.for !== \"string\" || !c.for || c.for.length > 128) return bad(\"bad_fields\", \"which attention?\");\n if (c.decision !== \"allow\" && c.decision !== \"deny\") return bad(\"bad_fields\", \"allow or deny?\");\n if (has(\"text\") || has(\"cwd\")) return bad(\"bad_fields\", \"a permission answer carries for, decision and note\");\n break;\n case \"cancel\":\n if (has(\"text\") || has(\"for\") || has(\"decision\") || has(\"cwd\"))\n return bad(\"bad_fields\", \"a cancel carries nothing\");\n break;\n case \"key.add\": {\n // A device the machine already trusts vouches for a new one (CONTROL.md \u00A72): the\n // new passkey's id, algorithm and public key are inside the signed bytes.\n if (c.session !== KEY_STORE_SESSION) return bad(\"bad_session\", `a key.add names ${KEY_STORE_SESSION}`);\n const k = c.key as { id?: unknown; alg?: unknown; spki?: unknown } | undefined;\n const b64 = (v: unknown, min: number, max: number) =>\n typeof v === \"string\" && v.length >= min && v.length <= max && /^[A-Za-z0-9_-]+$/.test(v);\n if (\n !k ||\n typeof k !== \"object\" ||\n !b64(k.id, 16, 1400) ||\n (k.alg !== -7 && k.alg !== -257) ||\n !b64(k.spki, 40, 2000)\n )\n return bad(\"bad_fields\", \"a key.add carries the key: id, alg (-7 or -257) and spki\");\n if (has(\"name\") && (typeof c.name !== \"string\" || !c.name.trim() || c.name.length > 80))\n return bad(\"bad_fields\", \"a device name is text, at most 80 characters\");\n if (has(\"text\") || has(\"for\") || has(\"decision\") || has(\"cwd\"))\n return bad(\"bad_fields\", \"a key.add carries the key and a name\");\n break;\n }\n }\n if (c.kind !== \"key.add\" && (has(\"key\") || has(\"name\"))) return bad(\"bad_fields\", \"only a key.add carries a key\");\n if (has(\"note\") && (typeof c.note !== \"string\" || c.note.length > NOTE_MAX))\n return bad(\"bad_fields\", `a note is text, at most ${NOTE_MAX} characters`);\n return { ok: true, cmd: c as unknown as ControlCommand };\n}\n\nfunction isAbsolute(p: string): boolean {\n return p.startsWith(\"/\") || /^[A-Za-z]:[\\\\/]/.test(p);\n}\n\n/** The grant's fields, read from its exact string. */\nexport function parseGrant(str: unknown, rpId: string): { ok: true; grant: Grant } | { ok: false; why: string } {\n if (typeof str !== \"string\" || !str || str.length > GRANT_STR_MAX)\n return { ok: false, why: \"the grant is missing or too long\" };\n let g: Record<string, unknown>;\n try {\n g = JSON.parse(str);\n } catch {\n return { ok: false, why: \"the grant is not JSON\" };\n }\n if (!g || typeof g !== \"object\" || Array.isArray(g)) return { ok: false, why: \"the grant is not an object\" };\n if (g.v !== 1 || g.t !== GRANT_TYPE) return { ok: false, why: \"not a sessionpipe grant\" };\n if (g.rp !== rpId) return { ok: false, why: `the grant is for another site, not ${rpId}` };\n if (typeof g.pub !== \"string\" || !fromB64url(g.pub)?.length || !isNum(g.iat) || !isNum(g.exp))\n return { ok: false, why: \"the grant is missing parts\" };\n if (g.exp <= g.iat) return { ok: false, why: \"the grant ends before it starts\" };\n if (g.exp - g.iat > GRANT_MAX_MS + SKEW_MS) return { ok: false, why: \"the grant lasts longer than a day\" };\n return { ok: true, grant: g as unknown as Grant };\n}\n\nasync function verifyCsig(cmd: string, csig: unknown, pub: string): Promise<boolean> {\n const sig = fromB64url(csig);\n const spki = fromB64url(pub);\n if (sig?.length !== 64 || !spki) return false;\n try {\n const key = await crypto.subtle.importKey(\"spki\", u8(spki), { name: \"ECDSA\", namedCurve: \"P-256\" }, false, [\n \"verify\",\n ]);\n return await crypto.subtle.verify({ name: \"ECDSA\", hash: \"SHA-256\" }, key, u8(sig), u8(enc.encode(cmd)));\n } catch {\n return false;\n }\n}\n\n/**\n * Is this a command this machine may run? The checks, in the spec's order\n * (CONTROL.md \u00A75): the exact bytes parse; the command is for this machine; it is\n * signed \u2014 a grant from a trusted key plus the day key's signature, or a confirm\n * over sha256(cmd); it was signed within the age window; its nonce is new.\n * The folder and open-attention checks that follow are the daemon's (they read\n * the machine, not the command).\n */\nexport async function verifyCommand(s: SignedCommand | null | undefined, o: VerifyOptions): Promise<Verdict> {\n if (!s || typeof s !== \"object\") return bad(\"malformed\", \"nothing to verify\");\n const p = parseCommand(s.cmd);\n if (!p.ok) return p;\n const c = p.cmd;\n if (c.machine !== o.machine) return bad(\"wrong_machine\", \"the command is for another machine\");\n\n let via: \"grant\" | \"confirm\" | null = null;\n let keyId = \"\";\n let refusal: { code: RefusalCode; why: string } | null = null;\n if (s.grant && s.csig) {\n const r = await checkGrantPath(s, c, o);\n if (r.ok) {\n via = \"grant\";\n keyId = r.key;\n } else refusal = r;\n }\n if (!via && s.confirm) {\n const key = o.trusted.find((k) => k && k.id === s.confirm?.cred);\n if (!key) refusal = { code: \"untrusted_key\", why: \"confirmed with a key this machine doesn't trust\" };\n else {\n const a = await verifyAssertion(await sha256(s.cmd), s.confirm, key, o.rpId);\n if (a.ok) {\n via = \"confirm\";\n keyId = key.id;\n } else refusal = { code: \"bad_assertion\", why: a.why };\n }\n }\n if (!via) {\n if (refusal) return bad(refusal.code, refusal.why);\n return bad(\"unsigned\", \"the command isn't signed\");\n }\n if (c.iat > o.now + SKEW_MS) return bad(\"future\", \"the command is dated in the future (is this clock right?)\");\n if (o.now - c.iat > (o.maxAgeMs ?? MACHINE_MAX_AGE_MS)) return bad(\"too_old\", \"the command was signed too long ago\");\n if (o.seenNonce) {\n let seen: boolean;\n try {\n seen = await o.seenNonce(c.nonce);\n } catch {\n return bad(\"nonce_store\", \"the nonce couldn't be recorded, so the command didn't run\");\n }\n if (seen) return bad(\"replay\", \"this command was already used once\");\n }\n return { ok: true, cmd: c, via, key: keyId };\n}\n\nasync function checkGrantPath(\n s: SignedCommand,\n c: ControlCommand,\n o: VerifyOptions,\n): Promise<{ ok: true; key: string } | { ok: false; code: RefusalCode; why: string }> {\n const bundle = s.grant as GrantBundle;\n const g = parseGrant(bundle.str, o.rpId);\n if (!g.ok) return bad(\"bad_grant\", g.why);\n const key = o.trusted.find((k) => k && k.id === bundle.cred);\n if (!key) return bad(\"untrusted_key\", \"the grant was signed with a key this machine doesn't trust\");\n const a = await verifyAssertion(await sha256(bundle.str), bundle, key, o.rpId);\n if (!a.ok) return bad(\"bad_assertion\", a.why);\n if (!(await verifyCsig(s.cmd, s.csig, g.grant.pub)))\n return bad(\"bad_csig\", \"the command's signature doesn't verify \u2014 it was changed after it was signed\");\n if (c.iat < g.grant.iat - SKEW_MS || c.iat > g.grant.exp)\n return bad(\"outside_grant\", \"the command was signed outside its grant's window\");\n return { ok: true, key: key.id };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The answer to a message delivered in place (spec/CONTROL.md \u00A76 `prompt`). A waiter or\n// a Stop block hands the message to the live session, which answers in its own turn;\n// the daemon reads that turn from the session's own transcript and sends it back as the\n// ack's `reply`, so the person sees the answer where they asked. Only the bytes the\n// transcript gained after the delivery are read: a long session's file is never parsed\n// whole, and nothing from before the message can be mistaken for its answer.\nimport { closeSync, openSync, readSync, statSync } from \"node:fs\";\n\n/** The transcript's size now: where its answer will start. */\nexport function transcriptEnd(file: string): number {\n try {\n return statSync(file).size;\n } catch {\n return 0;\n }\n}\n\n/** Claude Code records after the delivery \u2192 the turn's answer once the turn ended\n * (an assistant record with `stop_reason: \"end_turn\"`), else null. The answer is the\n * turn's assistant text, in order; sidechains (subagents) are not the session's words. */\nexport function answerIn(lines: string[]): { done: boolean; text: string } {\n const parts: string[] = [];\n for (const line of lines) {\n let j: {\n type?: string;\n isSidechain?: boolean;\n message?: { stop_reason?: string; content?: unknown };\n };\n try {\n j = JSON.parse(line);\n } catch {\n continue;\n }\n if (j.type !== \"assistant\" || j.isSidechain) continue;\n const content = j.message?.content;\n if (Array.isArray(content))\n for (const c of content as { type?: string; text?: unknown }[])\n if (c?.type === \"text\" && typeof c.text === \"string\" && c.text.trim()) parts.push(c.text.trim());\n if (j.message?.stop_reason === \"end_turn\") return { done: true, text: parts.join(\"\\n\\n\") };\n }\n return { done: false, text: parts.join(\"\\n\\n\") };\n}\n\n/** Wait for the turn that follows a delivery to end, reading the transcript from\n * `from` (its size at delivery). Resolves the answer, or null when the turn doesn't\n * end within `timeoutMs` (an interrupted turn, a session closed mid-answer). */\nexport async function awaitAnswer(\n file: string,\n from: number,\n o: {\n timeoutMs: number;\n pollMs?: number;\n now?: () => number;\n sleep?: (ms: number) => Promise<void>;\n /** The turn's text so far, each time it grows (for the progress ack). */\n onText?: (text: string) => void;\n },\n): Promise<string | null> {\n const now = o.now ?? Date.now;\n const sleep = o.sleep ?? ((ms: number) => new Promise<void>((r) => setTimeout(r, ms).unref?.()));\n const until = now() + o.timeoutMs;\n let offset = from;\n let partial = \"\";\n const lines: string[] = [];\n while (now() < until) {\n const size = transcriptEnd(file);\n if (size < offset) return null; // rewritten under us: nothing we can trust\n if (size > offset) {\n const fd = openSync(file, \"r\");\n try {\n const buf = Buffer.alloc(Math.min(size - offset, 4 * 1024 * 1024));\n const n = readSync(fd, buf, 0, buf.length, offset);\n offset += n;\n const chunk = partial + buf.subarray(0, n).toString(\"utf8\");\n const cut = chunk.lastIndexOf(\"\\n\");\n partial = cut < 0 ? chunk : chunk.slice(cut + 1);\n if (cut >= 0) lines.push(...chunk.slice(0, cut).split(\"\\n\").filter(Boolean));\n } finally {\n closeSync(fd);\n }\n const a = answerIn(lines);\n if (a.done) return a.text || null;\n if (a.text) o.onText?.(a.text);\n }\n await sleep(o.pollMs ?? 500);\n }\n return null;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The routing rule (spec/CONTROL.md \u00A76): the first delivery mode that fits, top to\n// bottom. Pure, so every branch is a unit test.\nimport type { ControlKind } from \"@sessionpipe/core/control\";\n\nexport type DeliveryMode = \"sdk\" | \"waiter\" | \"turn\" | \"api\" | \"resume\" | \"fork\";\n\nexport interface SessionView {\n harness: string;\n /** The daemon holds this session through the Agent SDK right now. */\n sdk: boolean;\n /** A `sessionpipe wait` for it is parked on the socket. */\n waiter: boolean;\n /** Between a turn's start and its Stop (the Stop hook will ask). */\n midTurn: boolean;\n /** A live process holds the session (registry entry or a fresh transcript write). */\n live: boolean;\n /** The transcript exists on this machine. */\n known: boolean;\n /** This Claude Code can copy a session (`--fork-session`). */\n canFork: boolean;\n /** The harness has an input API (OpenCode, Codex app-server) \u2014 none is wired yet. */\n api: boolean;\n}\n\nexport type Route = { mode: DeliveryMode } | { unsupported: string } | { refused: \"no_session\" };\n\n/** Where a prompt (or a start) goes. Never two writers on one transcript: a live\n * session gets a fork, never a resume. */\nexport function routePrompt(s: SessionView): Route {\n if (s.sdk) return { mode: \"sdk\" };\n if (s.waiter) return { mode: \"waiter\" };\n if (s.midTurn) return { mode: \"turn\" };\n if (s.api) return { mode: \"api\" };\n if (s.harness !== \"claude-code\") return { unsupported: `no idle delivery for ${s.harness} yet` };\n if (!s.known) return { refused: \"no_session\" };\n if (!s.live) return { mode: \"resume\" };\n if (s.canFork) return { mode: \"fork\" };\n return { unsupported: \"the session is open and this Claude Code can't copy it (no --fork-session)\" };\n}\n\n/** How each kind is delivered, before the session's state is looked at. */\nexport function kindPath(\n kind: ControlKind,\n harness: string,\n): \"prompt\" | \"permission\" | \"cancel\" | \"start\" | { unsupported: string } {\n switch (kind) {\n case \"prompt\":\n return \"prompt\";\n case \"permission.answer\":\n return harness === \"gemini-cli\" ? { unsupported: \"Gemini CLI has no permission answer channel\" } : \"permission\";\n case \"cancel\":\n return \"cancel\";\n case \"start\":\n return harness === \"claude-code\" ? \"start\" : { unsupported: `can't start a ${harness} session` };\n default:\n return { unsupported: `unknown kind ${String(kind)}` };\n }\n}\n\n/** The framed text a session receives (CONTROL.md \u00A76): the model and the person can\n * tell where it came from. */\n/** Said with every message that reaches a live session: the answer goes back by\n * itself (the daemon reads it from the transcript), so the model never invents a\n * command to reply with (a real session tried \\`sessionpipe send\\`, 2026-10-01). */\nexport const IN_PLACE_ANSWER =\n \"Answer it right here, as you would answer the person at the keyboard: your reply is sent back to them automatically. Don't run a command or call a tool just to send it.\";\n\nexport function frame(text: string, receiver: string): string {\n let host = receiver;\n try {\n host = new URL(receiver).host;\n } catch {}\n return `Message via ${host} (sessionpipe control, signed on the sender's device):\\n\\n${text}`;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// What the control daemon keeps on disk:\n// config/control.json the receivers this machine is paired with: machine id,\n// the machine's own token, the enrolled keys, folders, mode (0600)\n// state/control/nonces.jsonl every verified nonce for 25 h, fsync'd before a\n// command runs (a failed write refuses it)\n// state/control/acks.jsonl acks not yet accepted by their receiver\n// state/control/state.json forks: which copy a message to a session goes to\nimport {\n appendFileSync,\n chmodSync,\n closeSync,\n existsSync,\n fsyncSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n writeFileSync,\n} from \"node:fs\";\nimport path from \"node:path\";\nimport { configFile, stateDir } from \"@sessionpipe/core\";\nimport { NONCE_TTL_MS, type TrustedKey } from \"@sessionpipe/core/control\";\nimport {\n controlAccount,\n defaultRunner,\n type Runner,\n type SecretStore,\n type StoreName,\n secretDel,\n secretGet,\n secretSet,\n} from \"../secrets.js\";\n\nexport interface PairedReceiver {\n /** The receiver's origin, as the person typed it. */\n url: string;\n /** Absolute control endpoint (from the well-known file). */\n control: string;\n rpId: string;\n machine: string;\n /** The machine's own bearer (polls, acks, hello, off): opens nothing else. Empty\n * when it lives in a store this process can't read right now. */\n token: string;\n /** The token lives in this store, not in control.json (secrets.ts). */\n token_in?: SecretStore;\n keys: (TrustedKey & { name?: string; added_at: string })[];\n paired_at: string;\n}\n\nexport interface ControlConfig {\n name: string;\n /** Folders sessions may run in; compared on whole path segments, real paths. */\n folders: string[];\n mode: \"safe\" | \"auto\";\n receivers: PairedReceiver[];\n /** Caps this machine keeps whatever a receiver sends (defaults in daemon.ts,\n * LIMITS): new sessions running at once and per hour, headless Claude Code runs\n * at once. */\n limits?: { start_concurrent?: number; start_per_hour?: number; headless?: number };\n}\n\nexport const controlFile = (env: NodeJS.ProcessEnv = process.env) =>\n path.join(path.dirname(configFile(env)), \"control.json\");\nexport const controlState = (env: NodeJS.ProcessEnv = process.env) => path.join(stateDir(env), \"control\");\n\nfunction writePrivate(file: string, value: unknown): void {\n mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });\n const tmp = `${file}.${process.pid}.tmp`;\n writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n renameSync(tmp, file);\n try {\n chmodSync(file, 0o600);\n } catch {}\n}\n\nexport function readControl(env: NodeJS.ProcessEnv = process.env, run: Runner = defaultRunner): ControlConfig | null {\n try {\n const j = JSON.parse(readFileSync(controlFile(env), \"utf8\")) as ControlConfig;\n if (!j || !Array.isArray(j.receivers)) return null;\n return {\n name: j.name || \"machine\",\n folders: j.folders ?? [],\n mode: j.mode === \"auto\" ? \"auto\" : \"safe\",\n receivers: j.receivers.map((r) =>\n r.token_in ? { ...r, token: secretGet(r.token_in, controlAccount(r.machine), run) ?? \"\" } : r,\n ),\n ...(j.limits ? { limits: j.limits } : {}),\n };\n } catch {\n return null;\n }\n}\n\n/** A token kept in a store is never written back into the file. */\nexport const writeControl = (c: ControlConfig, env: NodeJS.ProcessEnv = process.env) =>\n writePrivate(controlFile(env), {\n ...c,\n receivers: c.receivers.map((r) => {\n if (!r.token_in) return r;\n const { token: _t, ...rest } = r;\n return rest;\n }),\n });\n\n/** Move every paired receiver's token into `to` (or back into control.json). A token\n * this process can't read is left where it is. */\nexport function moveControlSecrets(\n to: StoreName,\n o: { env?: NodeJS.ProcessEnv; run?: Runner } = {},\n): { moved: string[]; kept: string[] } {\n const run = o.run ?? defaultRunner;\n const cfg = readControl(o.env, run);\n const moved: string[] = [];\n const kept: string[] = [];\n if (!cfg) return { moved, kept };\n const drop: { store: SecretStore; machine: string }[] = [];\n for (const r of cfg.receivers) {\n if ((r.token_in ?? \"file\") === to) continue;\n if (!r.token) {\n kept.push(r.url);\n continue;\n }\n if (to !== \"file\" && !secretSet(to, controlAccount(r.machine), r.token, run)) {\n secretDel(to, controlAccount(r.machine), run);\n kept.push(r.url);\n continue;\n }\n if (r.token_in) drop.push({ store: r.token_in, machine: r.machine });\n if (to === \"file\") delete r.token_in;\n else r.token_in = to;\n moved.push(r.url);\n }\n writeControl(cfg, o.env);\n for (const d of drop) secretDel(d.store, controlAccount(d.machine), run);\n return { moved, kept };\n}\n\n/** Forget a receiver's token wherever it is (control off). */\nexport function dropControlSecret(r: PairedReceiver, run: Runner = defaultRunner): void {\n if (r.token_in) secretDel(r.token_in, controlAccount(r.machine), run);\n}\n\n/** Nonces the machine has run, for NONCE_TTL_MS. `seen()` records a new nonce\n * durably BEFORE it answers false; a write that fails throws, and the verifier\n * refuses the command (`nonce_store`). */\nexport class NonceStore {\n private readonly seenAt = new Map<string, number>();\n constructor(\n private readonly file: string,\n private readonly now: () => number = Date.now,\n ) {\n let raw = \"\";\n try {\n raw = readFileSync(file, \"utf8\");\n } catch {}\n const cut = this.now() - NONCE_TTL_MS;\n for (const line of raw.split(\"\\n\")) {\n if (!line) continue;\n try {\n const { n, t } = JSON.parse(line) as { n: string; t: number };\n if (typeof n === \"string\" && t > cut) this.seenAt.set(n, t);\n } catch {}\n }\n this.compact();\n }\n\n seen = (nonce: string): boolean => {\n const t = this.seenAt.get(nonce);\n if (t !== undefined && t > this.now() - NONCE_TTL_MS) return true;\n const at = this.now();\n mkdirSync(path.dirname(this.file), { recursive: true, mode: 0o700 });\n const fd = openSync(this.file, \"a\", 0o600);\n try {\n appendFileSync(fd, `${JSON.stringify({ n: nonce, t: at })}\\n`);\n fsyncSync(fd);\n } finally {\n closeSync(fd);\n }\n this.seenAt.set(nonce, at);\n return false;\n };\n\n /** Rewrite the file with only the live window (on start, and daily). */\n compact(): void {\n const cut = this.now() - NONCE_TTL_MS;\n for (const [n, t] of this.seenAt) if (t <= cut) this.seenAt.delete(n);\n if (!existsSync(this.file) && !this.seenAt.size) return;\n const body = [...this.seenAt].map(([n, t]) => JSON.stringify({ n, t })).join(\"\\n\");\n mkdirSync(path.dirname(this.file), { recursive: true, mode: 0o700 });\n writeFileSync(`${this.file}.tmp`, body ? `${body}\\n` : \"\", { mode: 0o600 });\n renameSync(`${this.file}.tmp`, this.file);\n }\n\n get size(): number {\n return this.seenAt.size;\n }\n}\n\nexport interface Ack {\n receiver: string;\n id: string;\n outcome: \"taken\" | \"delivered\" | \"expired\" | \"unsupported\" | \"failed\" | \"refused\";\n at: string;\n mode?: string;\n session?: string;\n code?: string;\n detail?: string;\n reply?: string;\n}\n\n/** Acks not yet accepted: appended before they are sent, rewritten when sent, so a\n * daemon restart re-sends rather than forgets (every message is acked exactly once\n * with a final outcome; a duplicate is tolerated by the receiver). */\nexport class AckOutbox {\n constructor(private readonly file: string) {}\n all(): Ack[] {\n try {\n return readFileSync(this.file, \"utf8\")\n .split(\"\\n\")\n .filter(Boolean)\n .map((l) => JSON.parse(l) as Ack);\n } catch {\n return [];\n }\n }\n add(a: Ack): void {\n mkdirSync(path.dirname(this.file), { recursive: true, mode: 0o700 });\n appendFileSync(this.file, `${JSON.stringify(a)}\\n`, { mode: 0o600 });\n }\n keep(left: Ack[]): void {\n mkdirSync(path.dirname(this.file), { recursive: true, mode: 0o700 });\n writeFileSync(`${this.file}.tmp`, left.map((a) => JSON.stringify(a)).join(\"\\n\") + (left.length ? \"\\n\" : \"\"), {\n mode: 0o600,\n });\n renameSync(`${this.file}.tmp`, this.file);\n }\n}\n\nexport interface DaemonState {\n /** Original session \u2192 the fork its messages go to. */\n copies: Record<string, string>;\n}\n\nexport function readState(file: string): DaemonState {\n try {\n const j = JSON.parse(readFileSync(file, \"utf8\")) as DaemonState;\n return { copies: j.copies && typeof j.copies === \"object\" ? j.copies : {} };\n } catch {\n return { copies: {} };\n }\n}\nexport const writeState = (file: string, s: DaemonState) => writePrivate(file, s);\n", "// SPDX-License-Identifier: Apache-2.0\n// The answer as it is written (spec/CONTROL.md \u00A710, the `progress` ack). A headless run\n// streams Claude Code's output (`--output-format stream-json --include-partial-\n// messages`) and a live session's transcript grows message by message; either way the\n// daemon sends the receiver the answer SO FAR, whole, with a rising seq. Reliability\n// comes from that shape, not from delivery: a progress ack is fire-and-forget, a lost\n// one is covered by the next, and the final `delivered` ack always carries the full\n// answer. At most one is in flight, at most one every `everyMs`.\n\n/** One stream-json line \u2192 text to append, or a message boundary (a new assistant\n * message after a tool step: its text starts a new paragraph). */\nexport function streamJsonPiece(line: string): { text?: string; boundary?: boolean } | null {\n let j: {\n type?: string;\n parent_tool_use_id?: unknown;\n event?: { type?: string; delta?: { type?: string; text?: unknown } };\n };\n try {\n j = JSON.parse(line);\n } catch {\n return null;\n }\n if (j.type !== \"stream_event\" || !j.event) return null;\n // A subagent's stream (a Task tool's) is not the session's answer.\n if (j.parent_tool_use_id) return null;\n const e = j.event;\n if (e.type === \"content_block_delta\" && e.delta?.type === \"text_delta\" && typeof e.delta.text === \"string\")\n return { text: e.delta.text };\n if (e.type === \"message_start\") return { boundary: true };\n return null;\n}\n\nexport class AnswerStream {\n private text = \"\";\n private sent = \"\";\n private seq = 0;\n private timer: NodeJS.Timeout | null = null;\n private inFlight = false;\n private closed = false;\n\n constructor(\n private readonly send: (text: string, seq: number) => Promise<void>,\n private readonly everyMs = 400,\n ) {}\n\n /** A stream-json line from a headless run. */\n feed(line: string): void {\n const p = streamJsonPiece(line);\n if (!p) return;\n if (p.boundary) {\n if (this.text && !this.text.endsWith(\"\\n\\n\")) this.text += \"\\n\\n\";\n return;\n }\n if (p.text) {\n this.text += p.text;\n this.schedule();\n }\n }\n\n /** The whole answer so far (a live session's transcript). */\n set(text: string): void {\n if (text === this.text) return;\n this.text = text;\n this.schedule();\n }\n\n /** No more progress: the final ack follows. */\n close(): void {\n this.closed = true;\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n }\n\n private schedule(): void {\n if (this.closed || this.timer || this.inFlight) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.everyMs);\n this.timer.unref?.();\n }\n\n private async flush(): Promise<void> {\n const t = this.text.trim();\n if (this.closed || !t || t === this.sent) return;\n this.inFlight = true;\n this.sent = t;\n try {\n await this.send(t, ++this.seq);\n } catch {\n // Best effort: the next one, or the final ack, carries everything.\n } finally {\n this.inFlight = false;\n }\n if (this.text.trim() !== this.sent) this.schedule();\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// `sessionpipe control pair <receiver>`: a key enters this machine's trust store only\n// from this terminal (spec/CONTROL.md \u00A72). The receiver hands back a passkey and a\n// proof over sha256(\"sessionpipe.pair:<machine>:<code>\"); the key is trusted only once\n// the proof verifies here. Also the service files (launchd / systemd) that keep the\n// daemon running, and `control off`.\nimport { execFileSync } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport { existsSync, mkdirSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { type TrustedKey, verifyEnrollment } from \"@sessionpipe/core/control\";\nimport {\n type ControlConfig,\n controlState,\n dropControlSecret,\n type PairedReceiver,\n readControl,\n writeControl,\n} from \"./store.js\";\n\ndeclare const __SESSIONPIPE_VERSION__: string;\nconst VERSION = typeof __SESSIONPIPE_VERSION__ === \"string\" ? __SESSIONPIPE_VERSION__ : \"0.0.0\";\n\nexport interface PairOptions {\n url: string;\n /** The person's sink token for this receiver (from `sink add`, or --token). Null:\n * open pairing, where the receiver offers it \u2014 the person approves a link and that\n * is the whole setup (CONTROL.md \u00A72). */\n token: string | null;\n folders: string[];\n mode: \"safe\" | \"auto\";\n name: string;\n out: (s: string) => void;\n fetch?: typeof fetch;\n sleep?: (ms: number) => Promise<void>;\n env?: NodeJS.ProcessEnv;\n /** Called with a sessions key the receiver handed over at pairing. */\n addSink?: (token: string) => void;\n}\n\nasync function json(r: Response): Promise<Record<string, unknown>> {\n try {\n return (await r.json()) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\nexport async function discover(\n url: string,\n f: typeof fetch,\n): Promise<{ control: string; rpId: string; open: boolean; events: string | null }> {\n const base = url.replace(/\\/$/, \"\");\n const r = await f(`${base}/.well-known/sessionpipe`);\n if (!r.ok) throw new Error(`${base} has no sessionpipe well-known file (HTTP ${r.status})`);\n const wk = (await r.json()) as {\n capabilities?: string[];\n endpoints?: { control?: string; events?: string };\n control?: { signing?: { rp_id?: string }; open_pairing?: boolean };\n };\n if (!wk.capabilities?.includes(\"control\") || !wk.endpoints?.control || !wk.control?.signing?.rp_id)\n throw new Error(`${base} doesn't serve control yet (its well-known file lists no control.signing)`);\n const abs = (ep: string) => (/^https?:\\/\\//.test(ep) ? ep : base + ep);\n return {\n control: abs(wk.endpoints.control),\n rpId: wk.control.signing.rp_id,\n open: wk.control.open_pairing === true,\n events: wk.endpoints.events ? abs(wk.endpoints.events) : null,\n };\n}\n\n/** Pair (or add a key to) this machine with one receiver. Returns the saved config. */\nexport async function pair(o: PairOptions): Promise<ControlConfig> {\n const f = o.fetch ?? fetch;\n const sleep = o.sleep ?? ((ms: number) => new Promise((r) => setTimeout(r, ms)));\n const { control, rpId, open } = await discover(o.url, f);\n if (!o.token && !open)\n throw new Error(\n `${o.url} needs a key to pair: add it as a sink first (\\`sessionpipe sink add ${o.url} --token \u2026\\`) or pass --token.`,\n );\n // Open pairing: a secret only this terminal knows. The receiver keeps its hash, and\n // the status poll that hands over the machine's token must present it \u2014 so the link,\n // which the person opens elsewhere, is not a credential by itself.\n const pollKey = o.token ? null : randomBytes(32).toString(\"base64url\");\n const cfg: ControlConfig = readControl(o.env) ?? { name: o.name, folders: [], mode: o.mode, receivers: [] };\n cfg.name = o.name || cfg.name;\n cfg.mode = o.mode;\n cfg.folders = [...new Set([...cfg.folders, ...o.folders.map((d) => path.resolve(d))])];\n const existing = cfg.receivers.find((r) => r.control === control);\n const auth = { authorization: `Bearer ${o.token ?? pollKey}`, \"content-type\": \"application/json\" };\n const started = await f(`${control}/pair`, {\n method: \"POST\",\n headers: o.token ? auth : { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n ...(pollKey ? { poll_key: pollKey } : {}),\n ...(existing ? { machine: existing.machine } : {}),\n name: cfg.name,\n harnesses: [\"claude-code\"],\n modes: [\"waiter\", \"turn\", \"resume\", \"fork\"],\n version: VERSION,\n folders: cfg.folders,\n mode: cfg.mode,\n }),\n });\n const s = await json(started);\n if (started.status !== 201 && started.status !== 200)\n throw new Error(\n `the receiver refused to start pairing (HTTP ${started.status}${s.reason ? `: ${String(s.reason)}` : \"\"})`,\n );\n const machine = String(s.machine);\n const code = String(s.code);\n o.out(\"\");\n const digits = String(s.check);\n const spaced = /^\\d{6}$/.test(digits) ? `${digits.slice(0, 3)} ${digits.slice(3)}` : digits;\n // The approval happens on whatever device holds the person's passkey, which is\n // rarely the machine being paired (a server may have no screen at all): say so, or\n // the \"Touch ID\" line reads as \"do it here\" (2026-10-02, four machines, one headless).\n const host = new URL(o.url).host;\n o.out(` On any phone or computer where you're signed in to ${host} (it doesn't have to be this one),`);\n if (pollKey) {\n // Open pairing: one address for everyone, and the digits are what the person types.\n o.out(` open ${String(s.url)} and enter: ${spaced}`);\n o.out(\" then approve with that device's passkey (Touch ID, Face ID, a security key).\");\n o.out(\" Pairing several machines? Run this on each one: every machine shows its own digits.\");\n } else {\n o.out(\" open this link and approve with that device's passkey (Touch ID, Face ID, a security key):\");\n o.out(` ${String(s.url)}`);\n o.out(` The page shows these digits too: ${digits}`);\n }\n o.out(\"\");\n const until = Date.parse(String(s.expires_at)) || Date.now() + 10 * 60_000;\n for (;;) {\n if (Date.now() > until) throw new Error(\"the pairing link expired; run `sessionpipe control pair` again\");\n await sleep(2000);\n const r = await f(`${control}/pair?code=${encodeURIComponent(code)}`, { headers: auth }).catch(() => null);\n if (!r) continue;\n if (r.status === 404) throw new Error(\"the receiver lost the pairing; run `sessionpipe control pair` again\");\n const p = await json(r);\n if (p.status === \"expired\") throw new Error(\"the pairing link expired; run `sessionpipe control pair` again\");\n if (p.status !== \"paired\") continue;\n const key = p.key as TrustedKey;\n const proof = p.proof as { cred: string; ad: string; cd: string; sig: string };\n const v = await verifyEnrollment({ machine, code, key, proof, rpId });\n if (!v.ok) throw new Error(`the receiver's key didn't prove itself (${v.why}); nothing was trusted`);\n const token = existing?.token || (typeof p.token === \"string\" ? p.token : \"\");\n if (!token) throw new Error(\"the receiver didn't hand this machine its token\");\n const rec: PairedReceiver = existing ?? {\n url: o.url.replace(/\\/$/, \"\"),\n control,\n rpId,\n machine,\n token,\n keys: [],\n paired_at: new Date().toISOString(),\n };\n if (!rec.keys.some((k) => k.id === key.id)) rec.keys.push({ ...key, added_at: new Date().toISOString() });\n if (!existing) cfg.receivers.push(rec);\n writeControl(cfg, o.env);\n o.out(` \u2713 Paired with ${rec.url} as ${machine} \u00B7 ${rec.keys.length} key(s) trusted on this machine`);\n // Whose passkey this machine now trusts: with open pairing, whoever approved the link.\n if (typeof p.account === \"string\")\n o.out(` Approved by ${p.account}. If that isn't you, run \\`sessionpipe control off\\` now.`);\n // The receiver may hand over a sessions-only key for the events lane, so its session\n // board shows this machine without a second step.\n if (typeof p.sink_token === \"string\" && o.addSink) o.addSink(p.sink_token);\n return cfg;\n }\n}\n\n/** `control off [<receiver>]`: tell the receiver, forget its token and keys. */\nexport async function off(o: {\n url?: string;\n out: (s: string) => void;\n fetch?: typeof fetch;\n env?: NodeJS.ProcessEnv;\n}) {\n const f = o.fetch ?? fetch;\n const cfg = readControl(o.env);\n if (!cfg) return o.out(\" control isn't set up on this machine\");\n const gone = cfg.receivers.filter((r) => !o.url || r.url === o.url.replace(/\\/$/, \"\"));\n for (const r of gone) {\n await f(`${r.control}/off`, { method: \"POST\", headers: { authorization: `Bearer ${r.token}` } }).catch(() => null);\n dropControlSecret(r);\n o.out(` removed ${r.url} (${r.machine}, ${r.keys.length} key(s))`);\n }\n cfg.receivers = cfg.receivers.filter((r) => !gone.includes(r));\n writeControl(cfg, o.env);\n return cfg;\n}\n\nexport function removeKey(id: string, env?: NodeJS.ProcessEnv): number {\n const cfg = readControl(env);\n if (!cfg) return 0;\n let n = 0;\n for (const r of cfg.receivers) {\n const before = r.keys.length;\n r.keys = r.keys.filter((k) => k.id !== id && !k.id.startsWith(id));\n n += before - r.keys.length;\n }\n writeControl(cfg, env);\n return n;\n}\n\n// --- the service -------------------------------------------------------------------\n\nconst LABEL = \"org.sessionpipe.control\";\nconst UNIT = \"sessionpipe-control.service\";\n\nexport function serviceFiles(o: { node: string; cli: string; logDir: string; home?: string }) {\n const home = o.home ?? os.homedir();\n const xml = (s: string) => s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key><string>${LABEL}</string>\n <key>ProgramArguments</key>\n <array><string>${xml(o.node)}</string><string>${xml(o.cli)}</string><string>control</string><string>run</string></array>\n <key>RunAtLoad</key><true/>\n <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>\n <key>ProcessType</key><string>Background</string>\n <key>StandardOutPath</key><string>${xml(path.join(o.logDir, \"daemon.log\"))}</string>\n <key>StandardErrorPath</key><string>${xml(path.join(o.logDir, \"daemon.log\"))}</string>\n</dict>\n</plist>\n`;\n const q = (s: string) => `\"${s.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/%/g, \"%%\")}\"`;\n const unit = `[Unit]\nDescription=sessionpipe control daemon (signed messages to your coding sessions)\nAfter=network-online.target\n\n[Service]\nExecStart=${q(o.node)} ${q(o.cli)} control run\nRestart=on-failure\nRestartSec=5\n\n[Install]\nWantedBy=default.target\n`;\n return {\n plist: { file: path.join(home, \"Library\", \"LaunchAgents\", `${LABEL}.plist`), body: plist },\n unit: { file: path.join(home, \".config\", \"systemd\", \"user\", UNIT), body: unit },\n };\n}\n\nexport type Exec = (cmd: string, args: string[]) => string;\nconst execQuiet: Exec = (cmd, args) =>\n execFileSync(cmd, args, { encoding: \"utf8\", stdio: [\"ignore\", \"pipe\", \"ignore\"], timeout: 15_000 });\n\n/** A systemd user service stops when its person's last login ends \u2014 closing the ssh\n * session to a lab workstation or a cloud machine stopped the daemon with it \u2014 unless\n * the user lingers. `loginctl enable-linger` for yourself needs no root on systemd's\n * default policy; where it does, say the one command that does it. */\nexport function ensureLinger(user: string, exec: Exec = execQuiet): { on: boolean; note: string } {\n const lingering = () => {\n try {\n return /^Linger=yes/m.test(exec(\"loginctl\", [\"show-user\", user, \"--property=Linger\"]));\n } catch {\n return false;\n }\n };\n if (lingering()) return { on: true, note: \"it keeps running after you log out (linger was already on)\" };\n try {\n exec(\"loginctl\", [\"enable-linger\", user]);\n } catch {}\n if (lingering()) return { on: true, note: \"it keeps running after you log out (turned linger on)\" };\n return {\n on: false,\n note: `it stops when you log out: run \\`sudo loginctl enable-linger ${user}\\` once to keep it running`,\n };\n}\n\n/** Write and start the service for this platform. Returns what it did, in words. */\nexport function installService(o: {\n node: string;\n cli: string;\n env?: NodeJS.ProcessEnv;\n exec?: Exec;\n platform?: NodeJS.Platform;\n}): string {\n const logDir = controlState(o.env);\n mkdirSync(logDir, { recursive: true, mode: 0o700 });\n const f = serviceFiles({ node: o.node, cli: o.cli, logDir });\n const run = o.exec ?? execQuiet;\n const platform = o.platform ?? process.platform;\n if (platform === \"darwin\") {\n mkdirSync(path.dirname(f.plist.file), { recursive: true });\n writeFileSync(f.plist.file, f.plist.body);\n const uid = String(process.getuid?.() ?? \"\");\n for (const d of [\"gui\", \"user\"])\n try {\n run(\"launchctl\", [\"bootout\", `${d}/${uid}/${LABEL}`]);\n } catch {}\n try {\n run(\"launchctl\", [\"bootstrap\", `gui/${uid}`, f.plist.file]);\n return `launchd agent ${LABEL} (log: ${path.join(logDir, \"daemon.log\")})`;\n } catch {}\n // No one logged in at the screen (an ssh session to a Mac mini): the gui domain\n // doesn't exist. The user domain runs it now; after a restart it starts again at\n // the next login at the screen.\n run(\"launchctl\", [\"bootstrap\", `user/${uid}`, f.plist.file]);\n return `launchd agent ${LABEL} in the background domain, since nobody is logged in at this Mac's screen; after a restart it starts again when someone logs in there (log: ${path.join(logDir, \"daemon.log\")})`;\n }\n if (platform === \"linux\") {\n mkdirSync(path.dirname(f.unit.file), { recursive: true });\n writeFileSync(f.unit.file, f.unit.body);\n try {\n run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n run(\"systemctl\", [\"--user\", \"enable\", \"--now\", UNIT]);\n } catch {\n return `wrote ${f.unit.file}, but systemd --user isn't reachable here; run \\`sessionpipe control run\\` yourself (tmux, screen)`;\n }\n const linger = ensureLinger(os.userInfo().username, run);\n return `systemd user unit ${UNIT}; ${linger.note} (journalctl --user -u ${UNIT})`;\n }\n return \"no service manager for this platform yet; run `sessionpipe control run` yourself\";\n}\n\nexport function uninstallService(env?: NodeJS.ProcessEnv): void {\n const f = serviceFiles({ node: \"\", cli: \"\", logDir: controlState(env) });\n const run = (cmd: string, args: string[]) => {\n try {\n execFileSync(cmd, args, { stdio: \"ignore\", timeout: 15_000 });\n } catch {}\n };\n if (process.platform === \"darwin\" && existsSync(f.plist.file)) {\n run(\"launchctl\", [\"bootout\", `gui/${process.getuid?.() ?? \"\"}/${LABEL}`]);\n run(\"launchctl\", [\"bootout\", `user/${process.getuid?.() ?? \"\"}/${LABEL}`]);\n unlinkSync(f.plist.file);\n }\n if (process.platform === \"linux\" && existsSync(f.unit.file)) {\n run(\"systemctl\", [\"--user\", \"disable\", \"--now\", UNIT]);\n unlinkSync(f.unit.file);\n run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The `sdk` delivery mode (spec/CONTROL.md \u00A76): a session the daemon starts itself\n// through the Claude Agent SDK's streaming input, and keeps while it is in use, so\n// the next message lands in the same process with no cold start. Optional: the SDK\n// is a large package with its own binary, so sessionpipe does not depend on it. When\n// it can be imported (installed beside sessionpipe, or SESSIONPIPE_AGENT_SDK names\n// it), `start` goes through it; otherwise `start` is a headless `claude -p`.\n//\n// Measured (P1 spike 4, Claude Code 2.1.286): first token 1.5 s cold, 1.1 s warm;\n// zero turns while idle; but ~300 MB resident per held session, so the daemon\n// closes one that has been idle for ten minutes and a later message resumes it.\nimport type { SdkHost, SdkSession } from \"./daemon.js\";\n\ntype SdkQuery = AsyncIterable<{ type: string; subtype?: string; result?: unknown; is_error?: boolean }> & {\n interrupt(): Promise<void>;\n close(): void;\n};\ntype QueryFn = (p: { prompt: AsyncIterable<unknown>; options: Record<string, unknown> }) => SdkQuery;\n\nexport async function loadSdk(o: {\n claudeBin: string | null;\n env?: NodeJS.ProcessEnv;\n log: (s: string) => void;\n}): Promise<SdkHost | null> {\n const spec = o.env?.SESSIONPIPE_AGENT_SDK || \"@anthropic-ai/claude-agent-sdk\";\n let query: QueryFn;\n try {\n const mod = (await import(/* @vite-ignore */ spec)) as { query?: QueryFn };\n if (typeof mod.query !== \"function\") return null;\n query = mod.query;\n } catch {\n return null;\n }\n o.log(`Agent SDK found (${spec}): new sessions start in place`);\n return {\n start({\n session,\n cwd,\n mode,\n allowedTools,\n }: {\n session: string;\n cwd: string;\n mode: \"safe\" | \"auto\";\n configDir?: string;\n allowedTools?: string[];\n }): SdkSession {\n const queue: unknown[] = [];\n let wake: (() => void) | null = null;\n let closed = false;\n async function* input() {\n while (!closed) {\n while (queue.length) yield queue.shift();\n await new Promise<void>((r) => {\n wake = r;\n });\n }\n }\n const q = query({\n prompt: input(),\n options: {\n sessionId: session,\n cwd,\n permissionMode: mode === \"auto\" ? \"auto\" : \"dontAsk\",\n ...(allowedTools?.length ? { allowedTools } : {}),\n ...(o.claudeBin ? { pathToClaudeCodeExecutable: o.claudeBin } : {}),\n env: { ...(o.env ?? process.env), SESSIONPIPE_CONTROL_JOB: \"1\" },\n },\n });\n const waiting: { resolve: (v: { reply: string; error?: string }) => void }[] = [];\n let busy = false;\n let lastUsed = Date.now();\n void (async () => {\n try {\n for await (const m of q) {\n if (m.type !== \"result\") continue;\n busy = waiting.length > 1;\n lastUsed = Date.now();\n const w = waiting.shift();\n const text =\n typeof m.result === \"string\" && m.result.trim() ? m.result : \"(finished without a written reply)\";\n w?.resolve(m.is_error ? { reply: \"\", error: text } : { reply: text });\n }\n } catch (e) {\n for (const w of waiting.splice(0)) w.resolve({ reply: \"\", error: String((e as Error)?.message || e) });\n }\n })();\n return {\n send(text: string) {\n busy = true;\n lastUsed = Date.now();\n return new Promise((resolve) => {\n waiting.push({ resolve });\n queue.push({ type: \"user\", message: { role: \"user\", content: text }, parent_tool_use_id: null });\n wake?.();\n });\n },\n interrupt: () => q.interrupt(),\n close() {\n closed = true;\n wake?.();\n try {\n q.close();\n } catch {}\n },\n get busy() {\n return busy;\n },\n get lastUsed() {\n return lastUsed;\n },\n };\n },\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// `sessionpipe wait` (spec/CONTROL.md \u00A78): run by a session as a BACKGROUND command.\n// It blocks on the daemon's local socket \u2014 no network, no polling, no output \u2014 until\n// a verified message for this session arrives, prints it and exits 0; the harness\n// then wakes the session with it. If the daemon restarts, it reconnects in silence.\nimport { stateDir } from \"@sessionpipe/core\";\nimport { parseSessionRef } from \"@sessionpipe/core/control\";\nimport { ask, socketPath } from \"./local.js\";\n\nexport const RE_ARM =\n \"(Answer it right here, as you would answer the person at the keyboard: your reply is sent back to them automatically, so don't run a command or call a tool just to send it. Then, without mentioning it, start `sessionpipe wait` again as a background command, with the longest timeout your harness allows, to keep receiving messages.)\";\n\n/** The session to wait for: --session, else the harness's own env. */\nexport function waitSession(flag: string | undefined, env: NodeJS.ProcessEnv = process.env): string | null {\n if (flag) return parseSessionRef(flag) ? flag : null;\n if (env.CLAUDE_CODE_SESSION_ID) return `claude-code:${env.CLAUDE_CODE_SESSION_ID}`;\n if (env.CODEX_SESSION_ID) return `codex:${env.CODEX_SESSION_ID}`;\n return null;\n}\n\nexport async function waitForMessage(\n session: string,\n o: { env?: NodeJS.ProcessEnv; retryMs?: number } = {},\n): Promise<string> {\n const sock = socketPath(stateDir(o.env), o.env);\n for (;;) {\n // No timeout of our own: the harness's background deadline is the only clock.\n const r = await ask(sock, { op: \"wait\", session, pid: process.pid }, 2 ** 31 - 1);\n if (r?.op === \"message\") return `${r.text}\\n\\n${RE_ARM}`;\n if (r?.op === \"replaced\")\n return \"(Another `sessionpipe wait` for this session took over; this one stopped. Nothing to do.)\";\n await new Promise((res) => setTimeout(res, o.retryMs ?? 1000));\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The hook's own home, outside every npm prefix: a copy of hook.js and worker.js and a\n// small sh launcher, which is what the harnesses run. A hook entry that named node and\n// hook.js by their install paths died with them \u2014 `nvm uninstall`, a Volta or asdf\n// switch, a moved npm prefix \u2014 and the harness said nothing; the machine just stopped\n// reporting. The launcher runs the node sessionpipe was installed with and, once that\n// one is gone, any node on PATH. Windows keeps the direct entry (it has no sh).\n// ~/.local/share/sessionpipe/ SESSIONPIPE_DATA, else $XDG_DATA_HOME/sessionpipe\nimport { accessSync, chmodSync, constants, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport const LAUNCHER = \"sessionpipe-hook\";\nconst COPIED = [\"worker.js\", \"hook.js\"] as const;\n\nexport function dataDir(env: NodeJS.ProcessEnv = process.env): string {\n if (env.SESSIONPIPE_DATA) return path.resolve(env.SESSIONPIPE_DATA);\n return path.join(env.XDG_DATA_HOME || path.join(os.homedir(), \".local\", \"share\"), \"sessionpipe\");\n}\nexport const launcherPath = (env: NodeJS.ProcessEnv = process.env): string => path.join(dataDir(env), LAUNCHER);\nexport const usesLauncher = (platform: NodeJS.Platform = process.platform): boolean => platform !== \"win32\";\n\nconst sq = (s: string): string => `'${s.replace(/'/g, `'\\\\''`)}'`;\n\n/** The launcher, in sh. No node at all prints what Antigravity needs and exits 0: the\n * hook must stay invisible to the harness whatever is missing. */\nexport function launcherScript(node: string, hook: string, version: string): string {\n return `#!/bin/sh\n# sessionpipe ${version} hook launcher, written by \\`sessionpipe install\\`. Harnesses run\n# this; it runs hook.js beside it with the node sessionpipe was installed with, or with\n# any node on PATH once that one is gone (an nvm uninstall, a Homebrew upgrade).\nn=${sq(node)}\n[ -x \"$n\" ] || n=$(command -v node) || { [ \"$1\" = antigravity ] && echo '{}'; exit 0; }\nexec \"$n\" ${sq(hook)} \"$@\"\n`;\n}\n\nfunction writeIfChanged(file: string, body: Buffer | string, mode: number): boolean {\n try {\n const cur = readFileSync(file);\n if (cur.equals(Buffer.isBuffer(body) ? body : Buffer.from(body))) {\n chmodSync(file, mode);\n return false;\n }\n } catch {}\n // A hook may start while this runs: write beside it and rename, never half a file.\n const tmp = `${file}.${process.pid}.tmp`;\n writeFileSync(tmp, body, { mode });\n renameSync(tmp, file);\n chmodSync(file, mode);\n return true;\n}\n\n/** Copy the hook and worker out of the npm install and (re)write the launcher. The\n * worker goes first, so a hook that starts mid-copy never spawns a missing one. */\nexport function installLauncher(o: { distDir: string; node: string; version: string; env?: NodeJS.ProcessEnv }): {\n launcher: string;\n changed: boolean;\n} {\n const dir = dataDir(o.env);\n mkdirSync(dir, { recursive: true, mode: 0o755 });\n let changed = false;\n for (const f of COPIED)\n changed = writeIfChanged(path.join(dir, f), readFileSync(path.join(o.distDir, f)), 0o644) || changed;\n const launcher = path.join(dir, LAUNCHER);\n changed = writeIfChanged(launcher, launcherScript(o.node, path.join(dir, \"hook.js\"), o.version), 0o755) || changed;\n return { launcher, changed };\n}\n\nexport function removeLauncher(env: NodeJS.ProcessEnv = process.env): void {\n for (const f of [LAUNCHER, ...COPIED]) rmSync(path.join(dataDir(env), f), { force: true });\n}\n\nexport interface LauncherState {\n file: string;\n present: boolean;\n /** The node the launcher names, and whether it can still run. */\n node: string | null;\n nodeOk: boolean;\n version: string | null;\n problems: string[];\n}\n\n/** What `doctor` says about the launcher. */\nexport function launcherState(version: string, env: NodeJS.ProcessEnv = process.env): LauncherState {\n const file = launcherPath(env);\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return {\n file,\n present: false,\n node: null,\n nodeOk: false,\n version: null,\n problems: [\"the hook launcher is missing; run `sessionpipe install` again\"],\n };\n }\n const node = /^n='((?:[^']|'\\\\'')*)'$/m.exec(text)?.[1]?.replace(/'\\\\''/g, \"'\") ?? null;\n const v = /^# sessionpipe (\\S+) hook launcher/m.exec(text)?.[1] ?? null;\n let nodeOk = false;\n try {\n if (node) {\n accessSync(node, constants.X_OK);\n nodeOk = true;\n }\n } catch {}\n const problems: string[] = [];\n if (!nodeOk)\n problems.push(\n `the node the hook launcher names (${node ?? \"?\"}) is gone; it falls back to the node on PATH. \\`sessionpipe install\\` points it at this one.`,\n );\n for (const f of COPIED)\n try {\n accessSync(path.join(path.dirname(file), f), constants.R_OK);\n } catch {\n problems.push(`${f} is missing beside the hook launcher; run \\`sessionpipe install\\` again`);\n }\n if (v && v !== version)\n problems.push(\n `the hooks run sessionpipe ${v}, this is ${version}; run \\`sessionpipe install\\` to bring them up to date`,\n );\n return { file, present: true, node, nodeOk, version: v, problems };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["execFileSync", "
|
|
3
|
+
"sources": ["../src/cli.ts", "../../core/src/adapters/antigravity.ts", "../../core/src/paths.ts", "../../core/src/readers/files.ts", "../../core/src/readers/transcripts.ts", "../../core/src/adapters/claude-shaped.ts", "../../core/src/adapters/claude-code.ts", "../../core/src/readers/git.ts", "../../core/src/adapters/codex.ts", "../../core/src/adapters/codex-config.ts", "../../core/src/adapters/gemini-cli.ts", "../../core/src/adapters/claude-code-control.ts", "../../core/src/adapters/index.ts", "../../core/src/config.ts", "../../core/src/ulid.ts", "../../core/src/events.ts", "../../core/src/outbox.ts", "../../core/src/privacy/pii.ts", "../../core/src/privacy/secrets.ts", "../../core/src/privacy/filter.ts", "../../core/src/sinks/file.ts", "../../core/src/sinks/stdout.ts", "../src/connect.ts", "../src/control/autoupdate.ts", "../src/update.ts", "../src/runtime.ts", "../src/run.ts", "../src/control/local.ts", "../src/http-sink.ts", "../src/secrets.ts", "../src/control/store.ts", "../../core/src/control/verify.ts", "../src/control/cli.ts", "../src/control/daemon.ts", "../src/control/reply.ts", "../src/control/route.ts", "../src/control/stream.ts", "../src/control/pair.ts", "../src/control/sdk.ts", "../src/control/wait.ts", "../src/launcher.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n// SPDX-License-Identifier: Apache-2.0\n// sessionpipe: install once, hook everything, choose per sink what leaves.\n// connect \u00B7 install \u00B7 uninstall \u00B7 sink add|list|remove|test \u00B7 secrets \u00B7 status \u00B7\n// doctor \u00B7 tail \u00B7 backfill \u00B7 forget \u00B7 replay \u00B7 update \u00B7 hook \u00B7 worker\nimport { execFileSync, spawnSync } from \"node:child_process\";\nimport { mkdtempSync, readdirSync, readFileSync, realpathSync, rmSync, statSync, unlinkSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n ADAPTERS,\n adapterByName,\n type BackfillRow,\n type Config,\n Cursors,\n claudeControl,\n claudeDirs,\n configFile,\n type Event,\n filterEvent,\n type HookCommand,\n machineName,\n makeEvent,\n Outbox,\n readConfig,\n type SinkConfig,\n stateDir,\n type Tier,\n tilde,\n writeConfig,\n} from \"@sessionpipe/core\";\nimport { connectFolders, connectTier } from \"./connect.js\";\nimport { autoUpdateOff, readUpdate, updateFile, updateLine, updateSummary } from \"./control/autoupdate.js\";\nimport { CONTROL_HELP, controlMain, enabledHarnesses, waitMain } from \"./control/cli.js\";\nimport { ask, socketPath } from \"./control/local.js\";\nimport { moveControlSecrets, pairedCount, readControl } from \"./control/store.js\";\nimport { installLauncher, launcherPath, launcherState, removeLauncher, usesLauncher } from \"./launcher.js\";\nimport { buildSinks, factsState, flush, jobsDir, runJob, VERSION } from \"./run.js\";\nimport { rerunGlobally, stableNode, viaNpx } from \"./runtime.js\";\nimport { bestStore, dropSinkSecrets, moveSinkSecrets, type StoreName, sinkWithSecrets, storeLabel } from \"./secrets.js\";\nimport { globalPrefix, installVersion, isNewer, latestVersion } from \"./update.js\";\n\nprocess.stdout.on(\"error\", (e: NodeJS.ErrnoException) => {\n if (e.code === \"EPIPE\") process.exit(0);\n});\nconst args = process.argv.slice(2);\nconst cmd = args[0] ?? \"help\";\nconst flag = (name: string): string | undefined => {\n const i = args.indexOf(name);\n return i >= 0 ? args[i + 1] : undefined;\n};\nconst has = (name: string): boolean => args.includes(name);\nconst out = (s = \"\"): void => {\n process.stdout.write(`${s}\\n`);\n};\nconst state = stateDir();\nconst distDir = path.dirname(fileURLToPath(import.meta.url));\n\n/** The command a hook entry runs: the launcher, which outlives node upgrades\n * (launcher.ts); on Windows, this node by a stable absolute path and hook.js by its\n * real path. */\nfunction hookCommand(): HookCommand {\n if (usesLauncher()) {\n const l = launcherPath();\n return (a) => ({ argv: [l, ...a], command: `${JSON.stringify(l)} ${a.join(\" \")}` });\n }\n const node = stableNode(process.execPath);\n let script = path.join(distDir, \"hook.js\");\n try {\n script = realpathSync(script);\n } catch {}\n return (a) => ({\n argv: [node, script, ...a],\n command: `${JSON.stringify(node)} ${JSON.stringify(script)} ${a.join(\" \")}`,\n });\n}\n\nfunction selectedAdapters(): typeof ADAPTERS {\n const named = ADAPTERS.filter((a) => has(`--${a.name}`));\n if (named.length) return named;\n return ADAPTERS.filter((a) => a.detect());\n}\n\nasync function main(): Promise<void> {\n switch (cmd) {\n case \"connect\":\n return connect();\n case \"install\":\n return install();\n case \"secrets\":\n return secrets();\n case \"uninstall\":\n return uninstall();\n case \"sink\":\n return sink();\n case \"status\":\n return status();\n case \"doctor\":\n return await doctor();\n case \"tail\":\n return tail();\n case \"backfill\":\n return backfill();\n case \"forget\":\n return forget();\n case \"replay\":\n return replay();\n case \"update\":\n return update();\n case \"worker\":\n return workerFromArgv();\n case \"control\":\n return controlMain(args, out, distDir);\n case \"wait\":\n return waitMain(args, out);\n case \"hook\":\n out(\"sessionpipe hook is dist/hook.js; harnesses run it directly\");\n return;\n case \"--version\":\n case \"-v\":\n case \"version\":\n out(VERSION);\n return;\n default:\n return help();\n }\n}\n\nfunction help(): void {\n out(`sessionpipe ${VERSION} \u2014 an open protocol for what your coding agents are doing\n\n sessionpipe connect <receiver> [--machine NAME] [--tier 0-3] [--mode safe|auto] [--folder DIR]\u2026\n (everything, in one go: hooks, a sink, signed messages, keys)\n sessionpipe install [--claude-code --codex --gemini-cli --antigravity] [--machine NAME] [--backfill DAYS] [--sink URL --tier N]\n sessionpipe uninstall [--keep-state]\n sessionpipe sink add <url|file:PATH|stdout> [--tier 0-3] [--token T] [--pii] [--name N]\n sessionpipe sink list | remove <name> | test <name>\n sessionpipe secrets [move keychain|secret-service|file] (where the machine's keys live)\n sessionpipe status | doctor [--json]\n sessionpipe tail [--session ID] [--tier N] [--harness NAME]\n sessionpipe backfill [--days 30] | forget <harness> <session> | replay --sink NAME\n sessionpipe update [off|on] (install the latest now; off/on: the daemon's daily update)\n${CONTROL_HELP}\n\nDocs: https://sessionpipe.org \u00B7 nothing leaves this machine until you add a sink.`);\n}\n\nasync function install(): Promise<void> {\n if (viaNpx(distDir)) return rerunGlobally(args, out);\n const cfg = readConfig();\n const machine = flag(\"--machine\");\n if (machine) cfg.machine = machine.slice(0, 80);\n // A sink URL given here is added first, so the install knows whether it needs\n // every tool event or only the heartbeat's one.\n const sinkUrl = flag(\"--sink\");\n if (sinkUrl) await sinkAdd(sinkUrl, cfg);\n const adapters = selectedAdapters();\n if (!adapters.length) {\n out(\n \" No supported harness found on this machine (Claude Code, Codex, Gemini CLI, Antigravity). Pass --<harness> to force one.\",\n );\n return;\n }\n out(` Machine: ${machineName(cfg, os.hostname())}`);\n const lean = isLean(cfg);\n if (lean)\n out(\n \" No sink above tier 0: hooking one tool event per harness (the heartbeat's). `sink add \u2026 --tier 1` or higher hooks the rest.\",\n );\n installHarnesses(adapters, cfg, lean);\n writeConfig(cfg);\n const days = Number(flag(\"--backfill\") ?? 30);\n if (days > 0) backfillRows(adapters, days, cfg);\n out(\"\");\n const live = cfg.sinks.filter((s) => !s.paused);\n if (live.length) out(` Reporting to ${live.map((s) => `${s.name} (tier ${s.tier})`).join(\", \")}.`);\n else\n out(\n \" Nothing leaves this machine yet: events go to the local outbox. `sessionpipe tail` shows them; `sessionpipe sink add <url> --tier N` sends them.\",\n );\n out(\" Sessions already running pick up hooks on their next start (Claude Code \u2265 2.1.280 picks them up live).\");\n}\n\n/** No sink takes tier \u2265 1: the harness only needs one tool event (issue #12). */\nfunction isLean(cfg: Config): boolean {\n return !cfg.sinks.some((s) => !s.paused && Math.min(s.tier, s.max_tier ?? 3) >= 1);\n}\n\n/** Write the hooks for these harnesses; remember which files sessionpipe created. */\nfunction installHarnesses(adapters: readonly (typeof ADAPTERS)[number][], cfg: Config, lean: boolean): void {\n if (usesLauncher()) {\n const node = stableNode(process.execPath);\n const l = installLauncher({ distDir, node, version: VERSION });\n if (l.changed)\n out(` \u2713 hook launcher: ${tilde(l.launcher)} (node ${tilde(node)}, or any node on PATH once that one is gone)`);\n }\n const hc = hookCommand();\n for (const a of adapters) {\n const prev = cfg.harnesses[a.name] ?? {};\n const created = new Set(prev.created ?? []);\n const reports = a.install(hc, process.env, { lean, created: [...created] });\n for (const r of reports) {\n if (r.created) created.add(r.file);\n const mark = r.skipped ? \"!\" : r.changed ? \"\u2713\" : \"=\";\n out(\n ` ${mark} ${a.name}: ${tilde(r.file)}${r.note ? ` \u2014 ${r.note}` : r.changed ? \" written\" : \" already current\"}`,\n );\n }\n cfg.harnesses[a.name] = { enabled: true, ...(created.size ? { created: [...created] } : {}) };\n if (a.name === \"gemini-cli\")\n out(\" note: Gemini CLI's own telemetry defaults logPrompts on; that is Google's setting, not sessionpipe's.\");\n if (a.name === \"codex\" && !reports.some((r) => r.skipped))\n out(\n \" note: Codex runs non-managed hooks only after you approve them: start `codex` and accept the hook review. The notify fallback reports turn ends meanwhile.\",\n );\n }\n}\n\n/** `sessionpipe connect <receiver>`: everything a machine needs, in one command and one\n * approval \u2014 the hooks for every agent and every Claude Code account here, a sink at\n * tier 2, signed messages (the daemon, paired with open pairing), the keys moved into\n * the keychain when there is one, the daemon kept running past logout, the last 30\n * days backfilled. Run it again and it only fixes what's missing. Asks nothing: the\n * mode is --mode or safe, the folders are --folder, this one, or where your recent\n * sessions ran \u2014 never the home folder. */\nasync function connect(): Promise<void> {\n const raw = args[1];\n if (!raw || raw.startsWith(\"-\"))\n return out(\n \"usage: sessionpipe connect <receiver> [--machine NAME] [--tier 0-3] [--mode safe|auto] [--folder DIR]\u2026 [--no-service]\",\n );\n if (viaNpx(distDir)) return rerunGlobally(args, out);\n const url = (/^https?:\\/\\//.test(raw) ? raw : `https://${raw}`).replace(/\\/$/, \"\");\n const host = new URL(url).host;\n const cfg = readConfig();\n const machine = flag(\"--machine\");\n if (machine) cfg.machine = machine.slice(0, 80);\n const name = machineName(cfg, os.hostname());\n const before = cfg.sinks.find((x) => x.url.replace(/\\/$/, \"\") === url);\n const tier = connectTier(flag(\"--tier\"), before?.tier);\n out(` Connecting ${name} to ${host}.`);\n\n // 1. The hooks, for every agent on this machine (and every Claude Code account).\n const adapters = ADAPTERS.filter((a) => a.detect());\n if (!adapters.length)\n out(\n \" ! No coding agent here yet (Claude Code, Codex, Gemini CLI, Antigravity): run `sessionpipe install` once you have one.\",\n );\n else installHarnesses(adapters, cfg, tier < 1);\n writeConfig(cfg);\n await reportClaudeAccounts();\n const rows = collectRows(adapters, 30);\n\n // 2. One approval on any signed-in device: the machine's control token and its\n // sessions key together.\n const control = readControl();\n const paired = control?.receivers.find((r) => r.url === url);\n const sinkNow = readConfig().sinks.find((x) => x.url.replace(/\\/$/, \"\") === url);\n if (paired && sinkNow && (sinkNow.token || sinkNow.token_in)) {\n out(` \u2713 Already paired with ${host} as ${paired.machine}: nothing to approve.`);\n } else {\n const recent = rows\n .slice()\n .sort((a, b) => b.row.last_at - a.row.last_at)\n .map((r) => r.row.session.cwd ?? \"\");\n const choice = connectFolders({\n cwd: process.cwd(),\n home: os.homedir(),\n flags: argsAll(\"--folder\"),\n existing: control?.folders ?? [],\n recent,\n exists: (d) => {\n try {\n return statSync(d).isDirectory();\n } catch {\n return false;\n }\n },\n });\n if (choice.from === \"recent\")\n out(` Folders from your recent sessions: ${choice.folders.map((d) => tilde(d)).join(\", \")}`);\n if (choice.from === \"none\")\n out(\n \" ! No folder for sessions you message yet (this ran from your home folder, and no recent session ran anywhere else). Run `sessionpipe control pair` again from a project folder, or with --folder.\",\n );\n const mode =\n flag(\"--mode\") === \"auto\" || flag(\"--mode\") === \"safe\" ? (flag(\"--mode\") as string) : (control?.mode ?? \"safe\");\n await controlMain(\n [\n \"control\",\n \"pair\",\n url,\n \"--mode\",\n mode,\n \"--tier\",\n String(tier),\n \"--name\",\n control?.name ?? name,\n ...choice.folders.flatMap((d) => [\"--folder\", d]),\n ...(has(\"--no-service\") ? [\"--no-service\"] : []),\n ],\n out,\n distDir,\n );\n if (mode === \"safe\")\n out(\n \" Safe mode: `sessionpipe control mode auto` lets sessions you message work unattended (Claude Code's auto mode).\",\n );\n }\n\n // 3. The sink at the tier asked for, with the receiver's cap and endpoints.\n const after = readConfig();\n const sink = after.sinks.find((x) => x.url.replace(/\\/$/, \"\") === url);\n if (sink) {\n const old = sink.tier;\n sink.tier = tier;\n await learnReceiver(sink, tier);\n writeConfig(after);\n const eff = Math.min(sink.tier, sink.max_tier ?? 3) as Tier;\n out(` \u2713 Sink ${sink.name}: tier ${eff}${old !== tier ? ` (was ${old})` : \"\"} \u2014 sends ${TIER_TEXT[eff]}`);\n } else out(` ! No sink for ${host}: \\`sessionpipe sink add ${url} --token <key> --tier ${tier}\\``);\n\n // 4. Keys into the keychain, when this session has one unlocked.\n const store = bestStore();\n if (store !== \"file\") {\n const a = moveSinkSecrets(store);\n const b = moveControlSecrets(store);\n const kept = [...a.kept, ...b.kept];\n out(` \u2713 Keys: in ${storeLabel(store)}${kept.length ? ` (left in the file: ${kept.join(\", \")})` : \"\"}`);\n } else\n out(\n ` Keys: in ${tilde(path.dirname(configFile()))} at 0600 \u2014 no unlocked keychain in this session${process.env.SSH_CONNECTION ? \" (an ssh shell)\" : \"\"}`,\n );\n\n // 5. The last 30 days, now that there is somewhere to send them.\n if (rows.length) queueBackfill(rows, 30, readConfig());\n out(\"\");\n out(` Done: ${name} reports to ${host} and takes messages you sign on a device it trusts.`);\n out(\" Run this again any time; it only fixes what's missing. `sessionpipe doctor` checks everything.\");\n}\n\nfunction argsAll(name: string): string[] {\n return args.flatMap((a, i) => (a === name && args[i + 1] ? [args[i + 1] as string] : []));\n}\n\n/** Each Claude Code account on this machine, and whether Claude Code says it's signed\n * in from here (a message's headless run uses this login). */\nasync function reportClaudeAccounts(): Promise<void> {\n const bin = claudeControl.findClaude();\n if (!bin) return;\n const dirs = claudeDirs();\n const answers = await Promise.all(dirs.map((d) => claudeControl.claudeLogin(bin, d)));\n dirs.forEach((d, i) => {\n const l = answers[i] as claudeControl.Login;\n if (l.loggedIn === true)\n out(\n ` \u2713 Claude Code ${tilde(d)}: signed in${l.method ? ` (${[l.method, l.subscription].filter(Boolean).join(\", \")})` : \"\"}`,\n );\n else if (l.loggedIn === false)\n out(\n ` ! Claude Code ${tilde(d)}: not signed in as this shell sees it \u2014 ${claudeControl.loginCommand(d)}${process.platform === \"darwin\" && process.env.SSH_CONNECTION ? \" (over ssh a Mac's keychain login can't be read; log in at the screen)\" : \"\"}`,\n );\n });\n}\n\n/** `sessionpipe secrets [move <store>]`: where this machine's keys live. */\nfunction secrets(): void {\n const sub = args[1];\n if (sub === \"move\") {\n const to = args[2] as StoreName | undefined;\n if (to !== \"keychain\" && to !== \"secret-service\" && to !== \"file\") {\n out(\"usage: sessionpipe secrets move keychain|secret-service|file\");\n return;\n }\n const a = moveSinkSecrets(to);\n const b = moveControlSecrets(to);\n const moved = [...a.moved, ...b.moved];\n const kept = [...a.kept, ...b.kept];\n out(\n moved.length ? ` \u2713 moved to ${storeLabel(to)}: ${moved.join(\", \")}` : ` nothing to move to ${storeLabel(to)}`,\n );\n if (kept.length)\n out(` ! left where they are (unreadable here, or ${storeLabel(to)} refused them): ${kept.join(\", \")}`);\n return;\n }\n const cfg = readConfig();\n const where = (s: SinkConfig): string =>\n s.token_in\n ? `${storeLabel(s.token_in)}${sinkWithSecrets(s) ? \"\" : \" \u2014 can't be read from this session (locked?)\"}`\n : s.token || s.secret\n ? `${tilde(configFile())} (0600)`\n : \"no key\";\n for (const s of cfg.sinks) out(` sink ${s.name.padEnd(20)} ${where(s)}`);\n for (const r of readControl()?.receivers ?? [])\n out(\n ` control ${new URL(r.url).host.padEnd(17)} ${r.token_in ? `${storeLabel(r.token_in)}${r.token ? \"\" : \" \u2014 can't be read from this session (locked?)\"}` : \"control.json (0600)\"}`,\n );\n if (!cfg.sinks.length && !readControl()?.receivers.length) out(\" no keys on this machine\");\n out(` best store from this session: ${storeLabel(bestStore())}`);\n}\n\nfunction uninstall(): void {\n const cfg = readConfig();\n for (const a of ADAPTERS) {\n const created = cfg.harnesses[a.name]?.created ?? [];\n for (const r of a.uninstall(process.env, { created }))\n if (r.changed) out(` \u2713 ${a.name}: ${r.note ?? `hooks removed from ${tilde(r.file)}`}`);\n else if (r.skipped) out(` ! ${a.name}: ${tilde(r.file)} \u2014 ${r.note}`);\n delete cfg.harnesses[a.name];\n }\n writeConfig(cfg);\n if (usesLauncher()) removeLauncher();\n if (!has(\"--keep-state\"))\n out(\n ` Outbox and state kept under ${tilde(state)} (delete it yourself, or pass nothing: it prunes after ${readConfig().keep_days ?? 30} days).`,\n );\n out(\" Done. Every config file is byte-identical except for the entries sessionpipe wrote.\");\n}\n\nasync function sink(): Promise<void> {\n const sub = args[1];\n const cfg = readConfig();\n if (sub === \"add\" && args[2]) return sinkAdd(args[2], cfg);\n if (sub === \"list\") {\n if (!cfg.sinks.length) out(\" no sinks\");\n for (const s of cfg.sinks)\n out(\n ` ${s.name.padEnd(16)} ${s.url.padEnd(44)} tier ${s.tier}${s.max_tier !== undefined && s.max_tier < s.tier ? ` (capped ${s.max_tier})` : \"\"}${s.pii ? \" pii\" : \"\"}${s.control ? \" control\" : \"\"}${s.paused ? ` PAUSED ${s.paused}` : \"\"}`,\n );\n return;\n }\n if (sub === \"remove\" && args[2]) {\n const n = cfg.sinks.length;\n for (const s of cfg.sinks) if (s.name === args[2]) dropSinkSecrets(s);\n cfg.sinks = cfg.sinks.filter((s) => s.name !== args[2]);\n writeConfig(cfg);\n out(cfg.sinks.length < n ? ` \u2713 removed ${args[2]}` : ` no sink named ${args[2]}`);\n return;\n }\n if (sub === \"test\" && args[2]) {\n const s = cfg.sinks.find((x) => x.name === args[2]);\n if (!s) return out(` no sink named ${args[2]}`);\n const [sk] = buildSinks([s]);\n if (!sk) return out(\" sink type not supported yet\");\n // One heartbeat, then its forget: the receiver sees the round trip and keeps no row.\n const session = { id: `test-${Date.now()}`, machine: machineName(cfg, os.hostname()) };\n const mk = (type: string, seq: number) =>\n makeEvent(\n { type, harnessEvent: \"test\", data: {} },\n { harness: { name: \"sessionpipe\" }, session: { ...session, seq } },\n );\n const r = await sk.send([\n filterEvent(mk(\"session.heartbeat\", 0), sk.tier, sk.pii) as Event,\n filterEvent(mk(\"session.forgotten\", 1), sk.tier, sk.pii) as Event,\n ]);\n out(\n r.ok\n ? ` \u2713 ${s.name}: ${r.status ?? \"ok\"} accepted ${r.accepted ?? 2} (a heartbeat and its forget)`\n : ` \u2717 ${s.name}: ${r.status ?? \"\"} ${r.error ?? \"\"} (${r.action})`,\n );\n return;\n }\n out(\n \"usage: sessionpipe sink add <url|file:PATH|stdout> [--tier N] [--token T] [--pii] [--name N] | list | remove <name> | test <name>\",\n );\n}\n\nasync function sinkAdd(url: string, cfg: Config): Promise<void> {\n const tier = Math.max(0, Math.min(3, Number(flag(\"--tier\") ?? 0))) as Tier;\n const name = flag(\"--name\") ?? (url === \"stdout\" ? \"stdout\" : url.startsWith(\"file:\") ? \"file\" : new URL(url).host);\n // Control is not a property of a sink: it is set up per machine, with keys enrolled\n // at this terminal (spec/CONTROL.md \u00A72, `sessionpipe control pair`). A sink never\n // carries `control: true`.\n if (has(\"--control\"))\n out(\" --control is ignored: control is set up per machine (`sessionpipe control pair <url>`, spec/CONTROL.md)\");\n const s: SinkConfig = { name, url, tier, pii: has(\"--pii\") };\n // Changing a sink's tier keeps the key it has (pairing may have handed it over, and\n // it may live in a keychain): only --token / --secret replace one.\n const prev = cfg.sinks.find((x) => x.name === name && x.url === url);\n const token = flag(\"--token\");\n const secret = flag(\"--secret\");\n if (prev?.token_in && !token && !secret) s.token_in = prev.token_in;\n else {\n const kept = prev ? sinkWithSecrets(prev) : null;\n const t = token ?? kept?.token;\n const sec = secret ?? kept?.secret;\n if (t) s.token = t;\n if (sec) s.secret = sec;\n if (prev?.token_in) dropSinkSecrets(prev);\n }\n await learnReceiver(s, tier);\n cfg.sinks = cfg.sinks.filter((x) => x.name !== name).concat([s]);\n writeConfig(cfg);\n out(` \u2713 sink ${name}: ${url} at tier ${Math.min(tier, s.max_tier ?? 3)}${s.pii ? \", pii\" : \"\"}`);\n out(` tier ${tier} sends: ${TIER_TEXT[Math.min(tier, s.max_tier ?? 3) as Tier]}`);\n}\n/** Read the receiver's well-known file onto the sink: its tier cap and endpoints. */\nasync function learnReceiver(s: SinkConfig, tier: Tier): Promise<void> {\n if (!/^https?:\\/\\//.test(s.url)) return;\n try {\n const r = await fetch(`${s.url.replace(/\\/$/, \"\")}/.well-known/sessionpipe`, { signal: AbortSignal.timeout(8000) });\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n const wk = (await r.json()) as { max_tier?: number; endpoints?: { events?: string }; capabilities?: string[] };\n if (typeof wk.max_tier === \"number\") {\n s.max_tier = wk.max_tier as Tier;\n if (wk.max_tier < tier) out(` receiver's max_tier is ${wk.max_tier}: sending tier ${wk.max_tier}, not ${tier}`);\n }\n if (wk.endpoints) (s as SinkConfig & { endpoints?: unknown }).endpoints = wk.endpoints;\n s.well_known_at = new Date().toISOString();\n } catch (e) {\n out(\n ` ! ${s.url} has no readable /.well-known/sessionpipe (${(e as Error).message}); added anyway, at tier ${tier}`,\n );\n }\n}\n\nconst TIER_TEXT: Record<Tier, string> = {\n 0: \"session state and timing, machine, folder, repo, branch, model, title, link, the KIND of attention needed \u2014 no tool names, no words\",\n 1: \"tier 0 + tool names, durations, ok/error, file paths, the attention message, subagents, compactions \u2014 no prompts\",\n 2: \"tier 1 + your prompts and the assistant's text, secrets removed\",\n 3: \"everything, including tool input and output\",\n};\n\n/** Each harness's sessions of the last `days` days, as the backfill reads them. */\nfunction collectRows(\n adapters: readonly (typeof ADAPTERS)[number][],\n days: number,\n): { harness: string; row: BackfillRow }[] {\n const since = Date.now() - days * 86_400_000;\n const rows: { harness: string; row: BackfillRow }[] = [];\n for (const a of adapters) {\n try {\n for (const row of a.backfill(since)) rows.push({ harness: a.name, row });\n } catch {}\n }\n return rows;\n}\n\nfunction backfillRows(adapters: readonly (typeof ADAPTERS)[number][], days: number, cfg: Config): void {\n queueBackfill(collectRows(adapters, days), days, cfg);\n}\n\nfunction queueBackfill(rows: { harness: string; row: BackfillRow }[], days: number, cfg: Config): void {\n const outbox = new Outbox(state);\n let n = 0;\n const machine = machineName(cfg, os.hostname());\n for (const { harness, row } of rows) {\n const ref = { harness, session: row.session.id };\n const facts = factsState(state).get(harness, row.session.id);\n if (facts.backfilled) continue;\n const { id, ...rest } = row.session;\n const e = makeEvent(\n {\n type: \"session.backfill\",\n harnessEvent: \"backfill\",\n data: {\n started_at: new Date(row.started_at).toISOString(),\n last_at: new Date(row.last_at).toISOString(),\n ...(row.turns !== undefined ? { turns: row.turns } : {}),\n },\n },\n {\n harness: { name: harness },\n session: { ...rest, id, seq: outbox.nextSeq(ref), machine, ...(rest.cwd ? { cwd: tilde(rest.cwd) } : {}) },\n now: row.last_at,\n },\n );\n outbox.append(ref, [e]);\n factsState(state).save(harness, row.session.id, { backfilled: true });\n n++;\n }\n out(` \u2713 Backfill: ${n} session${n === 1 ? \"\" : \"s\"} from the last ${days} days queued as session.backfill`);\n void flush(state, cfg.sinks, outbox);\n}\n\nfunction backfill(): void {\n backfillRows(selectedAdapters(), Number(flag(\"--days\") ?? 30), readConfig());\n}\n\nasync function forget(): Promise<void> {\n const [, harness, session] = args;\n if (!harness || !session) return out(\"usage: sessionpipe forget <harness> <session>\");\n const cfg = readConfig();\n const outbox = new Outbox(state);\n const ref = { harness, session };\n const e = makeEvent(\n { type: \"session.forgotten\", harnessEvent: \"forget\", data: {} },\n {\n harness: { name: harness },\n session: { id: session, seq: outbox.nextSeq(ref), machine: machineName(cfg, os.hostname()) },\n },\n );\n const sinks = buildSinks(cfg.sinks);\n for (const s of sinks) {\n const r = await s.send([filterEvent(e, s.tier, s.pii) as Event]);\n out(r.ok ? ` \u2713 ${s.name}: asked to delete ${harness}:${session}` : ` \u2717 ${s.name}: ${r.error ?? r.status}`);\n }\n outbox.delete(ref);\n out(\" local outbox for the session removed\");\n}\n\nasync function replay(): Promise<void> {\n const name = flag(\"--sink\");\n const cfg = readConfig();\n const sinks = name ? cfg.sinks.filter((s) => s.name === name) : cfg.sinks;\n if (!sinks.length) return out(\" no such sink\");\n for (const s of sinks) {\n if (has(\"--from-start\")) new Cursors(state, s.name).write({});\n }\n const d = await flush(state, sinks, new Outbox(state));\n for (const [k, v] of Object.entries(d)) out(` ${k}: ${v} event${v === 1 ? \"\" : \"s\"} delivered`);\n}\n\nfunction status(): void {\n const cfg = readConfig();\n const hc = hookCommand();\n out(` machine: ${machineName(cfg, os.hostname())} sessionpipe ${VERSION} state ${tilde(state)}`);\n for (const a of ADAPTERS) {\n if (!a.detect() && !cfg.harnesses[a.name]) continue;\n for (const r of a.installed(hc, process.env, { lean: isLean(cfg) }))\n out(\n ` ${a.name.padEnd(12)} ${tilde(r.file).padEnd(44)} ${r.state}${r.state !== \"current\" && r.note ? ` \u2014 ${r.note}` : \"\"}`,\n );\n }\n if (!cfg.sinks.length) out(\" sinks: none (events stay in the local outbox)\");\n for (const s of cfg.sinks) {\n const c = new Cursors(state, s.name).read();\n const outbox = new Outbox(state);\n let pending = 0;\n for (const ref of outbox.sessions()) {\n const f = outbox.file(ref);\n try {\n pending += Math.max(0, statSync(f).size - (c[`${ref.harness}/${ref.session}`] ?? 0)) > 0 ? 1 : 0;\n } catch {}\n }\n out(\n ` sink ${s.name.padEnd(16)} tier ${Math.min(s.tier, s.max_tier ?? 3)} ${s.paused ? `PAUSED ${s.paused}` : pending ? `${pending} session file(s) with undelivered events` : \"up to date\"}`,\n );\n }\n out(` update: ${updateLine(updateState(cfg), Date.now())}`);\n const t = timing();\n if (t)\n out(\n ` hook: in-process p50 ${t.p50} ms over ${t.n} runs (\\`sessionpipe doctor\\` measures the wall clock the harness waits)`,\n );\n const jobs = jobsDir(state);\n try {\n const n = readdirSync(jobs).length;\n if (n) out(` jobs: ${n} waiting`);\n } catch {}\n}\n\n/** Spawn the hook the way a harness does and time the whole process (issue #12:\n * the in-process clock misses Node's startup, ~200 ms on an older Intel Mac). */\nfunction hookWall(runs = 8): { n: number; p50: number; p95: number } | null {\n const hook = path.join(distDir, \"hook.js\");\n const tmp = mkdtempSync(path.join(os.tmpdir(), \"sessionpipe-doctor-\"));\n const env = {\n ...process.env,\n SESSIONPIPE_STATE: tmp,\n SESSIONPIPE_CONFIG: path.join(tmp, \"config.json\"),\n SESSIONPIPE_NO_WORKER: \"1\",\n };\n const input = JSON.stringify({\n session_id: \"doctor\",\n hook_event_name: \"PostToolUse\",\n tool_name: \"Bash\",\n cwd: process.cwd(),\n });\n const times: number[] = [];\n try {\n for (let i = 0; i < runs; i++) {\n const t0 = process.hrtime.bigint();\n const r = spawnSync(process.execPath, [hook, \"claude-code\", \"PostToolUse\"], { input, env, encoding: \"utf8\" });\n if (r.status !== 0) return null;\n times.push(Number(process.hrtime.bigint() - t0) / 1e6);\n }\n } catch {\n return null;\n } finally {\n rmSync(tmp, { recursive: true, force: true });\n }\n times.sort((a, b) => a - b);\n const q = (p: number) => Math.round(times[Math.min(times.length - 1, Math.floor(p * times.length))] ?? 0);\n return { n: times.length, p50: q(0.5), p95: q(0.95) };\n}\n\nfunction timing(): { n: number; p50: number; p95: number } | null {\n try {\n const lines = readFileSync(path.join(state, \"timing.jsonl\"), \"utf8\").trim().split(\"\\n\").slice(-100);\n const ms = lines\n .map((l) => (JSON.parse(l) as { ms: number }).ms)\n .filter((x) => x >= 0)\n .sort((a, b) => a - b);\n if (!ms.length) return null;\n const q = (p: number) => Math.round(ms[Math.min(ms.length - 1, Math.floor(p * ms.length))] ?? 0);\n return { n: ms.length, p50: q(0.5), p95: q(0.95) };\n } catch {\n return null;\n }\n}\n\nasync function doctor(): Promise<void> {\n const cfg = readConfig();\n const hc = hookCommand();\n const report: Record<string, unknown> = {\n version: VERSION,\n node: process.version,\n node_path: stableNode(process.execPath),\n machine: machineName(cfg, os.hostname()),\n state: state,\n config: configFile(),\n harnesses: {},\n sinks: [],\n timing: timing(),\n hook_wall_ms: hookWall(),\n update: updateState(cfg),\n warnings: [] as string[],\n };\n const warnings = report.warnings as string[];\n const upd = report.update as ReturnType<typeof updateState>;\n if (upd.failed)\n warnings.push(\n `the control daemon couldn't install sessionpipe ${upd.failed.version}: ${upd.failed.error}. It tries again tomorrow; \\`sessionpipe update\\` tries now.`,\n );\n if (usesLauncher()) {\n const l = launcherState(VERSION);\n report.launcher = { file: tilde(l.file), node: l.node, node_ok: l.nodeOk, version: l.version };\n if (Object.keys(cfg.harnesses).length) warnings.push(...l.problems);\n }\n // Where each key lives, and whether this session can read it.\n const keys: { what: string; where: string; readable: boolean }[] = [];\n for (const s of cfg.sinks)\n if (s.token_in || s.token || s.secret)\n keys.push({ what: `sink ${s.name}`, where: s.token_in ?? \"file\", readable: !!sinkWithSecrets(s) });\n const control = readControl();\n for (const r of control?.receivers ?? [])\n keys.push({ what: `control ${new URL(r.url).host}`, where: r.token_in ?? \"file\", readable: !!r.token });\n report.keys = keys;\n for (const k of keys)\n if (!k.readable)\n warnings.push(\n `${k.what}: its key is in ${storeLabel(k.where as StoreName)}, which this session can't read (locked, or an ssh shell). Events wait; the control daemon sends them from your own session.`,\n );\n // Each Claude Code account: a message's headless run needs its login.\n const claudeBin = claudeControl.findClaude();\n if (claudeBin) {\n const dirs = claudeDirs();\n const logins = await Promise.all(dirs.map((d) => claudeControl.claudeLogin(claudeBin, d)));\n report.claude_accounts = dirs.map((d, i) => ({ dir: tilde(d), signed_in: logins[i]?.loggedIn ?? null }));\n dirs.forEach((d, i) => {\n if (logins[i]?.loggedIn === false && control?.receivers.length)\n warnings.push(`Claude Code ${tilde(d)} isn't signed in from here: ${claudeControl.loginCommand(d)}`);\n });\n }\n // A systemd user service stops at logout unless the user lingers.\n if (process.platform === \"linux\" && control?.receivers.length) {\n let linger: boolean | null = null;\n try {\n linger = /^Linger=yes/m.test(\n execFileSync(\"loginctl\", [\"show-user\", os.userInfo().username, \"--property=Linger\"], {\n encoding: \"utf8\",\n timeout: 5000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }),\n );\n } catch {}\n report.linger = linger;\n if (linger === false)\n warnings.push(\n `the control daemon stops when you log out: \\`loginctl enable-linger ${os.userInfo().username}\\` (with sudo if refused) keeps it running`,\n );\n }\n if (/\\/Cellar\\/node(?:@\\d+)?\\/[^/]+\\//.test(distDir))\n warnings.push(\n \"sessionpipe is installed inside Homebrew's versioned node folder; `brew upgrade node` will delete it. Install with `npm install -g --prefix ~/.local sessionpipe`.\",\n );\n for (const a of ADAPTERS) {\n if (!a.detect()) continue;\n const st = a.installed(hc, process.env, { lean: isLean(cfg) });\n (report.harnesses as Record<string, unknown>)[a.name] = st.map((r) => ({\n file: tilde(r.file),\n state: r.state,\n ...(r.note ? { note: r.note } : {}),\n }));\n for (const r of st)\n if (r.state === \"inactive\")\n warnings.push(`${a.name}: hooks are written but the harness will not run them \u2014 ${r.note ?? \"\"}`);\n for (const r of st)\n if (r.state === \"stale\")\n warnings.push(\n `${a.name}: the hook in ${tilde(r.file)} points at an old node or script path; run \\`sessionpipe install\\` again.`,\n );\n for (const r of st)\n if (r.state === \"misplaced\")\n warnings.push(\n `${a.name}: the notify line in ${tilde(r.file)} sits inside a [table], where Codex never reads it; run \\`sessionpipe install\\` again.`,\n );\n }\n for (const s of cfg.sinks)\n (report.sinks as unknown[]).push({\n name: s.name,\n url: s.url,\n tier: s.tier,\n max_tier: s.max_tier ?? null,\n pii: !!s.pii,\n control: !!s.control,\n paused: s.paused ?? null,\n token: s.token_in ? `in ${s.token_in}` : s.token ? `${s.token.slice(0, 4)}\u2026` : null,\n });\n const w = report.hook_wall_ms as { p50: number; p95: number; n: number } | null;\n if (w && w.p50 > 150)\n warnings.push(\n `the harness waits ${w.p50} ms per hook (p50, target < 150): that is Node's own startup on this machine. A lean install (no sink above tier 0) hooks fewer events.`,\n );\n if (has(\"--json\")) {\n out(JSON.stringify(report, null, 2));\n return;\n }\n out(` sessionpipe ${VERSION} \u00B7 node ${process.version} at ${report.node_path}`);\n out(` config ${tilde(configFile())} \u00B7 state ${tilde(state)}`);\n for (const [h, st] of Object.entries(report.harnesses as Record<string, { file: string; state: string }[]>))\n for (const r of st) out(` ${h.padEnd(12)} ${r.file.padEnd(44)} ${r.state}`);\n for (const s of report.sinks as { name: string; tier: number; max_tier: number | null; paused: string | null }[])\n out(\n ` sink ${s.name.padEnd(16)} tier ${s.tier}${s.max_tier !== null ? ` (receiver max ${s.max_tier})` : \"\"}${s.paused ? ` PAUSED ${s.paused}` : \"\"}`,\n );\n const lr = report.launcher as { file: string; node: string | null; node_ok: boolean } | undefined;\n if (lr)\n out(` hooks run ${lr.file} \u2192 node ${lr.node ? tilde(lr.node) : \"?\"}${lr.node_ok ? \"\" : \" (gone: PATH's node)\"}`);\n for (const k of keys)\n out(` key ${k.what.padEnd(28)} ${storeLabel(k.where as StoreName)}${k.readable ? \"\" : \" (unreadable here)\"}`);\n for (const a of (report.claude_accounts as { dir: string; signed_in: boolean | null }[] | undefined) ?? [])\n out(\n ` claude ${a.dir.padEnd(26)} ${a.signed_in === true ? \"signed in\" : a.signed_in === false ? \"NOT signed in from here\" : \"can't tell\"}`,\n );\n out(` update ${updateLine(upd, Date.now())}`);\n const t = report.timing as { p50: number; p95: number; n: number } | null;\n out(\n w\n ? ` hook wall clock (what the harness waits): p50 ${w.p50} ms \u00B7 p95 ${w.p95} ms over ${w.n} spawns`\n : \" hook wall clock: could not spawn dist/hook.js\",\n );\n out(\n t\n ? ` hook in-process: p50 ${t.p50} ms \u00B7 p95 ${t.p95} ms over the last ${t.n} runs`\n : \" hook in-process: no runs yet\",\n );\n for (const w of warnings) out(` ! ${w}`);\n if (!warnings.length) out(\" no warnings\");\n}\n\n/** Follow the local outbox: one event per line, filtered to a tier. The zero-server demo. */\nasync function tail(): Promise<void> {\n const tier = Math.max(0, Math.min(3, Number(flag(\"--tier\") ?? 1))) as Tier;\n const onlySession = flag(\"--session\");\n const onlyHarness = flag(\"--harness\");\n const outbox = new Outbox(state);\n const offsets = new Map<string, number>();\n const fmt = (e: Event): string => {\n const t = e.time.slice(11, 19);\n const d = e.data as Record<string, unknown>;\n let detail = \"\";\n switch (e.type) {\n case \"session.started\":\n detail = `source=${d.source} ${e.session.cwd ?? \"\"} ${e.session.branch ?? \"\"}`;\n break;\n case \"turn.started\":\n detail = d.prompt_chars !== undefined ? `prompt_chars=${d.prompt_chars}` : \"\";\n break;\n case \"tool.started\":\n detail = String(d.tool ?? \"\");\n break;\n case \"tool.ended\":\n detail = `${d.tool} ${d.ok ? \"ok\" : \"error\"}${d.ms !== undefined ? ` ${d.ms}ms` : \"\"}`;\n break;\n case \"attention.needed\":\n detail = `${d.kind}${d.tool ? ` ${d.tool}` : \"\"}${d.message ? ` \"${String(d.message).slice(0, 60)}\"` : \"\"}`;\n break;\n case \"turn.ended\":\n detail = String(d.reason ?? \"\");\n break;\n case \"session.ended\":\n detail = `reason=${d.reason}`;\n break;\n case \"turn.transcript\":\n detail = `#${d.turn} \"${String(d.user).slice(0, 50).replace(/\\s+/g, \" \")}\"`;\n break;\n case \"session.backfill\":\n detail = `${e.session.title ?? \"\"}`;\n break;\n default:\n detail = JSON.stringify(d).slice(0, 80);\n }\n return `${t} ${e.harness.name.padEnd(11)} ${e.session.id.slice(0, 4)}\u2026 ${e.type.padEnd(17)} ${detail}`;\n };\n out(`sessionpipe tail \u00B7 tier ${tier} \u00B7 ${tilde(state)}/outbox (Ctrl-C to stop)`);\n // Start at the end of each file unless --all.\n for (const ref of outbox.sessions()) {\n try {\n offsets.set(`${ref.harness}/${ref.session}`, has(\"--all\") ? 0 : statSync(outbox.file(ref)).size);\n } catch {}\n }\n for (;;) {\n for (const ref of outbox.sessions()) {\n if (onlyHarness && ref.harness !== onlyHarness) continue;\n if (onlySession && !ref.session.startsWith(onlySession)) continue;\n const k = `${ref.harness}/${ref.session}`;\n const from = offsets.get(k) ?? 0;\n const { events, offset } = outbox.read(ref, from, 200);\n offsets.set(k, offset);\n for (const e of events) {\n const f = filterEvent(e, tier, false);\n if (f) out(has(\"--json\") ? JSON.stringify(f) : fmt(f));\n }\n }\n await new Promise((r) => setTimeout(r, 500));\n }\n}\n\nasync function workerFromArgv(): Promise<void> {\n const f = args[1];\n if (!f) return;\n const job = JSON.parse(readFileSync(f, \"utf8\"));\n try {\n unlinkSync(f);\n } catch {}\n await runJob(job);\n}\n\n/** Whether the daemon updates this copy by itself, and what it last found. */\nfunction updateState(cfg: Config) {\n return updateSummary({\n // The shell's own SESSIONPIPE_NO_UPDATE_CHECK says nothing about the daemon's\n // environment; the daemon records that one itself.\n off: autoUpdateOff({ env: {}, config: cfg, distDir }),\n paired: pairedCount() > 0,\n rec: readUpdate(updateFile()),\n });\n}\n\n/** `sessionpipe update [off|on]`: install the latest release into this copy's prefix\n * now, then have the daemon restart onto it once idle; or switch the daemon's daily\n * update off or on (config.json `update_check`; the daemon reads it every ten minutes). */\nasync function update(): Promise<void> {\n const sub = args[1];\n if (sub === \"off\" || sub === \"on\") {\n const cfg = readConfig();\n cfg.update_check = sub === \"on\";\n writeConfig(cfg);\n return out(\n sub === \"off\"\n ? \" \u2713 The control daemon no longer checks npm or updates itself. `sessionpipe update` still updates by hand; `sessionpipe update on` undoes this.\"\n : \" \u2713 The control daemon checks npm once a day and installs a new release when it's idle.\",\n );\n }\n if (process.env.SESSIONPIPE_NO_UPDATE_CHECK) return out(\" update check is off (SESSIONPIPE_NO_UPDATE_CHECK)\");\n let latest: string;\n try {\n latest = await latestVersion();\n } catch (e) {\n return out(` couldn't check npm: ${(e as Error).message}`);\n }\n if (!isNewer(latest, VERSION)) return out(` sessionpipe ${VERSION} is current (npm latest: ${latest})`);\n const prefix = globalPrefix(distDir);\n if (!prefix)\n return out(\n ` ${latest} is available (you run ${VERSION}), but this copy isn't a global npm install (npx, a checkout or a dev build): \\`npm install -g sessionpipe@${latest}\\` installs one.`,\n );\n out(` ${latest} is available (you run ${VERSION}); installing into ${tilde(prefix)}\u2026`);\n const r = await installVersion(latest, {\n node: process.execPath,\n distDir,\n harnesses: enabledHarnesses(readConfig().harnesses),\n });\n if (!r.ok) {\n process.exitCode = 1;\n return out(` \u2717 ${r.error}`);\n }\n out(` \u2713 sessionpipe ${latest} installed in ${(r.ms / 1000).toFixed(1)} s; ${r.hooks}`);\n // The daemon still runs the old code: it restarts onto this copy when nothing is in hand.\n const sock = socketPath(state);\n const st = await ask(sock, { op: \"status\" }, 2000);\n if (st?.op !== \"status\") return;\n const running = (st.status as { version?: string }).version ?? \"?\";\n if (running === latest) return;\n const r2 = await ask(sock, { op: \"restart\" }, 2000);\n if (r2?.op === \"ok\") out(` The control daemon (${running}) restarts onto ${latest} as soon as nothing is in hand.`);\n else\n out(\n ` The control daemon still runs ${running} and can't restart itself: ${\n process.platform === \"darwin\"\n ? `\\`launchctl kickstart -k gui/${process.getuid?.() ?? \"$(id -u)\"}/org.sessionpipe.control\\``\n : process.platform === \"linux\"\n ? \"`systemctl --user restart sessionpipe-control.service`\"\n : \"stop `sessionpipe control run` and start it again\"\n } moves it (a run in progress stops).`,\n );\n}\n\nmain().catch((e) => {\n process.stderr.write(`sessionpipe: ${(e as Error).message}\\n`);\n process.exit(1);\n});\n", "// SPDX-License-Identifier: Apache-2.0\n// Antigravity (Google) \u2014 docs: https://antigravity.google/docs/hooks\n// Config: ~/.gemini/config/hooks.json \u2014 top-level keys are hook NAMES, ours is\n// \"sessionpipe\". stdin is camelCase with NO event name (it rides in argv). A hook's\n// stdout is its answer; non-JSON is a deny. Timeouts in seconds. No session end\n// exists. Ported from spacesheep-cli lib/sessions.js (facts, remote url, projects).\n//\n// No PreToolUse. Its answer must carry a `decision` (allow / deny / ask / force_ask),\n// none of which means \"carry on\": `{}` is read as a deny with no reason, which blocked\n// every tool call on every machine 0.1\u20130.6.0 was installed on (2026-10-04, Antigravity\n// 2.19.1), and `allow` would wave calls past the person's own review settings. So the\n// tool events come from PostToolUse alone, which carries no tool name (only `stepIdx`\n// and `error`): it is a \"still working\" beat.\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport path from \"node:path\";\nimport { HOME } from \"../paths.js\";\nimport { ends, parseLines } from \"../readers/files.js\";\nimport { readAntigravity } from \"../readers/transcripts.js\";\nimport { formatJson, readJsonFile } from \"./claude-shaped.js\";\nimport type {\n Adapter,\n BackfillRow,\n FactsState,\n HookCommand,\n HookInput,\n HookResult,\n InstallOptions,\n InstallReport,\n SessionFacts,\n} from \"./types.js\";\n\nconst NAME = \"antigravity\";\nconst HOOK_NAME = \"sessionpipe\";\nexport const AG_EVENTS = [\"PreInvocation\", \"PostInvocation\", \"PostToolUse\", \"Stop\"] as const;\n/** What a PreToolUse entry an older install left behind gets, until a restarted\n * conversation reads the rewritten hooks.json: the person's own prompt, with why. The\n * hook (cli/src/hook.ts) and the launcher (cli/src/launcher.ts) print the same line. */\nexport const AG_STALE_PRETOOL =\n '{\"decision\":\"ask\",\"reason\":\"sessionpipe: an outdated PreToolUse hook is still loaded. Restart this conversation (or run sessionpipe install) to drop it.\"}\\n';\n/** Antigravity's answer for one event: `{}` is \"carry on\" for every event we register. */\nexport const antigravityAnswer = (event: string): string => (event === \"PreToolUse\" ? AG_STALE_PRETOOL : \"{}\\n\");\nconst gemini = (env: NodeJS.ProcessEnv) => env.GEMINI_CLI_HOME || path.join(HOME, \".gemini\");\nconst hooksFile = (env: NodeJS.ProcessEnv) => path.join(gemini(env), \"config\", \"hooks.json\");\nconst projectsDir = (env: NodeJS.ProcessEnv) => path.join(gemini(env), \"config\", \"projects\");\nconst dataDirs = (env: NodeJS.ProcessEnv) =>\n [\"antigravity\", \"antigravity-cli\", \"antigravity-ide\"].map((d) => path.join(gemini(env), d));\nconst ID_RE = /^[A-Za-z0-9_-]{1,128}$/;\nconst validTool = (n: unknown): n is string => typeof n === \"string\" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);\n\n// One tool event already, so a lean install is the same entry.\nfunction entry(cmd: HookCommand) {\n const handler = (e: string) => ({ type: \"command\", command: cmd([NAME, e]).command, timeout: 5 });\n const out: Record<string, unknown> = { enabled: true };\n for (const e of AG_EVENTS) out[e] = /Tool/.test(e) ? [{ matcher: \"*\", hooks: [handler(e)] }] : [handler(e)];\n return out;\n}\n\nexport const antigravity: Adapter = {\n name: NAME,\n events: AG_EVENTS,\n detect: (env = process.env) =>\n existsSync(path.join(gemini(env), \"config\")) || dataDirs(env).some((d) => existsSync(d)),\n configFiles: (env = process.env) => [hooksFile(env)],\n install(cmd, env = process.env): InstallReport[] {\n const file = hooksFile(env);\n const f = readJsonFile(file);\n if (!f.ok) return [{ file, changed: false, skipped: true, note: `${f.reason}; not touched` }];\n const hooks = f.value;\n const e = entry(cmd);\n if (JSON.stringify(hooks[HOOK_NAME]) === JSON.stringify(e)) return [{ file, changed: false }];\n hooks[HOOK_NAME] = e;\n mkdirSync(path.dirname(file), { recursive: true });\n writeFileSync(file, formatJson(hooks, f));\n return [\n {\n file,\n changed: true,\n created: !f.existed,\n note: \"hooks.json is read when a conversation starts; open ones report after a restart\",\n },\n ];\n },\n uninstall(env = process.env, opts: InstallOptions = {}): InstallReport[] {\n const file = hooksFile(env);\n if (!existsSync(file)) return [{ file, changed: false }];\n const f = readJsonFile(file);\n if (!f.ok) return [{ file, changed: false, skipped: true, note: `${f.reason}; not touched` }];\n const hooks = f.value;\n if (!(HOOK_NAME in hooks)) return [{ file, changed: false }];\n delete hooks[HOOK_NAME];\n if (opts.created?.includes(file) && !Object.keys(hooks).length) {\n unlinkSync(file);\n return [{ file, changed: true, note: \"removed (sessionpipe created it)\" }];\n }\n writeFileSync(file, formatJson(hooks, f));\n return [{ file, changed: true }];\n },\n installed(cmd, env = process.env) {\n const file = hooksFile(env);\n const f = readJsonFile(file);\n const have = f.ok ? f.value[HOOK_NAME] : undefined;\n return [\n {\n file,\n state: !have ? \"missing\" : JSON.stringify(have) === JSON.stringify(entry(cmd)) ? \"current\" : \"stale\",\n },\n ];\n },\n\n fromHook(input: HookInput): HookResult | null {\n const event = input.argv[1] ?? \"\";\n let s: Record<string, unknown> = {};\n try {\n s = input.stdin ? (JSON.parse(input.stdin) as Record<string, unknown>) : {};\n } catch {}\n const id = (s.conversationId ?? s.session_id ?? s.sessionId) as string | undefined;\n const stdout = antigravityAnswer(event);\n if (!id) return { session: { id: \"\" }, events: [], stdout };\n const workspaces = agWorkspaces(s.workspacePaths);\n const session: HookResult[\"session\"] = { id: String(id), cwd: workspaces[0] ?? input.cwd };\n if (typeof s.modelName === \"string\" && s.modelName !== \"auto\") session.model = s.modelName;\n const toolCall = s.toolCall as { name?: unknown; args?: unknown } | undefined;\n const tool = validTool(toolCall?.name) ? toolCall?.name : validTool(s.toolName) ? s.toolName : undefined;\n const ev = (type: string, data: Record<string, unknown>) => ({ type, data: prune(data), harnessEvent: event });\n const events: HookResult[\"events\"] = [];\n switch (event) {\n case \"PreInvocation\":\n // Fires before every model call of an execution; only the first is the person's ask.\n if (Number(s.invocationNum) === 0 || s.invocationNum === undefined) {\n events.push(ev(\"session.started\", { source: \"unknown\" }));\n events.push(ev(\"turn.started\", {}));\n } else events.push(ev(\"session.heartbeat\", {}));\n break;\n case \"PostInvocation\":\n break;\n case \"PreToolUse\":\n if (tool) events.push(ev(\"tool.started\", { tool, input: toolCall?.args }));\n break;\n case \"PostToolUse\":\n // Antigravity names no tool here; a beat keeps a long run of tools \"working\".\n if (!tool) events.push(ev(\"session.heartbeat\", {}));\n else\n events.push(\n ev(\"tool.ended\", {\n tool,\n ok: !s.error,\n error: typeof s.error === \"string\" ? s.error.slice(0, 2000) : undefined,\n input: toolCall?.args,\n }),\n );\n break;\n case \"Stop\":\n events.push(ev(\"turn.ended\", { reason: s.error ? \"error\" : \"stop\" }));\n break;\n default:\n return { session, events: [], stdout };\n }\n const r: HookResult = { session, events, stdout, hints: { workspaces } };\n if (typeof s.transcriptPath === \"string\") r.transcript = s.transcriptPath;\n return r;\n },\n\n readTranscript(file, fromLine) {\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { turns: [], line: fromLine };\n }\n return readAntigravity(text.split(\"\\n\"), fromLine);\n },\n\n facts(session, transcript, hints, state): SessionFacts {\n if (!transcript) return {};\n return antigravityFacts(transcript, {\n conversation: session.id,\n workspaces: (hints.workspaces as string[] | undefined) ?? (session.cwd ? [session.cwd] : []),\n state,\n env: process.env,\n });\n },\n\n backfill(sinceMs, env = process.env): BackfillRow[] {\n const rows: BackfillRow[] = [];\n const noState: FactsState = { get: () => ({}), save: () => {} };\n for (const data of dataDirs(env)) {\n let ids: string[] = [];\n try {\n ids = readdirSync(path.join(data, \"brain\")).filter((n) => /^[0-9a-f-]{36}$/i.test(n));\n } catch {}\n for (const id of ids) {\n const f = path.join(data, \"brain\", id, \".system_generated\", \"logs\", \"transcript.jsonl\");\n try {\n if (statSync(f).mtimeMs < sinceMs) continue;\n } catch {\n continue;\n }\n const facts = antigravityFacts(f, { conversation: id, workspaces: [], state: noState, env });\n if (!facts.started_at || !facts.last_at) continue;\n const { started_at, last_at, first_ask: _fa, harness_version: _hv, ...rest } = facts;\n rows.push({ session: { id, ...rest }, started_at, last_at });\n }\n }\n return rows;\n },\n};\n\nfunction prune<T extends Record<string, unknown>>(o: T): T {\n for (const k of Object.keys(o)) if (o[k] === undefined) delete o[k];\n return o;\n}\n\n/** A folder as Antigravity writes it (a file:// URI or a path) \u2192 an absolute path, or null. */\nexport function agPath(p: unknown): string | null {\n if (typeof p !== \"string\" || !p) return null;\n let s = p;\n if (/^file:/i.test(s)) {\n try {\n s = decodeURIComponent(new URL(s).pathname);\n } catch {\n return null;\n }\n if (process.platform === \"win32\" && /^\\/[A-Za-z]:/.test(s)) s = s.slice(1);\n } else if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(s)) return null;\n if (!path.isAbsolute(s)) return null;\n return path.resolve(s);\n}\nexport const agWorkspaces = (paths: unknown): string[] =>\n (Array.isArray(paths) ? paths : [])\n .map(agPath)\n .filter((p): p is string => !!p)\n .filter((p, i, a) => a.indexOf(p) === i);\n\nfunction agVariants(p: string): string[] {\n const out = [p];\n try {\n const r = realpathSync.native(p);\n if (r !== p) out.push(r);\n } catch {}\n return out;\n}\nfunction agProjects(dir: string): { id: string; folders: string[] }[] {\n const out: { id: string; folders: string[] }[] = [];\n let names: string[] = [];\n try {\n names = readdirSync(dir).filter((n) => n.endsWith(\".json\"));\n } catch {\n return out;\n }\n for (const n of names) {\n const id = n.slice(0, -5);\n if (!ID_RE.test(id)) continue;\n let j: { projectResources?: { resources?: { folderUri?: unknown }[] } };\n try {\n j = JSON.parse(readFileSync(path.join(dir, n), \"utf8\"));\n } catch {\n continue;\n }\n const folders: string[] = [];\n for (const r of j?.projectResources?.resources ?? []) {\n const f = agPath(r?.folderUri);\n if (f) folders.push(...agVariants(f));\n }\n if (folders.length) out.push({ id, folders });\n }\n return out;\n}\n/** The project whose folder is the workspace or contains it; the deepest wins. */\nexport function agMatchProject(projects: { id: string; folders: string[] }[], workspaces: string[]): string | null {\n const ws: string[] = [];\n for (const w of workspaces) {\n const p = agPath(w);\n if (p) ws.push(...agVariants(p));\n }\n let best: string | null = null;\n let bestLen = -1;\n for (const pr of projects)\n for (const f of pr.folders) {\n const within = ws.some((w) => w === f || w.startsWith(f.endsWith(path.sep) ? f : f + path.sep));\n if (within && f.length > bestLen) {\n best = pr.id;\n bestLen = f.length;\n }\n }\n return best;\n}\n\n/** Antigravity's web remote: https://antigravity.google.com/r/<installation uuid>-v2, with\n * ?p=c/<conversation>?section=<project> when the project is known. */\nexport function antigravityRemoteUrl(\n transcript: string,\n opts: { conversation?: string; workspaces?: string[]; env: NodeJS.ProcessEnv; projectsDir?: string },\n): string | null {\n const i = transcript.indexOf(`${path.sep}brain${path.sep}`);\n const dirs = (i > 0 ? [transcript.slice(0, i)] : []).concat(dataDirs(opts.env));\n for (const d of dirs) {\n try {\n const m = /installation_uuid:\\s*\"([0-9a-f-]{36})\"/i.exec(\n readFileSync(path.join(d, \"antigravity_state.pbtxt\"), \"utf8\"),\n );\n if (!m) continue;\n const base = `https://antigravity.google.com/r/${m[1]}-v2`;\n const conv = opts.conversation ?? \"\";\n if (!ID_RE.test(conv) || !opts.workspaces?.length) return base;\n const project = agMatchProject(agProjects(opts.projectsDir ?? projectsDir(opts.env)), opts.workspaces);\n return project ? `${base}?p=${encodeURIComponent(`c/${conv}?section=${project}`)}` : base;\n } catch {}\n }\n return null;\n}\n\nexport function antigravityFacts(\n file: string,\n opts: { conversation: string; workspaces: string[]; state: FactsState; env: NodeJS.ProcessEnv },\n): SessionFacts {\n const { head, tail } = ends(file, 128 * 1024, 64 * 1024);\n const H = parseLines(head);\n const T = parseLines(tail);\n const out: SessionFacts = {};\n const url = antigravityRemoteUrl(file, opts);\n if (url) out.url = url;\n for (const j of H) {\n if (j.type !== \"USER_INPUT\" || typeof j.content !== \"string\") continue;\n const m = /<USER_REQUEST>([\\s\\S]*?)(?:<\\/USER_REQUEST>|$)/.exec(j.content);\n const text = (m ? (m[1] ?? \"\") : j.content).trim();\n const line = (text.split(\"\\n\").find((l) => l.trim()) ?? \"\").trim();\n if (!line || /^<[a-z_-]+>/i.test(line)) continue;\n out.title = line.length > 80 ? `${line.slice(0, 80).replace(/\\s+\\S*$/, \"\")}\u2026` : line;\n out.title_source = \"first-ask\";\n break;\n }\n const times = H.concat(T)\n .map((j) => Date.parse(String(j.created_at ?? j.timestamp ?? \"\")))\n .filter((n) => n > 0);\n if (times.length) {\n out.started_at = Math.min(...times);\n out.last_at = Math.max(...times);\n }\n return out;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Where sessionpipe keeps its files (spec: the client's Files section).\n// config ~/.config/sessionpipe/config.json SESSIONPIPE_CONFIG\n// state ~/.local/state/sessionpipe/ SESSIONPIPE_STATE\n// Windows %APPDATA%\\sessionpipe\\ and %LOCALAPPDATA%\\sessionpipe\\\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport const HOME = os.homedir();\n\nexport function configFile(env: NodeJS.ProcessEnv = process.env): string {\n if (env.SESSIONPIPE_CONFIG) return path.resolve(env.SESSIONPIPE_CONFIG);\n if (process.platform === \"win32\")\n return path.join(env.APPDATA || path.join(HOME, \"AppData\", \"Roaming\"), \"sessionpipe\", \"config.json\");\n return path.join(env.XDG_CONFIG_HOME || path.join(HOME, \".config\"), \"sessionpipe\", \"config.json\");\n}\n\nexport function stateDir(env: NodeJS.ProcessEnv = process.env): string {\n if (env.SESSIONPIPE_STATE) return path.resolve(env.SESSIONPIPE_STATE);\n if (process.platform === \"win32\")\n return path.join(env.LOCALAPPDATA || path.join(HOME, \"AppData\", \"Local\"), \"sessionpipe\");\n return path.join(env.XDG_STATE_HOME || path.join(HOME, \".local\", \"state\"), \"sessionpipe\");\n}\n\n/** `~` for the home directory, as the session block writes paths. */\nexport function tilde(p: string, home: string = HOME): string {\n if (!p) return p;\n if (p === home) return \"~\";\n return p.startsWith(home + path.sep) || p.startsWith(`${home}/`) ? `~${p.slice(home.length)}` : p;\n}\n\n/** A file-name-safe id. */\nexport const safeId = (s: string): string =>\n String(s)\n .replace(/[^A-Za-z0-9_.-]/g, \"_\")\n .slice(0, 160);\n", "// SPDX-License-Identifier: Apache-2.0\n// Reading the ends of large files, JSON lines, and recent files under a root.\nimport { closeSync, fstatSync, openSync, readdirSync, readSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\n\n/** The first and last bytes of a file, as lines \u2014 a transcript can be tens of MB. */\nexport function ends(file: string, headBytes: number, tailBytes: number): { head: string[]; tail: string[] } {\n let fd: number | undefined;\n try {\n fd = openSync(file, \"r\");\n const size = fstatSync(fd).size;\n const read = (pos: number, len: number) => {\n const b = Buffer.alloc(len);\n const n = readSync(fd as number, b, 0, len, pos);\n return b.subarray(0, n).toString(\"utf8\");\n };\n const head = read(0, Math.min(size, headBytes));\n const tail = size > headBytes ? read(Math.max(0, size - tailBytes), Math.min(size, tailBytes)) : head;\n return { head: head.split(\"\\n\").slice(0, -1), tail: tail.split(\"\\n\").slice(size > headBytes ? 1 : 0) };\n } catch {\n return { head: [], tail: [] };\n } finally {\n if (fd !== undefined)\n try {\n closeSync(fd);\n } catch {}\n }\n}\n\nexport const parseLines = (lines: string[]): Record<string, unknown>[] =>\n lines\n .map((l) => {\n try {\n return JSON.parse(l) as Record<string, unknown>;\n } catch {\n return null;\n }\n })\n .filter((x): x is Record<string, unknown> => !!x);\n\n/** Read line by line up to `cap` bytes, stopping when `visit` returns a value. */\nexport function scanLines<T>(file: string, visit: (line: string) => T | null, cap = 16 * 1024 * 1024): T | null {\n let fd: number | undefined;\n try {\n fd = openSync(file, \"r\");\n const buf = Buffer.alloc(1024 * 1024);\n let pos = 0;\n let rest: Buffer = Buffer.alloc(0);\n while (pos < cap) {\n const n = readSync(fd, buf, 0, buf.length, pos);\n if (!n) break;\n pos += n;\n let chunk = Buffer.concat([rest, buf.subarray(0, n)]);\n let nl = chunk.indexOf(10);\n while (nl >= 0) {\n const r = visit(chunk.subarray(0, nl).toString(\"utf8\"));\n if (r !== null) return r;\n chunk = chunk.subarray(nl + 1);\n nl = chunk.indexOf(10);\n }\n rest = chunk;\n }\n } catch {\n } finally {\n if (fd !== undefined)\n try {\n closeSync(fd);\n } catch {}\n }\n return null;\n}\n\nexport function recentFiles(root: string, depth: number, sinceMs: number, match: (name: string) => boolean): string[] {\n const out: string[] = [];\n const walk = (dir: string, d: number) => {\n let names: import(\"node:fs\").Dirent[] = [];\n try {\n names = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of names) {\n const p = path.join(dir, e.name);\n if (e.isDirectory()) {\n if (d < depth) walk(p, d + 1);\n continue;\n }\n if (!match(e.name)) continue;\n try {\n if (statSync(p).mtimeMs >= sinceMs) out.push(p);\n } catch {}\n }\n };\n walk(root, 0);\n return out;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Transcript readers: complete turns (a person's message + everything the assistant\n// said before the next one), each with the line it ends on, and the line the\n// cursor may advance to once every turn is delivered. Ported from spacesheep-cli\n// lib/memory.js. One reader per harness file format; nothing else is vendor code.\nimport type { TranscriptRead } from \"../adapters/types.js\";\n\ninterface Msg {\n role: \"user\" | \"assistant\";\n text: string;\n at: number;\n line: number;\n}\n\nexport function pairTurns(msgs: Msg[], endLine: number): TranscriptRead {\n const turns: { user: string; assistant: string; at: number; startLine: number; endLine: number }[] = [];\n let cur: (typeof turns)[number] | null = null;\n for (const m of msgs) {\n if (m.role === \"user\") {\n // Never overwrite a prompt that has no reply yet: in an agentic turn the reply\n // comes after tool calls, and a second user record is not a new question.\n if (cur && !cur.assistant) {\n cur.user += `\\n\\n${m.text}`;\n continue;\n }\n if (cur) turns.push(cur);\n cur = { user: m.text, assistant: \"\", at: m.at, startLine: m.line, endLine: m.line };\n } else {\n if (!cur) cur = { user: \"\", assistant: \"\", at: m.at, startLine: m.line, endLine: m.line };\n cur.assistant += (cur.assistant ? \"\\n\\n\" : \"\") + m.text;\n cur.endLine = m.line;\n }\n }\n if (cur?.assistant) turns.push(cur);\n // A user message with no reply yet stays unsent: the cursor stops before it.\n const line = cur && !cur.assistant ? cur.startLine : endLine;\n return { turns: turns.map((t) => ({ user: t.user, assistant: t.assistant, at: t.at, endLine: t.endLine })), line };\n}\n\n/** Injected context the person never typed: <tag>\u2026</tag> wrappers, HTML comments, slash-command expansions. */\nexport const isInjected = (text: string): boolean =>\n (/^<[a-z_-]+>/i.test(text) && /<\\/[a-z_-]+>\\s*$/i.test(text)) || /^<!--\\s/.test(text) || /^<command-/.test(text);\n\nconst endOf = (lines: string[]) => (lines[lines.length - 1] === \"\" ? lines.length - 1 : lines.length);\nconst parse = (raw: string): Record<string, unknown> | null => {\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return null;\n }\n};\nconst textParts = (c: unknown, kinds: string[]): string => {\n if (typeof c === \"string\") return c;\n if (!Array.isArray(c)) return \"\";\n return c\n .filter(\n (b) =>\n b &&\n typeof b === \"object\" &&\n kinds.includes((b as { type?: string }).type ?? \"\") &&\n typeof (b as { text?: unknown }).text === \"string\",\n )\n .map((b) => (b as { text: string }).text)\n .join(\"\\n\");\n};\n\n/** Claude Code / Droid: {type:\"user\"|\"assistant\", message:{content}, timestamp, isMeta, isSidechain, origin}. */\nexport function readClaude(lines: string[], from: number): TranscriptRead {\n const msgs: Msg[] = [];\n for (let i = from; i < lines.length; i++) {\n const j = lines[i] ? parse(lines[i] as string) : null;\n if (!j || j.isSidechain) continue;\n const origin = j.origin as { kind?: string } | undefined;\n if (j.type === \"user\" && (j.isMeta || (origin?.kind && origin.kind !== \"human\"))) continue;\n const at = Date.parse(String(j.timestamp ?? \"\")) || Date.now();\n const c = (j.message as { content?: unknown } | undefined)?.content;\n if (j.type === \"user\") {\n const text = textParts(c, [\"text\"]).trim();\n if (!text || isInjected(text)) continue;\n msgs.push({ role: \"user\", text, at, line: i });\n } else if (j.type === \"assistant\" && Array.isArray(c)) {\n const text = textParts(c, [\"text\"]).trim();\n if (text) msgs.push({ role: \"assistant\", text, at, line: i });\n }\n }\n return pairTurns(msgs, endOf(lines));\n}\n\n/** Codex rollout: {type:\"response_item\", payload:{type:\"message\", role, content:[{type:\"input_text\"|\"output_text\", text}]}}. */\nexport function readCodex(lines: string[], from: number): TranscriptRead {\n const msgs: Msg[] = [];\n for (let i = from; i < lines.length; i++) {\n const j = lines[i] ? parse(lines[i] as string) : null;\n if (!j || j.type !== \"response_item\") continue;\n const p = j.payload as { type?: string; role?: string; content?: unknown } | undefined;\n if (!p || p.type !== \"message\") continue;\n const at = Date.parse(String(j.timestamp ?? \"\")) || Date.now();\n const text = textParts(p.content, [\"input_text\", \"output_text\"]).trim();\n if (!text) continue;\n if (p.role === \"user\") {\n if (/^<[a-z_-]+>/i.test(text)) continue; // <environment_context>: Codex's own injections\n msgs.push({ role: \"user\", text, at, line: i });\n } else if (p.role === \"assistant\") msgs.push({ role: \"assistant\", text, at, line: i });\n }\n return pairTurns(msgs, endOf(lines));\n}\n\n/** Gemini CLI chat log: {type:\"user\"|\"gemini\", content|message|text, timestamp}. */\nexport function readGemini(lines: string[], from: number): TranscriptRead {\n const msgs: Msg[] = [];\n for (let i = from; i < lines.length; i++) {\n const j = lines[i] ? parse(lines[i] as string) : null;\n if (!j) continue;\n const role = j.type === \"user\" ? \"user\" : j.type === \"gemini\" || j.type === \"model\" ? \"assistant\" : null;\n if (!role) continue;\n const raw = j.content ?? j.message ?? j.text;\n const text = (typeof raw === \"string\" ? raw : textParts(raw, [\"text\"])).trim();\n if (!text) continue;\n const at = Date.parse(String(j.timestamp ?? \"\")) || Date.now();\n msgs.push({ role, text, at, line: i });\n }\n return pairTurns(msgs, endOf(lines));\n}\n\n/** Antigravity: one step per line, type USER_INPUT | PLANNER_RESPONSE, content with <USER_REQUEST> wrapping. */\nexport function readAntigravity(lines: string[], from: number): TranscriptRead {\n const msgs: Msg[] = [];\n for (let i = from; i < lines.length; i++) {\n const j = lines[i] ? parse(lines[i] as string) : null;\n if (!j || typeof j.content !== \"string\") continue;\n const at = Date.parse(String(j.created_at ?? j.timestamp ?? \"\")) || Date.now();\n if (j.type === \"USER_INPUT\") {\n const m = /<USER_REQUEST>([\\s\\S]*?)(?:<\\/USER_REQUEST>|$)/.exec(j.content);\n const text = (m ? (m[1] ?? \"\") : j.content).trim();\n if (text) msgs.push({ role: \"user\", text, at, line: i });\n } else if (j.type === \"PLANNER_RESPONSE\") {\n const text = j.content.trim();\n if (text) msgs.push({ role: \"assistant\", text, at, line: i });\n }\n }\n return pairTurns(msgs, endOf(lines));\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The hooks file shape Claude Code introduced and Codex, Droid and (with\n// `version: 1`) Cursor and Copilot reuse: {\"hooks\":{\"<Event>\":[{\"matcher\"?,\n// \"hooks\":[{\"type\":\"command\",\"command\",\"timeout\"}]}]}}. Ours is one entry per\n// event; a re-install replaces a stale entry of ours (an old node path) and never\n// touches anyone else's.\n//\n// Two rules from issue #8: a file that is not plain JSON (a comment, a trailing\n// comma, a write in progress) is never written back \u2014 the harness is skipped and\n// the report says why; and a file is written back in its own shape (indent, final\n// newline) so uninstall leaves it byte-identical. A file that did not exist before\n// install is reported `created`, and uninstall deletes it once it is empty again.\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HookCommand, InstallReport } from \"./types.js\";\n\nexport interface ClaudeShapedOptions {\n /** Which events take a `matcher` (tool and permission events). */\n matcherFor: (event: string) => string | undefined;\n /** Seconds (milliseconds for Gemini CLI). */\n timeout: number;\n /** A longer timeout for one event (Claude Code's PermissionRequest, which may wait\n * for a verified control answer: spec/CONTROL.md \u00A76). */\n timeoutFor?: (event: string) => number | undefined;\n /** Extra top-level keys the file must carry (Cursor/Copilot: version: 1). */\n top?: Record<string, unknown>;\n}\n\n/** A command of ours: a path that contains \"sessionpipe\" and ends in hook.js (or in\n * sessionpipe-hook, the launcher that outlives a node upgrade), then a harness and an event. */\nexport const OURS = /(?:sessionpipe[^\"\\n]*[\\\\/]hook\\.js|[\\\\/]sessionpipe-hook)\"?\\s+[a-z][a-z-]*\\s+[A-Za-z]+\\s*$/;\nexport const isOurs = (h: { hooks?: { command?: string }[] }): boolean =>\n Array.isArray(h?.hooks) && h.hooks.some((x) => typeof x.command === \"string\" && OURS.test(x.command));\n\nexport type JsonFile =\n | {\n ok: true;\n existed: true;\n value: Record<string, unknown>;\n raw: string;\n indent: string;\n eol: string;\n finalNewline: boolean;\n }\n | { ok: true; existed: false; value: Record<string, unknown>; raw: \"\"; indent: \" \"; eol: \"\\n\"; finalNewline: true }\n | { ok: false; existed: true; reason: string };\n\n/** Read a JSON config file with its shape. Never guesses: a parse failure is a\n * refusal to touch the file, not an empty object. */\nexport function readJsonFile(file: string): JsonFile {\n let raw: string;\n try {\n raw = readFileSync(file, \"utf8\");\n } catch {\n return { ok: true, existed: false, value: {}, raw: \"\", indent: \" \", eol: \"\\n\", finalNewline: true };\n }\n let value: unknown;\n try {\n value = JSON.parse(raw);\n } catch {\n const hint = /^\\s*\\/\\/|\\/\\*/m.test(raw) ? \"not plain JSON (it has comments)\" : \"not plain JSON\";\n return { ok: false, existed: true, reason: hint };\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n return { ok: false, existed: true, reason: \"not a JSON object\" };\n const eol = raw.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const m = /^( +|\\t+)\\S/m.exec(raw);\n const indent = m?.[1] ?? \" \";\n return {\n ok: true,\n existed: true,\n value: value as Record<string, unknown>,\n raw,\n indent,\n eol,\n finalNewline: /\\r?\\n$/.test(raw),\n };\n}\n\n/** Serialise in the file's own shape. */\nexport function formatJson(value: unknown, f: { indent: string; eol: string; finalNewline: boolean }): string {\n const text = JSON.stringify(value, null, f.indent).replace(/\\n/g, f.eol);\n return f.finalNewline ? text + f.eol : text;\n}\n\n/** Back-compat helper for callers that only read. */\nexport function readJson(file: string): Record<string, unknown> {\n const f = readJsonFile(file);\n return f.ok ? f.value : {};\n}\n\nfunction entryFor(event: string, harness: string, cmd: HookCommand, o: ClaudeShapedOptions) {\n const matcher = o.matcherFor(event);\n return {\n ...(matcher !== undefined ? { matcher } : {}),\n hooks: [{ type: \"command\", command: cmd([harness, event]).command, timeout: o.timeoutFor?.(event) ?? o.timeout }],\n };\n}\n\nexport function installClaudeShaped(\n file: string,\n harness: string,\n events: readonly string[],\n cmd: HookCommand,\n o: ClaudeShapedOptions,\n): InstallReport {\n const f = readJsonFile(file);\n if (!f.ok) return { file, changed: false, skipped: true, note: `${f.reason}; not touched` };\n const settings = f.value;\n const hooks = (settings.hooks && typeof settings.hooks === \"object\" ? settings.hooks : {}) as Record<\n string,\n unknown[]\n >;\n let changed = false;\n const want = new Set(events);\n // Events we no longer hook (a lean install) lose their entry of ours.\n for (const ev of Object.keys(hooks)) {\n if (want.has(ev)) continue;\n const list = Array.isArray(hooks[ev]) ? hooks[ev] : [];\n const kept = list.filter((h) => !isOurs(h as never));\n if (kept.length !== list.length) {\n changed = true;\n if (kept.length) hooks[ev] = kept;\n else delete hooks[ev];\n }\n }\n for (const ev of events) {\n const list = Array.isArray(hooks[ev]) ? hooks[ev] : [];\n const entry = entryFor(ev, harness, cmd, o);\n const mine = list.filter((h) => isOurs(h as never));\n if (mine.length === 1 && JSON.stringify(mine[0]) === JSON.stringify(entry)) continue;\n hooks[ev] = list.filter((h) => !isOurs(h as never)).concat([entry]);\n changed = true;\n }\n if (o.top)\n for (const [k, v] of Object.entries(o.top))\n if (settings[k] !== v) {\n settings[k] = v;\n changed = true;\n }\n if (changed) {\n settings.hooks = hooks;\n mkdirSync(path.dirname(file), { recursive: true });\n writeFileSync(file, formatJson(settings, f));\n }\n return { file, changed, created: !f.existed && changed };\n}\n\nexport function uninstallClaudeShaped(\n file: string,\n events: readonly string[],\n opts: { created?: boolean | undefined } = {},\n): InstallReport {\n if (!existsSync(file)) return { file, changed: false };\n const f = readJsonFile(file);\n if (!f.ok) return { file, changed: false, skipped: true, note: `${f.reason}; not touched` };\n const settings = f.value;\n const hooks = settings.hooks as Record<string, unknown[]> | undefined;\n if (!hooks || typeof hooks !== \"object\") return { file, changed: false };\n let changed = false;\n for (const ev of [...events, ...Object.keys(hooks)]) {\n const list = Array.isArray(hooks[ev]) ? hooks[ev] : [];\n const kept = list.filter((h) => !isOurs(h as never));\n if (kept.length !== list.length) {\n changed = true;\n if (kept.length) hooks[ev] = kept;\n else delete hooks[ev];\n }\n }\n if (!changed) return { file, changed: false };\n if (!Object.keys(hooks).length) delete settings.hooks;\n if (opts.created && !Object.keys(settings).length) {\n unlinkSync(file);\n return { file, changed: true, note: \"removed (sessionpipe created it)\" };\n }\n const next = formatJson(settings, f);\n if (next !== f.raw) writeFileSync(file, next);\n return { file, changed: true };\n}\n\nexport function installedClaudeShaped(\n file: string,\n harness: string,\n events: readonly string[],\n cmd: HookCommand,\n o: ClaudeShapedOptions,\n): \"current\" | \"stale\" | \"missing\" {\n const f = readJsonFile(file);\n const hooks = (f.ok ? (f.value.hooks ?? {}) : {}) as Record<string, unknown[]>;\n let present = 0;\n let current = 0;\n for (const ev of events) {\n const list = Array.isArray(hooks[ev]) ? hooks[ev] : [];\n const mine = list.filter((h) => isOurs(h as never));\n if (mine.length) present++;\n if (mine.length === 1 && JSON.stringify(mine[0]) === JSON.stringify(entryFor(ev, harness, cmd, o))) current++;\n }\n // An entry of ours on an event outside the wanted set (a lean install after a full one) is stale.\n for (const ev of Object.keys(hooks))\n if (!events.includes(ev) && (Array.isArray(hooks[ev]) ? hooks[ev] : []).some((h) => isOurs(h as never)))\n return \"stale\";\n if (!present) return \"missing\";\n return current === events.length ? \"current\" : \"stale\";\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Claude Code (Anthropic) \u2014 docs: https://code.claude.com/docs/en/hooks\n// Config: settings.json in EVERY config dir (~/.claude, $CLAUDE_CONFIG_DIR, ~/.claude-*):\n// one per account; hooks written to one never fire for the others. Reads only the\n// hook's stdin, the transcript it names, the per-pid session registry and the config\n// dir's .claude.json account id. Ported from spacesheep-cli lib/sessions.js.\n\nimport { execFileSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { HOME } from \"../paths.js\";\nimport { ends, parseLines, recentFiles, scanLines } from \"../readers/files.js\";\nimport { gitFacts } from \"../readers/git.js\";\nimport { isInjected, readClaude } from \"../readers/transcripts.js\";\nimport { installClaudeShaped, installedClaudeShaped, uninstallClaudeShaped } from \"./claude-shaped.js\";\nimport type {\n Adapter,\n BackfillRow,\n FactsState,\n HookCommand,\n HookInput,\n HookResult,\n InstallOptions,\n SessionFacts,\n} from \"./types.js\";\n\nconst NAME = \"claude-code\";\nexport const CLAUDE_EVENTS = [\n \"SessionStart\",\n \"UserPromptSubmit\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PostToolUseFailure\",\n \"PermissionRequest\",\n \"Notification\",\n \"Stop\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PreCompact\",\n \"PostCompact\",\n \"SessionEnd\",\n \"StopFailure\",\n] as const;\n/** With no sink above tier 0 only the heartbeat needs a tool event: one, not three (issue #12). */\nconst LEAN_SKIP = new Set([\"PreToolUse\", \"PostToolUseFailure\"]);\nconst eventsFor = (lean?: boolean) => (lean ? CLAUDE_EVENTS.filter((e) => !LEAN_SKIP.has(e)) : [...CLAUDE_EVENTS]);\nconst OPTS = {\n matcherFor: (e: string) => (/Tool|Permission/.test(e) ? \"\" : undefined),\n timeout: 5,\n // The hook waits up to 125 s for a verified control answer, and only when control\n // is paired on this machine; everywhere else it exits in milliseconds as before.\n timeoutFor: (e: string) => (e === \"PermissionRequest\" ? 130 : undefined),\n};\nconst DESKTOP_ID = /^local_[A-Za-z0-9-]{1,64}$/;\n\n/** Every Claude Code config dir on this machine. `home` follows the env's HOME, so a\n * caller with its own env (a test) never reaches the real ~/.claude: the install test\n * once rewrote a real settings.json with its fake hook paths on every run. */\nexport function claudeDirs(env: NodeJS.ProcessEnv = process.env, home = env.HOME || HOME): string[] {\n const out: string[] = [];\n const add = (d?: string) => {\n if (!d) return;\n const r = path.resolve(d);\n if (!out.includes(r)) out.push(r);\n };\n add(path.join(home, \".claude\"));\n add(env.CLAUDE_CONFIG_DIR);\n try {\n for (const e of readdirSync(home, { withFileTypes: true })) {\n if (!e.isDirectory() || !/^\\.claude[-_.]/.test(e.name)) continue;\n const d = path.join(home, e.name);\n if (existsSync(path.join(d, \"projects\")) || existsSync(path.join(d, \"settings.json\"))) add(d);\n }\n } catch {}\n return out.filter((d, i) => i === 0 || existsSync(d));\n}\nconst settingsIn = (dir: string) => path.join(dir, \"settings.json\");\nconst configDirOf = (transcript: string) => path.dirname(path.dirname(path.dirname(transcript)));\n\nconst validTool = (n: unknown): n is string => typeof n === \"string\" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);\nconst endReason = (r: unknown): \"clear\" | \"logout\" | \"exit\" | \"other\" =>\n r === \"clear\" || r === \"logout\" || r === \"exit\" ? r : r === \"prompt_input_exit\" ? \"exit\" : \"other\";\nconst notifKind = (t: unknown): \"permission\" | \"question\" | \"elicitation\" | \"idle\" | \"error\" =>\n t === \"permission_prompt\"\n ? \"permission\"\n : t === \"idle_prompt\"\n ? \"idle\"\n : t === \"elicitation_dialog\"\n ? \"elicitation\"\n : \"question\";\n\nexport const claudeCode: Adapter = {\n name: NAME,\n events: CLAUDE_EVENTS,\n detect: (env = process.env) => claudeDirs(env).some((d) => existsSync(d)),\n configFiles: (env = process.env) => claudeDirs(env).map(settingsIn),\n install: (cmd, env = process.env, opts: InstallOptions = {}) =>\n claudeDirs(env).map((d) => installClaudeShaped(settingsIn(d), NAME, eventsFor(opts.lean), cmd, OPTS)),\n uninstall: (env = process.env, opts: InstallOptions = {}) =>\n claudeDirs(env).map((d) =>\n uninstallClaudeShaped(settingsIn(d), CLAUDE_EVENTS, { created: opts.created?.includes(settingsIn(d)) }),\n ),\n installed: (cmd, env = process.env, opts: InstallOptions = {}) =>\n claudeDirs(env).map((d) => ({\n file: settingsIn(d),\n state: installedClaudeShaped(settingsIn(d), NAME, eventsFor(opts.lean), cmd, OPTS),\n })),\n\n fromHook(input: HookInput): HookResult | null {\n const event = input.argv[1] ?? \"\";\n let s: Record<string, unknown> = {};\n try {\n s = input.stdin ? (JSON.parse(input.stdin) as Record<string, unknown>) : {};\n } catch {}\n const id = (s.session_id ?? s.sessionId) as string | undefined;\n if (!id) return null;\n const session: HookResult[\"session\"] = { id: String(id), cwd: typeof s.cwd === \"string\" ? s.cwd : input.cwd };\n if (typeof s.model === \"string\") session.model = s.model;\n if (typeof s.agent_id === \"string\" && event.startsWith(\"Subagent\") === false && s.agent_id)\n session.parent_id = null;\n const turn_id = typeof s.prompt_id === \"string\" ? s.prompt_id : undefined;\n const tool = validTool(s.tool_name) ? s.tool_name : undefined;\n const call_id = typeof s.tool_use_id === \"string\" ? s.tool_use_id : undefined;\n const ms = typeof s.duration_ms === \"number\" ? Math.round(s.duration_ms) : undefined;\n const agent_id = typeof s.agent_id === \"string\" ? s.agent_id : undefined;\n // PermissionRequest carries no tool_use_id (recorded 2026-09-28): the id is a hash\n // of the prompt, the tool and its input, so the same prompt yields the same id and\n // a later control answer can name it.\n const permissionId = () =>\n `perm-${createHash(\"sha256\")\n .update(`${turn_id ?? \"\"}|${tool ?? \"\"}|${JSON.stringify(s.tool_input ?? null)}`)\n .digest(\"hex\")\n .slice(0, 16)}`;\n const ev = (type: string, data: Record<string, unknown>) => ({ type, data: prune(data), harnessEvent: event });\n const events: HookResult[\"events\"] = [];\n switch (event) {\n case \"SessionStart\":\n events.push(ev(\"session.started\", { source: pickSource(s.source ?? s.trigger) }));\n break;\n case \"UserPromptSubmit\":\n events.push(\n ev(\"turn.started\", {\n turn_id,\n prompt_chars: typeof s.prompt === \"string\" ? [...s.prompt].length : undefined,\n }),\n );\n break;\n case \"PreToolUse\":\n if (tool) events.push(ev(\"tool.started\", { tool, call_id, turn_id, agent_id, input: s.tool_input }));\n break;\n case \"PostToolUse\":\n if (tool)\n events.push(\n ev(\"tool.ended\", {\n tool,\n call_id,\n turn_id,\n agent_id,\n ms,\n ok: true,\n input: s.tool_input,\n output: s.tool_response,\n }),\n );\n break;\n case \"PostToolUseFailure\":\n if (tool)\n events.push(\n ev(\"tool.ended\", {\n tool,\n call_id,\n turn_id,\n agent_id,\n ms,\n ok: false,\n error: errText(s.error ?? s.tool_response),\n input: s.tool_input,\n output: s.tool_response,\n }),\n );\n break;\n case \"PermissionRequest\":\n events.push(\n ev(\"attention.needed\", {\n attention_id: call_id ?? permissionId(),\n kind: \"permission\",\n tool,\n message: tool ? `${tool}${describe(s.tool_input)}` : undefined,\n }),\n );\n break;\n case \"Notification\":\n events.push(\n ev(\"attention.needed\", {\n attention_id: `notif-${Date.now()}`,\n kind: notifKind(s.notification_type),\n message: typeof s.message === \"string\" ? s.message.slice(0, 200) : undefined,\n }),\n );\n break;\n case \"Stop\":\n events.push(ev(\"turn.ended\", { turn_id, reason: \"stop\" }));\n break;\n case \"StopFailure\":\n // The turn ended on an API error (rate_limit, overloaded, authentication_failed,\n // server_error \u2026); the payload key is `error` (issue #10, recorded 2026-09-28).\n events.push(\n ev(\"turn.ended\", {\n turn_id,\n reason: \"error\",\n error: typeof s.error === \"string\" ? s.error.slice(0, 200) : undefined,\n }),\n );\n break;\n case \"SubagentStart\":\n events.push(\n ev(\"subagent.started\", {\n agent_id: String(s.agent_id ?? \"\"),\n agent_type: typeof s.agent_type === \"string\" ? s.agent_type : undefined,\n }),\n );\n break;\n case \"SubagentStop\":\n events.push(\n ev(\"subagent.ended\", {\n agent_id: String(s.agent_id ?? \"\"),\n agent_type: typeof s.agent_type === \"string\" ? s.agent_type : undefined,\n }),\n );\n break;\n case \"PreCompact\":\n events.push(ev(\"context.compacted\", { trigger: s.trigger === \"manual\" ? \"manual\" : \"auto\" }));\n break;\n case \"PostCompact\":\n break; // PreCompact already said it; a second event would double-count\n case \"SessionEnd\":\n events.push(ev(\"session.ended\", { reason: endReason(s.reason) }));\n break;\n default:\n return null;\n }\n const hints: Record<string, unknown> = {};\n const host = input.env.CLAUDE_CODE_HOST_SESSION_ID;\n if (host && DESKTOP_ID.test(host)) hints.desktop_id = host;\n // The registry file is found while the process tree stands (the detached\n // worker's parent is gone by the time it runs). Heartbeat-class events skip it.\n if (event !== \"PreToolUse\" && event !== \"PostToolUse\") hints.claude_pid = claudePid(input.env);\n const r: HookResult = { session, events, hints };\n if (typeof s.transcript_path === \"string\") r.transcript = s.transcript_path;\n return r;\n },\n\n readTranscript(file, fromLine) {\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { turns: [], line: fromLine };\n }\n return readClaude(text.split(\"\\n\"), fromLine);\n },\n\n facts(session, transcript, hints, state): SessionFacts {\n const out: SessionFacts = {};\n if (transcript) Object.assign(out, claudeFacts(transcript, session.id, hints, state));\n const cwd = out.cwd ?? session.cwd;\n Object.assign(out, gitFacts(cwd), out.branch ? { branch: out.branch } : {});\n if (!out.url && typeof hints.desktop_id === \"string\") out.url = `claude://code/continue/${hints.desktop_id}`;\n return out;\n },\n\n backfill(sinceMs, env = process.env): BackfillRow[] {\n const rows: BackfillRow[] = [];\n const files: string[] = [];\n for (const d of claudeDirs(env))\n files.push(...recentFiles(path.join(d, \"projects\"), 1, sinceMs, (n) => /^[0-9a-f-]{36}\\.jsonl$/.test(n)));\n const noState: FactsState = { get: () => ({}), save: () => {} };\n for (const f of files) {\n const id = path.basename(f, \".jsonl\");\n const facts = claudeFacts(f, id, {}, noState);\n if (!facts.started_at || !facts.last_at) continue;\n const { started_at, last_at, first_ask: _fa, harness_version: _hv, ...rest } = facts;\n const cwd = rest.cwd;\n rows.push({\n session: { id, ...rest, ...gitFacts(cwd), ...(rest.branch ? { branch: rest.branch } : {}) },\n started_at,\n last_at,\n });\n }\n return rows;\n },\n};\n\nfunction prune<T extends Record<string, unknown>>(o: T): T {\n for (const k of Object.keys(o)) if (o[k] === undefined) delete o[k];\n return o;\n}\nfunction pickSource(v: unknown): string {\n return typeof v === \"string\" && [\"startup\", \"resume\", \"clear\", \"compact\", \"fork\"].includes(v) ? v : \"unknown\";\n}\nfunction errText(v: unknown): string | undefined {\n if (typeof v === \"string\") return v.slice(0, 2000);\n if (v && typeof v === \"object\") {\n const e = v as { error?: unknown; message?: unknown };\n if (typeof e.error === \"string\") return e.error.slice(0, 2000);\n if (typeof e.message === \"string\") return e.message.slice(0, 2000);\n }\n return undefined;\n}\nfunction describe(input: unknown): string {\n if (!input || typeof input !== \"object\") return \"\";\n const i = input as Record<string, unknown>;\n const v = i.command ?? i.file_path ?? i.path ?? i.url ?? i.pattern;\n return typeof v === \"string\" ? ` ${v.slice(0, 120)}` : \"\";\n}\n\n// --- facts: title, url, model, account, from Claude Code's own files ------------------\n\nconst NAME_RANK: Record<string, \"custom\" | \"harness\"> = {\n user: \"custom\",\n auto: \"harness\",\n hook: \"harness\",\n peer: \"harness\",\n};\ninterface Registry {\n sessionId: string | null;\n name: string | null;\n name_source: \"custom\" | \"harness\" | null;\n bridge: string | null;\n}\nfunction registryEntry(j: unknown): Registry | null {\n if (!j || typeof j !== \"object\") return null;\n const r = j as { sessionId?: unknown; name?: unknown; nameSource?: string; bridgeSessionId?: unknown };\n const source = r.nameSource ? NAME_RANK[r.nameSource] : undefined;\n return {\n sessionId: r.sessionId ? String(r.sessionId) : null,\n name: source && typeof r.name === \"string\" && r.name.trim() ? r.name.trim() : null,\n name_source: source ?? null,\n bridge: typeof r.bridgeSessionId === \"string\" ? r.bridgeSessionId : null,\n };\n}\nconst liveCache = new Map<string, Map<string, Registry>>();\nfunction claudeLive(dir: string): Map<string, Registry> {\n const hit = liveCache.get(dir);\n if (hit) return hit;\n const map = new Map<string, Registry>();\n let names: string[] = [];\n try {\n names = readdirSync(path.join(dir, \"sessions\")).filter((n) => n.endsWith(\".json\"));\n } catch {}\n for (const n of names) {\n try {\n const e = registryEntry(JSON.parse(readFileSync(path.join(dir, \"sessions\", n), \"utf8\")));\n if (e?.sessionId) map.set(e.sessionId, e);\n } catch {}\n }\n liveCache.set(dir, map);\n return map;\n}\nfunction claudeLiveByPid(dir: string, pid: unknown): Registry | null {\n if (!pid) return null;\n try {\n return registryEntry(JSON.parse(readFileSync(path.join(dir, \"sessions\", `${pid}.json`), \"utf8\")));\n } catch {\n return null;\n }\n}\n/** The Claude Code process that ran this hook: the nearest ancestor with a registry\n * file (hooks run under a shell, so usually the parent's parent). */\nexport function claudePid(env: NodeJS.ProcessEnv = process.env): number | null {\n try {\n const dirs = claudeDirs(env);\n const has = (pid: number) => dirs.some((d) => existsSync(path.join(d, \"sessions\", `${pid}.json`)));\n let pid = process.ppid;\n if (has(pid)) return pid;\n const parent = parentOf();\n for (let hop = 0; hop < 6 && pid > 1; hop++) {\n pid = parent(pid);\n if (pid > 1 && has(pid)) return pid;\n }\n } catch {}\n return null;\n}\nfunction parentOf(): (pid: number) => number {\n if (process.platform === \"linux\") {\n return (pid) => {\n try {\n const st = readFileSync(`/proc/${pid}/stat`, \"utf8\");\n return Number(st.slice(st.lastIndexOf(\")\") + 2).split(\" \")[1]) || 0;\n } catch {\n return 0;\n }\n };\n }\n const table = new Map<number, number>();\n try {\n const out = execFileSync(\"ps\", [\"-axo\", \"pid=,ppid=\"], {\n encoding: \"utf8\",\n timeout: 2000,\n maxBuffer: 8 * 1024 * 1024,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n for (const l of out.split(\"\\n\")) {\n const m = /^\\s*(\\d+)\\s+(\\d+)/.exec(l);\n if (m) table.set(Number(m[1]), Number(m[2]));\n }\n } catch {}\n return (pid) => table.get(pid) || 0;\n}\nconst accountCache = new Map<string, string | null>();\n/** The account id (never the email) from the config dir's .claude.json. */\nfunction claudeAccount(dir: string): string | null {\n const hit = accountCache.get(dir);\n if (hit !== undefined) return hit;\n const files = [path.join(dir, \".claude.json\")];\n if (path.resolve(dir) === path.join(HOME, \".claude\")) files.unshift(path.join(HOME, \".claude.json\"));\n let acct: string | null = null;\n for (const f of files) {\n try {\n const a = (JSON.parse(readFileSync(f, \"utf8\")) as { oauthAccount?: { accountUuid?: string } }).oauthAccount;\n if (a?.accountUuid) {\n acct = String(a.accountUuid);\n break;\n }\n } catch {}\n }\n accountCache.set(dir, acct);\n return acct;\n}\nconst LINK_RE = /^https:\\/\\/claude\\.ai\\/code\\/session_[A-Za-z0-9]+$/;\nfunction transcriptLink(records: Record<string, unknown>[]): string | null {\n for (let i = records.length - 1; i >= 0; i--) {\n const j = records[i] as { type?: string; subtype?: string; url?: unknown; bridgeSessionId?: unknown };\n if (j.type === \"system\" && j.subtype === \"bridge_status\" && typeof j.url === \"string\" && LINK_RE.test(j.url))\n return j.url;\n if (j.type === \"bridge-session\" && typeof j.bridgeSessionId === \"string\") {\n const m = /^(?:cse|session)_([A-Za-z0-9]+)$/.exec(j.bridgeSessionId);\n if (m) return `https://claude.ai/code/session_${m[1]}`;\n }\n }\n return null;\n}\n/** A first ask as the Claude Code app titles an untitled session: whitespace\n * collapsed, whole up to 50 characters, else its first 50 and \"...\". */\nexport function appTitle(text: string): string {\n const t = String(text).replace(/\\s+/g, \" \").trim();\n return t.length > 50 ? `${t.slice(0, 50)}...` : t;\n}\nfunction askText(j: Record<string, unknown> | null): string | null {\n if (!j || j.type !== \"user\" || j.isMeta || j.isSidechain) return null;\n const origin = j.origin as { kind?: string } | undefined;\n if (origin?.kind && origin.kind !== \"human\") return null;\n const c = (j.message as { content?: unknown } | undefined)?.content;\n const text = (\n typeof c === \"string\"\n ? c\n : Array.isArray(c)\n ? c\n .filter((b) => b && b.type === \"text\" && typeof b.text === \"string\")\n .map((b) => b.text as string)\n .join(\"\\n\")\n : \"\"\n ).trim();\n if (!text || isInjected(text)) return null;\n return text;\n}\nfunction firstAsk(records: Record<string, unknown>[]): string | null {\n for (const j of records) {\n const t = askText(j);\n if (t) return appTitle(t);\n }\n return null;\n}\nfunction scanTitles(file: string, from: number, found: { custom?: string | null; ai?: string | null }) {\n const out = { custom: found.custom ?? null, ai: found.ai ?? null, upto: from };\n let size = 0;\n try {\n size = statSync(file).size;\n } catch {\n return out;\n }\n if (size < from) {\n out.upto = 0;\n out.custom = out.ai = null;\n from = 0;\n }\n // Only lines carrying a title record are parsed; the rest of the new bytes are skipped.\n let pos = 0;\n scanLines<null>(\n file,\n (l) => {\n pos += Buffer.byteLength(l, \"utf8\") + 1;\n if (pos <= from || l.indexOf('-title\"') < 0) return null;\n try {\n const j = JSON.parse(l) as { type?: string; customTitle?: string; aiTitle?: string };\n if (j.type === \"custom-title\" && j.customTitle) out.custom = j.customTitle;\n if (j.type === \"ai-title\" && j.aiTitle) out.ai = j.aiTitle;\n } catch {}\n return null;\n },\n 512 * 1024 * 1024,\n );\n out.upto = size;\n return out;\n}\n\n/** A session's title and where it came from, best first: /rename (registry \"user\"\n * name or custom-title) \u2192 Claude Code's own title (registry \"auto\" name or\n * ai-title) \u2192 the first ask, marked first-ask so a real title later replaces it. */\nexport function claudeFacts(\n file: string,\n sessionId: string,\n hints: Record<string, unknown>,\n state: FactsState,\n): SessionFacts {\n const { head, tail } = ends(file, 64 * 1024, 256 * 1024);\n const H = parseLines(head);\n const T = parseLines(tail);\n const out: SessionFacts = {};\n const id = sessionId || path.basename(file, \".jsonl\");\n const mem = state.get(NAME, id);\n let custom: string | null = null;\n let ai: string | null = null;\n for (const j of H.concat(T)) {\n if (j.type === \"custom-title\" && typeof j.customTitle === \"string\") custom = j.customTitle;\n if (j.type === \"ai-title\" && typeof j.aiTitle === \"string\") ai = j.aiTitle;\n }\n let size = 0;\n try {\n size = statSync(file).size;\n } catch {}\n if (!custom && !ai && size > 64 * 1024 + 256 * 1024) {\n const s = scanTitles(file, Number(mem.scan_upto) || 0, {\n custom: mem.scan_custom as string | null,\n ai: mem.scan_ai as string | null,\n });\n custom = s.custom;\n ai = s.ai;\n state.save(NAME, id, { scan_upto: s.upto, scan_custom: s.custom, scan_ai: s.ai });\n }\n const dir = configDirOf(file);\n const live = claudeLive(dir).get(id) ?? claudeLiveByPid(dir, hints.claude_pid);\n if (live?.name) state.save(NAME, id, { name: live.name, name_source: live.name_source });\n const bridge =\n live?.bridge && /^session_[A-Za-z0-9]+$/.test(live.bridge) ? `https://claude.ai/code/${live.bridge}` : null;\n const url = bridge ?? transcriptLink(T) ?? transcriptLink(H) ?? (typeof mem.url === \"string\" ? mem.url : null);\n if (url) {\n out.url = url;\n state.save(NAME, id, { url });\n }\n const name = live?.name\n ? { title: live.name, source: live.name_source as \"custom\" | \"harness\" }\n : typeof mem.name === \"string\"\n ? { title: mem.name, source: mem.name_source as \"custom\" | \"harness\" }\n : null;\n const pick =\n (name && name.source === \"custom\" && name) ||\n (custom && { title: custom, source: \"custom\" as const }) ||\n name ||\n (ai && { title: ai, source: \"harness\" as const });\n let ask = typeof mem.first_ask === \"string\" ? mem.first_ask : firstAsk(H);\n if (!ask && size > 64 * 1024 && !mem.first_ask_none) {\n ask = scanLines<string>(file, (l) => {\n try {\n const t = askText(JSON.parse(l) as Record<string, unknown>);\n return t ? appTitle(t) : null;\n } catch {\n return null;\n }\n });\n if (!ask && size > 16 * 1024 * 1024) state.save(NAME, id, { first_ask_none: true });\n }\n if (ask) {\n out.first_ask = ask;\n if (!mem.first_ask) state.save(NAME, id, { first_ask: ask });\n }\n if (pick) {\n out.title = String(pick.title).slice(0, 120);\n out.title_source = pick.source;\n } else if (ask) {\n out.title = ask;\n out.title_source = \"first-ask\";\n }\n const acct = claudeAccount(dir);\n if (acct) out.account_id = acct;\n for (let i = T.length - 1; i >= 0; i--) {\n const m = (T[i] as { message?: { model?: string } }).message?.model;\n if (T[i]?.type === \"assistant\" && m && m !== \"<synthetic>\") {\n out.model = m;\n break;\n }\n }\n const meta = [...T].reverse().find((j) => j.version) ?? H.find((j) => j.version);\n if (meta?.version) out.harness_version = String(meta.version);\n const times = H.concat(T)\n .map((j) => Date.parse(String(j.timestamp ?? \"\")))\n .filter((n) => n > 0);\n if (times.length) {\n out.started_at = Math.min(...times);\n out.last_at = Math.max(...times);\n }\n const withCwd = H.find((j) => typeof j.cwd === \"string\");\n if (withCwd) {\n out.cwd = withCwd.cwd as string;\n if (typeof withCwd.gitBranch === \"string\" && withCwd.gitBranch !== \"HEAD\") out.branch = withCwd.gitBranch;\n }\n return out;\n}\n\n/** For tests: each hook runs in a fresh process; a test that edits the registry mid-run clears the cache. */\nexport const _resetClaudeCaches = (): void => {\n liveCache.clear();\n accountCache.clear();\n};\n", "// SPDX-License-Identifier: Apache-2.0\n// The repo and branch of a folder, from git itself; credentials stripped from the\n// remote. Cached per folder for the life of the process (a worker run).\nimport { execFileSync } from \"node:child_process\";\n\nconst cache = new Map<string, { repo?: string; branch?: string }>();\n\nexport function gitFacts(cwd: string | undefined): { repo?: string; branch?: string } {\n if (!cwd) return {};\n const hit = cache.get(cwd);\n if (hit) return hit;\n const run = (args: string[]) => {\n try {\n return execFileSync(\"git\", [\"-C\", cwd, ...args], {\n encoding: \"utf8\",\n timeout: 1500,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n } catch {\n return \"\";\n }\n };\n const out: { repo?: string; branch?: string } = {};\n const repo = run([\"remote\", \"get-url\", \"origin\"]);\n if (repo) out.repo = stripCredentials(repo);\n const branch = run([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"]);\n if (branch && branch !== \"HEAD\") out.branch = branch;\n cache.set(cwd, out);\n return out;\n}\n\n/** `https://user:token@host/x` \u2192 `https://host/x`; `git@github.com:a/b.git` \u2192 `github.com/a/b`. */\nexport function stripCredentials(url: string): string {\n let u = url.replace(/\\/\\/[^/@]*@/, \"//\");\n const ssh = /^(?:ssh:\\/\\/)?git@([^:/]+)[:/](.+?)(?:\\.git)?$/.exec(u);\n if (ssh) u = `${ssh[1]}/${ssh[2]}`;\n return u.replace(/^https?:\\/\\//, \"\").replace(/\\.git$/, \"\");\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Codex CLI (OpenAI) \u2014 docs: https://learn.chatgpt.com/docs/hooks\n// Config: ~/.codex/hooks.json (Claude-shaped, 12 events, timeouts in seconds) AND\n// `notify` at the top level of config.toml as the fallback when hooks are off or\n// not yet trusted (non-managed hooks need a /hooks review in the CLI). An existing\n// notify (Codex Computer Use) is chained through --previous-notify, never replaced.\nimport { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { HOME } from \"../paths.js\";\nimport { ends, parseLines, recentFiles } from \"../readers/files.js\";\nimport { readCodex } from \"../readers/transcripts.js\";\nimport { installClaudeShaped, installedClaudeShaped, uninstallClaudeShaped } from \"./claude-shaped.js\";\nimport * as toml from \"./codex-config.js\";\nimport type {\n Adapter,\n BackfillRow,\n HookCommand,\n HookInput,\n HookResult,\n InstalledReport,\n InstallOptions,\n SessionFacts,\n} from \"./types.js\";\n\nconst NAME = \"codex\";\nexport const CODEX_EVENTS = [\n \"SessionStart\",\n \"UserPromptSubmit\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PermissionRequest\",\n \"Stop\",\n \"Interrupt\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PreCompact\",\n \"PostCompact\",\n \"SessionEnd\",\n] as const;\nconst OPTS = { matcherFor: (e: string) => (/Tool|Permission/.test(e) ? \"\" : undefined), timeout: 5 };\nconst eventsFor = (lean?: boolean) => (lean ? CODEX_EVENTS.filter((e) => e !== \"PreToolUse\") : [...CODEX_EVENTS]);\n\nconst codexHome = (env: NodeJS.ProcessEnv) => env.CODEX_HOME || path.join(HOME, \".codex\");\nconst hooksFile = (env: NodeJS.ProcessEnv) => path.join(codexHome(env), \"hooks.json\");\nconst configFile = (env: NodeJS.ProcessEnv) => path.join(codexHome(env), \"config.toml\");\nconst sessionsDir = (env: NodeJS.ProcessEnv) => path.join(codexHome(env), \"sessions\");\n\nconst validTool = (n: unknown): n is string => typeof n === \"string\" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);\nconst endReason = (r: unknown): \"clear\" | \"logout\" | \"exit\" | \"other\" =>\n r === \"clear\" || r === \"logout\" || r === \"exit\" ? r : \"other\";\n\nfunction installNotify(cmd: HookCommand, env: NodeJS.ProcessEnv) {\n const file = configFile(env);\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {}\n const argv = cmd([NAME, \"notify\"]).argv;\n const line = `notify = ${JSON.stringify(argv)}`;\n const n = toml.readNotify(text);\n const write = (next: string) => {\n mkdirSync(path.dirname(file), { recursive: true });\n writeFileSync(file, next);\n };\n if (n && !n.other) {\n if (!n.misplaced && JSON.stringify(n.argv) === JSON.stringify(argv))\n return { file, changed: false, note: \"notify current\" };\n write(toml.withNotify(text, line));\n return {\n file,\n changed: true,\n note: n.misplaced\n ? \"notify moved to the top level (it sat inside a [table], where Codex never reads it)\"\n : \"notify updated\",\n };\n }\n if (n?.other) {\n const prev = toml.previousNotify(n.argv);\n if (toml.isComputerUse(n.argv)) {\n if (prev && toml.OURS.test(JSON.stringify(prev))) {\n if (JSON.stringify(prev) === JSON.stringify(argv))\n return { file, changed: false, note: \"notify current (after Codex Computer Use)\" };\n }\n if (!prev || toml.OURS.test(JSON.stringify(prev))) {\n const next = toml.replaceNotify(text, `notify = ${toml.withPreviousRaw(n.raw, argv)}`);\n if (next) {\n write(next);\n return { file, changed: true, note: \"chained after Codex Computer Use (--previous-notify)\" };\n }\n }\n }\n return {\n file,\n changed: false,\n skipped: true,\n note: `notify belongs to ${(n.argv?.[0] ?? n.raw).replace(/^.*\\//, \"\").slice(0, 40)}; left alone. Codex will report nothing until you approve the hooks: start \\`codex\\` and accept the hook review`,\n };\n }\n write(toml.withNotify(text, line));\n return { file, changed: true, note: \"notify set at the top level\" };\n}\n\nfunction uninstallNotify(env: NodeJS.ProcessEnv) {\n const file = configFile(env);\n let text: string;\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { file, changed: false };\n }\n const n = toml.readNotify(text);\n if (!n) return { file, changed: false };\n if (!n.other) {\n writeFileSync(file, toml.withoutNotify(text));\n return { file, changed: true };\n }\n const prev = toml.previousNotify(n.argv);\n if (toml.isComputerUse(n.argv) && prev && toml.OURS.test(JSON.stringify(prev))) {\n const next = toml.replaceNotify(text, `notify = ${toml.stripPreviousRaw(n.raw)}`);\n if (next) writeFileSync(file, next);\n return { file, changed: true };\n }\n return { file, changed: false };\n}\n\nfunction findRollout(threadId: string, env: NodeJS.ProcessEnv): string | null {\n let best: string | null = null;\n const walk = (dir: string, depth: number) => {\n let names: string[] = [];\n try {\n names = readdirSync(dir);\n } catch {\n return;\n }\n for (const n of names.sort().reverse()) {\n const p = path.join(dir, n);\n if (n.endsWith(\".jsonl\") && n.includes(threadId)) {\n best = p;\n return;\n }\n if (depth < 3) {\n walk(p, depth + 1);\n if (best) return;\n }\n }\n };\n walk(sessionsDir(env), 0);\n return best;\n}\n\nexport const codex: Adapter = {\n name: NAME,\n events: CODEX_EVENTS,\n detect: (env = process.env) => existsSync(codexHome(env)),\n configFiles: (env = process.env) => [hooksFile(env), configFile(env)],\n install: (cmd, env = process.env, opts: InstallOptions = {}) => [\n installClaudeShaped(hooksFile(env), NAME, eventsFor(opts.lean), cmd, OPTS),\n installNotify(cmd, env),\n ],\n uninstall: (env = process.env, opts: InstallOptions = {}) => [\n uninstallClaudeShaped(hooksFile(env), CODEX_EVENTS, { created: opts.created?.includes(hooksFile(env)) }),\n uninstallNotify(env),\n ],\n installed: (cmd, env = process.env, opts: InstallOptions = {}) => {\n const out: InstalledReport[] = [\n {\n file: hooksFile(env),\n state: installedClaudeShaped(hooksFile(env), NAME, eventsFor(opts.lean), cmd, OPTS),\n note: \"Codex runs non-managed hooks only after the review in `codex` (/hooks); until then nothing is reported unless the notify fallback is ours\",\n },\n ];\n let text = \"\";\n try {\n text = readFileSync(configFile(env), \"utf8\");\n } catch {}\n const n = toml.readNotify(text);\n const argv = cmd([NAME, \"notify\"]).argv;\n const prev = n ? toml.previousNotify(n.argv) : null;\n const ours = n && (!n.other || (prev && JSON.stringify(prev) === JSON.stringify(argv)));\n out.push({\n file: configFile(env),\n state:\n !n || (n.other && !ours)\n ? \"missing\"\n : n.misplaced\n ? \"misplaced\"\n : JSON.stringify(n.argv) === JSON.stringify(argv) || (prev && JSON.stringify(prev) === JSON.stringify(argv))\n ? \"current\"\n : \"stale\",\n });\n return out;\n },\n\n fromHook(input: HookInput): HookResult | null {\n const event = input.argv[1] ?? \"\";\n let s: Record<string, unknown> = {};\n if (event === \"notify\") {\n // Codex's notify passes one JSON argument: {\"type\":\"agent-turn-complete\",\"thread-id\":\u2026,\"turn-id\":\u2026,\"cwd\":\u2026}\n const raw = input.argv.find((a) => a.startsWith(\"{\")) ?? input.stdin;\n try {\n s = raw ? (JSON.parse(raw) as Record<string, unknown>) : {};\n } catch {}\n const id = (s[\"thread-id\"] ?? s.thread_id ?? s[\"session-id\"] ?? s.session_id) as string | undefined;\n if (!id) return null;\n const r: HookResult = {\n session: { id: String(id), cwd: typeof s.cwd === \"string\" ? s.cwd : input.cwd },\n events: [\n {\n type: \"turn.ended\",\n data: { reason: \"stop\", ...(typeof s[\"turn-id\"] === \"string\" ? { turn_id: s[\"turn-id\"] } : {}) },\n harnessEvent: \"notify\",\n },\n ],\n hints: {},\n };\n const file = findRollout(String(id), input.env as NodeJS.ProcessEnv);\n if (file) r.transcript = file;\n return r;\n }\n try {\n s = input.stdin ? (JSON.parse(input.stdin) as Record<string, unknown>) : {};\n } catch {}\n const id = s.session_id as string | undefined;\n if (!id) return null;\n const session: HookResult[\"session\"] = { id: String(id), cwd: typeof s.cwd === \"string\" ? s.cwd : input.cwd };\n if (typeof s.model === \"string\") session.model = s.model;\n const turn_id = typeof s.turn_id === \"string\" ? s.turn_id : undefined;\n const tool = validTool(s.tool_name) ? s.tool_name : undefined;\n const call_id = typeof s.tool_use_id === \"string\" ? s.tool_use_id : undefined;\n const ev = (type: string, data: Record<string, unknown>) => ({ type, data: prune(data), harnessEvent: event });\n const events: HookResult[\"events\"] = [];\n switch (event) {\n case \"SessionStart\":\n events.push(\n ev(\"session.started\", {\n source:\n typeof s.source === \"string\" && [\"startup\", \"resume\", \"clear\", \"compact\", \"fork\"].includes(s.source)\n ? s.source\n : \"unknown\",\n }),\n );\n break;\n case \"UserPromptSubmit\":\n events.push(\n ev(\"turn.started\", {\n turn_id,\n prompt_chars: typeof s.prompt === \"string\" ? [...s.prompt].length : undefined,\n }),\n );\n break;\n case \"PreToolUse\":\n if (tool) events.push(ev(\"tool.started\", { tool, call_id, turn_id, input: s.tool_input }));\n break;\n case \"PostToolUse\":\n if (tool)\n events.push(\n ev(\"tool.ended\", { tool, call_id, turn_id, ok: true, input: s.tool_input, output: s.tool_response }),\n );\n break;\n case \"PermissionRequest\":\n events.push(\n ev(\"attention.needed\", { attention_id: call_id ?? `perm-${Date.now()}`, kind: \"permission\", tool }),\n );\n break;\n case \"Stop\":\n events.push(ev(\"turn.ended\", { turn_id, reason: \"stop\" }));\n break;\n case \"Interrupt\":\n events.push(ev(\"turn.ended\", { turn_id, reason: \"interrupt\" }));\n break;\n case \"SubagentStart\":\n events.push(\n ev(\"subagent.started\", {\n agent_id: String(s.agent_id ?? s.subagent_id ?? \"\"),\n agent_type: typeof s.agent_type === \"string\" ? s.agent_type : undefined,\n }),\n );\n break;\n case \"SubagentStop\":\n events.push(\n ev(\"subagent.ended\", {\n agent_id: String(s.agent_id ?? s.subagent_id ?? \"\"),\n agent_type: typeof s.agent_type === \"string\" ? s.agent_type : undefined,\n }),\n );\n break;\n case \"PreCompact\":\n events.push(ev(\"context.compacted\", { trigger: s.trigger === \"manual\" ? \"manual\" : \"auto\" }));\n break;\n case \"PostCompact\":\n break;\n case \"SessionEnd\":\n events.push(ev(\"session.ended\", { reason: endReason(s.reason) }));\n break;\n default:\n return null;\n }\n const r: HookResult = { session, events, hints: {} };\n if (typeof s.transcript_path === \"string\") r.transcript = s.transcript_path;\n return r;\n },\n\n readTranscript(file, fromLine) {\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { turns: [], line: fromLine };\n }\n return readCodex(text.split(\"\\n\"), fromLine);\n },\n\n facts(session, transcript): SessionFacts {\n const out: SessionFacts = {};\n if (transcript) Object.assign(out, codexFacts(transcript));\n return out;\n },\n\n backfill(sinceMs, env = process.env): BackfillRow[] {\n const rows: BackfillRow[] = [];\n for (const f of recentFiles(sessionsDir(env), 3, sinceMs, (n) => /^rollout-.*\\.jsonl$/.test(n))) {\n const m = /([0-9a-f]{8}-[0-9a-f-]{27,})\\.jsonl$/i.exec(path.basename(f));\n if (!m?.[1]) continue;\n const facts = codexFacts(f);\n if (!facts.started_at || !facts.last_at) continue;\n const { started_at, last_at, first_ask: _fa, harness_version: _hv, ...rest } = facts;\n rows.push({ session: { id: m[1], ...rest }, started_at, last_at });\n }\n return rows;\n },\n};\n\nfunction prune<T extends Record<string, unknown>>(o: T): T {\n for (const k of Object.keys(o)) if (o[k] === undefined) delete o[k];\n return o;\n}\n\n/** Codex keeps no title; its first real ask stands in. */\nexport function codexFacts(file: string): SessionFacts {\n const { head, tail } = ends(file, 128 * 1024, 64 * 1024);\n const H = parseLines(head);\n const T = parseLines(tail);\n const out: SessionFacts = {};\n const meta = H.find((j) => j.type === \"session_meta\" && j.payload) as\n | { payload?: { cwd?: string; cli_version?: string; git?: { branch?: string; repository_url?: string } } }\n | undefined;\n if (meta?.payload) {\n const p = meta.payload;\n if (p.cwd) out.cwd = p.cwd;\n if (p.cli_version) out.harness_version = String(p.cli_version);\n if (p.git?.branch) out.branch = p.git.branch;\n if (p.git?.repository_url) out.repo = String(p.git.repository_url).replace(/\\/\\/[^/@]*@/, \"//\");\n }\n const ctx = H.concat(T)\n .reverse()\n .find((j) => j.type === \"turn_context\" && (j.payload as { model?: string } | undefined)?.model) as\n | { payload?: { model?: string } }\n | undefined;\n if (ctx?.payload?.model) out.model = ctx.payload.model;\n for (const j of H) {\n const p = j.payload as { type?: string; role?: string; content?: { type?: string; text?: string }[] } | undefined;\n if (j.type !== \"response_item\" || !p || p.type !== \"message\" || p.role !== \"user\") continue;\n const text = (p.content ?? [])\n .filter((b) => b && b.type === \"input_text\" && typeof b.text === \"string\")\n .map((b) => b.text as string)\n .join(\"\\n\")\n .trim();\n if (!text || /^<[a-z_-]+>/i.test(text)) continue;\n const line = text.split(\"\\n\").find((l) => l.trim()) ?? \"\";\n out.title = line.length > 80 ? `${line.slice(0, 80).replace(/\\s+\\S*$/, \"\")}\u2026` : line;\n out.title_source = \"first-ask\";\n break;\n }\n const times = H.concat(T)\n .map((j) => Date.parse(String(j.timestamp ?? \"\")))\n .filter((n) => n > 0);\n if (times.length) {\n out.started_at = Math.min(...times);\n out.last_at = Math.max(...times);\n }\n return out;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Codex's ~/.codex/config.toml, as far as the notify fallback needs it: its one\n// top-level `notify` command. Codex reads `notify` only at the top level \u2014 before\n// the first [table] \u2014 and Codex itself appends a [projects.\"<path>\"] table for every\n// folder it trusts, so a line appended at the end lands inside one and never runs.\n// Ported from spacesheep-cli lib/codex-config.js. Pure text in, text out.\n\nconst NOTIFY_LINE = /^[ \\t]*notify[ \\t]*=[ \\t]*(\\[.*\\])[ \\t]*(?:#.*)?$/m;\nconst NOTIFY_KEY = /^[ \\t]*notify[ \\t]*=/m;\n/** A notify that runs sessionpipe's hook directly (or through its launcher). */\nexport const OURS = /(?:hook\\.js|sessionpipe-hook)\",\\s*\"codex\",\\s*\"notify\"/;\n\nfunction scan(line: string, st: { depth: number; str: string | null }): void {\n let i = 0;\n while (i < line.length) {\n if (st.str) {\n const j = line.indexOf(st.str, i);\n if (j < 0) return;\n i = j + 3;\n st.str = null;\n continue;\n }\n const ch = line[i];\n if (ch === \"#\") return;\n if (line.startsWith('\"\"\"', i) || line.startsWith(\"'''\", i)) {\n st.str = line.slice(i, i + 3);\n i += 3;\n continue;\n }\n if (ch === '\"') {\n i++;\n while (i < line.length && line[i] !== '\"') i += line[i] === \"\\\\\" ? 2 : 1;\n i++;\n continue;\n }\n if (ch === \"'\") {\n const j = line.indexOf(\"'\", i + 1);\n i = j < 0 ? line.length : j + 1;\n continue;\n }\n if (ch === \"[\") st.depth++;\n else if (ch === \"]\") st.depth = Math.max(0, st.depth - 1);\n i++;\n }\n}\n\n/** Offset of the first table header, or -1. */\nexport function firstTableAt(text: string): number {\n const st = { depth: 0, str: null as string | null };\n let pos = 0;\n for (const line of text.split(\"\\n\")) {\n if (!st.str && st.depth === 0 && /^[ \\t]*\\[/.test(line)) return pos;\n scan(line, st);\n pos += line.length + 1;\n }\n return -1;\n}\n\nfunction split(text: string) {\n const at = firstTableAt(text);\n return at < 0 ? { head: text, tail: \"\", at: text.length } : { head: text.slice(0, at), tail: text.slice(at), at };\n}\n\nexport function parseArgv(raw: string): string[] | null {\n try {\n const a = JSON.parse(raw) as unknown;\n return Array.isArray(a) && a.every((x) => typeof x === \"string\") ? (a as string[]) : null;\n } catch {\n return null;\n }\n}\n\nexport interface Notify {\n raw: string;\n argv: string[] | null;\n index: number;\n length: number;\n misplaced: boolean;\n other: boolean;\n}\n\n/** notify as Codex sees it; `misplaced` for a line of ours inside a table. */\nexport function readNotify(text: string): Notify | null {\n const { head, tail, at } = split(text);\n const m = NOTIFY_LINE.exec(head);\n if (m)\n return {\n raw: m[1] ?? \"\",\n argv: parseArgv(m[1] ?? \"\"),\n index: m.index,\n length: m[0].length,\n misplaced: false,\n other: !OURS.test(m[1] ?? \"\"),\n };\n const k = NOTIFY_KEY.exec(head);\n if (k) {\n const rest = head.slice(k.index).split(\"\\n\")[0] ?? \"\";\n return {\n raw: rest.replace(NOTIFY_KEY, \"\").trim(),\n argv: null,\n index: k.index,\n length: 0,\n misplaced: false,\n other: true,\n };\n }\n const t = NOTIFY_LINE.exec(tail);\n if (t && OURS.test(t[1] ?? \"\"))\n return {\n raw: t[1] ?? \"\",\n argv: parseArgv(t[1] ?? \"\"),\n index: at + t.index,\n length: t[0].length,\n misplaced: true,\n other: false,\n };\n return null;\n}\n\nfunction dropLine(text: string, index: number, length: number): string {\n return text.slice(0, index) + text.slice(index + length).replace(/^\\r?\\n/, \"\");\n}\n\n/** Put `line` at the top level: before the first table, or at the end of a file that has none. */\nexport function insertTopLevel(text: string, line: string): string {\n const { head, tail } = split(text);\n if (!tail) return (head.trim() ? head.replace(/\\s*$/, \"\\n\") : \"\") + line + \"\\n\";\n return `${(head.trim() ? head.replace(/\\s*$/, \"\\n\") : \"\") + line}\\n\\n${tail}`;\n}\n\n/** The config with `line` as its notify, for a config whose notify is ours or absent. */\nexport function withNotify(text: string, line: string): string {\n const n = readNotify(text);\n if (n && !n.misplaced && !n.other) return text.slice(0, n.index) + line + text.slice(n.index + n.length);\n if (n?.misplaced) return insertTopLevel(dropLine(text, n.index, n.length), line);\n return insertTopLevel(text, line);\n}\n\n/** The config with its top-level notify line replaced by `line`. */\nexport function replaceNotify(text: string, line: string): string | null {\n const n = readNotify(text);\n if (!n || n.misplaced || !n.length) return null;\n return text.slice(0, n.index) + line + text.slice(n.index + n.length);\n}\n\n/** The config with our top-level or misplaced notify removed. */\nexport function withoutNotify(text: string): string {\n const n = readNotify(text);\n if (!n || n.other || !n.length) return text;\n return dropLine(text, n.index, n.length);\n}\n\n// Codex Computer Use takes the notify slot itself and keeps the command it found in\n// its own argv: [client, \"turn-ended\", \"--previous-notify\", \"<that command as JSON>\"].\nconst PREVIOUS = \"--previous-notify\";\nexport function previousNotify(argv: string[] | null): string[] | null {\n if (!Array.isArray(argv)) return null;\n const i = argv.indexOf(PREVIOUS);\n return i >= 0 && typeof argv[i + 1] === \"string\" ? parseArgv(argv[i + 1] as string) : null;\n}\nexport function withPrevious(argv: string[], prev: string[] | null): string[] {\n const out = argv.slice();\n const i = out.indexOf(PREVIOUS);\n if (i >= 0) out.splice(i, 2);\n if (prev) out.push(PREVIOUS, JSON.stringify(prev));\n return out;\n}\n/** The raw notify value with its --previous-notify pair removed, formatting kept. */\nexport function stripPreviousRaw(raw: string): string {\n return raw.replace(/,\\s*\"--previous-notify\",\\s*\"(?:[^\"\\\\]|\\\\.)*\"\\s*(?=\\])/, \"\");\n}\n/** The raw notify value with `prev` as its --previous-notify, formatting of the rest kept. */\nexport function withPreviousRaw(raw: string, prev: string[]): string {\n const base = stripPreviousRaw(raw).replace(/\\s*\\]\\s*$/, \"\");\n return `${base}, \"--previous-notify\", ${JSON.stringify(JSON.stringify(prev))}]`;\n}\nexport const isComputerUse = (argv: string[] | null): boolean =>\n Array.isArray(argv) && typeof argv[0] === \"string\" && /(^|\\/)SkyComputerUseClient$/.test(argv[0]);\n", "// SPDX-License-Identifier: Apache-2.0\n// Gemini CLI (Google) \u2014 docs: https://geminicli.com/docs/hooks/reference\n// Config: ~/.gemini/settings.json `hooks` key, same array-of-groups shape as Claude\n// Code but timeouts in MILLISECONDS and a `name` per handler. stdout must be JSON or\n// empty. Its own telemetry defaults logPrompts on; the installer says so once.\nimport { execFileSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { HOME } from \"../paths.js\";\nimport { ends, parseLines } from \"../readers/files.js\";\nimport { readGemini } from \"../readers/transcripts.js\";\nimport { installClaudeShaped, installedClaudeShaped, uninstallClaudeShaped } from \"./claude-shaped.js\";\nimport type { Adapter, HookInput, HookResult, InstallOptions, SessionFacts } from \"./types.js\";\n\nconst NAME = \"gemini-cli\";\nexport const GEMINI_EVENTS = [\n \"SessionStart\",\n \"BeforeAgent\",\n \"BeforeTool\",\n \"AfterTool\",\n \"Notification\",\n \"AfterAgent\",\n \"PreCompress\",\n \"SessionEnd\",\n] as const;\nconst OPTS = { matcherFor: (e: string) => (/Tool/.test(e) ? \".*\" : undefined), timeout: 5000 };\nconst geminiDir = (env: NodeJS.ProcessEnv) => env.GEMINI_CLI_HOME || path.join(HOME, \".gemini\");\nconst settings = (env: NodeJS.ProcessEnv) => path.join(geminiDir(env), \"settings.json\");\nconst validTool = (n: unknown): n is string => typeof n === \"string\" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);\nconst eventsFor = (lean?: boolean) => (lean ? GEMINI_EVENTS.filter((e) => e !== \"BeforeTool\") : [...GEMINI_EVENTS]);\n\n/** Before 0.46 the hooks system is off unless tools.enableHooks is true (issue #11). */\nexport function geminiHooksActive(settingsFile: string): { active: boolean; note?: string } {\n let tools: { enableHooks?: unknown } | undefined;\n try {\n tools = (JSON.parse(readFileSync(settingsFile, \"utf8\")) as { tools?: { enableHooks?: unknown } }).tools;\n } catch {}\n if (tools?.enableHooks === true) return { active: true };\n if (tools?.enableHooks === false)\n return { active: false, note: \"inactive: tools.enableHooks is false in settings.json\" };\n let version = \"\";\n try {\n version = execFileSync(\"gemini\", [\"--version\"], {\n encoding: \"utf8\",\n timeout: 4000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n } catch {\n return {\n active: true,\n note: \"could not run `gemini --version`; hooks need tools.enableHooks on versions before 0.46\",\n };\n }\n const m = /(\\d+)\\.(\\d+)/.exec(version);\n if (m && (Number(m[1]) > 0 || Number(m[2]) >= 46)) return { active: true };\n return {\n active: false,\n note: `inactive: Gemini CLI ${version || \"?\"} runs hooks only with \"tools\": {\"enableHooks\": true} in settings.json`,\n };\n}\n\nexport const geminiCli: Adapter = {\n name: NAME,\n events: GEMINI_EVENTS,\n // ~/.gemini also belongs to Antigravity; Gemini CLI is here when its settings or its chat logs exist.\n detect: (env = process.env) => existsSync(settings(env)) || existsSync(path.join(geminiDir(env), \"tmp\")),\n configFiles: (env = process.env) => [settings(env)],\n install: (cmd, env = process.env, opts: InstallOptions = {}) => {\n const r = installClaudeShaped(settings(env), NAME, eventsFor(opts.lean), cmd, OPTS);\n const a = geminiHooksActive(settings(env));\n return [a.note && !r.skipped ? { ...r, note: [r.note, a.note].filter(Boolean).join(\"; \") } : r];\n },\n uninstall: (env = process.env, opts: InstallOptions = {}) => [\n uninstallClaudeShaped(settings(env), GEMINI_EVENTS, { created: opts.created?.includes(settings(env)) }),\n ],\n installed: (cmd, env = process.env, opts: InstallOptions = {}) => {\n const state = installedClaudeShaped(settings(env), NAME, eventsFor(opts.lean), cmd, OPTS);\n const a = geminiHooksActive(settings(env));\n return [\n {\n file: settings(env),\n state: state === \"current\" && !a.active ? \"inactive\" : state,\n ...(a.note ? { note: a.note } : {}),\n },\n ];\n },\n\n fromHook(input: HookInput): HookResult | null {\n const event = input.argv[1] ?? \"\";\n let s: Record<string, unknown> = {};\n try {\n s = input.stdin ? (JSON.parse(input.stdin) as Record<string, unknown>) : {};\n } catch {}\n const id = s.session_id as string | undefined;\n if (!id) return null;\n const session: HookResult[\"session\"] = { id: String(id), cwd: typeof s.cwd === \"string\" ? s.cwd : input.cwd };\n const tool = validTool(s.tool_name) ? s.tool_name : undefined;\n const ev = (type: string, data: Record<string, unknown>) => ({ type, data: prune(data), harnessEvent: event });\n const events: HookResult[\"events\"] = [];\n switch (event) {\n case \"SessionStart\":\n events.push(\n ev(\"session.started\", {\n source:\n typeof s.source === \"string\" && [\"startup\", \"resume\", \"clear\"].includes(s.source) ? s.source : \"unknown\",\n }),\n );\n break;\n case \"BeforeAgent\":\n events.push(\n ev(\"turn.started\", { prompt_chars: typeof s.prompt === \"string\" ? [...s.prompt].length : undefined }),\n );\n break;\n case \"BeforeTool\":\n if (tool) events.push(ev(\"tool.started\", { tool, input: s.tool_input }));\n break;\n case \"AfterTool\": {\n const resp = s.tool_response as { error?: unknown; llmContent?: unknown } | undefined;\n const err =\n resp && typeof resp === \"object\" && resp.error\n ? String(typeof resp.error === \"string\" ? resp.error : JSON.stringify(resp.error)).slice(0, 2000)\n : undefined;\n if (tool)\n events.push(\n ev(\"tool.ended\", {\n tool,\n ok: !err,\n error: err,\n input: s.tool_input,\n output: resp?.llmContent ?? s.tool_response,\n }),\n );\n break;\n }\n case \"Notification\":\n events.push(\n ev(\"attention.needed\", {\n attention_id: `notif-${Date.now()}`,\n kind: s.notification_type === \"ToolPermission\" ? \"permission\" : \"question\",\n message: typeof s.message === \"string\" ? s.message.slice(0, 200) : undefined,\n }),\n );\n break;\n case \"AfterAgent\":\n events.push(ev(\"turn.ended\", { reason: \"stop\" }));\n break;\n case \"PreCompress\":\n events.push(ev(\"context.compacted\", { trigger: s.trigger === \"manual\" ? \"manual\" : \"auto\" }));\n break;\n case \"SessionEnd\":\n events.push(\n ev(\"session.ended\", {\n reason:\n s.reason === \"clear\" || s.reason === \"logout\" || s.reason === \"exit\"\n ? s.reason\n : s.reason === \"prompt_input_exit\"\n ? \"exit\"\n : \"other\",\n }),\n );\n break;\n default:\n return null;\n }\n const r: HookResult = { session, events, hints: {} };\n if (typeof s.transcript_path === \"string\") r.transcript = s.transcript_path;\n return r;\n },\n\n readTranscript(file, fromLine) {\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return { turns: [], line: fromLine };\n }\n return readGemini(text.split(\"\\n\"), fromLine);\n },\n\n facts(_session, transcript): SessionFacts {\n const out: SessionFacts = {};\n if (!transcript) return out;\n const { head, tail } = ends(transcript, 64 * 1024, 64 * 1024);\n const H = parseLines(head);\n const T = parseLines(tail);\n const first = H.find((j) => j.type === \"user\");\n const raw = first ? (first.content ?? first.message ?? first.text) : undefined;\n const text = typeof raw === \"string\" ? raw.trim() : \"\";\n if (text) {\n const line = text.split(\"\\n\").find((l) => l.trim()) ?? \"\";\n out.title = line.length > 80 ? `${line.slice(0, 80).replace(/\\s+\\S*$/, \"\")}\u2026` : line;\n out.title_source = \"first-ask\";\n }\n const times = H.concat(T)\n .map((j) => Date.parse(String(j.timestamp ?? \"\")))\n .filter((n) => n > 0);\n if (times.length) {\n out.started_at = Math.min(...times);\n out.last_at = Math.max(...times);\n }\n return out;\n },\n\n backfill: () => [], // chat logs are keyed by a project hash, not a session id we can name; the first hook of a resumed session reports it\n};\n\nfunction prune<T extends Record<string, unknown>>(o: T): T {\n for (const k of Object.keys(o)) if (o[k] === undefined) delete o[k];\n return o;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Claude Code (Anthropic) \u2014 control delivery (spec/CONTROL.md \u00A76). Claude Code on\n// this machine, as the control daemon needs it: which `claude` to\n// run and with which permission flags, where a session's transcript is and which\n// folder it runs in, whether a live process holds it, and running one headless\n// turn (`claude -p --resume`, `--fork-session`, `--session-id`). Ported from the\n// spacesheep CLI's machine listener (lib/machine.js, 1.22), which ran it in\n// production first.\nimport { execFile, execFileSync, spawn } from \"node:child_process\";\nimport { accessSync, closeSync, constants, openSync, readdirSync, readFileSync, readSync, statSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nexport const JOB_TIMEOUT_MS = 30 * 60_000;\nconst OUT_CAP = 1024 * 1024;\n/** A transcript someone else wrote this recently is in use. */\nconst LIVE_WRITE_MS = 90_000;\n\nexport type Mode = \"safe\" | \"auto\";\n\nfunction isExe(p: string): boolean {\n try {\n if (!statSync(p).isFile()) return false;\n accessSync(p, constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nconst cmpVersion = (a: string, b: string) => {\n const pa = a.split(\".\").map(Number);\n const pb = b.split(\".\").map(Number);\n for (let i = 0; i < Math.max(pa.length, pb.length); i++)\n if ((pa[i] ?? 0) !== (pb[i] ?? 0)) return (pa[i] ?? 0) - (pb[i] ?? 0);\n return 0;\n};\n\n/** The `claude` to run: on PATH, else where the installers put it, else the newest\n * copy the desktop app ships. Null when this machine has none. */\nexport function findClaude(env: NodeJS.ProcessEnv = process.env, home = os.homedir()): string | null {\n if (env.SESSIONPIPE_CLAUDE && isExe(env.SESSIONPIPE_CLAUDE)) return env.SESSIONPIPE_CLAUDE;\n const names = process.platform === \"win32\" ? [\"claude.exe\", \"claude.cmd\"] : [\"claude\"];\n for (const d of String(env.PATH || \"\").split(path.delimiter)) {\n if (!d || !path.isAbsolute(d)) continue;\n for (const n of names) if (isExe(path.join(d, n))) return path.join(d, n);\n }\n for (const p of [\n path.join(home, \".claude\", \"local\", \"claude\"),\n path.join(home, \".local\", \"bin\", \"claude\"),\n \"/opt/homebrew/bin/claude\",\n \"/usr/local/bin/claude\",\n ])\n if (isExe(p)) return p;\n const app = path.join(home, \"Library\", \"Application Support\", \"Claude\", \"claude-code\");\n let versions: string[] = [];\n try {\n versions = readdirSync(app)\n .filter((n) => /^\\d+(\\.\\d+)*$/.test(n))\n .sort(cmpVersion)\n .reverse();\n } catch {}\n for (const v of versions) {\n const p = path.join(app, v, \"claude.app\", \"Contents\", \"MacOS\", \"claude\");\n if (isExe(p)) return p;\n }\n return null;\n}\n\n/** One option's text in `claude --help`: its line and the deeper-indented lines under it. */\nfunction optionBlock(help: string, flag: string): string | null {\n const lines = help.split(\"\\n\");\n const re = new RegExp(`^\\\\s{0,4}(?:-\\\\w, )?${flag.replace(/-/g, \"\\\\-\")}(?![\\\\w-])`);\n const start = lines.findIndex((l) => re.test(l));\n if (start < 0) return null;\n const out = [lines[start] as string];\n for (let i = start + 1; i < lines.length && lines[i]?.trim() && !/^\\s{0,4}-/.test(lines[i] as string); i++)\n out.push(lines[i] as string);\n return out.join(\" \");\n}\n\nexport interface Caps {\n hasMode: boolean;\n modes: string[];\n promptsNone: boolean;\n fork: boolean;\n /** `--output-format stream-json` with `--include-partial-messages`: the answer can be\n * forwarded as it is written. Optional so older callers' literals still type. */\n stream?: boolean;\n}\n\nexport function parseCaps(help: string): Caps {\n const pm = optionBlock(help, \"--permission-mode\");\n const pp = optionBlock(help, \"--permission-prompts\");\n return {\n hasMode: !!pm,\n modes: pm ? [...pm.matchAll(/\"([A-Za-z]+)\"/g)].map((m) => m[1] as string) : [],\n promptsNone: !!pp && /\"none\"/.test(pp),\n fork: !!optionBlock(help, \"--fork-session\"),\n stream: !!optionBlock(help, \"--include-partial-messages\"),\n };\n}\n\n/** Permission flags for the machine's mode. Safe: `dontAsk` (nothing that needs\n * approval runs). Auto: Claude Code's own auto mode, or a refusal. Never\n * bypassPermissions \u2014 no path here writes it. */\nexport function modeFlags(mode: Mode, caps: Caps): { args: string[] } | { error: string } {\n if (mode === \"auto\") {\n if (!caps.modes.includes(\"auto\"))\n return { error: \"this machine is in auto mode, but its Claude Code has no auto permission mode\" };\n return { args: [\"--permission-mode\", \"auto\"] };\n }\n if (caps.modes.includes(\"dontAsk\")) return { args: [\"--permission-mode\", \"dontAsk\"] };\n const args: string[] = [];\n if (caps.hasMode)\n args.push(\n \"--permission-mode\",\n caps.modes.includes(\"manual\") && !caps.modes.includes(\"default\") ? \"manual\" : \"default\",\n );\n if (caps.promptsNone) args.push(\"--permission-prompts\", \"none\");\n return { args };\n}\n\n/** The env a headless turn runs with: ours, minus the markers that make Claude Code\n * think it runs inside another session, with CLAUDE_CONFIG_DIR naming the account. */\nexport function claudeEnv(configDir?: string, env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {\n const e = { ...env };\n for (const k of [\n \"CLAUDECODE\",\n \"CLAUDE_CODE_SESSION_ID\",\n \"CLAUDE_CODE_HOST_SESSION_ID\",\n \"CLAUDE_CODE_ENTRYPOINT\",\n \"CLAUDE_CODE_SESSION_ATTENDED\",\n \"CLAUDE_CODE_SSE_PORT\",\n ])\n delete e[k];\n e.SESSIONPIPE_CONTROL_JOB = \"1\";\n if (configDir !== undefined) {\n if (path.resolve(configDir) === path.resolve(os.homedir(), \".claude\")) delete e.CLAUDE_CONFIG_DIR;\n else e.CLAUDE_CONFIG_DIR = configDir;\n }\n return e;\n}\n\n/** Whether Claude Code is signed in for one account, in Claude Code's own words\n * (`claude auth status --json`). `loggedIn: null` means this Claude Code can't say\n * (too old for `auth status`, or it didn't answer): never a reason to refuse. */\nexport interface Login {\n loggedIn: boolean | null;\n /** claude.ai, an API key, a long-lived token\u2026 as Claude Code names it. */\n method?: string;\n subscription?: string;\n}\n\nexport function parseAuthStatus(stdout: string | null | undefined): Login {\n const text = String(stdout || \"\").trim();\n const start = text.indexOf(\"{\");\n if (start < 0) return { loggedIn: null };\n try {\n const j = JSON.parse(text.slice(start)) as Record<string, unknown>;\n if (typeof j.loggedIn !== \"boolean\") return { loggedIn: null };\n return {\n loggedIn: j.loggedIn,\n ...(typeof j.authMethod === \"string\" ? { method: j.authMethod } : {}),\n ...(typeof j.subscriptionType === \"string\" ? { subscription: j.subscriptionType } : {}),\n };\n } catch {\n return { loggedIn: null };\n }\n}\n\n/** Ask Claude Code whether the account in `configDir` (the default one when omitted)\n * is signed in, from this process \u2014 which is the point: a login kept in the macOS\n * keychain is readable from the screen's own session and not from a background\n * service on a Mac nobody is logged in to, or from an ssh shell, so a headless turn\n * started there dies with \"please run /login\". */\nexport function claudeLogin(bin: string, configDir?: string, env: NodeJS.ProcessEnv = process.env): Promise<Login> {\n return new Promise((resolve) => {\n execFile(\n bin,\n [\"auth\", \"status\", \"--json\"],\n { encoding: \"utf8\", timeout: 20_000, env: claudeEnv(configDir, env), maxBuffer: 256 * 1024 },\n // `auth status` may exit non-zero when signed out; its JSON still says so.\n (_err, stdout) => resolve(parseAuthStatus(stdout)),\n );\n });\n}\n\n/** The command that signs one account in, quoted for a sentence. */\nexport function loginCommand(configDir: string | undefined): string {\n const home = os.homedir();\n const isDefault = !configDir || path.resolve(configDir) === path.resolve(home, \".claude\");\n return isDefault ? \"`claude auth login`\" : `\\`CLAUDE_CONFIG_DIR=${configDir.replace(home, \"~\")} claude auth login\\``;\n}\n\n/** What to tell the person when an account isn't signed in for the daemon. */\nexport function loginHint(configDir: string | undefined, platform: NodeJS.Platform = process.platform): string {\n const shown = configDir ? configDir.replace(os.homedir(), \"~\") : \"~/.claude\";\n const login = loginCommand(configDir);\n if (platform === \"darwin\")\n return `Claude Code (${shown}) isn't signed in as this machine's background service sees it. On a Mac its login lives in the login keychain, which a background service can read only while someone is logged in at the screen: log in at the Mac, or run ${login} there.`;\n return `Claude Code (${shown}) isn't signed in on this machine: run ${login} there.`;\n}\n\nexport function detectCaps(bin: string): Caps {\n let help = \"\";\n try {\n help = execFileSync(bin, [\"--help\"], {\n encoding: \"utf8\",\n timeout: 30_000,\n env: claudeEnv(),\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n maxBuffer: 4 * 1024 * 1024,\n });\n } catch (e) {\n help = String((e as { stdout?: string })?.stdout || \"\");\n }\n return parseCaps(help);\n}\n\nexport interface Transcript {\n file: string;\n configDir: string;\n project: string;\n}\n\n/** <config dir>/projects/<folder>/<session>.jsonl in any Claude Code config dir. */\nexport function findTranscript(session: string, dirs: string[]): Transcript | null {\n if (!UUID_RE.test(session)) return null;\n for (const dir of dirs) {\n let projects: import(\"node:fs\").Dirent[] = [];\n try {\n projects = readdirSync(path.join(dir, \"projects\"), { withFileTypes: true });\n } catch {\n continue;\n }\n for (const p of projects) {\n if (!p.isDirectory()) continue;\n const file = path.join(dir, \"projects\", p.name, `${session}.jsonl`);\n try {\n if (statSync(file).isFile()) return { file, configDir: dir, project: p.name };\n } catch {}\n }\n }\n return null;\n}\n\nconst projectName = (cwd: string) => cwd.replace(/[^a-zA-Z0-9]/g, \"-\");\n\n/** The folder a session runs in, from its transcript's own records (never from a\n * command): the `cwd` whose project name is the folder the transcript is filed\n * under, else the first `cwd`. Streams; a line over 2 MB is skipped. */\nexport function sessionFolder(t: Transcript, cap = 8 * 1024 * 1024): string | null {\n let first: string | null = null;\n let count = 0;\n let fd: number | undefined;\n const look = (line: Buffer): string | null => {\n if (line.indexOf('\"cwd\"') < 0) return null;\n let j: { cwd?: unknown };\n try {\n j = JSON.parse(line.toString(\"utf8\"));\n } catch {\n return null;\n }\n if (!j || typeof j.cwd !== \"string\" || !path.isAbsolute(j.cwd)) return null;\n if (projectName(j.cwd) === t.project) return j.cwd;\n first ??= j.cwd;\n count++;\n return null;\n };\n try {\n fd = openSync(t.file, \"r\");\n const buf = Buffer.alloc(256 * 1024);\n let pos = 0;\n let rest = Buffer.alloc(0);\n let skipping = false;\n while (pos < cap && count < 50) {\n const n = readSync(fd, buf, 0, buf.length, pos);\n if (!n) {\n if (!skipping && rest.length) {\n const hit = look(rest);\n if (hit) return hit;\n }\n break;\n }\n pos += n;\n let chunk = rest.length ? Buffer.concat([rest, buf.subarray(0, n)]) : buf.subarray(0, n);\n let nl = chunk.indexOf(10);\n while (nl >= 0) {\n const line = chunk.subarray(0, nl);\n chunk = chunk.subarray(nl + 1);\n if (skipping) skipping = false;\n else {\n const hit = look(line);\n if (hit) return hit;\n }\n nl = chunk.indexOf(10);\n }\n if (chunk.length > 2 * 1024 * 1024) {\n skipping = true;\n rest = Buffer.alloc(0);\n } else rest = skipping ? Buffer.alloc(0) : Buffer.from(chunk);\n }\n } catch {\n } finally {\n if (fd !== undefined)\n try {\n closeSync(fd);\n } catch {}\n }\n return first;\n}\n\nfunction pidAlive(pid: number): boolean {\n if (!Number.isSafeInteger(pid) || pid <= 1) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n return (e as { code?: string }).code === \"EPERM\";\n }\n}\n\n/** A Claude Code process holds this session right now: its registry file,\n * <config>/sessions/<pid>.json, names it and the pid is alive (interactive and\n * Agent SDK sessions both file one). */\nexport function liveProcess(session: string, configDir: string): boolean {\n let names: string[] = [];\n try {\n names = readdirSync(path.join(configDir, \"sessions\")).filter((n) => /^\\d+\\.json$/.test(n));\n } catch {\n return false;\n }\n for (const n of names) {\n try {\n const j = JSON.parse(readFileSync(path.join(configDir, \"sessions\", n), \"utf8\")) as {\n sessionId?: unknown;\n pid?: unknown;\n };\n if (String(j.sessionId) !== session) continue;\n if (pidAlive(Number(j.pid ?? n.slice(0, -5)))) return true;\n } catch {}\n }\n return false;\n}\n\n/** Written in the last 90 s, and not by a job of ours. */\nexport function recentlyWritten(file: string, ourLastEnd?: number, now = Date.now()): boolean {\n let m: number;\n try {\n m = statSync(file).mtimeMs;\n } catch {\n return false;\n }\n if (now - m > LIVE_WRITE_MS) return false;\n return !(ourLastEnd && m <= ourLastEnd + 2000);\n}\n\nexport interface RunResult {\n error?: string;\n code?: number | null;\n signal?: NodeJS.Signals | null;\n stdout?: string | null;\n tooBig?: boolean;\n stderr?: string;\n timedOut?: boolean;\n}\n\n/** Run one headless turn in its own process group, holding at most 1 MB of stdout. */\nexport function runClaude(\n bin: string,\n args: string[],\n o: {\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeoutMs?: number;\n /** Streaming (`--output-format stream-json`): each stdout line as it arrives. Only\n * the `result` line is kept for the RunResult, so a long stream never hits the cap. */\n onLine?: (line: string) => void;\n },\n): Promise<RunResult> {\n return new Promise((resolve) => {\n let out: Buffer[] = [];\n let outLen = 0;\n let tooBig = false;\n let errTail = \"\";\n let timedOut = false;\n let settled = false;\n let child: import(\"node:child_process\").ChildProcess;\n try {\n child = spawn(bin, args, {\n cwd: o.cwd,\n env: o.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: process.platform !== \"win32\",\n windowsHide: true,\n });\n } catch (e) {\n resolve({ error: (e as Error).message });\n return;\n }\n const kill = (sig: NodeJS.Signals) => {\n try {\n if (process.platform !== \"win32\" && child.pid) process.kill(-child.pid, sig);\n else child.kill(sig);\n } catch {\n try {\n child.kill(sig);\n } catch {}\n }\n };\n let partial = \"\";\n child.stdout?.on(\"data\", (b: Buffer) => {\n if (o.onLine) {\n const chunk = partial + b.toString(\"utf8\");\n const lines = chunk.split(\"\\n\");\n partial = lines.pop() ?? \"\";\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n o.onLine(line);\n } catch {}\n if (line.includes('\"type\":\"result\"')) {\n out = [Buffer.from(line)];\n outLen = line.length;\n }\n }\n if (partial.length > OUT_CAP) partial = \"\";\n return;\n }\n if (tooBig) return;\n if (outLen + b.length > OUT_CAP) {\n tooBig = true;\n out = [];\n return;\n }\n out.push(b);\n outLen += b.length;\n });\n child.stderr?.on(\"data\", (b: Buffer) => {\n errTail = (errTail + b.toString(\"utf8\")).slice(-4000);\n });\n const timer = setTimeout(() => {\n timedOut = true;\n kill(\"SIGTERM\");\n setTimeout(() => kill(\"SIGKILL\"), 10_000).unref();\n }, o.timeoutMs ?? JOB_TIMEOUT_MS);\n const result = (code: number | null, signal: NodeJS.Signals | null): RunResult => ({\n code,\n signal,\n stdout: tooBig ? null : Buffer.concat(out).toString(\"utf8\"),\n tooBig,\n stderr: errTail,\n timedOut,\n });\n const finish = (r: RunResult) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(r);\n };\n child.on(\"error\", (e) => finish({ error: e.message }));\n // A tool the agent left running can hold stdout open after Claude Code exits.\n child.on(\"exit\", (code, signal) => setTimeout(() => finish(result(code, signal)), 2000).unref());\n child.on(\"close\", (code, signal) => {\n // The last line may end without a newline: it is often the result itself.\n if (o.onLine && partial.trim()) {\n try {\n o.onLine(partial);\n } catch {}\n if (partial.includes('\"type\":\"result\"')) {\n out = [Buffer.from(partial)];\n outLen = partial.length;\n }\n partial = \"\";\n }\n finish(result(code, signal));\n });\n });\n}\n\nexport interface ClaudeResult {\n type?: string;\n result?: unknown;\n is_error?: boolean;\n subtype?: string;\n session_id?: unknown;\n permission_denials?: { tool_name?: unknown }[];\n}\n\n/** `--output-format json`: one result object, or an array whose last `result` entry it is. */\nexport function parseResult(stdout: string | null | undefined): ClaudeResult | null {\n const s = String(stdout || \"\").trim();\n if (!s) return null;\n const pick = (j: unknown): ClaudeResult | null => {\n if (Array.isArray(j)) {\n for (let i = j.length - 1; i >= 0; i--) if (j[i]?.type === \"result\") return j[i];\n return null;\n }\n return j && typeof j === \"object\" ? (j as ClaudeResult) : null;\n };\n try {\n return pick(JSON.parse(s));\n } catch {}\n const lines = s.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n try {\n const j = pick(JSON.parse(lines[i] as string));\n if (j && (j.type === \"result\" || \"result\" in j)) return j;\n } catch {}\n }\n return null;\n}\n\nexport const isUuid = (s: unknown): s is string => typeof s === \"string\" && UUID_RE.test(s);\n", "// SPDX-License-Identifier: Apache-2.0\n// The registry: the only place that lists vendors. A new harness is one file here\n// plus its fixtures and its row in spec/ADAPTERS.md.\nimport { antigravity } from \"./antigravity.js\";\nimport { claudeCode } from \"./claude-code.js\";\nimport { codex } from \"./codex.js\";\nimport { geminiCli } from \"./gemini-cli.js\";\nimport type { Adapter } from \"./types.js\";\n\nexport const ADAPTERS: readonly Adapter[] = [claudeCode, codex, geminiCli, antigravity];\nexport const adapterByName = (name: string): Adapter | undefined => ADAPTERS.find((a) => a.name === name);\nexport { AG_STALE_PRETOOL, antigravityAnswer } from \"./antigravity.js\";\nexport { claudeDirs } from \"./claude-code.js\";\nexport * as claudeControl from \"./claude-code-control.js\";\nexport type {\n Adapter,\n AdapterEvent,\n BackfillRow,\n FactsState,\n HookCommand,\n HookInput,\n HookResult,\n InstallReport,\n SessionFacts,\n TranscriptRead,\n Turn,\n} from \"./types.js\";\nexport { antigravity, claudeCode, codex, geminiCli };\n", "// SPDX-License-Identifier: Apache-2.0\n// ~/.config/sessionpipe/config.json, mode 0600: the machine's name, the sinks with\n// their tier and token, per-harness switches, the update check.\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { configFile } from \"./paths.js\";\nimport type { Tier } from \"./types.js\";\n\nexport interface SinkConfig {\n name: string;\n /** https://\u2026, file:PATH, stdout, otlp:URL */\n url: string;\n tier: Tier;\n pii?: boolean;\n /** @deprecated Never set: control is per machine (spec/CONTROL.md \u00A72). Kept so an\n * older config still reads. */\n control?: boolean;\n token?: string;\n /** whsec_\u2026 for Standard Webhooks signatures. */\n secret?: string;\n /** The token (and secret) live in this store instead of in this file; the client\n * reads them from it when it sends. */\n token_in?: \"keychain\" | \"secret-service\";\n /** Learned from the receiver's well-known file; re-read daily. */\n max_tier?: Tier;\n well_known_at?: string;\n paused?: string;\n}\n\nexport interface Config {\n machine?: string;\n sinks: SinkConfig[];\n harnesses: Record<string, { enabled?: boolean; created?: string[] }>;\n update_check?: boolean;\n keep_days?: number;\n}\n\nexport const DEFAULT_CONFIG: Config = { sinks: [], harnesses: {}, update_check: true, keep_days: 30 };\n\nexport function readConfig(file: string = configFile()): Config {\n try {\n const j = JSON.parse(readFileSync(file, \"utf8\")) as Partial<Config>;\n return {\n ...DEFAULT_CONFIG,\n ...j,\n sinks: Array.isArray(j.sinks) ? j.sinks : [],\n harnesses: j.harnesses && typeof j.harnesses === \"object\" ? j.harnesses : {},\n };\n } catch {\n return { ...DEFAULT_CONFIG, sinks: [], harnesses: {} };\n }\n}\n\nexport function writeConfig(c: Config, file: string = configFile()): void {\n mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });\n writeFileSync(file, `${JSON.stringify(c, null, 2)}\\n`, { mode: 0o600 });\n if (process.platform !== \"win32\" && existsSync(file)) {\n try {\n chmodSync(file, 0o600);\n } catch {}\n }\n}\n\n/** The machine's name: what the person configured, else the hostname without a\n * local suffix. Never guessed from anything else (a hand-typed name once linked 64\n * versions to nothing). */\nexport function machineName(c: Config, hostname: string): string {\n if (c.machine) return String(c.machine).slice(0, 80);\n return hostname.replace(/\\.(local|lan|home)$/i, \"\");\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// ULID: 48-bit ms timestamp + 80 random bits, Crockford base32. Monotonic within a\n// process so two events in the same millisecond still sort in emit order.\nimport { randomBytes } from \"node:crypto\";\n\nconst ALPHABET = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\nlet lastTime = 0;\nlet lastRand: number[] = [];\n\nfunction encodeTime(t: number): string {\n let out = \"\";\n let n = t;\n for (let i = 0; i < 10; i++) {\n out = ALPHABET[n % 32] + out;\n n = Math.floor(n / 32);\n }\n return out;\n}\n\nexport function ulid(now: number = Date.now()): string {\n if (now === lastTime) {\n // increment the random part\n for (let i = lastRand.length - 1; i >= 0; i--) {\n const v = (lastRand[i] ?? 0) + 1;\n if (v < 32) {\n lastRand[i] = v;\n break;\n }\n lastRand[i] = 0;\n }\n } else {\n lastTime = now;\n const b = randomBytes(16);\n lastRand = Array.from({ length: 16 }, (_, i) => (b[i] ?? 0) % 32);\n }\n return encodeTime(now) + lastRand.map((v) => ALPHABET[v]).join(\"\");\n}\n\nexport const isUlid = (s: string): boolean => /^[0-9A-HJKMNP-TV-Z]{26}$/.test(s);\n", "// SPDX-License-Identifier: Apache-2.0\n// From an adapter's output to a protocol event: id, time, the full session block\n// as known now, and the raw (tier 3) data. Filtering per sink happens later.\nimport type { AdapterEvent } from \"./adapters/types.js\";\nimport type { Event, Session } from \"./types.js\";\nimport { ulid } from \"./ulid.js\";\n\nexport interface EventContext {\n harness: { name: string; version?: string };\n session: Session;\n now?: number;\n}\n\nexport function makeEvent(a: AdapterEvent, ctx: EventContext): Event {\n const now = ctx.now ?? Date.now();\n const harness: Event[\"harness\"] = { name: ctx.harness.name, event: a.harnessEvent };\n if (ctx.harness.version) harness.version = ctx.harness.version;\n return {\n protocol: 1,\n id: ulid(now),\n type: a.type,\n time: new Date(now).toISOString(),\n tier: 3,\n harness,\n session: ctx.session,\n privacy: { rulesets: [], pii: false },\n data: a.data,\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The outbox: append-only JSONL per (harness, session) under\n// <state>/outbox/<harness>/<session>.jsonl, a per-session seq counter, a per-sink\n// cursor that moves only when the sink acknowledged, and a per-session lock so two\n// workers never interleave. Never lose, never duplicate.\nimport {\n appendFileSync,\n closeSync,\n existsSync,\n mkdirSync,\n openSync,\n readdirSync,\n readFileSync,\n readSync,\n renameSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport path from \"node:path\";\nimport { safeId } from \"./paths.js\";\nimport type { Event } from \"./types.js\";\n\nexport interface OutboxRef {\n harness: string;\n session: string;\n}\n\nexport class Outbox {\n constructor(readonly root: string) {}\n\n dir(harness: string): string {\n return path.join(this.root, \"outbox\", safeId(harness));\n }\n file(ref: OutboxRef): string {\n return path.join(this.dir(ref.harness), `${safeId(ref.session)}.jsonl`);\n }\n private seqFile(ref: OutboxRef): string {\n return path.join(this.dir(ref.harness), `${safeId(ref.session)}.seq`);\n }\n\n /** The next seq for a session, persisted (survives a hibernating machine and a\n * restart; an in-memory counter would restart at 0 and collide). */\n nextSeq(ref: OutboxRef): number {\n const f = this.seqFile(ref);\n let n = 0;\n try {\n n = Number(readFileSync(f, \"utf8\")) || 0;\n } catch {\n // A missing counter with an existing outbox: recover from the file's last line.\n n = this.lastSeqInFile(ref) + 1;\n }\n mkdirSync(path.dirname(f), { recursive: true, mode: 0o700 });\n writeFileSync(f, String(n + 1), { mode: 0o600 });\n return n;\n }\n\n private lastSeqInFile(ref: OutboxRef): number {\n const f = this.file(ref);\n if (!existsSync(f)) return -1;\n const lines = readFileSync(f, \"utf8\").trim().split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n try {\n const j = JSON.parse(lines[i] ?? \"\") as Event;\n if (typeof j.session?.seq === \"number\") return j.session.seq;\n } catch {}\n }\n return -1;\n }\n\n append(ref: OutboxRef, events: Event[]): void {\n if (!events.length) return;\n mkdirSync(this.dir(ref.harness), { recursive: true, mode: 0o700 });\n appendFileSync(this.file(ref), `${events.map((e) => JSON.stringify(e)).join(\"\\n\")}\\n`, { mode: 0o600 });\n }\n\n /** Every session file, newest first. */\n sessions(): OutboxRef[] {\n const out: { ref: OutboxRef; mtime: number }[] = [];\n const base = path.join(this.root, \"outbox\");\n if (!existsSync(base)) return [];\n for (const h of readdirSync(base)) {\n const d = path.join(base, h);\n let names: string[] = [];\n try {\n names = readdirSync(d).filter((n) => n.endsWith(\".jsonl\"));\n } catch {\n continue;\n }\n for (const n of names) {\n try {\n out.push({ ref: { harness: h, session: n.slice(0, -6) }, mtime: statSync(path.join(d, n)).mtimeMs });\n } catch {}\n }\n }\n return out.sort((a, b) => b.mtime - a.mtime).map((x) => x.ref);\n }\n\n /** Read events after byte offset `from`; returns them and the new offset. Lines\n * are read whole; a partial trailing line (a write in progress) is left. */\n read(ref: OutboxRef, from: number, maxEvents = 500): { events: Event[]; offset: number } {\n const f = this.file(ref);\n if (!existsSync(f)) return { events: [], offset: from };\n const size = statSync(f).size;\n if (from >= size) return { events: [], offset: from };\n const fd = openSync(f, \"r\");\n try {\n const buf = Buffer.alloc(Math.min(size - from, 8 * 1024 * 1024));\n const n = readSync(fd, buf, 0, buf.length, from);\n const text = buf.subarray(0, n).toString(\"utf8\");\n const events: Event[] = [];\n let offset = from;\n let pos = 0;\n while (events.length < maxEvents) {\n const nl = text.indexOf(\"\\n\", pos);\n if (nl < 0) break;\n const line = text.slice(pos, nl);\n pos = nl + 1;\n offset = from + Buffer.byteLength(text.slice(0, pos), \"utf8\");\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as Event);\n } catch {}\n }\n return { events, offset };\n } finally {\n closeSync(fd);\n }\n }\n\n /** Files older than `days` are pruned; the cursor files with them. */\n prune(days: number, now = Date.now()): number {\n let n = 0;\n const cutoff = now - days * 86_400_000;\n for (const ref of this.sessions()) {\n const f = this.file(ref);\n try {\n if (statSync(f).mtimeMs < cutoff) {\n unlinkSync(f);\n try {\n unlinkSync(this.seqFile(ref));\n } catch {}\n n++;\n }\n } catch {}\n }\n return n;\n }\n\n delete(ref: OutboxRef): void {\n for (const f of [this.file(ref), this.seqFile(ref)]) {\n try {\n unlinkSync(f);\n } catch {}\n }\n }\n}\n\n/** Per-sink cursor: byte offset per session file, moved only on a 2xx. */\nexport class Cursors {\n constructor(\n readonly root: string,\n readonly sink: string,\n ) {}\n private file(): string {\n return path.join(this.root, \"cursors\", `${safeId(this.sink)}.json`);\n }\n read(): Record<string, number> {\n try {\n return JSON.parse(readFileSync(this.file(), \"utf8\")) as Record<string, number>;\n } catch {\n return {};\n }\n }\n write(c: Record<string, number>): void {\n const f = this.file();\n mkdirSync(path.dirname(f), { recursive: true, mode: 0o700 });\n const tmp = `${f}.${process.pid}.tmp`;\n writeFileSync(tmp, JSON.stringify(c), { mode: 0o600 });\n renameSync(tmp, f);\n }\n key(ref: OutboxRef): string {\n return `${ref.harness}/${ref.session}`;\n }\n}\n\n/** A lock per session so two workers never interleave. Stale after 5 min. */\nexport function takeLock(root: string, ref: OutboxRef, staleMs = 5 * 60_000): (() => void) | null {\n const dir = path.join(root, \"locks\");\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n const f = path.join(dir, `${safeId(ref.harness)}-${safeId(ref.session)}.lock`);\n try {\n if (Date.now() - statSync(f).mtimeMs > staleMs) unlinkSync(f);\n else return null;\n } catch {}\n try {\n writeFileSync(f, String(process.pid), { flag: \"wx\" });\n } catch {\n return null;\n }\n return () => {\n try {\n unlinkSync(f);\n } catch {}\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// pii@1 \u2014 an opt-in second pass that reduces identifiers (spec/PRIVACY.md \u00A72). It\n// does not promise anonymity; it removes the obvious.\nimport { createHash } from \"node:crypto\";\n\nexport const RULESET_PII = \"pii@1\";\n\nconst EMAIL = /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/g;\n/** E.164 and common national forms: an optional +, 7\u201315 digits with separators,\n * optional area-code parentheses. A version number (22.23.1) or an IP never matches:\n * the run must not sit between dots, and needs \u2265 7 digits. */\nconst PHONE = /(?<![\\w.])(?:\\+\\d{1,3}[ .-]?)?(?:\\(\\d{2,4}\\)[ .-]?)?\\d{2,4}(?:[ .-]?\\d{2,4}){1,3}(?!\\w)/g;\n\nfunction looksPhone(s: string): boolean {\n const digits = s.replace(/\\D/g, \"\");\n if (digits.length < 7 || digits.length > 15) return false;\n // \"port 8891, pr 12345\": a bare run with no separator or + is a number, not a phone.\n if (!/[+() .-]/.test(s)) return false;\n // \"22.23.1\", \"185.199.108.153\": dots alone are a version or an address.\n if (!/[+() -]/.test(s)) return false;\n return true;\n}\n\n/** Replace emails and phone numbers, and write `home` as `~`. */\nexport function reducePii(text: string, home?: string): string {\n if (!text) return text;\n let out = text.replace(EMAIL, \"[email]\");\n out = out.replace(PHONE, (m) => (looksPhone(m) ? \"[phone]\" : m));\n if (home) {\n const h = home.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n out = out.replace(new RegExp(`(?<![A-Za-z0-9_])${h}(?=/|$|\\\\s|[\"'\\`])`, \"g\"), \"~\");\n }\n return out;\n}\n\n/** The machine's name under pii@1: the first 8 hex of its SHA-256. */\nexport function hashMachine(name: string): string {\n return createHash(\"sha256\").update(name).digest(\"hex\").slice(0, 8);\n}\n\n/** Apply pii@1 to every string in a value; `home` becomes `~`. */\nexport function reducePiiDeep<T>(v: T, home?: string): T {\n if (typeof v === \"string\") return reducePii(v, home) as T;\n if (Array.isArray(v)) return v.map((x) => reducePiiDeep(x, home)) as T;\n if (v && typeof v === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, x] of Object.entries(v as Record<string, unknown>)) out[k] = reducePiiDeep(x, home);\n return out as T;\n }\n return v;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// secrets@1 \u2014 credentials out of every string, on the person's machine, before an\n// event reaches the outbox. Ported from spacesheep-cli lib/redact.js (Michael\n// Makarov, MIT \u2192 Apache-2.0, see NOTICE). The ruleset is defined in\n// spec/PRIVACY.md \u00A72 and pinned by conformance/redaction/secrets.json.\n//\n// Every pattern is linear: bounded repetition, no nested quantifiers. The\n// adversarial vectors (password_ \u00D7 5000, a 50 000-space run) pin that.\n\nexport const RULESET_SECRETS = \"secrets@1\";\nexport const REDACTED = \"[redacted]\";\n\n/** Token formats that are a credential by their shape alone. Each is anchored on a\n * vendor prefix, so a commit sha or a UUID never matches. */\nconst TOKEN_PATTERNS: RegExp[] = [\n /-----BEGIN [A-Z0-9 ]*PRIVATE KEY(?: BLOCK)?-----[\\s\\S]*?(?:-----END [A-Z0-9 ]*PRIVATE KEY(?: BLOCK)?-----|$)/g,\n /\\b(?:AKIA|ASIA|ABIA|ACCA)[0-9A-Z]{16}\\b/g, // AWS access key id\n /\\bgh[pousr]_[A-Za-z0-9]{30,}\\b/g, // GitHub\n /\\bgithub_pat_[A-Za-z0-9_]{30,}\\b/g,\n /\\bglpat-[A-Za-z0-9_-]{20,}\\b/g, // GitLab\n /\\bxox[abposre]-[A-Za-z0-9-]{10,}\\b/g, // Slack\n /\\bhttps:\\/\\/hooks\\.slack\\.com\\/services\\/[A-Za-z0-9/_-]+/g,\n /\\bhttps:\\/\\/(?:ptb\\.|canary\\.)?discord(?:app)?\\.com\\/api\\/webhooks\\/[0-9]+\\/[A-Za-z0-9_-]+/g,\n /\\bsk-(?:ant-|proj-|svcacct-|admin-|or-v1-)?[A-Za-z0-9_-]{20,}\\b/g, // Anthropic, OpenAI, DeepSeek, OpenRouter\n /\\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\\b/g, // Stripe secret / restricted\n /\\bwhsec_[A-Za-z0-9+/=]{20,}/g, // Stripe / Svix / Standard Webhooks secret\n /\\bAIza[0-9A-Za-z_-]{35}\\b/g, // Google API key\n /\\bya29\\.[0-9A-Za-z_-]{20,}/g, // Google OAuth access token\n /\\b1\\/\\/0[0-9A-Za-z_-]{30,}/g, // Google OAuth refresh token\n /\\bGOCSPX-[0-9A-Za-z_-]{20,}/g, // Google OAuth client secret\n /\\bxai-[A-Za-z0-9]{30,}\\b/g,\n /\\bgsk_[A-Za-z0-9]{30,}\\b/g, // Groq\n /\\bpplx-[A-Za-z0-9]{30,}\\b/g, // Perplexity\n /\\bhf_[A-Za-z0-9]{30,}\\b/g, // Hugging Face\n /\\bpcsk_[A-Za-z0-9_]{30,}\\b/g, // Pinecone\n /\\bnpm_[A-Za-z0-9]{30,}\\b/g,\n /\\bpypi-[A-Za-z0-9_-]{50,}/g,\n /\\bSG\\.[A-Za-z0-9_-]{16,}\\.[A-Za-z0-9_-]{16,}/g, // SendGrid\n /\\bshp(?:at|ss|ca|pa)_[a-fA-F0-9]{32}\\b/g, // Shopify\n /\\bdop_v1_[a-f0-9]{64}\\b/g, // DigitalOcean\n /\\b(?:lin_api|lin_oauth)_[A-Za-z0-9]{30,}\\b/g, // Linear\n /\\b(?:ntn|secret)_[A-Za-z0-9]{40,}\\b/g, // Notion\n /\\bsbp_[a-f0-9]{40}\\b/g, // Supabase\n /\\bfigd_[A-Za-z0-9_-]{30,}/g, // Figma\n /\\bdp\\.(?:pt|st|sa|ct)\\.[A-Za-z0-9]{30,}/g, // Doppler\n /\\bgrn_[A-Za-z0-9_-]{20,}/g, // Granola\n /\\bss_[a-f0-9]{32,}\\b/g, // spacesheep API keys\n /\\b[0-9]{8,10}:AA[A-Za-z0-9_-]{33}\\b/g, // Telegram bot token\n /\\beyJ[A-Za-z0-9_-]{10,}\\.eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}/g, // JWT\n];\n/** `scheme://user:password@host` \u2014 the password goes, the user and host stay. */\nconst URL_CREDENTIALS = /\\b([a-z][a-z0-9+.-]{1,20}:\\/\\/[^\\s:/@'\"`<>]{1,100}:)([^\\s@/'\"`<>]{1,200})(@)/gi;\n/** `Authorization: Bearer \u2026` / `Basic \u2026`, and a bare `Bearer <token>` in a curl line. */\nconst AUTH_HEADER = /\\b((?:Bearer|Basic|Token)\\s+)([A-Za-z0-9._~+/=-]{16,})/g;\n// The words that name a secret, in prose. `key` alone is too common (\"the key\n// point\"), so it only counts with a qualifier.\nconst SECRET_WORD =\n \"(?:pass(?:word|wd|phrase|code)?s?|pwd|secret(?:[ _-]?key)?s?|client[ _-]?secret|api[ _-]?keys?|apikeys?|access[ _-]?keys?|access[ _-]?tokens?|auth[ _-]?tokens?|refresh[ _-]?tokens?|private[ _-]?keys?|tokens?|credentials?|creds)\";\n/** Strict form: a NAME, an explicit separator (`=`, `:`, `=>`), a value. The name is\n * one flat run of identifier characters judged in code (isSecretName), never by a\n * nested pattern. Only a secret name goes on to consume its value \u2014 otherwise\n * `https:` would swallow the `?token=\u2026` behind it. */\nconst NAME_SEP = /(?<![A-Za-z0-9_])([A-Za-z][A-Za-z0-9_-]{1,79})([\"']?\\s{0,3}(?::=|=>|=|:)\\s{0,3})/g;\nconst VALUE = /\"([^\"\\n]{1,300})\"|'([^'\\n]{1,300})'|`([^`\\n]{1,300})`|([^\\s\"'`,;&)}\\]]{1,300})/y;\n\nfunction redactAssignments(text: string): string {\n let out = \"\";\n let last = 0;\n NAME_SEP.lastIndex = 0;\n for (let m = NAME_SEP.exec(text); m; m = NAME_SEP.exec(text)) {\n const name = m[1] ?? \"\";\n if (!isSecretName(name)) continue;\n VALUE.lastIndex = NAME_SEP.lastIndex;\n const v = VALUE.exec(text);\n if (!v) continue;\n const value = v[1] ?? v[2] ?? v[3] ?? v[4] ?? \"\";\n NAME_SEP.lastIndex = VALUE.lastIndex;\n if (isPlaceholder(value) || value.includes(REDACTED)) continue;\n // `max_tokens: 4096`, `input_tokens=12k` \u2014 a token COUNT, not a token.\n if (/tokens?$/i.test(name) && /^\\d+(?:[.,]\\d+)*[km]?$/i.test(value)) continue;\n const q = v[1] != null ? '\"' : v[2] != null ? \"'\" : v[3] != null ? \"`\" : \"\";\n out += text.slice(last, v.index) + q + REDACTED + q;\n last = VALUE.lastIndex;\n }\n return last ? out + text.slice(last) : text;\n}\n\n/** Is this identifier the name of a secret? `DB_PASSWORD`, `apiKey`, `client-secret`,\n * `AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`; an env-style `STRIPE_KEY` too. Not\n * `password_hash`, `tokenizer`, `sort_key`. */\nexport function isSecretName(name: string): boolean {\n if (/^[A-Z0-9_]+_KEY$/.test(name)) return true;\n const flat = name.toLowerCase().replace(/[_-]/g, \"\");\n return /(?:pass(?:word|wd|phrase|code)|pwd|secret|secretkey|secretaccesskey|clientsecret|apikey|accesskey|accesstoken|authtoken|refreshtoken|privatekey|token|credential|creds)s?$/.test(\n flat,\n );\n}\n\n/** Loose form: prose. \"password is Hunter2!\", \"the token was ghx\u2026\". Only a value\n * that looks generated counts, so \"the password is wrong\" passes untouched.\n * Whitespace runs are bounded so a long run can't make the match quadratic. */\nconst PROSE = new RegExp(\n `(\\\\b${SECRET_WORD}(?:[ \\\\t]{1,3}(?:is|was|=|:|to|as|of|for[ \\\\t]{1,3}\\\\S{1,40}[ \\\\t]{1,3}is))?[ \\\\t]{1,3})([\"'\\`]?)([^\\\\s\"'\\`]{6,200})\\\\2`,\n \"gi\",\n);\n\n/** A value that is plainly not the secret itself: a type, a variable, a template, an\n * already-redacted marker, an env lookup. */\nfunction isPlaceholder(v: string): boolean {\n const s = v.replace(/[.,;:!?]+$/, \"\");\n if (!s) return true;\n if (\n /^(?:string|number|boolean|bool|str|int|any|unknown|null|undefined|none|nil|true|false|optional|required|text|varchar|password|secret|token|env|string\\[\\]|object|bytes)$/i.test(\n s,\n )\n )\n return true;\n if (/^\\[?redacted\\]?$/i.test(s) || /^\\*+$/.test(s) || /^x{3,}$/i.test(s) || /^\\.{3}$|^\u2026$/.test(s)) return true;\n if (/^[<{$%]/.test(s)) return true; // <your-key>, ${VAR}, {{var}}, $VAR, %VAR%\n if (\n /^(?:process\\.env|env|os\\.environ|c\\.env|this\\.env|import\\.meta\\.env|getenv|config|settings|secrets|args|opts|options|req|request|body|params|input|data|user|self|this)\\b/i.test(\n s,\n )\n )\n return true;\n if (/^[A-Za-z_$][\\w$]*(?:\\.[A-Za-z_$][\\w$]*)+$/.test(s)) return true; // a member path: form.password\n if (/[(]/.test(s)) return true; // a call: hash(pw), getSecret()\n if (/^(?:your|my|the|a|an|some|new|old)[-_ ]/i.test(s)) return true; // your-api-key\n return false;\n}\n\n/** Does a prose value look like something generated, rather than an English word? */\nfunction looksSecret(v: string): boolean {\n const s = v.replace(/[.,;:!?)]+$/, \"\");\n if (s.length < 6) return false;\n if (isPlaceholder(s)) return false;\n if (/^https?:\\/\\//i.test(s)) return false; // a link, handled by URL_CREDENTIALS if it carries one\n if (/^[a-z]+(?:[-'][a-z]+)*$/.test(s)) return false; // a lowercase word\n if (/^[A-Z][a-z]+$/.test(s)) return false; // a capitalised word\n if (/^\\d+(?:[.,]\\d+)*[a-z%]*$/i.test(s)) return false; // a count: 4096, 128k, 3.5, 50%\n if (/^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/.test(s)) return false; // an env var's NAME\n const kinds = [/[a-z]/, /[A-Z]/, /[0-9]/, /[^A-Za-z0-9]/].filter((r) => r.test(s)).length;\n return kinds >= 3 || (/[0-9]/.test(s) && /[A-Za-z]/.test(s));\n}\n\n/** Redact every credential in `text`. Returns the same string when there is none. */\nexport function redactSecrets(text: string): string {\n if (!text) return text;\n let out = text;\n for (const re of TOKEN_PATTERNS) out = out.replace(re, REDACTED);\n out = out.replace(URL_CREDENTIALS, (_m, head: string, _pw: string, at: string) => `${head}${REDACTED}${at}`);\n out = out.replace(AUTH_HEADER, (m, head: string, v: string) => (v.includes(REDACTED) ? m : `${head}${REDACTED}`));\n out = redactAssignments(out);\n out = out.replace(PROSE, (m, head: string, q: string, v: string) =>\n !looksSecret(v) || v.includes(REDACTED) ? m : `${head}${q}${REDACTED}${q}`,\n );\n return out;\n}\n\n/** Did redaction change anything? */\nexport function hasSecret(text: string): boolean {\n return !!text && redactSecrets(text) !== text;\n}\n\n/** Redact every string in a JSON-able value (keys are left alone). */\nexport function redactDeep<T>(v: T): T {\n if (typeof v === \"string\") return redactSecrets(v) as T;\n if (Array.isArray(v)) return v.map(redactDeep) as T;\n if (v && typeof v === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, x] of Object.entries(v as Record<string, unknown>)) out[k] = redactDeep(x);\n return out as T;\n }\n return v;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// filter(event, tier, pii): the pure function every sink runs an event through.\n// Removes by ALLOWLIST per type and tier (spec/PRIVACY.md \u00A71), redacts every string\n// above tier 0 with secrets@1, and runs pii@1 when asked. Returns null when the\n// type is not carried at the tier. The conformance runner runs the same function.\nimport type { Event, Tier } from \"../types.js\";\nimport { hashMachine, RULESET_PII, reducePiiDeep } from \"./pii.js\";\nimport { RULESET_SECRETS, redactDeep } from \"./secrets.js\";\n\n/** The lowest tier that carries each known type (kept in step with schema/v1.ts). */\nexport const TYPE_TIER: Record<string, Tier> = {\n \"session.started\": 0,\n \"session.heartbeat\": 0,\n \"session.ended\": 0,\n \"session.backfill\": 0,\n \"session.forgotten\": 0,\n \"turn.started\": 0,\n \"turn.ended\": 0,\n \"turn.transcript\": 2,\n \"tool.started\": 1,\n \"tool.ended\": 1,\n \"files.changed\": 1,\n \"attention.needed\": 0,\n \"attention.cleared\": 0,\n \"subagent.started\": 1,\n \"subagent.ended\": 1,\n \"context.compacted\": 1,\n native: 3,\n};\n\n/** data keys allowed per type at tier N (cumulative: tier 1 includes tier 0's). */\nconst DATA_ALLOW: Record<string, Partial<Record<Tier, string[]>>> = {\n \"session.started\": { 0: [\"source\"] },\n \"session.heartbeat\": { 0: [] },\n \"session.ended\": { 0: [\"reason\"] },\n \"session.backfill\": { 0: [\"started_at\", \"last_at\", \"turns\"] },\n \"session.forgotten\": { 0: [] },\n \"turn.started\": { 0: [\"turn_id\"], 1: [\"prompt_chars\"] },\n \"turn.ended\": { 0: [\"turn_id\", \"reason\", \"ms\"], 1: [\"error\"] },\n \"turn.transcript\": { 2: [\"turn\", \"user\", \"assistant\", \"at\"] },\n \"tool.started\": { 1: [\"tool\", \"call_id\", \"turn_id\", \"agent_id\"], 3: [\"input\"] },\n \"tool.ended\": { 1: [\"tool\", \"call_id\", \"turn_id\", \"agent_id\", \"ms\", \"ok\", \"error\"], 3: [\"input\", \"output\"] },\n \"files.changed\": { 1: [\"paths\"] },\n \"attention.needed\": { 0: [\"attention_id\", \"kind\"], 1: [\"tool\", \"message\"] },\n \"attention.cleared\": { 0: [\"attention_id\", \"how\"] },\n \"subagent.started\": { 1: [\"agent_id\", \"agent_type\"] },\n \"subagent.ended\": { 1: [\"agent_id\", \"agent_type\"] },\n \"context.compacted\": { 1: [\"trigger\"] },\n};\n\nconst SESSION_ALLOW = [\n \"id\",\n \"seq\",\n \"machine\",\n \"cwd\",\n \"repo\",\n \"branch\",\n \"model\",\n \"title\",\n \"title_source\",\n \"url\",\n \"account_id\",\n \"parent_id\",\n];\nconst MAX_SIDE = 20_000;\nconst MAX_IO = 64 * 1024;\n\nfunction allowedKeys(type: string, tier: Tier): string[] | null {\n const table = DATA_ALLOW[type];\n if (!table) return null; // unknown type: kept whole (receivers keep extra keys), redacted\n const out: string[] = [];\n for (let t = 0; t <= tier; t++) for (const k of table[t as Tier] ?? []) out.push(k);\n return out;\n}\n\nfunction cap(v: unknown, max: number): unknown {\n if (typeof v === \"string\") return v.length > max ? `${v.slice(0, max)}\u2026` : v;\n if (v && typeof v === \"object\") {\n const s = JSON.stringify(v);\n return s.length > max ? `${s.slice(0, max)}\u2026` : v;\n }\n return v;\n}\n\nexport interface FilterOptions {\n /** The person's home directory, for pii@1's `~` rewrite. */\n home?: string;\n}\n\n/** The event as a sink at `tier` may see it, or null when the type is above the tier. */\nexport function filterEvent(event: Event, tier: Tier, pii: boolean, opts: FilterOptions = {}): Event | null {\n const minTier = TYPE_TIER[event.type];\n if (minTier !== undefined && minTier > tier) return null;\n if (event.type === \"native\" && tier < 3) return null;\n\n const session: Record<string, unknown> = {};\n for (const k of SESSION_ALLOW)\n if (event.session[k as keyof typeof event.session] !== undefined)\n session[k] = event.session[k as keyof typeof event.session];\n\n let data: Record<string, unknown> = {};\n const keys = allowedKeys(event.type, tier);\n if (keys === null) data = { ...event.data };\n else for (const k of keys) if (event.data[k] !== undefined) data[k] = event.data[k];\n if (typeof data.user === \"string\") data.user = cap(data.user, MAX_SIDE);\n if (typeof data.assistant === \"string\") data.assistant = cap(data.assistant, MAX_SIDE);\n if (data.input !== undefined) data.input = cap(data.input, MAX_IO);\n if (data.output !== undefined) data.output = cap(data.output, MAX_IO);\n if (typeof data.message === \"string\") data.message = cap(data.message, 200);\n\n const rulesets: string[] = [];\n let out: Event = { ...event, tier, session: session as Event[\"session\"], data, privacy: { rulesets, pii } };\n if (tier > 0) {\n // Redact, then the caps above already applied: a cut before redaction could leave half a key.\n out = { ...out, session: redactDeep(out.session), data: redactDeep(out.data) };\n rulesets.push(RULESET_SECRETS);\n }\n if (pii) {\n const s = reducePiiDeep(out.session, opts.home) as Record<string, unknown>;\n if (typeof s.machine === \"string\") s.machine = hashMachine(s.machine);\n delete s.account_id;\n out = { ...out, session: s as Event[\"session\"], data: reducePiiDeep(out.data, opts.home) };\n rulesets.push(RULESET_PII);\n }\n out.privacy = { rulesets, pii };\n return out;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// file:PATH \u2014 append filtered events as JSONL. The zero-server sink.\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Event, Tier } from \"../types.js\";\nimport type { DeliveryResult, Sink } from \"./types.js\";\n\nexport class FileSink implements Sink {\n constructor(\n readonly name: string,\n readonly file: string,\n readonly tier: Tier,\n readonly pii: boolean,\n ) {}\n async send(events: Event[]): Promise<DeliveryResult> {\n try {\n mkdirSync(path.dirname(this.file), { recursive: true });\n appendFileSync(this.file, `${events.map((e) => JSON.stringify(e)).join(\"\\n\")}\\n`);\n return { ok: true, acknowledged: events.length, accepted: events.length, duplicates: 0, rejected: [] };\n } catch (e) {\n return { ok: false, acknowledged: 0, error: String((e as Error).message), action: \"retry\" };\n }\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// stdout \u2014 one JSON line per event to a writable (the worker's stdout is ignored\n// when spawned by a hook, so this sink is for `sessionpipe tail` and tests).\nimport type { Event, Tier } from \"../types.js\";\nimport type { DeliveryResult, Sink } from \"./types.js\";\n\nexport class StdoutSink implements Sink {\n constructor(\n readonly name: string,\n readonly tier: Tier,\n readonly pii: boolean,\n private readonly write: (line: string) => void = (l) => process.stdout.write(`${l}\\n`),\n ) {}\n async send(events: Event[]): Promise<DeliveryResult> {\n for (const e of events) this.write(JSON.stringify(e));\n return { ok: true, acknowledged: events.length, accepted: events.length, duplicates: 0, rejected: [] };\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The pure half of `sessionpipe connect`: which folders a machine allows sessions you\n// message to run in, when nobody said. Never the home folder or anything above it:\n// \"allow everything I own\" is not a default anyone should find out about later.\nimport path from \"node:path\";\n\n/** The home folder, or a folder that contains it (/, /Users), or the filesystem root. */\nexport function isBroad(dir: string, home: string): boolean {\n const d = path.resolve(dir);\n const h = path.resolve(home);\n if (d === path.parse(d).root) return true;\n return d === h || h.startsWith(d.endsWith(path.sep) ? d : d + path.sep);\n}\n\nconst inside = (child: string, parent: string): boolean =>\n child !== parent && child.startsWith(parent.endsWith(path.sep) ? parent : parent + path.sep);\n\nexport interface FolderChoice {\n folders: string[];\n /** Where they came from: the flags, the machine's own list, the folder this ran in,\n * the folders recent sessions ran in, or nowhere. */\n from: \"flags\" | \"existing\" | \"here\" | \"recent\" | \"none\";\n}\n\n/** `recent`: the folders this machine's sessions ran in, newest first. */\nexport function connectFolders(o: {\n cwd: string;\n home: string;\n flags: string[];\n existing: string[];\n recent: string[];\n exists?: (dir: string) => boolean;\n max?: number;\n}): FolderChoice {\n if (o.flags.length) return { folders: o.flags.map((d) => path.resolve(d)), from: \"flags\" };\n if (o.existing.length) return { folders: [], from: \"existing\" };\n if (!isBroad(o.cwd, o.home)) return { folders: [path.resolve(o.cwd)], from: \"here\" };\n const exists = o.exists ?? (() => true);\n const picked: string[] = [];\n for (const raw of o.recent) {\n if (!raw || !path.isAbsolute(raw)) continue;\n const d = path.resolve(raw);\n if (isBroad(d, o.home) || picked.includes(d) || !exists(d)) continue;\n if (picked.some((p) => inside(d, p))) continue;\n // A wider folder replaces the narrower ones already picked under it.\n for (let i = picked.length - 1; i >= 0; i--) if (inside(picked[i] as string, d)) picked.splice(i, 1);\n picked.push(d);\n if (picked.length >= (o.max ?? 8)) break;\n }\n return picked.length ? { folders: picked, from: \"recent\" } : { folders: [], from: \"none\" };\n}\n\n/** The tier `connect` reports at: --tier when given; otherwise 2 (what a session board\n * needs: the asks and the answers, secrets removed), never lowering a sink set higher. */\nexport function connectTier(flag: string | undefined, current: number | undefined): 0 | 1 | 2 | 3 {\n if (flag !== undefined && flag !== \"\")\n return Math.max(0, Math.min(3, Math.trunc(Number(flag)) || 0)) as 0 | 1 | 2 | 3;\n return Math.max(2, Math.min(3, current ?? 0)) as 2 | 3;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The control daemon keeps its own copy current. About a minute after it starts, and\n// then once a day by the wall clock (state/control/update.json remembers the last\n// check, so a restart or a machine that slept doesn't ask twice in a day), it reads\n// npm's `latest`. When that is newer it waits until the daemon has nothing in hand \u2014\n// no message being delivered, no headless run or start, no held SDK session mid-turn,\n// no permission prompt open, no session on the machine mid-turn, no acks being sent \u2014\n// stops taking new messages, installs the release into the prefix it runs from\n// (update.ts), and restarts onto it:\n//\n// launchd / systemd exit UPDATE_EXIT; the service restarts it on the new code\n// (every plist and unit sessionpipe ever wrote restarts on a\n// non-zero exit).\n// anything else this process stops being the daemon and becomes its parent:\n// it runs the new `control run` as its child with the same env\n// and output, restarts it on UPDATE_EXIT, and exits with it\n// otherwise. Whatever waits on this process (a terminal, a\n// container's init, a setsid'd shell) keeps waiting.\n//\n// Off with SESSIONPIPE_NO_UPDATE_CHECK, `update_check: false` in config.json\n// (`sessionpipe update off`), or when the running copy isn't a global npm install.\nimport { type ChildProcess, spawn } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Config } from \"@sessionpipe/core\";\nimport { compareVersions, globalPrefix, isNewer, unwritable } from \"../update.js\";\nimport { controlState, writePrivate } from \"./store.js\";\n\n/** EX_TEMPFAIL: \"start me again, on the code now on disk\". */\nexport const UPDATE_EXIT = 75;\nexport const DAY_MS = 24 * 3600_000;\nconst LABEL = \"org.sessionpipe.control\";\nconst UNIT = \"sessionpipe-control.service\";\n\n/** What the daemon remembers about updating, in state/control/update.json. */\nexport interface UpdateRecord {\n /** The last time it asked npm, whatever the answer. */\n checked_at?: string;\n /** What npm said was `latest` then; null when the check failed. */\n latest?: string | null;\n error?: string | null;\n /** The version that checked. */\n running?: string;\n /** Why the daemon's auto-update is off, as the daemon sees it (its own env), or null. */\n off?: string | null;\n /** A newer release waiting for the daemon to be idle. */\n pending?: string | null;\n updated?: { from: string; to: string; at: string; ms: number } | null;\n failed?: { version: string; at: string; error: string } | null;\n}\n\nexport const updateFile = (env: NodeJS.ProcessEnv = process.env): string => path.join(controlState(env), \"update.json\");\n\nexport function readUpdate(file: string): UpdateRecord {\n try {\n const j = JSON.parse(readFileSync(file, \"utf8\")) as UpdateRecord;\n return j && typeof j === \"object\" ? j : {};\n } catch {\n return {};\n }\n}\n\n/** Due when it never checked, last checked a day or more ago, or the clock went back. */\nexport function isDue(rec: UpdateRecord, now: number): boolean {\n const t = Date.parse(rec.checked_at ?? \"\");\n if (!Number.isFinite(t)) return true;\n if (t > now + 5 * 60_000) return true;\n return now - t >= DAY_MS;\n}\n\n/** Why auto-update is off for this copy, or null when it is on. */\nexport function autoUpdateOff(o: {\n env: NodeJS.ProcessEnv;\n config: Pick<Config, \"update_check\">;\n distDir: string;\n platform?: NodeJS.Platform;\n}): string | null {\n if (o.env.SESSIONPIPE_NO_UPDATE_CHECK) return \"SESSIONPIPE_NO_UPDATE_CHECK is set\";\n if (o.config.update_check === false) return \"update_check is false in config.json (`sessionpipe update on`)\";\n const prefix = globalPrefix(o.distDir, o.platform);\n if (!prefix) return \"this copy isn't a global npm install (npx, a checkout or a dev build)\";\n return unwritable(prefix, o.platform);\n}\n\n/** What `status` and `doctor` say about updating. */\nexport interface UpdateSummary {\n auto: boolean;\n /** Why updates are by hand only, or null. */\n off: string | null;\n last_check: string | null;\n latest: string | null;\n last_error: string | null;\n pending: string | null;\n updated: UpdateRecord[\"updated\"] | null;\n failed: UpdateRecord[\"failed\"] | null;\n}\n\nexport function updateSummary(o: {\n /** autoUpdateOff() for this copy, from this shell (its env aside: the daemon's counts). */\n off: string | null;\n paired: boolean;\n rec: UpdateRecord;\n}): UpdateSummary {\n const daemonEnv = o.rec.off?.startsWith(\"SESSIONPIPE_NO_UPDATE_CHECK\")\n ? \"SESSIONPIPE_NO_UPDATE_CHECK is set in the daemon's environment\"\n : null;\n const off =\n o.off ?? (o.paired ? daemonEnv : \"it runs in the control daemon, which isn't set up here (`sessionpipe connect`)\");\n return {\n auto: !off,\n off,\n last_check: o.rec.checked_at ?? null,\n latest: o.rec.latest ?? null,\n last_error: o.rec.error ?? null,\n pending: o.rec.pending ?? null,\n updated: o.rec.updated ?? null,\n failed: o.rec.failed ?? null,\n };\n}\n\nexport function ago(iso: string, now: number): string {\n const ms = now - Date.parse(iso);\n if (!Number.isFinite(ms)) return \"at an unreadable time\";\n if (ms < 90_000) return \"just now\";\n if (ms < 90 * 60_000) return `${Math.round(ms / 60_000)} min ago`;\n if (ms < 36 * 3600_000) return `${Math.round(ms / 3600_000)} h ago`;\n return `${Math.round(ms / DAY_MS)} days ago`;\n}\n\n/** One line: whether it's automatic, when it last looked, what it found. */\nexport function updateLine(s: UpdateSummary, now: number): string {\n const parts = [\n s.auto\n ? \"automatic (the control daemon checks npm once a day and installs when idle; `sessionpipe update off` stops it)\"\n : `not automatic: ${s.off}`,\n ];\n if (s.last_check)\n parts.push(\n s.last_error\n ? `last check ${ago(s.last_check, now)} failed: ${s.last_error}`\n : `last check ${ago(s.last_check, now)}: latest ${s.latest ?? \"?\"}`,\n );\n else if (s.auto) parts.push(\"not checked yet (a minute after the daemon starts)\");\n if (s.pending) parts.push(`${s.pending} waits for the daemon to be idle`);\n if (s.failed) parts.push(`installing ${s.failed.version} failed ${ago(s.failed.at, now)}: ${s.failed.error}`);\n else if (s.updated) parts.push(`updated ${s.updated.from} \u2192 ${s.updated.to} ${ago(s.updated.at, now)}`);\n return parts.join(\" \u00B7 \");\n}\n\nexport type RestartVia = \"launchd\" | \"systemd\" | \"supervisor\";\n\n/** Who restarts this process when it exits UPDATE_EXIT, or null when nobody will (it\n * then supervises the new daemon itself). A wrong \"nobody\" costs one extra process; a\n * wrong \"somebody\" would leave the machine without a daemon, so each answer is checked\n * against the process's own parentage \u2014 a variable inherited by a child of the daemon\n * (a session it started) never counts. */\nexport function restartVia(o: {\n env: NodeJS.ProcessEnv;\n platform: NodeJS.Platform;\n pid: number;\n ppid: number;\n /** /proc/self/cgroup (Linux). */\n cgroup?: () => string;\n}): RestartVia | null {\n const s = o.env.SESSIONPIPE_SERVICE ?? \"\";\n if (s.startsWith(\"supervisor:\") && s === `supervisor:${o.ppid}`) return \"supervisor\";\n if (o.platform === \"darwin\" && o.ppid === 1 && (s === \"launchd\" || o.env.XPC_SERVICE_NAME === LABEL))\n return \"launchd\";\n if (o.platform === \"linux\") {\n let cg = \"\";\n try {\n cg = (o.cgroup ?? (() => readFileSync(\"/proc/self/cgroup\", \"utf8\")))();\n } catch {}\n const inUnit = cg.split(\"\\n\").some((l) => l.endsWith(`/${UNIT}`) || l.includes(`/${UNIT}/`));\n const mainPid = !o.env.SYSTEMD_EXEC_PID || o.env.SYSTEMD_EXEC_PID === String(o.pid);\n if (inUnit && mainPid) return \"systemd\";\n }\n return null;\n}\n\n/** What the daemon offers the updater. */\nexport interface Quiescent {\n /** Null when nothing is in hand; otherwise what is. */\n busy(): string | null;\n /** Stop taking new messages (in-flight long-polls end); the receiver keeps them. */\n pauseIntake(): void;\n resumeIntake(): void;\n}\n\nexport interface UpdaterDeps {\n now: () => number;\n log: (line: string) => void;\n /** The running version. */\n version: string;\n file: string;\n /** Why it is off right now (re-read every tick: config.json may have changed). */\n off: () => string | null;\n latest: () => Promise<string>;\n /** The version of the copy on disk. */\n installed: () => Promise<string | null>;\n install: (version: string) => Promise<{ ok: true; ms: number; hooks?: string } | { ok: false; error: string }>;\n daemon: Quiescent;\n /** Stop the daemon and come back on the code on disk. Doesn't return in production. */\n restart: (from: string, to: string) => Promise<void>;\n firstCheckMs?: number;\n /** How often it looks at the clock; a check runs only when one is due. */\n tickMs?: number;\n idlePollMs?: number;\n}\n\nconst sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms).unref?.());\n\nexport class AutoUpdater {\n private first: NodeJS.Timeout | null = null;\n private every: NodeJS.Timeout | null = null;\n private stopped = false;\n private busyWith: Promise<void> | null = null;\n private lastOff: string | null | undefined = undefined;\n\n constructor(private readonly d: UpdaterDeps) {}\n\n start(): void {\n // A wait that a restart cut short is picked up again from `latest` by tick().\n if (this.record().pending) this.save({ pending: null });\n this.first = setTimeout(() => void this.tick(), this.d.firstCheckMs ?? 60_000);\n this.first.unref?.();\n // A look at the clock every ten minutes (one small file read): a machine that\n // sleeps catches up soon after it wakes, not up to an hour of awake time later.\n this.every = setInterval(() => void this.tick(), this.d.tickMs ?? 10 * 60_000);\n this.every.unref?.();\n }\n\n stop(): void {\n this.stopped = true;\n if (this.first) clearTimeout(this.first);\n if (this.every) clearInterval(this.every);\n }\n\n record(): UpdateRecord {\n return readUpdate(this.d.file);\n }\n\n private save(patch: Partial<UpdateRecord>): void {\n try {\n writePrivate(this.d.file, { ...readUpdate(this.d.file), ...patch });\n } catch {}\n }\n\n /** One look at the clock: check when a check is due and nothing is under way. */\n async tick(): Promise<void> {\n if (this.stopped || this.busyWith) return;\n const off = this.d.off();\n if (off !== this.lastOff) {\n if (off) this.d.log(`auto-update off: ${off}`);\n else if (this.lastOff) this.d.log(\"auto-update on\");\n this.lastOff = off;\n this.save({ off });\n }\n if (off) return;\n const rec = this.record();\n if (isDue(rec, this.d.now())) return this.check();\n // Not due, but the last check found a release this daemon never got to (it was\n // restarted while it waited to be idle): carry on. One that failed waits a day.\n const known = rec.latest;\n if (known && isNewer(known, this.d.version) && rec.failed?.version !== known)\n return this.guard(() => this.apply(known));\n }\n\n /** One update job at a time; whatever it throws is logged, never left unhandled. */\n private guard(job: () => Promise<void>): Promise<void> {\n if (this.busyWith) return this.busyWith;\n this.busyWith = job()\n .catch((e) => {\n if (!this.stopped) this.d.log(`update: ${String((e as Error)?.message || e)}`);\n })\n .finally(() => {\n this.busyWith = null;\n });\n return this.busyWith;\n }\n\n /** Ask npm now; when it has a newer release, install it once idle and restart. */\n check(): Promise<void> {\n return this.guard(async () => {\n const t0 = this.d.now();\n let latest: string;\n try {\n latest = await this.d.latest();\n } catch (e) {\n const error = String((e as Error)?.message || e).slice(0, 200);\n this.save({ checked_at: new Date(t0).toISOString(), latest: null, error, running: this.d.version });\n this.d.log(`update check: failed after ${this.d.now() - t0} ms: ${error}`);\n return;\n }\n const ms = this.d.now() - t0;\n this.save({ checked_at: new Date(t0).toISOString(), latest, error: null, running: this.d.version });\n if (!isNewer(latest, this.d.version)) {\n this.save({ pending: null });\n this.d.log(`update check: ${this.d.version} is current (npm latest ${latest}, ${ms} ms)`);\n return;\n }\n this.d.log(`update check: ${latest} is out (running ${this.d.version}, ${ms} ms); updating once idle`);\n await this.apply(latest);\n });\n }\n\n /** Restart onto the copy on disk once idle (`sessionpipe update` installed it). */\n restartWhenIdle(): boolean {\n if (this.stopped) return false;\n // An update under way ends the same way: on the newest copy on disk.\n if (this.busyWith) return true;\n void this.guard(async () => {\n const onDisk = await this.d.installed();\n if (!onDisk || onDisk === this.d.version) {\n this.d.log(`restart asked: the copy on disk is ${onDisk ?? \"unreadable\"}, the one running; staying`);\n return;\n }\n await this.quiesce(onDisk, false);\n await this.resumeOnError(async () => {\n this.d.log(`restart: ${this.d.version} \u2192 ${onDisk} (installed by hand)`);\n this.save({ updated: { from: this.d.version, to: onDisk, at: new Date(this.d.now()).toISOString(), ms: 0 } });\n await this.d.restart(this.d.version, onDisk);\n });\n });\n return true;\n }\n\n /** Wait until the daemon has nothing in hand, then stop its intake. A message that\n * slipped in between is let through and waited for. An automatic update turned off\n * meanwhile (`sessionpipe update off`) stops waiting. */\n private async quiesce(target: string, auto = true): Promise<void> {\n let said = false;\n for (;;) {\n let why = this.d.daemon.busy();\n while (why) {\n if (this.stopped) throw new Error(\"stopped\");\n const off = auto ? this.d.off() : null;\n if (off) {\n this.save({ pending: null });\n throw new Error(`${target} not installed: auto-update was turned off (${off})`);\n }\n if (!said) {\n this.d.log(`update: ${target} waits until the daemon is idle (${why})`);\n said = true;\n }\n await sleep(this.d.idlePollMs ?? 15_000);\n why = this.d.daemon.busy();\n }\n this.d.daemon.pauseIntake();\n if (!this.d.daemon.busy()) return;\n this.d.daemon.resumeIntake();\n }\n }\n\n /** Intake is paused from quiesce() on: whatever goes wrong after it lets it go. */\n private async resumeOnError(fn: () => Promise<void>): Promise<void> {\n try {\n await fn();\n } catch (e) {\n this.d.daemon.resumeIntake();\n throw e;\n }\n }\n\n private async apply(target: string): Promise<void> {\n this.save({ pending: target });\n await this.quiesce(target);\n await this.resumeOnError(() => this.installAndRestart(target));\n }\n\n private async installAndRestart(target: string): Promise<void> {\n const from = this.d.version;\n const t0 = this.d.now();\n const onDisk = await this.d.installed();\n let note = \"\";\n // Someone already installed it (or something newer) by hand: never install over a\n // newer copy, just restart onto what is there.\n const c = onDisk ? compareVersions(onDisk, target) : null;\n if (onDisk && c !== null && c >= 0) {\n target = onDisk;\n note = \" (already on disk)\";\n } else {\n const r = await this.d.install(target);\n if (!r.ok) {\n this.d.daemon.resumeIntake();\n const ms = this.d.now() - t0;\n this.save({\n pending: null,\n failed: { version: target, at: new Date(this.d.now()).toISOString(), error: r.error },\n });\n this.d.log(`update: ${from} \u2192 ${target} failed after ${ms} ms: ${r.error}; still running ${from}`);\n return;\n }\n if (r.hooks) note = `; ${r.hooks}`;\n }\n const ms = this.d.now() - t0;\n // Anything that came in over the socket while npm ran (a permission prompt) ends\n // first. The new copy is on disk by now, so it is restarted onto whatever happens.\n if (this.d.daemon.busy()) {\n this.d.daemon.resumeIntake();\n await this.quiesce(target, false);\n }\n this.save({\n pending: null,\n failed: null,\n updated: { from, to: target, at: new Date(this.d.now()).toISOString(), ms },\n });\n this.d.log(`update: ${from} \u2192 ${target} in ${ms} ms${note}; restarting`);\n await this.d.restart(from, target);\n }\n}\n\n/** The parent left behind when no service manager will restart the daemon: runs\n * `control run` as a child with the same env and output, starts it again when it exits\n * UPDATE_EXIT (an update) or fails (after 5 s, like the service files), and exits\n * with it when it exits cleanly or is told to stop. */\nexport function supervise(o: {\n node: string;\n args: string[];\n env: NodeJS.ProcessEnv;\n log: (line: string) => void;\n spawn?: typeof spawn;\n exit?: (code: number) => void;\n failDelayMs?: number;\n}): { stop: (sig?: NodeJS.Signals) => void } {\n const run = o.spawn ?? spawn;\n const exit = o.exit ?? ((c: number) => process.exit(c));\n const env = { ...o.env, SESSIONPIPE_SERVICE: `supervisor:${process.pid}` };\n let child: ChildProcess | null = null;\n let stopping = false;\n let later: NodeJS.Timeout | null = null;\n const start = () => {\n later = null;\n const c = run(o.node, o.args, { env, stdio: \"inherit\", windowsHide: true });\n child = c;\n let done = false;\n const ended = (code: number | null, signal: NodeJS.Signals | null) => {\n if (done) return;\n done = true;\n child = null;\n if (stopping) return exit(code ?? 0);\n if (code === UPDATE_EXIT) {\n o.log(\"the daemon is restarting onto its new version\");\n return start();\n }\n if (code === 0) return exit(0);\n o.log(`the daemon exited (${signal ?? `code ${code}`}); starting it again in 5 s`);\n later = setTimeout(start, o.failDelayMs ?? 5000);\n };\n c.on(\"exit\", ended);\n c.on(\"error\", (e) => {\n o.log(`couldn't start the daemon: ${e.message}`);\n ended(1, null);\n });\n };\n const stop = (sig: NodeJS.Signals = \"SIGTERM\") => {\n stopping = true;\n if (later) clearTimeout(later);\n if (child) child.kill(sig);\n else exit(0);\n };\n start();\n return { stop };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Updating this copy of sessionpipe from npm: what the latest release is, whether this\n// copy is one npm can update in place, and the install itself. `sessionpipe update`\n// runs it by hand; the control daemon runs it once a day (control/autoupdate.ts).\n//\n// Only a global npm install updates itself. A copy in the npx cache, a git checkout or\n// a dev build is somebody's deliberate choice of code, and npm installing over it\n// would be wrong or impossible: for those `globalPrefix` is null and nothing happens.\nimport { spawn } from \"node:child_process\";\nimport { accessSync, constants, existsSync, realpathSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { viaNpx } from \"./runtime.js\";\n\nexport const REGISTRY_LATEST = \"https://registry.npmjs.org/sessionpipe/latest\";\n\nconst VERSION_RE = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/;\n\ninterface Parsed {\n n: [number, number, number];\n pre: string | null;\n}\nfunction parse(v: string): Parsed | null {\n const m = VERSION_RE.exec(String(v).trim());\n if (!m) return null;\n return { n: [Number(m[1]), Number(m[2]), Number(m[3])], pre: m[4] ?? null };\n}\n\n/** Order two versions: <0, 0, >0, or null if either isn't one. A release sorts above\n * its own prereleases; prereleases compare by their tag. */\nexport function compareVersions(a: string, b: string): number | null {\n const x = parse(a);\n const y = parse(b);\n if (!x || !y) return null;\n for (let i = 0; i < 3; i++) if (x.n[i] !== y.n[i]) return (x.n[i] as number) - (y.n[i] as number);\n if (x.pre === y.pre) return 0;\n if (x.pre === null) return 1;\n if (y.pre === null) return -1;\n return x.pre.localeCompare(y.pre, \"en\", { numeric: true });\n}\n\n/** `a` is a release newer than `b`. A prerelease is never offered as an update: the\n * `latest` dist-tag is a release, and anything else is someone's experiment. */\nexport function isNewer(a: string, b: string): boolean {\n const x = parse(a);\n if (!x || x.pre !== null) return false;\n const c = compareVersions(a, b);\n return c !== null && c > 0;\n}\n\n/** The registry's `latest` for sessionpipe: one GET, nothing sent but the request. */\nexport async function latestVersion(f: typeof fetch = fetch, timeoutMs = 8000): Promise<string> {\n const r = await f(REGISTRY_LATEST, {\n signal: AbortSignal.timeout(timeoutMs),\n headers: { accept: \"application/json\" },\n });\n if (!r.ok) throw new Error(`the npm registry answered HTTP ${r.status}`);\n const j = (await r.json()) as { version?: unknown };\n if (typeof j.version !== \"string\" || !parse(j.version)) throw new Error(\"the npm registry named no version\");\n return j.version;\n}\n\n/** The prefix a global npm install of sessionpipe lives under, from the running copy's\n * dist folder (`<prefix>/lib/node_modules/sessionpipe/dist`, on Windows\n * `<prefix>\\node_modules\\sessionpipe\\dist`). */\nexport function prefixOf(distDir: string, platform: NodeJS.Platform = process.platform): string | null {\n const re =\n platform === \"win32\" ? /^(.*?)[\\\\/]node_modules[\\\\/]sessionpipe[\\\\/]/ : /^(.*)\\/lib\\/node_modules\\/sessionpipe\\//;\n return re.exec(`${distDir}/`)?.[1] ?? null;\n}\n\n/** The npm prefix this copy was installed into with `npm install -g`, or null when it\n * isn't a global npm install (the npx cache, a git checkout, a project's\n * node_modules, a dev build). A global install always has its bin link in the prefix. */\nexport function globalPrefix(distDir: string, platform: NodeJS.Platform = process.platform): string | null {\n if (viaNpx(distDir)) return null;\n const prefix = prefixOf(distDir, platform);\n if (!prefix) return null;\n const bin = platform === \"win32\" ? path.join(prefix, \"sessionpipe.cmd\") : path.join(prefix, \"bin\", \"sessionpipe\");\n return existsSync(bin) ? prefix : null;\n}\n\n/** Why npm can't write this prefix (installed with sudo, a read-only image), or null. */\nexport function unwritable(prefix: string, platform: NodeJS.Platform = process.platform): string | null {\n const dir = platform === \"win32\" ? path.join(prefix, \"node_modules\") : path.join(prefix, \"lib\", \"node_modules\");\n try {\n accessSync(dir, constants.W_OK);\n return null;\n } catch {\n return `${dir} isn't writable by this user (installed with sudo?)`;\n }\n}\n\n/** npm, run by this very node: under launchd PATH is /usr/bin:/bin, so neither `npm`\n * nor the `node` its shebang asks for is on it. Its npm-cli.js sits beside the node\n * binary (nvm, Homebrew, the official builds, the node Docker images). */\nexport function npmArgv(node: string, platform: NodeJS.Platform = process.platform): string[] {\n const dir = path.dirname(node);\n const candidates =\n platform === \"win32\"\n ? [path.join(dir, \"node_modules\", \"npm\", \"bin\", \"npm-cli.js\")]\n : [path.join(dir, \"npm\"), path.join(dir, \"..\", \"lib\", \"node_modules\", \"npm\", \"bin\", \"npm-cli.js\")];\n for (const c of candidates) {\n try {\n const real = realpathSync(c);\n if (real.endsWith(\".js\")) return [node, real];\n } catch {}\n }\n return [platform === \"win32\" ? \"npm.cmd\" : \"npm\"];\n}\n\nexport interface ExecResult {\n code: number | null;\n stdout: string;\n stderr: string;\n error?: string;\n}\nexport type Exec = (argv: string[], o: { env: NodeJS.ProcessEnv; timeoutMs: number }) => Promise<ExecResult>;\n\n/** Run a command to the end, keeping the tail of its output. */\nexport const execCapture: Exec = (argv, o) =>\n new Promise((resolve) => {\n const [cmd, ...rest] = argv as [string, ...string[]];\n let stdout = \"\";\n let stderr = \"\";\n const keep = (s: string, b: Buffer) => (s + b.toString(\"utf8\")).slice(-16_000);\n let child: ReturnType<typeof spawn>;\n try {\n child = spawn(cmd, rest, {\n env: o.env,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n windowsHide: true,\n shell: process.platform === \"win32\" && cmd.endsWith(\".cmd\"),\n });\n } catch (e) {\n resolve({ code: null, stdout, stderr, error: (e as Error).message });\n return;\n }\n const t = setTimeout(() => child.kill(\"SIGTERM\"), o.timeoutMs);\n child.stdout?.on(\"data\", (b: Buffer) => {\n stdout = keep(stdout, b);\n });\n child.stderr?.on(\"data\", (b: Buffer) => {\n stderr = keep(stderr, b);\n });\n child.on(\"error\", (e) => {\n clearTimeout(t);\n resolve({ code: null, stdout, stderr, error: e.message });\n });\n child.on(\"close\", (code) => {\n clearTimeout(t);\n resolve({ code, stdout, stderr });\n });\n });\n\nexport interface InstallOptions {\n /** The node running this copy (process.execPath). */\n node: string;\n /** The running copy's dist folder: where the new one lands, under the same prefix. */\n distDir: string;\n /** Harnesses whose hooks to re-arm afterwards (config.harnesses that are enabled). */\n harnesses: string[];\n env?: NodeJS.ProcessEnv;\n exec?: Exec;\n platform?: NodeJS.Platform;\n}\n\nexport type InstallResult =\n | { ok: true; ms: number; hooks: string }\n | { ok: false; ms: number; error: string; stage: \"prefix\" | \"npm\" | \"verify\" };\n\nconst lastLine = (r: ExecResult): string =>\n (r.error || r.stderr.trim().split(\"\\n\").filter(Boolean).slice(-2).join(\" \") || `exit ${r.code}`).slice(0, 300);\n\n/** The version of the copy on disk (which may not be the one running). */\nexport async function installedVersion(o: {\n node: string;\n distDir: string;\n env?: NodeJS.ProcessEnv;\n exec?: Exec;\n}): Promise<string | null> {\n const r = await (o.exec ?? execCapture)([o.node, path.join(o.distDir, \"cli.js\"), \"--version\"], {\n env: o.env ?? process.env,\n timeoutMs: 30_000,\n });\n const v = r.stdout.trim();\n return r.code === 0 && parse(v) ? v : null;\n}\n\n/** `npm install -g sessionpipe@<version>` into the prefix the running copy came from,\n * check the copy on disk says that version, then re-copy the hook launcher's files\n * (the hooks run copies in ~/.local/share/sessionpipe, which npm never touches) for\n * the harnesses already set up here. Lifecycle scripts are off: sessionpipe has none,\n * and an unattended install runs nothing it fetched. */\nexport async function installVersion(version: string, o: InstallOptions): Promise<InstallResult> {\n const t0 = Date.now();\n const platform = o.platform ?? process.platform;\n const exec = o.exec ?? execCapture;\n const base = o.env ?? process.env;\n // npm and anything it starts find this node first.\n const env = { ...base, PATH: [path.dirname(o.node), base.PATH].filter(Boolean).join(path.delimiter) };\n const prefix = globalPrefix(o.distDir, platform);\n if (!prefix)\n return { ok: false, ms: Date.now() - t0, stage: \"prefix\", error: \"this copy isn't a global npm install\" };\n const npm = npmArgv(o.node, platform);\n const r = await exec(\n [\n ...npm,\n \"install\",\n \"--global\",\n \"--prefix\",\n prefix,\n \"--ignore-scripts\",\n \"--no-audit\",\n \"--no-fund\",\n `sessionpipe@${version}`,\n ],\n { env, timeoutMs: 5 * 60_000 },\n );\n if (r.code !== 0) return { ok: false, ms: Date.now() - t0, stage: \"npm\", error: `npm install: ${lastLine(r)}` };\n const now = await installedVersion({ node: o.node, distDir: o.distDir, env, exec });\n if (now !== version)\n return {\n ok: false,\n ms: Date.now() - t0,\n stage: \"verify\",\n error: `npm finished, but the copy in ${prefix} says ${now ?? \"nothing\"}, not ${version}`,\n };\n let hooks = \"no harness set up here; nothing to re-arm\";\n if (o.harnesses.length) {\n const h = await exec(\n [o.node, path.join(o.distDir, \"cli.js\"), \"install\", \"--backfill\", \"0\", ...o.harnesses.map((n) => `--${n}`)],\n { env, timeoutMs: 2 * 60_000 },\n );\n hooks =\n h.code === 0\n ? `hooks re-armed for ${o.harnesses.join(\", \")}`\n : `re-arming the hooks failed (${lastLine(h)}); \\`sessionpipe install\\` does it`;\n }\n return { ok: true, ms: Date.now() - t0, hooks };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Persistent paths shared by hook installation and control pairing.\nimport { execFileSync } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { VERSION } from \"./run.js\";\n\n/** Homebrew's versioned Cellar path dies on `brew upgrade node`; its stable links survive. */\nexport function stableNode(exe: string): string {\n const m = /^(.*)\\/Cellar\\/(node(?:@\\d+)?)\\/[^/]+\\/bin\\/node$/.exec(exe);\n if (!m) return exe;\n let real: string;\n try {\n real = realpathSync(exe);\n } catch {\n return exe;\n }\n for (const c of [`${m[1]}/opt/${m[2]}/bin/node`, `${m[1]}/bin/node`]) {\n try {\n if (realpathSync(c) === real) return c;\n } catch {}\n }\n return exe;\n}\n\nexport function viaNpx(distDir: string): boolean {\n return /[\\\\/]_npx[\\\\/]/.test(distDir) || /[\\\\/]\\.npm[\\\\/]/.test(distDir);\n}\n\n/** Install the running version persistently and hand off the original command before side effects. */\nexport function rerunGlobally(argv: string[], out: (s: string) => void): void {\n out(` Installing sessionpipe@${VERSION} globally, so hooks and services use a persistent copy\u2026`);\n let bin: string;\n try {\n // Homebrew's default prefix is the versioned Cellar folder that `brew upgrade\n // node` deletes, and its bin is not on PATH (issue #13): install into ~/.local\n // there, and run the copy from the prefix we installed into.\n let prefix = \"\";\n try {\n prefix = execFileSync(\"npm\", [\"prefix\", \"-g\"], {\n encoding: \"utf8\",\n timeout: 15000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n } catch {}\n const target = /\\/Cellar\\/node(?:@\\d+)?\\/[^/]+/.test(prefix) ? path.join(os.homedir(), \".local\") : prefix;\n execFileSync(\"npm\", [\"install\", \"-g\", `sessionpipe@${VERSION}`, ...(target ? [\"--prefix\", target] : [])], {\n stdio: [\"ignore\", \"ignore\", \"inherit\"],\n });\n bin =\n process.platform === \"win32\"\n ? path.join(target, \"sessionpipe.cmd\")\n : target\n ? path.join(target, \"bin\", \"sessionpipe\")\n : \"sessionpipe\";\n if (target && target !== prefix)\n out(` Installed into ${target}; make sure ${path.join(target, \"bin\")} is on your PATH.`);\n } catch {\n out(\n \" ! couldn't install globally (`npm install -g sessionpipe` failed). Run it yourself, then retry this command.\",\n );\n process.exit(1);\n }\n // The command's own failure (a pairing that expired) is its own to report, not an\n // install that failed: it has said why; pass its exit status on.\n try {\n execFileSync(bin, argv, { stdio: \"inherit\", shell: process.platform === \"win32\" });\n } catch (e) {\n process.exit(typeof (e as { status?: unknown }).status === \"number\" ? (e as { status: number }).status : 1);\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// What a worker run does, as a function so tests and `sessionpipe replay` share it.\nimport {\n appendFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport {\n adapterByName,\n Cursors,\n type Event,\n type FactsState,\n FileSink,\n filterEvent,\n gitFacts,\n machineName,\n makeEvent,\n Outbox,\n readConfig,\n redactDeep,\n type Session,\n type Sink,\n type SinkConfig,\n StdoutSink,\n safeId,\n stateDir,\n takeLock,\n tilde,\n writeConfig,\n} from \"@sessionpipe/core\";\nimport { ask, socketPath } from \"./control/local.js\";\nimport { HttpSink } from \"./http-sink.js\";\nimport { sinkWithSecrets } from \"./secrets.js\";\n\nasync function tellDaemon(state: string, job: Job, session: string, transcript?: string): Promise<void> {\n const sock = socketPath(state);\n if (process.platform !== \"win32\" && !existsSync(sock)) return;\n await ask(\n sock,\n {\n op: \"event\",\n session: `claude-code:${session}`,\n event: job.event,\n cwd: job.cwd,\n ...(transcript ? { transcript } : {}),\n },\n 300,\n );\n}\n\ndeclare const __SESSIONPIPE_VERSION__: string;\nconst VERSION = typeof __SESSIONPIPE_VERSION__ === \"string\" ? __SESSIONPIPE_VERSION__ : \"0.0.0\";\n\nexport interface Job {\n harness: string;\n event: string;\n argv: string[];\n stdin: string;\n cwd: string;\n env: Record<string, string>;\n ppid?: number;\n at: number;\n}\n\n/** A job file the worker will pick up: random suffix, 0600, in a 0700 dir. */\nexport function enqueueJob(state: string, job: Job): string {\n const jobs = jobsDir(state);\n mkdirSync(jobs, { recursive: true, mode: 0o700 });\n const f = path.join(jobs, `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}.json`);\n writeFileSync(f, JSON.stringify(job), { mode: 0o600 });\n return f;\n}\n\n/** Jobs another worker left behind (a lost lock race, a killed worker): every\n * worker sweeps the ones older than `olderThanMs` before it exits, so no event\n * is lost (ground rule 4). Each is removed before it runs, so two sweepers\n * never run one twice. */\nexport async function sweepJobs(state: string, olderThanMs = 3000, limit = 20): Promise<number> {\n const jobs = jobsDir(state);\n let names: string[] = [];\n try {\n names = readdirSync(jobs).filter((n) => n.endsWith(\".json\"));\n } catch {\n return 0;\n }\n let ran = 0;\n for (const n of names.sort().slice(0, limit)) {\n const f = path.join(jobs, n);\n let job: Job | null = null;\n try {\n if (Date.now() - statSync(f).mtimeMs < olderThanMs) continue;\n job = JSON.parse(readFileSync(f, \"utf8\")) as Job;\n unlinkSync(f);\n } catch {\n continue;\n }\n await runJob(job, { state }).catch(() => {});\n ran++;\n }\n return ran;\n}\n\nexport function log(state: string, line: string): void {\n try {\n mkdirSync(state, { recursive: true, mode: 0o700 });\n const f = path.join(state, \"log\");\n try {\n if (statSync(f).size > 1024 * 1024) renameSync(f, `${f}.1`);\n } catch {}\n appendFileSync(f, `${new Date().toISOString()} ${line}\\n`);\n } catch {}\n}\n\n/** <state>/facts/<harness>/<session>.json \u2014 what the machine learned about a session. */\nexport function factsState(state: string): FactsState {\n const file = (h: string, s: string) => path.join(state, \"facts\", safeId(h), `${safeId(s)}.json`);\n return {\n get(h, s) {\n try {\n return JSON.parse(readFileSync(file(h, s), \"utf8\")) as Record<string, unknown>;\n } catch {\n return {};\n }\n },\n save(h, s, patch) {\n const cur = this.get(h, s);\n const next = { ...cur, ...patch };\n if (JSON.stringify(next) === JSON.stringify(cur)) return;\n mkdirSync(path.dirname(file(h, s)), { recursive: true, mode: 0o700 });\n writeFileSync(file(h, s), JSON.stringify(next), { mode: 0o600 });\n },\n };\n}\n\nexport function buildSinks(sinks: SinkConfig[], o: { locked?: (name: string) => void } = {}): Sink[] {\n const out: Sink[] = [];\n for (const raw of sinks) {\n if (raw.paused) continue;\n // A token kept in a keychain is read now; one this process can't read (a keychain\n // locked in an ssh session) leaves the sink's events waiting, never sent unsigned.\n const s = sinkWithSecrets(raw);\n if (!s) {\n o.locked?.(raw.name);\n continue;\n }\n const tier = Math.min(s.tier, s.max_tier ?? 3) as 0 | 1 | 2 | 3;\n if (s.url === \"stdout\") out.push(new StdoutSink(s.name, tier, !!s.pii));\n else if (s.url.startsWith(\"file:\"))\n out.push(new FileSink(s.name, s.url.slice(5).replace(/^~(?=\\/|$)/, os.homedir()), tier, !!s.pii));\n else if (/^https?:\\/\\//.test(s.url)) out.push(new HttpSink(s, tier));\n }\n return out;\n}\n\n/** Run one hook job end to end: events \u2192 outbox \u2192 sinks. Returns what happened. */\nexport async function runJob(\n job: Job,\n opts: { state?: string; now?: number } = {},\n): Promise<{ events: Event[]; delivered: Record<string, number> }> {\n const state = opts.state ?? stateDir();\n const cfg = readConfig();\n const adapter = adapterByName(job.harness);\n if (!adapter) return { events: [], delivered: {} };\n const r = adapter.fromHook({ argv: job.argv, stdin: job.stdin, env: { ...process.env, ...job.env }, cwd: job.cwd });\n if (!r || !r.session.id) return { events: [], delivered: {} };\n // The control daemon learns each Claude Code session's turn state from its events\n // (a message for a session mid-turn waits for its Stop; a pending permission prompt\n // closes when the tool runs). A local round trip, and nothing when no daemon runs.\n if (job.harness === \"claude-code\") await tellDaemon(state, job, r.session.id, r.transcript);\n const outbox = new Outbox(state);\n const ref = { harness: job.harness, session: r.session.id };\n // Hooks of one session fire close together (parallel subagents, issue #9): wait\n // for the lock with a short backoff before giving the job back to the queue.\n let release = takeLock(state, ref);\n for (let wait = 50; !release && wait <= 3200; wait *= 2) {\n await new Promise((res) => setTimeout(res, wait));\n release = takeLock(state, ref);\n }\n if (!release) {\n log(state, `${job.harness} ${job.event}: session ${r.session.id} locked for 6 s, re-queued`);\n enqueueJob(state, job);\n return { events: [], delivered: {} };\n }\n try {\n const facts = factsState(state);\n const mem = facts.get(job.harness, r.session.id);\n // Heartbeat-class events read no facts (they fire every tool call); the rest refresh them.\n const heavy = !/^(PreToolUse|PostToolUse|PostToolUseFailure|BeforeTool|AfterTool|PostInvocation)$/.test(job.event);\n let learned: Partial<Session> = {};\n if (heavy) {\n const f = adapter.facts(r.session, r.transcript, r.hints ?? {}, facts);\n const { started_at: _s, last_at: _l, first_ask: _fa, harness_version, ...rest } = f;\n learned = rest;\n if (harness_version) facts.save(job.harness, r.session.id, { harness_version });\n facts.save(job.harness, r.session.id, { session: { ...(mem.session as object), ...learned } });\n }\n const known = (mem.session as Partial<Session> | undefined) ?? {};\n const cwdRaw = learned.cwd ?? r.session.cwd ?? known.cwd;\n const git = heavy ? gitFacts(cwdRaw) : {};\n const session: Session = {\n ...known,\n ...learned,\n ...git,\n ...(learned.branch ? { branch: learned.branch } : {}),\n id: r.session.id,\n seq: 0,\n machine: machineName(cfg, os.hostname()),\n ...(cwdRaw ? { cwd: tilde(cwdRaw) } : {}),\n ...(r.session.model ? { model: r.session.model } : {}),\n };\n const version = (facts.get(job.harness, r.session.id).harness_version as string | undefined) ?? undefined;\n const events: Event[] = [];\n for (const a of r.events) {\n const e = makeEvent(a, {\n harness: { name: job.harness, ...(version ? { version } : {}) },\n session: { ...session, seq: outbox.nextSeq(ref) },\n now: opts.now ?? job.at,\n });\n events.push(e);\n }\n // Tier 2: after a turn ends, the transcript's new turns become turn.transcript events.\n const wantsTranscript = cfg.sinks.some((s) => !s.paused && Math.min(s.tier, s.max_tier ?? 3) >= 2);\n if (\n wantsTranscript &&\n r.transcript &&\n r.events.some((e) => e.type === \"turn.ended\" || e.type === \"session.ended\")\n ) {\n const cur = facts.get(job.harness, r.session.id);\n const fromLine = Number(cur.transcript_line) || 0;\n let turnNo = Number(cur.transcript_turns) || 0;\n const read = adapter.readTranscript(r.transcript, fromLine);\n for (const t of read.turns) {\n events.push(\n makeEvent(\n {\n type: \"turn.transcript\",\n harnessEvent: job.event,\n data: { turn: turnNo++, user: t.user, assistant: t.assistant, at: new Date(t.at).toISOString() },\n },\n {\n harness: { name: job.harness, ...(version ? { version } : {}) },\n session: { ...session, seq: outbox.nextSeq(ref) },\n now: opts.now ?? job.at,\n },\n ),\n );\n }\n if (read.turns.length)\n facts.save(job.harness, r.session.id, { transcript_line: read.line, transcript_turns: turnNo });\n }\n // At rest the outbox holds redacted strings (advisory GHSA-8f6f-c3c9-j5p6): the\n // tier-3 fields stay, with their secrets already gone; filterEvent runs the same\n // idempotent pass again per sink.\n outbox.append(\n ref,\n events.map((e) => ({ ...e, session: redactDeep(e.session), data: redactDeep(e.data) })),\n );\n log(\n state,\n `${job.harness} ${job.event}: ${events.map((e) => e.type).join(\",\") || \"nothing\"} (${r.session.id.slice(0, 8)})`,\n );\n const delivered = await flush(state, cfg.sinks, outbox, ref);\n if (Math.random() < 0.02) outbox.prune(cfg.keep_days ?? 30);\n return { events, delivered };\n } finally {\n release();\n }\n}\n\nconst BATCH = 50;\nconst MAX_PER_RUN = 500;\n\n/** Drain every sink from its cursor: this session first, then any backlog. Events\n * from many sessions are packed into one batch of up to BATCH, so a first\n * install's 400-session backfill is nine POSTs, not four hundred (the receiver's\n * write limit ended the first replay at 278 events, 2026-09-28). A cursor moves\n * only after its batch was acknowledged; a refused batch stops the sink for this\n * run and the next worker starts from the same cursors. */\nexport async function flush(\n state: string,\n sinkConfigs: SinkConfig[],\n outbox: Outbox,\n first?: { harness: string; session: string },\n): Promise<Record<string, number>> {\n const delivered: Record<string, number> = {};\n const sinks = buildSinks(sinkConfigs, {\n locked: (name) => log(state, `sink ${name}: its token is in a keychain this process can't read; left for later`),\n });\n const refs = outbox.sessions();\n if (first) {\n const k = `${first.harness}/${safeId(first.session)}`;\n refs.sort((a, b) => (`${a.harness}/${a.session}` === k ? -1 : `${b.harness}/${b.session}` === k ? 1 : 0));\n }\n for (const sink of sinks) {\n const cursors = new Cursors(state, sink.name);\n const c = cursors.read();\n let sent = 0;\n let stalled = false;\n // Pull filtered events session by session into one batch; remember where each\n // session's offset would land if the batch goes through.\n let batch: Event[] = [];\n let pending: Record<string, number> = {};\n const send = async (): Promise<boolean> => {\n if (!batch.length) {\n Object.assign(c, pending);\n pending = {};\n cursors.write(c);\n return true;\n }\n const res = await sink.send(batch);\n if (!res.ok) {\n log(state, `sink ${sink.name}: ${res.status ?? \"\"} ${res.error ?? \"\"} \u2192 ${res.action ?? \"retry\"}`);\n if (res.action === \"pause\" || res.action === \"lower-tier\") applySinkVerdict(sink.name, res);\n if (res.action !== \"drop\") {\n batch = [];\n pending = {};\n return false;\n }\n }\n sent += batch.length;\n Object.assign(c, pending);\n cursors.write(c);\n batch = [];\n pending = {};\n return true;\n };\n for (const ref of refs) {\n if (stalled || sent >= MAX_PER_RUN) break;\n let offset = pending[cursors.key(ref)] ?? c[cursors.key(ref)] ?? 0;\n for (;;) {\n const room = BATCH - batch.length;\n const { events, offset: next } = outbox.read(ref, offset, room);\n if (!events.length) break;\n for (const e of events) {\n const f = filterEvent(e, sink.tier, sink.pii, { home: os.homedir() });\n if (f) batch.push(f);\n }\n offset = next;\n pending[cursors.key(ref)] = offset;\n if (batch.length >= BATCH) {\n if (!(await send())) {\n stalled = true;\n break;\n }\n if (sent >= MAX_PER_RUN) break;\n }\n }\n }\n if (!stalled && (batch.length || Object.keys(pending).length)) if (!(await send())) stalled = true;\n delivered[sink.name] = sent;\n }\n return delivered;\n}\n\nfunction applySinkVerdict(name: string, res: { action?: string; max_tier?: number; error?: string }): void {\n try {\n const cfg = readConfig();\n const s = cfg.sinks.find((x) => x.name === name);\n if (!s) return;\n if (res.action === \"pause\") s.paused = `${new Date().toISOString()} ${res.error ?? \"unauthorized\"}`;\n if (res.action === \"lower-tier\" && typeof res.max_tier === \"number\") s.max_tier = res.max_tier as 0 | 1 | 2 | 3;\n writeConfig(cfg);\n } catch {}\n}\n\nexport { VERSION };\nexport const versionLine = (): string => `sessionpipe ${VERSION}`;\nexport const jobsDir = (state: string): string => path.join(state, \"jobs\");\nexport const hasJobs = (state: string): boolean => existsSync(jobsDir(state));\n", "// SPDX-License-Identifier: Apache-2.0\n// The daemon's local socket (spec/CONTROL.md \u00A78): how the waiter, the Stop and\n// PermissionRequest hooks and the worker talk to the one daemon on this machine.\n// Line-delimited JSON, one request per connection. A Unix socket in the state\n// directory (0600, in a 0700 dir); a per-user named pipe on Windows. Only node:\n// builtins \u2014 the hook bundle imports this.\nimport net from \"node:net\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nexport type LocalRequest =\n /** A waiter parks until a message for its session arrives. */\n | { op: \"wait\"; session: string; pid?: number }\n /** A Stop hook asks for a queued message (turn mode). */\n | { op: \"stop\"; session: string; active: boolean }\n /** A PermissionRequest hook parks until a verified answer, or until it's released. */\n | { op: \"permission\"; session: string; attention: string; tool?: string }\n /** The worker reports a hook event: turn state and attention closure. */\n | { op: \"event\"; session: string; event: string; transcript?: string; cwd?: string }\n /** `sessionpipe control status`. */\n | { op: \"status\" }\n /** `sessionpipe update` installed a new copy: restart onto it once nothing is in hand. */\n | { op: \"restart\" };\n\nexport type LocalReply =\n | { op: \"message\"; text: string; id: string }\n | { op: \"block\"; reason: string; id: string }\n | { op: \"decision\"; behavior: \"allow\" | \"deny\"; message?: string; id: string }\n | { op: \"none\" }\n /** A newer waiter for the same session took over; this one stops. */\n | { op: \"replaced\" }\n | { op: \"ok\" }\n | { op: \"status\"; status: unknown };\n\n/** Where the daemon listens. `SESSIONPIPE_SOCKET` overrides (tests). */\nexport function socketPath(state: string, env: NodeJS.ProcessEnv = process.env): string {\n if (env.SESSIONPIPE_SOCKET) return env.SESSIONPIPE_SOCKET;\n if (process.platform === \"win32\") return `\\\\\\\\.\\\\pipe\\\\sessionpipe-control-${os.userInfo().username}`;\n return path.join(state, \"control.sock\");\n}\n\n/** One request, one reply. `timeoutMs` bounds the whole exchange; null on any\n * failure (no daemon, a timeout, a garbled reply) \u2014 callers treat that as \"none\". */\nexport function ask(sock: string, req: LocalRequest, timeoutMs: number): Promise<LocalReply | null> {\n return new Promise((resolve) => {\n let buf = \"\";\n let done = false;\n const s = net.connect(sock);\n const finish = (r: LocalReply | null) => {\n if (done) return;\n done = true;\n clearTimeout(t);\n s.destroy();\n resolve(r);\n };\n const t = setTimeout(() => finish(null), timeoutMs);\n s.on(\"connect\", () => s.write(`${JSON.stringify(req)}\\n`));\n s.on(\"data\", (d) => {\n buf += d.toString(\"utf8\");\n const i = buf.indexOf(\"\\n\");\n if (i < 0) return;\n try {\n finish(JSON.parse(buf.slice(0, i)) as LocalReply);\n } catch {\n finish(null);\n }\n });\n s.on(\"error\", () => finish(null));\n s.on(\"close\", () => finish(null));\n });\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The HTTP sink (spec/HTTP.md \u00A72): POST {events} with the protocol header, a bearer\n// token and optional Standard Webhooks signature; errors map to what the sender\n// does next. The cursor moves only on 202. Retry/backoff is the worker's cadence\n// (each hook run drains the backlog); this class reports, it does not sleep.\nimport { createHash, createHmac } from \"node:crypto\";\nimport type { DeliveryResult, Event, Sink, SinkConfig, Tier } from \"@sessionpipe/core\";\n\nconst TIMEOUT_MS = 15_000;\n\n/** The Standard Webhooks message id (HTTP.md \u00A72): the same batch sent again carries\n * the same id, so a receiver that dedupes on webhook-id sees a retry as one message.\n * Derived from the events' own ids, which the outbox keeps across retries. */\nexport function webhookId(events: Pick<Event, \"id\">[]): string {\n return `msg_${createHash(\"sha256\")\n .update(events.map((e) => e.id).join(\",\"))\n .digest(\"base64url\")\n .slice(0, 32)}`;\n}\n\nexport class HttpSink implements Sink {\n readonly name: string;\n readonly pii: boolean;\n private readonly url: string;\n constructor(\n private readonly cfg: SinkConfig,\n readonly tier: Tier,\n ) {\n this.name = cfg.name;\n this.pii = !!cfg.pii;\n this.url = cfg.url.replace(/\\/$/, \"\");\n }\n\n private eventsUrl(): string {\n // The endpoint from the well-known file is stored beside the url at `sink add`;\n // until then the spec's default path.\n const ep = (this.cfg as { endpoints?: { events?: string } }).endpoints?.events ?? \"/api/sessionpipe/v1/events\";\n return /^https?:\\/\\//.test(ep) ? ep : this.url + ep;\n }\n\n async send(events: Event[]): Promise<DeliveryResult> {\n const body = JSON.stringify({ events });\n const headers: Record<string, string> = { \"content-type\": \"application/json\", \"sessionpipe-protocol\": \"1\" };\n if (this.cfg.token) headers.authorization = `Bearer ${this.cfg.token}`;\n if (this.cfg.secret?.startsWith(\"whsec_\")) {\n const id = webhookId(events);\n const ts = Math.floor(Date.now() / 1000);\n const key = Buffer.from(this.cfg.secret.slice(6), \"base64\");\n const sig = createHmac(\"sha256\", key).update(`${id}.${ts}.${body}`).digest(\"base64\");\n headers[\"webhook-id\"] = id;\n headers[\"webhook-timestamp\"] = String(ts);\n headers[\"webhook-signature\"] = `v1,${sig}`;\n }\n const ctl = new AbortController();\n const t = setTimeout(() => ctl.abort(), TIMEOUT_MS);\n try {\n const r = await fetch(this.eventsUrl(), { method: \"POST\", headers, body, signal: ctl.signal });\n const text = await r.text();\n let j: Record<string, unknown> = {};\n try {\n j = text ? (JSON.parse(text) as Record<string, unknown>) : {};\n } catch {}\n if (r.status === 202 || r.status === 200) {\n return {\n ok: true,\n acknowledged: events.length,\n accepted: Number(j.accepted ?? events.length),\n duplicates: Number(j.duplicates ?? 0),\n rejected: Array.isArray(j.rejected) ? (j.rejected as { id: string; reason: string }[]) : [],\n ...(typeof j.max_tier === \"number\" ? { max_tier: j.max_tier as Tier } : {}),\n status: r.status,\n };\n }\n const err = typeof j.reason === \"string\" ? j.reason : text.slice(0, 200);\n if (r.status === 400) return { ok: false, acknowledged: 0, status: 400, error: err, action: \"drop\" };\n if (r.status === 401) return { ok: false, acknowledged: 0, status: 401, error: err, action: \"pause\" };\n if (r.status === 403)\n return {\n ok: false,\n acknowledged: 0,\n status: 403,\n error: err,\n action: \"lower-tier\",\n ...(typeof j.max_tier === \"number\" ? { max_tier: j.max_tier as Tier } : {}),\n };\n if (r.status === 413) return { ok: false, acknowledged: 0, status: 413, error: err, action: \"split\" };\n if (r.status === 429)\n return {\n ok: false,\n acknowledged: 0,\n status: 429,\n error: err,\n action: \"retry\",\n retryAfterMs: Number(r.headers.get(\"retry-after\") ?? 60) * 1000,\n };\n return { ok: false, acknowledged: 0, status: r.status, error: err, action: \"retry\" };\n } catch (e) {\n return { ok: false, acknowledged: 0, error: String((e as Error).message ?? e), action: \"retry\" };\n } finally {\n clearTimeout(t);\n }\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Where this machine's secrets live: each sink's token (and Webhooks secret) and each\n// paired receiver's machine token. In the operating system's keychain when this person\n// has one unlocked \u2014 the macOS Keychain, or the Secret Service (GNOME Keyring, KWallet)\n// in a Linux desktop session \u2014 and otherwise in config.json / control.json at mode\n// 0600, which is all a headless server has (the same as ~/.ssh). A secret in a store\n// leaves `token_in` in the file and no token.\n//\n// What a store protects against, plainly: a dotfiles repo, a backup, a synced\n// ~/.config, a `cat` over a shoulder. Not a program running as you: `security` hands an\n// item it wrote back without asking, which is also how the hook's worker reads it.\n\nimport { spawnSync } from \"node:child_process\";\nimport { createHash, randomBytes } from \"node:crypto\";\nimport { configFile, readConfig, type SinkConfig, writeConfig } from \"@sessionpipe/core\";\n\nexport type SecretStore = \"keychain\" | \"secret-service\";\nexport type StoreName = SecretStore | \"file\";\n\nconst SERVICE = \"sessionpipe\";\n\nexport type Runner = (cmd: string, args: string[], input?: string) => { status: number | null; stdout: string };\nexport const defaultRunner: Runner = (cmd, args, input) => {\n const r = spawnSync(cmd, args, {\n input: input ?? \"\",\n encoding: \"utf8\",\n timeout: 8000,\n stdio: [\"pipe\", \"pipe\", \"ignore\"],\n });\n return { status: r.error ? null : r.status, stdout: r.stdout ?? \"\" };\n};\n\n/** A sink's item. The machine has one config, so a sink's name is enough \u2014 except\n * where SESSIONPIPE_CONFIG points at another (a second profile, a test): then the\n * item names that config too, so two configs' sinks of one name never share a key. */\nexport const sinkAccount = (name: string, what: \"token\" | \"secret\" = \"token\"): string => {\n const scope = process.env.SESSIONPIPE_CONFIG\n ? `@${createHash(\"sha256\").update(configFile()).digest(\"hex\").slice(0, 8)}`\n : \"\";\n return `sink:${name}:${what}${scope}`;\n};\nexport const controlAccount = (machine: string): string => `control:${machine}`;\n\n/** `security -i` reads its commands from stdin, so the value never sits in argv (and in\n * `ps`). Its parser takes double-quoted words: a value with a quote, a backslash or a\n * space isn't stored there and stays in the file. */\nconst KC_SAFE = /^[\\x21\\x23-\\x5b\\x5d-\\x7e]{1,4096}$/;\nconst NAME_SAFE = /^[\\x20\\x21\\x23-\\x5b\\x5d-\\x7e]{1,200}$/;\n\nexport function secretGet(store: SecretStore, account: string, run: Runner = defaultRunner): string | null {\n const r =\n store === \"keychain\"\n ? run(\"security\", [\"find-generic-password\", \"-s\", SERVICE, \"-a\", account, \"-w\"])\n : run(\"secret-tool\", [\"lookup\", \"service\", SERVICE, \"account\", account]);\n if (r.status !== 0) return null;\n const v = r.stdout.replace(/\\r?\\n$/, \"\");\n return v || null;\n}\n\nexport function secretSet(store: SecretStore, account: string, value: string, run: Runner = defaultRunner): boolean {\n if (store === \"keychain\") {\n if (!KC_SAFE.test(value) || !NAME_SAFE.test(account)) return false;\n run(\n \"security\",\n [\"-i\"],\n `add-generic-password -U -s ${SERVICE} -a \"${account}\" -l \"${SERVICE} ${account}\" -w \"${value}\"\\n`,\n );\n } else {\n run(\"secret-tool\", [\"store\", \"--label\", `${SERVICE} ${account}`, \"service\", SERVICE, \"account\", account], value);\n }\n // Trust only a read-back: `security -i` exits 0 whatever its commands did.\n return secretGet(store, account, run) === value;\n}\n\nexport function secretDel(store: SecretStore, account: string, run: Runner = defaultRunner): void {\n if (store === \"keychain\") run(\"security\", [\"delete-generic-password\", \"-s\", SERVICE, \"-a\", account]);\n else run(\"secret-tool\", [\"clear\", \"service\", SERVICE, \"account\", account]);\n}\n\n/** Can this process write, read back and delete an item in the store right now? */\nexport function probe(store: SecretStore, run: Runner = defaultRunner): boolean {\n const account = `probe:${randomBytes(6).toString(\"hex\")}`;\n const ok = secretSet(store, account, randomBytes(12).toString(\"base64url\"), run);\n secretDel(store, account, run);\n return ok;\n}\n\n/** The best place for secrets on this machine, from this session. SESSIONPIPE_SECRETS\n * (file | keychain | secret-service) overrides. The Secret Service is used only in a\n * desktop session: on a server its keyring is locked whenever nobody is logged in,\n * which is exactly when the daemon needs its token. */\nexport function bestStore(\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n run: Runner = defaultRunner,\n): StoreName {\n const want = env.SESSIONPIPE_SECRETS;\n if (want === \"file\") return \"file\";\n const candidates: SecretStore[] =\n want === \"keychain\" || want === \"secret-service\"\n ? [want]\n : platform === \"darwin\"\n ? [\"keychain\"]\n : platform === \"linux\" && env.DBUS_SESSION_BUS_ADDRESS && (env.DISPLAY || env.WAYLAND_DISPLAY)\n ? [\"secret-service\"]\n : [];\n for (const s of candidates) if (probe(s, run)) return s;\n return \"file\";\n}\n\nexport const storeLabel = (s: StoreName | undefined): string =>\n s === \"keychain\" ? \"the macOS Keychain\" : s === \"secret-service\" ? \"the Secret Service keyring\" : \"a 0600 file\";\n\n/** The sink with its token and secret filled in from its store. Null when they live in\n * a store this process can't read right now (a keychain locked in an ssh session):\n * the caller leaves the events in the outbox rather than sending them unsigned. */\nexport function sinkWithSecrets(s: SinkConfig, run: Runner = defaultRunner): SinkConfig | null {\n if (!s.token_in) return s;\n const token = secretGet(s.token_in, sinkAccount(s.name), run);\n if (!token) return null;\n const secret = secretGet(s.token_in, sinkAccount(s.name, \"secret\"), run);\n return { ...s, token, ...(secret ? { secret } : {}) };\n}\n\n/** Store a sink's secrets in `to` (or back in the file) and save the config. */\nexport function moveSinkSecrets(\n to: StoreName,\n o: { run?: Runner; file?: string } = {},\n): { moved: string[]; kept: string[] } {\n const run = o.run ?? defaultRunner;\n const cfg = o.file ? readConfig(o.file) : readConfig();\n const moved: string[] = [];\n const kept: string[] = [];\n for (const s of cfg.sinks) {\n const from = s.token_in;\n if ((from ?? \"file\") === to) continue;\n const full = sinkWithSecrets(s, run);\n if (!full) {\n kept.push(s.name);\n continue;\n }\n if (!full.token && !full.secret) continue;\n if (to === \"file\") {\n if (full.token) s.token = full.token;\n if (full.secret) s.secret = full.secret;\n delete s.token_in;\n } else {\n const ok =\n (!full.token || secretSet(to, sinkAccount(s.name), full.token, run)) &&\n (!full.secret || secretSet(to, sinkAccount(s.name, \"secret\"), full.secret, run));\n if (!ok) {\n secretDel(to, sinkAccount(s.name), run);\n secretDel(to, sinkAccount(s.name, \"secret\"), run);\n kept.push(s.name);\n continue;\n }\n delete s.token;\n delete s.secret;\n s.token_in = to;\n }\n moved.push(s.name);\n if (from) {\n // Written first, then the file says where; only then is the old copy dropped.\n if (o.file) writeConfig(cfg, o.file);\n else writeConfig(cfg);\n secretDel(from, sinkAccount(s.name), run);\n secretDel(from, sinkAccount(s.name, \"secret\"), run);\n }\n }\n if (o.file) writeConfig(cfg, o.file);\n else writeConfig(cfg);\n return { moved, kept };\n}\n\n/** Forget a sink's secrets wherever they are (sink remove, uninstall). */\nexport function dropSinkSecrets(s: SinkConfig, run: Runner = defaultRunner): void {\n if (!s.token_in) return;\n secretDel(s.token_in, sinkAccount(s.name), run);\n secretDel(s.token_in, sinkAccount(s.name, \"secret\"), run);\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// What the control daemon keeps on disk:\n// config/control.json the receivers this machine is paired with: machine id,\n// the machine's own token, the enrolled keys, folders, mode (0600)\n// state/control/nonces.jsonl every verified nonce for 25 h, fsync'd before a\n// command runs (a failed write refuses it)\n// state/control/acks.jsonl acks not yet accepted by their receiver\n// state/control/state.json forks: which copy a message to a session goes to\nimport {\n appendFileSync,\n chmodSync,\n closeSync,\n existsSync,\n fsyncSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n writeFileSync,\n} from \"node:fs\";\nimport path from \"node:path\";\nimport { configFile, stateDir } from \"@sessionpipe/core\";\nimport { NONCE_TTL_MS, type TrustedKey } from \"@sessionpipe/core/control\";\nimport {\n controlAccount,\n defaultRunner,\n type Runner,\n type SecretStore,\n type StoreName,\n secretDel,\n secretGet,\n secretSet,\n} from \"../secrets.js\";\n\nexport interface PairedReceiver {\n /** The receiver's origin, as the person typed it. */\n url: string;\n /** Absolute control endpoint (from the well-known file). */\n control: string;\n rpId: string;\n machine: string;\n /** The machine's own bearer (polls, acks, hello, off): opens nothing else. Empty\n * when it lives in a store this process can't read right now. */\n token: string;\n /** The token lives in this store, not in control.json (secrets.ts). */\n token_in?: SecretStore;\n keys: (TrustedKey & { name?: string; added_at: string })[];\n paired_at: string;\n}\n\nexport interface ControlConfig {\n name: string;\n /** Folders sessions may run in; compared on whole path segments, real paths. */\n folders: string[];\n mode: \"safe\" | \"auto\";\n receivers: PairedReceiver[];\n /** Caps this machine keeps whatever a receiver sends (defaults in daemon.ts,\n * LIMITS): new sessions running at once and per hour, headless Claude Code runs\n * at once. */\n limits?: { start_concurrent?: number; start_per_hour?: number; headless?: number };\n}\n\nexport const controlFile = (env: NodeJS.ProcessEnv = process.env) =>\n path.join(path.dirname(configFile(env)), \"control.json\");\nexport const controlState = (env: NodeJS.ProcessEnv = process.env) => path.join(stateDir(env), \"control\");\n\nexport function writePrivate(file: string, value: unknown): void {\n mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });\n const tmp = `${file}.${process.pid}.tmp`;\n writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 });\n renameSync(tmp, file);\n try {\n chmodSync(file, 0o600);\n } catch {}\n}\n\nexport function readControl(env: NodeJS.ProcessEnv = process.env, run: Runner = defaultRunner): ControlConfig | null {\n try {\n const j = JSON.parse(readFileSync(controlFile(env), \"utf8\")) as ControlConfig;\n if (!j || !Array.isArray(j.receivers)) return null;\n return {\n name: j.name || \"machine\",\n folders: j.folders ?? [],\n mode: j.mode === \"auto\" ? \"auto\" : \"safe\",\n receivers: j.receivers.map((r) =>\n r.token_in ? { ...r, token: secretGet(r.token_in, controlAccount(r.machine), run) ?? \"\" } : r,\n ),\n ...(j.limits ? { limits: j.limits } : {}),\n };\n } catch {\n return null;\n }\n}\n\n/** How many receivers this machine is paired with, from control.json alone (no\n * keychain read: `status` shouldn't ask one). */\nexport function pairedCount(env: NodeJS.ProcessEnv = process.env): number {\n try {\n const j = JSON.parse(readFileSync(controlFile(env), \"utf8\")) as { receivers?: unknown };\n return Array.isArray(j.receivers) ? j.receivers.length : 0;\n } catch {\n return 0;\n }\n}\n\n/** A token kept in a store is never written back into the file. */\nexport const writeControl = (c: ControlConfig, env: NodeJS.ProcessEnv = process.env) =>\n writePrivate(controlFile(env), {\n ...c,\n receivers: c.receivers.map((r) => {\n if (!r.token_in) return r;\n const { token: _t, ...rest } = r;\n return rest;\n }),\n });\n\n/** Move every paired receiver's token into `to` (or back into control.json). A token\n * this process can't read is left where it is. */\nexport function moveControlSecrets(\n to: StoreName,\n o: { env?: NodeJS.ProcessEnv; run?: Runner } = {},\n): { moved: string[]; kept: string[] } {\n const run = o.run ?? defaultRunner;\n const cfg = readControl(o.env, run);\n const moved: string[] = [];\n const kept: string[] = [];\n if (!cfg) return { moved, kept };\n const drop: { store: SecretStore; machine: string }[] = [];\n for (const r of cfg.receivers) {\n if ((r.token_in ?? \"file\") === to) continue;\n if (!r.token) {\n kept.push(r.url);\n continue;\n }\n if (to !== \"file\" && !secretSet(to, controlAccount(r.machine), r.token, run)) {\n secretDel(to, controlAccount(r.machine), run);\n kept.push(r.url);\n continue;\n }\n if (r.token_in) drop.push({ store: r.token_in, machine: r.machine });\n if (to === \"file\") delete r.token_in;\n else r.token_in = to;\n moved.push(r.url);\n }\n writeControl(cfg, o.env);\n for (const d of drop) secretDel(d.store, controlAccount(d.machine), run);\n return { moved, kept };\n}\n\n/** Forget a receiver's token wherever it is (control off). */\nexport function dropControlSecret(r: PairedReceiver, run: Runner = defaultRunner): void {\n if (r.token_in) secretDel(r.token_in, controlAccount(r.machine), run);\n}\n\n/** Nonces the machine has run, for NONCE_TTL_MS. `seen()` records a new nonce\n * durably BEFORE it answers false; a write that fails throws, and the verifier\n * refuses the command (`nonce_store`). */\nexport class NonceStore {\n private readonly seenAt = new Map<string, number>();\n constructor(\n private readonly file: string,\n private readonly now: () => number = Date.now,\n ) {\n let raw = \"\";\n try {\n raw = readFileSync(file, \"utf8\");\n } catch {}\n const cut = this.now() - NONCE_TTL_MS;\n for (const line of raw.split(\"\\n\")) {\n if (!line) continue;\n try {\n const { n, t } = JSON.parse(line) as { n: string; t: number };\n if (typeof n === \"string\" && t > cut) this.seenAt.set(n, t);\n } catch {}\n }\n this.compact();\n }\n\n seen = (nonce: string): boolean => {\n const t = this.seenAt.get(nonce);\n if (t !== undefined && t > this.now() - NONCE_TTL_MS) return true;\n const at = this.now();\n mkdirSync(path.dirname(this.file), { recursive: true, mode: 0o700 });\n const fd = openSync(this.file, \"a\", 0o600);\n try {\n appendFileSync(fd, `${JSON.stringify({ n: nonce, t: at })}\\n`);\n fsyncSync(fd);\n } finally {\n closeSync(fd);\n }\n this.seenAt.set(nonce, at);\n return false;\n };\n\n /** Rewrite the file with only the live window (on start, and daily). */\n compact(): void {\n const cut = this.now() - NONCE_TTL_MS;\n for (const [n, t] of this.seenAt) if (t <= cut) this.seenAt.delete(n);\n if (!existsSync(this.file) && !this.seenAt.size) return;\n const body = [...this.seenAt].map(([n, t]) => JSON.stringify({ n, t })).join(\"\\n\");\n mkdirSync(path.dirname(this.file), { recursive: true, mode: 0o700 });\n writeFileSync(`${this.file}.tmp`, body ? `${body}\\n` : \"\", { mode: 0o600 });\n renameSync(`${this.file}.tmp`, this.file);\n }\n\n get size(): number {\n return this.seenAt.size;\n }\n}\n\nexport interface Ack {\n receiver: string;\n id: string;\n outcome: \"taken\" | \"delivered\" | \"expired\" | \"unsupported\" | \"failed\" | \"refused\";\n at: string;\n mode?: string;\n session?: string;\n code?: string;\n detail?: string;\n reply?: string;\n}\n\n/** Acks not yet accepted: appended before they are sent, rewritten when sent, so a\n * daemon restart re-sends rather than forgets (every message is acked exactly once\n * with a final outcome; a duplicate is tolerated by the receiver). */\nexport class AckOutbox {\n constructor(private readonly file: string) {}\n all(): Ack[] {\n try {\n return readFileSync(this.file, \"utf8\")\n .split(\"\\n\")\n .filter(Boolean)\n .map((l) => JSON.parse(l) as Ack);\n } catch {\n return [];\n }\n }\n add(a: Ack): void {\n mkdirSync(path.dirname(this.file), { recursive: true, mode: 0o700 });\n appendFileSync(this.file, `${JSON.stringify(a)}\\n`, { mode: 0o600 });\n }\n keep(left: Ack[]): void {\n mkdirSync(path.dirname(this.file), { recursive: true, mode: 0o700 });\n writeFileSync(`${this.file}.tmp`, left.map((a) => JSON.stringify(a)).join(\"\\n\") + (left.length ? \"\\n\" : \"\"), {\n mode: 0o600,\n });\n renameSync(`${this.file}.tmp`, this.file);\n }\n}\n\nexport interface DaemonState {\n /** Original session \u2192 the fork its messages go to. */\n copies: Record<string, string>;\n}\n\nexport function readState(file: string): DaemonState {\n try {\n const j = JSON.parse(readFileSync(file, \"utf8\")) as DaemonState;\n return { copies: j.copies && typeof j.copies === \"object\" ? j.copies : {} };\n } catch {\n return { copies: {} };\n }\n}\nexport const writeState = (file: string, s: DaemonState) => writePrivate(file, s);\n", "// SPDX-License-Identifier: Apache-2.0\n// The one verifier for signed control commands (spec/CONTROL.md \u00A74\u2013\u00A75). A machine\n// runs a command only when this says yes; a receiver MAY run it too, as an early\n// word, so a bad command is refused where the person can see why.\n//\n// WebCrypto only (globalThis.crypto.subtle), no node: imports, no clock of its own\n// (`now` is passed in): the same file runs in a Cloudflare Worker, in a browser and\n// in Node \u2265 20, and conformance/control-vectors/ pins its answers.\n//\n// Every signature covers the EXACT bytes as transmitted (`cmd`, `grant.str`): the\n// strings are parsed to read their fields and never re-serialized to verify.\n\n/** One passkey tap vouches for a day key for at most this long. */\nexport const GRANT_MAX_MS = 24 * 3600_000;\n/** Clock slack between the signing device, the receiver and the machine. */\nexport const SKEW_MS = 5 * 60_000;\n/** The machine judges a command by when it was SIGNED: a message sent while the lid\n * was shut still runs when the machine wakes, up to a day later. */\nexport const MACHINE_MAX_AGE_MS = 24 * 3600_000;\n/** A receiver's early check is stricter: a command is carried within ten minutes of\n * being signed, or not at all. */\nexport const RECEIVER_MAX_AGE_MS = 10 * 60_000;\n/** How long a machine remembers a nonce: longer than MACHINE_MAX_AGE_MS + SKEW_MS. */\nexport const NONCE_TTL_MS = 25 * 3600_000;\n/** The whole command string, in UTF-16 code units (what JSON.parse sees). */\nexport const CMD_MAX = 48_000;\n/** A prompt's text, in characters. */\nexport const TEXT_MAX = 20_000;\n/** A permission answer's note. */\nexport const NOTE_MAX = 2_000;\n/** A grant string. */\nexport const GRANT_STR_MAX = 2_000;\n\nexport const COMMAND_TYPE = \"sessionpipe.control\";\nexport const GRANT_TYPE = \"sessionpipe.grant\";\nexport const CONTROL_KINDS = [\"prompt\", \"permission.answer\", \"cancel\", \"start\", \"key.add\"] as const;\n/** The session a `key.add` names: the machine's own key store, not a coding session. */\nexport const KEY_STORE_SESSION = \"sessionpipe:keys\";\nexport type ControlKind = (typeof CONTROL_KINDS)[number];\n\n/** COSE algorithm ids a trusted key may use. */\nexport const ES256 = -7;\nexport const RS256 = -257;\n\n/** A key enrolled on the machine: a passkey's credential id, COSE alg and SPKI (base64url). */\nexport interface TrustedKey {\n id: string;\n alg: number;\n spki: string;\n}\n/** A WebAuthn assertion: credential id, authenticatorData, clientDataJSON, signature (base64url). */\nexport interface Assertion {\n cred: string;\n ad: string;\n cd: string;\n sig: string;\n}\n/** The day's grant: a passkey's assertion over sha256(str), where str names the day key. */\nexport interface GrantBundle extends Assertion {\n str: string;\n}\n/** What a receiver carries for one command (control.json minus the receiver's envelope). */\nexport interface SignedCommand {\n cmd: string;\n csig?: string | null;\n grant?: GrantBundle | null;\n confirm?: Assertion | null;\n}\nexport interface Grant {\n v: 1;\n t: typeof GRANT_TYPE;\n pub: string;\n iat: number;\n exp: number;\n rp: string;\n}\nexport interface ControlCommand {\n v: 1;\n t: typeof COMMAND_TYPE;\n machine: string;\n kind: ControlKind;\n /** `<harness>:<id>`, e.g. `claude-code:8c132906-\u2026`. */\n session: string;\n text?: string;\n for?: string;\n decision?: \"allow\" | \"deny\";\n note?: string;\n cwd?: string;\n /** key.add only: the passkey to trust from now on, as the receiver holds it. */\n key?: { id: string; alg: -7 | -257; spki: string };\n /** key.add only: what the person calls the device (\"iPhone\"), for `control keys`. */\n name?: string;\n nonce: string;\n iat: number;\n}\n\n/** Why a command was refused. Stable: conformance vectors and acks name these. */\nexport type RefusalCode =\n | \"malformed\"\n | \"not_a_command\"\n | \"wrong_machine\"\n | \"unknown_kind\"\n | \"bad_session\"\n | \"bad_fields\"\n | \"bad_nonce\"\n | \"too_old\"\n | \"future\"\n | \"unsigned\"\n | \"untrusted_key\"\n | \"bad_assertion\"\n | \"bad_grant\"\n | \"outside_grant\"\n | \"bad_csig\"\n | \"replay\"\n | \"nonce_store\";\n\nexport type Verdict =\n | { ok: true; cmd: ControlCommand; via: \"grant\" | \"confirm\"; key: string }\n | { ok: false; code: RefusalCode; why: string };\n\nexport interface VerifyOptions {\n /** This machine's id; a command for another machine is refused. */\n machine: string;\n /** The receiver's WebAuthn rp id the keys were enrolled for (well-known control.signing.rp_id). */\n rpId: string;\n /** The keys enrolled on this machine (or, for a receiver's early check, the account's). */\n trusted: TrustedKey[];\n /** Epoch ms. */\n now: number;\n /** MACHINE_MAX_AGE_MS on a machine (default), RECEIVER_MAX_AGE_MS on a receiver. */\n maxAgeMs?: number;\n /** Called once, last, only for a command whose signatures all verified: answer\n * true when the nonce was seen before, otherwise record it (durably) and answer\n * false. A throw refuses the command (`nonce_store`): never run what could not\n * be remembered. Omit it on a receiver's early check. */\n seenNonce?: (nonce: string) => boolean | Promise<boolean>;\n}\n\nconst NONCE_RE = /^[A-Za-z0-9_-]{22,64}$/;\nconst MACHINE_RE = /^m_[A-Za-z0-9_-]{16,40}$/;\nconst HARNESS_RE = /^[a-z][a-z0-9-]{0,39}$/;\nconst SESSION_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/;\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst B64URL_RE = /^[A-Za-z0-9_-]*$/;\nconst UP = 0x01;\nconst UV = 0x04;\n\n// --- encodings ------------------------------------------------------------------\n\nconst enc = new TextEncoder();\nconst dec = new TextDecoder();\n\nexport function b64url(bytes: Uint8Array | ArrayBuffer): string {\n const u = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);\n let s = \"\";\n for (const b of u) s += String.fromCharCode(b);\n return btoa(s).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/** base64url without padding, strictly; null for anything else. */\nexport function fromB64url(s: unknown): Uint8Array | null {\n if (typeof s !== \"string\" || !B64URL_RE.test(s) || s.length % 4 === 1) return null;\n try {\n const bin = atob(s.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((s.length + 3) % 4));\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n } catch {\n return null;\n }\n}\n\nexport async function sha256(data: string | Uint8Array): Promise<Uint8Array> {\n const bytes = typeof data === \"string\" ? enc.encode(data) : data;\n return new Uint8Array(await crypto.subtle.digest(\"SHA-256\", bytes as Uint8Array<ArrayBuffer>));\n}\n\nfunction concat(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(a.length + b.length);\n out.set(a, 0);\n out.set(b, a.length);\n return out;\n}\n\nfunction sameBytes(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let d = 0;\n for (let i = 0; i < a.length; i++) d |= (a[i] as number) ^ (b[i] as number);\n return d === 0;\n}\n\n/** A DER ECDSA signature (what WebAuthn returns) as the 64-byte r\u2016s WebCrypto verifies.\n * Strict: every length must match the bytes, so one signature has one encoding (a\n * P-256 signature is at most 72 bytes, so the short length form is the only one). */\nexport function derToRaw(der: Uint8Array): Uint8Array | null {\n if (der[0] !== 0x30 || der.length < 8 || der[1] !== der.length - 2) return null;\n let i = 2;\n const part = (): Uint8Array | null => {\n if (der[i] !== 0x02) return null;\n const len = der[i + 1] as number;\n if (len < 1 || len > 33) return null;\n let v = der.slice(i + 2, i + 2 + len);\n if (v.length !== len) return null;\n // Minimal integers only: no needless leading zero, and never negative.\n if ((v[0] as number) & 0x80) return null;\n if (len > 1 && v[0] === 0 && !((v[1] as number) & 0x80)) return null;\n i += 2 + len;\n while (v.length > 32 && v[0] === 0) v = v.slice(1);\n if (v.length > 32) return null;\n const out = new Uint8Array(32);\n out.set(v, 32 - v.length);\n return out;\n };\n const r = part();\n const s = part();\n return r && s && i === der.length ? concat(r, s) : null;\n}\n\nconst u8 = (b: Uint8Array) => b as Uint8Array<ArrayBuffer>;\n/** WebCrypto's key type, named without the DOM lib (Workers, Node and browsers all have it). */\ntype CryptoKey = Awaited<ReturnType<typeof crypto.subtle.importKey>>;\n\nasync function importKey(key: TrustedKey): Promise<CryptoKey | null> {\n const spki = fromB64url(key.spki);\n if (!spki?.length) return null;\n try {\n if (key.alg === ES256)\n return await crypto.subtle.importKey(\"spki\", u8(spki), { name: \"ECDSA\", namedCurve: \"P-256\" }, false, [\"verify\"]);\n if (key.alg === RS256) {\n const k = await crypto.subtle.importKey(\"spki\", u8(spki), { name: \"RSASSA-PKCS1-v1_5\", hash: \"SHA-256\" }, false, [\n \"verify\",\n ]);\n const bits = (k.algorithm as { modulusLength?: number }).modulusLength ?? 0;\n return bits >= 2048 ? k : null;\n }\n } catch {}\n return null;\n}\n\n/** Can this key be enrolled at all? A machine refuses to trust a key it could never verify with. */\nexport async function keyUsable(key: TrustedKey): Promise<boolean> {\n return (\n !!key &&\n typeof key.id === \"string\" &&\n /^[A-Za-z0-9_-]{16,1400}$/.test(key.id) &&\n (key.alg === ES256 || key.alg === RS256) &&\n !!(await importKey(key))\n );\n}\n\n// --- WebAuthn -------------------------------------------------------------------\n\n/** A WebAuthn origin a key may have been used from: https on the rp id or a subdomain;\n * for rp id `localhost`, plain http on any port too. A bare origin, as a browser writes it. */\nexport function originAllowed(origin: unknown, rpId: string): boolean {\n if (typeof origin !== \"string\" || !rpId) return false;\n let u: URL;\n try {\n u = new URL(origin);\n } catch {\n return false;\n }\n if (u.origin !== origin) return false;\n if (u.hostname !== rpId && !u.hostname.endsWith(`.${rpId}`)) return false;\n if (u.protocol === \"https:\") return true;\n return u.protocol === \"http:\" && rpId === \"localhost\";\n}\n\ntype Check = { ok: true } | { ok: false; why: string };\nconst no = (why: string): Check => ({ ok: false, why });\n\n/** One passkey assertion over `challenge`, made with `key`, by a verified person. */\nexport async function verifyAssertion(\n challenge: Uint8Array,\n a: Assertion | null | undefined,\n key: TrustedKey,\n rpId: string,\n): Promise<Check> {\n if (!a || typeof a !== \"object\") return no(\"no passkey signature\");\n if (a.cred !== key.id) return no(\"signed with a key this machine doesn't trust\");\n const cdBytes = fromB64url(a.cd);\n const ad = fromB64url(a.ad);\n const sig = fromB64url(a.sig);\n if (!cdBytes || !ad || !sig?.length) return no(\"the passkey signature is malformed\");\n let cd: { type?: unknown; challenge?: unknown; origin?: unknown; crossOrigin?: unknown };\n try {\n cd = JSON.parse(dec.decode(cdBytes));\n } catch {\n return no(\"the passkey signature is malformed\");\n }\n if (!cd || typeof cd !== \"object\") return no(\"the passkey signature is malformed\");\n if (cd.type !== \"webauthn.get\") return no(\"the passkey answered a different question\");\n if (cd.challenge !== b64url(challenge)) return no(\"the passkey signed something else\");\n if (!originAllowed(cd.origin, rpId)) return no(`the passkey was used on another site, not ${rpId}`);\n if (cd.crossOrigin === true) return no(\"the passkey was used inside another site's frame\");\n if (ad.length < 37) return no(\"the passkey signature is malformed\");\n if (!sameBytes(ad.slice(0, 32), await sha256(rpId))) return no(`the passkey belongs to another site, not ${rpId}`);\n const flags = ad[32] as number;\n if (!(flags & UP) || !(flags & UV)) return no(\"the passkey signed without verifying the person\");\n const pub = await importKey(key);\n if (!pub) return no(\"a trusted key is unusable\");\n const signed = concat(ad, await sha256(cdBytes));\n let good = false;\n try {\n if (key.alg === ES256) {\n const raw = derToRaw(sig);\n good = !!raw && (await crypto.subtle.verify({ name: \"ECDSA\", hash: \"SHA-256\" }, pub, u8(raw), u8(signed)));\n } else {\n good = await crypto.subtle.verify({ name: \"RSASSA-PKCS1-v1_5\" }, pub, u8(sig), u8(signed));\n }\n } catch {\n good = false;\n }\n return good ? { ok: true } : no(\"the passkey signature doesn't verify\");\n}\n\n/** What a passkey signs to enroll on a machine: bound to that machine and that pairing code. */\nexport function pairChallenge(machine: string, code: string): Promise<Uint8Array> {\n return sha256(`sessionpipe.pair:${machine}:${code}`);\n}\n\n/** The enrollment proof: the new key's assertion over pairChallenge(machine, code).\n * Only after this verifies does the key go into the machine's trust store. */\nexport async function verifyEnrollment(o: {\n machine: string;\n code: string;\n key: TrustedKey;\n proof: Assertion;\n rpId: string;\n}): Promise<Check> {\n if (!(await keyUsable(o.key))) return no(\"the key is in a shape this machine can't use\");\n return verifyAssertion(await pairChallenge(o.machine, o.code), o.proof, o.key, o.rpId);\n}\n\n// --- the command ------------------------------------------------------------------\n\ntype Parsed = { ok: true; cmd: ControlCommand } | { ok: false; code: RefusalCode; why: string };\nconst bad = (code: RefusalCode, why: string): { ok: false; code: RefusalCode; why: string } => ({\n ok: false,\n code,\n why,\n});\nconst isNum = (n: unknown): n is number => typeof n === \"number\" && Number.isFinite(n);\n\n/** The session id rule per harness (ADAPTERS.md): Claude Code ids are UUIDs. */\nexport function sessionIdOk(harness: string, id: string): boolean {\n if (!SESSION_ID_RE.test(id)) return false;\n if (harness === \"claude-code\") return UUID_RE.test(id);\n return true;\n}\n\n/** Split `<harness>:<id>`; null when either half breaks its rule. */\nexport function parseSessionRef(ref: unknown): { harness: string; id: string } | null {\n if (typeof ref !== \"string\") return null;\n const i = ref.indexOf(\":\");\n if (i <= 0) return null;\n const harness = ref.slice(0, i);\n const id = ref.slice(i + 1);\n return HARNESS_RE.test(harness) && sessionIdOk(harness, id) ? { harness, id } : null;\n}\n\n/** Read the command's fields from the exact string. Structure only; no clock, no keys. */\nexport function parseCommand(str: unknown): Parsed {\n if (typeof str !== \"string\" || !str || str.length > CMD_MAX)\n return bad(\"malformed\", \"the command is missing or too long\");\n let c: Record<string, unknown>;\n try {\n c = JSON.parse(str);\n } catch {\n return bad(\"malformed\", \"the command is not JSON\");\n }\n if (!c || typeof c !== \"object\" || Array.isArray(c)) return bad(\"malformed\", \"the command is not an object\");\n if (c.v !== 1 || c.t !== COMMAND_TYPE) return bad(\"not_a_command\", \"not a sessionpipe control command\");\n if (typeof c.machine !== \"string\" || !MACHINE_RE.test(c.machine)) return bad(\"malformed\", \"which machine?\");\n if (!CONTROL_KINDS.includes(c.kind as ControlKind))\n return bad(\"unknown_kind\", \"the command asks for something unknown\");\n const ref = parseSessionRef(c.session);\n if (!ref) return bad(\"bad_session\", \"which session?\");\n if (typeof c.nonce !== \"string\" || !NONCE_RE.test(c.nonce))\n return bad(\"bad_nonce\", \"the nonce is missing or malformed\");\n if (!isNum(c.iat) || !Number.isInteger(c.iat) || c.iat <= 0)\n return bad(\"malformed\", \"the command has no signing time\");\n const has = (k: string) => c[k] !== undefined;\n const text = () => typeof c.text === \"string\" && c.text.trim().length > 0 && c.text.length <= TEXT_MAX;\n switch (c.kind as ControlKind) {\n case \"prompt\":\n if (!text()) return bad(\"bad_fields\", `a prompt needs text, at most ${TEXT_MAX} characters`);\n if (has(\"for\") || has(\"decision\") || has(\"cwd\")) return bad(\"bad_fields\", \"a prompt carries only text\");\n break;\n case \"start\":\n if (!text()) return bad(\"bad_fields\", `a new session needs text, at most ${TEXT_MAX} characters`);\n if (ref.harness !== \"claude-code\") return bad(\"bad_fields\", \"only Claude Code sessions can be started\");\n if (typeof c.cwd !== \"string\" || !isAbsolute(c.cwd) || c.cwd.length > 1024)\n return bad(\"bad_fields\", \"a new session needs an absolute folder\");\n if (has(\"for\") || has(\"decision\")) return bad(\"bad_fields\", \"a start carries text and cwd\");\n break;\n case \"permission.answer\":\n if (typeof c.for !== \"string\" || !c.for || c.for.length > 128) return bad(\"bad_fields\", \"which attention?\");\n if (c.decision !== \"allow\" && c.decision !== \"deny\") return bad(\"bad_fields\", \"allow or deny?\");\n if (has(\"text\") || has(\"cwd\")) return bad(\"bad_fields\", \"a permission answer carries for, decision and note\");\n break;\n case \"cancel\":\n if (has(\"text\") || has(\"for\") || has(\"decision\") || has(\"cwd\"))\n return bad(\"bad_fields\", \"a cancel carries nothing\");\n break;\n case \"key.add\": {\n // A device the machine already trusts vouches for a new one (CONTROL.md \u00A72): the\n // new passkey's id, algorithm and public key are inside the signed bytes.\n if (c.session !== KEY_STORE_SESSION) return bad(\"bad_session\", `a key.add names ${KEY_STORE_SESSION}`);\n const k = c.key as { id?: unknown; alg?: unknown; spki?: unknown } | undefined;\n const b64 = (v: unknown, min: number, max: number) =>\n typeof v === \"string\" && v.length >= min && v.length <= max && /^[A-Za-z0-9_-]+$/.test(v);\n if (\n !k ||\n typeof k !== \"object\" ||\n !b64(k.id, 16, 1400) ||\n (k.alg !== -7 && k.alg !== -257) ||\n !b64(k.spki, 40, 2000)\n )\n return bad(\"bad_fields\", \"a key.add carries the key: id, alg (-7 or -257) and spki\");\n if (has(\"name\") && (typeof c.name !== \"string\" || !c.name.trim() || c.name.length > 80))\n return bad(\"bad_fields\", \"a device name is text, at most 80 characters\");\n if (has(\"text\") || has(\"for\") || has(\"decision\") || has(\"cwd\"))\n return bad(\"bad_fields\", \"a key.add carries the key and a name\");\n break;\n }\n }\n if (c.kind !== \"key.add\" && (has(\"key\") || has(\"name\"))) return bad(\"bad_fields\", \"only a key.add carries a key\");\n if (has(\"note\") && (typeof c.note !== \"string\" || c.note.length > NOTE_MAX))\n return bad(\"bad_fields\", `a note is text, at most ${NOTE_MAX} characters`);\n return { ok: true, cmd: c as unknown as ControlCommand };\n}\n\nfunction isAbsolute(p: string): boolean {\n return p.startsWith(\"/\") || /^[A-Za-z]:[\\\\/]/.test(p);\n}\n\n/** The grant's fields, read from its exact string. */\nexport function parseGrant(str: unknown, rpId: string): { ok: true; grant: Grant } | { ok: false; why: string } {\n if (typeof str !== \"string\" || !str || str.length > GRANT_STR_MAX)\n return { ok: false, why: \"the grant is missing or too long\" };\n let g: Record<string, unknown>;\n try {\n g = JSON.parse(str);\n } catch {\n return { ok: false, why: \"the grant is not JSON\" };\n }\n if (!g || typeof g !== \"object\" || Array.isArray(g)) return { ok: false, why: \"the grant is not an object\" };\n if (g.v !== 1 || g.t !== GRANT_TYPE) return { ok: false, why: \"not a sessionpipe grant\" };\n if (g.rp !== rpId) return { ok: false, why: `the grant is for another site, not ${rpId}` };\n if (typeof g.pub !== \"string\" || !fromB64url(g.pub)?.length || !isNum(g.iat) || !isNum(g.exp))\n return { ok: false, why: \"the grant is missing parts\" };\n if (g.exp <= g.iat) return { ok: false, why: \"the grant ends before it starts\" };\n if (g.exp - g.iat > GRANT_MAX_MS + SKEW_MS) return { ok: false, why: \"the grant lasts longer than a day\" };\n return { ok: true, grant: g as unknown as Grant };\n}\n\nasync function verifyCsig(cmd: string, csig: unknown, pub: string): Promise<boolean> {\n const sig = fromB64url(csig);\n const spki = fromB64url(pub);\n if (sig?.length !== 64 || !spki) return false;\n try {\n const key = await crypto.subtle.importKey(\"spki\", u8(spki), { name: \"ECDSA\", namedCurve: \"P-256\" }, false, [\n \"verify\",\n ]);\n return await crypto.subtle.verify({ name: \"ECDSA\", hash: \"SHA-256\" }, key, u8(sig), u8(enc.encode(cmd)));\n } catch {\n return false;\n }\n}\n\n/**\n * Is this a command this machine may run? The checks, in the spec's order\n * (CONTROL.md \u00A75): the exact bytes parse; the command is for this machine; it is\n * signed \u2014 a grant from a trusted key plus the day key's signature, or a confirm\n * over sha256(cmd); it was signed within the age window; its nonce is new.\n * The folder and open-attention checks that follow are the daemon's (they read\n * the machine, not the command).\n */\nexport async function verifyCommand(s: SignedCommand | null | undefined, o: VerifyOptions): Promise<Verdict> {\n if (!s || typeof s !== \"object\") return bad(\"malformed\", \"nothing to verify\");\n const p = parseCommand(s.cmd);\n if (!p.ok) return p;\n const c = p.cmd;\n if (c.machine !== o.machine) return bad(\"wrong_machine\", \"the command is for another machine\");\n\n let via: \"grant\" | \"confirm\" | null = null;\n let keyId = \"\";\n let refusal: { code: RefusalCode; why: string } | null = null;\n if (s.grant && s.csig) {\n const r = await checkGrantPath(s, c, o);\n if (r.ok) {\n via = \"grant\";\n keyId = r.key;\n } else refusal = r;\n }\n if (!via && s.confirm) {\n const key = o.trusted.find((k) => k && k.id === s.confirm?.cred);\n if (!key) refusal = { code: \"untrusted_key\", why: \"confirmed with a key this machine doesn't trust\" };\n else {\n const a = await verifyAssertion(await sha256(s.cmd), s.confirm, key, o.rpId);\n if (a.ok) {\n via = \"confirm\";\n keyId = key.id;\n } else refusal = { code: \"bad_assertion\", why: a.why };\n }\n }\n if (!via) {\n if (refusal) return bad(refusal.code, refusal.why);\n return bad(\"unsigned\", \"the command isn't signed\");\n }\n if (c.iat > o.now + SKEW_MS) return bad(\"future\", \"the command is dated in the future (is this clock right?)\");\n if (o.now - c.iat > (o.maxAgeMs ?? MACHINE_MAX_AGE_MS)) return bad(\"too_old\", \"the command was signed too long ago\");\n if (o.seenNonce) {\n let seen: boolean;\n try {\n seen = await o.seenNonce(c.nonce);\n } catch {\n return bad(\"nonce_store\", \"the nonce couldn't be recorded, so the command didn't run\");\n }\n if (seen) return bad(\"replay\", \"this command was already used once\");\n }\n return { ok: true, cmd: c, via, key: keyId };\n}\n\nasync function checkGrantPath(\n s: SignedCommand,\n c: ControlCommand,\n o: VerifyOptions,\n): Promise<{ ok: true; key: string } | { ok: false; code: RefusalCode; why: string }> {\n const bundle = s.grant as GrantBundle;\n const g = parseGrant(bundle.str, o.rpId);\n if (!g.ok) return bad(\"bad_grant\", g.why);\n const key = o.trusted.find((k) => k && k.id === bundle.cred);\n if (!key) return bad(\"untrusted_key\", \"the grant was signed with a key this machine doesn't trust\");\n const a = await verifyAssertion(await sha256(bundle.str), bundle, key, o.rpId);\n if (!a.ok) return bad(\"bad_assertion\", a.why);\n if (!(await verifyCsig(s.cmd, s.csig, g.grant.pub)))\n return bad(\"bad_csig\", \"the command's signature doesn't verify \u2014 it was changed after it was signed\");\n if (c.iat < g.grant.iat - SKEW_MS || c.iat > g.grant.exp)\n return bad(\"outside_grant\", \"the command was signed outside its grant's window\");\n return { ok: true, key: key.id };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// `sessionpipe control pair | keys | off | run | status` and `sessionpipe wait`.\nimport { existsSync, realpathSync, unwatchFile, watchFile } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { claudeControl, claudeDirs, Outbox, readConfig, stateDir, type Tier, writeConfig } from \"@sessionpipe/core\";\n\nconst { claudeLogin, detectCaps, findClaude, runClaude } = claudeControl;\n\nimport { isBroad } from \"../connect.js\";\nimport { flush, VERSION } from \"../run.js\";\nimport { rerunGlobally, stableNode, viaNpx } from \"../runtime.js\";\nimport { controlAccount, secretGet, sinkWithSecrets } from \"../secrets.js\";\nimport { installedVersion, installVersion, latestVersion } from \"../update.js\";\nimport { AutoUpdater, autoUpdateOff, restartVia, supervise, UPDATE_EXIT, updateFile } from \"./autoupdate.js\";\nimport { ControlDaemon, DaemonRunning } from \"./daemon.js\";\nimport { ask, socketPath } from \"./local.js\";\nimport { installService, off, pair, removeKey, uninstallService } from \"./pair.js\";\nimport { loadSdk } from \"./sdk.js\";\nimport { controlFile, controlState, readControl, writeControl } from \"./store.js\";\nimport { waitForMessage, waitSession } from \"./wait.js\";\n\nexport const CONTROL_HELP = ` sessionpipe control pair <receiver> [--folder DIR]\u2026 [--mode safe|auto] [--tier 0-3] [--token T] [--name N] [--no-service]\n sessionpipe control mode auto|safe (how sessions run when you message them)\n sessionpipe control status | keys [remove <id>] | off [<receiver>] | run\n sessionpipe wait [--session <harness>:<id>] (a session runs this in the background)`;\n\nconst MODE_TEXT = ` auto Claude Code's auto mode: the session reads, edits and runs commands, and Claude Code's\n own safety check stops what looks dangerous. Pick this to get work done from your phone.\n safe Only what each folder's Claude Code settings already allow: with no allow rules, a\n session can't even read a file. Pick this if this machine holds things no agent\n should touch unattended.`;\n\n/** Ask the person at this machine, once: auto or safe. Not a terminal (an agent ran the\n * pair command): safe, and say how to change it. */\nasync function askMode(out: (s?: string) => void): Promise<\"safe\" | \"auto\"> {\n if (!process.stdin.isTTY) {\n out(\" Mode: safe for now. Run `sessionpipe control mode auto` to let sessions you message work unattended.\");\n return \"safe\";\n }\n out(\"\");\n out(\" When you message a session on this machine from your phone, how may it run?\");\n out(MODE_TEXT);\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n for (;;) {\n const a = (await rl.question(\" auto or safe? [auto] \")).trim().toLowerCase();\n if (a === \"\" || a === \"a\" || a === \"auto\") return \"auto\";\n if (a === \"s\" || a === \"safe\") return \"safe\";\n }\n } finally {\n rl.close();\n }\n}\n\nexport async function controlMain(argv: string[], out: (s?: string) => void, distDir: string): Promise<void> {\n const flag = (n: string) => {\n const i = argv.indexOf(n);\n return i >= 0 ? argv[i + 1] : undefined;\n };\n const flags = (n: string) => argv.flatMap((a, i) => (a === n && argv[i + 1] ? [argv[i + 1] as string] : []));\n const sub = argv[1];\n switch (sub) {\n case \"pair\": {\n // `spacesheep.dev` is enough: a bare host means https.\n const raw = argv[2];\n if (!raw || raw.startsWith(\"-\")) return out(`usage:\\n${CONTROL_HELP}`);\n if (viaNpx(distDir)) return rerunGlobally(argv, out);\n const url = (/^https?:\\/\\//.test(raw) ? raw : `https://${raw}`).replace(/\\/$/, \"\");\n const cfg = readConfig();\n const sink = cfg.sinks.find((s) => s.url.replace(/\\/$/, \"\") === url);\n // No token is fine where the receiver offers open pairing: the person approves the\n // link signed in, and that is the whole setup.\n const token = flag(\"--token\") ?? (sink ? sinkWithSecrets(sink)?.token : undefined) ?? null;\n if (token !== null && !/^[\\x21-\\x7e]+$/.test(token))\n return out(\n \" That token has a character a key never has (a placeholder like ss_\u2026 pasted as is?). Leave --token out to pair with a link instead.\",\n );\n const folders = flags(\"--folder\");\n const existing = readControl();\n // The folder this ran in \u2014 unless that is the home folder or above it, which\n // would let a message start a session anywhere you own.\n if (!folders.length && !existing?.folders.length) {\n if (!isBroad(process.cwd(), os.homedir())) folders.push(process.cwd());\n else\n out(\n ` ! Not allowing all of ${process.cwd()}: sessions you message may run only in folders you name. Pass --folder <project>, or run this from inside one.`,\n );\n }\n // How sessions run when a message arrives is the person's call, asked once here at\n // the machine \u2014 never a default they find out about when a session can't read a file.\n const mode: \"safe\" | \"auto\" =\n flag(\"--mode\") === \"auto\" || flag(\"--mode\") === \"safe\"\n ? (flag(\"--mode\") as \"safe\" | \"auto\")\n : existing?.mode && existing.receivers.length\n ? existing.mode\n : await askMode(out);\n const tier = argv.includes(\"--tier\") ? (Math.max(0, Math.min(3, Number(flag(\"--tier\")) || 0)) as Tier) : 0;\n await pair({\n url,\n token,\n // The key the receiver handed over at pairing becomes this machine's sink for it,\n // at --tier (0 \u2014 session state only \u2014 unless given), unless one is configured.\n addSink: (t) => {\n const r = adoptSinkToken(url, t, tier);\n if (r === \"kept\") return;\n out(\n r === \"filled\"\n ? ` \u2713 Sink ${new URL(url).host} now carries the key the receiver handed over.`\n : tier >= 2\n ? ` \u2713 Sink ${new URL(url).host} added at tier ${tier}.`\n : ` \u2713 Sink ${new URL(url).host} added (tier ${tier}: ${tier ? \"tool activity\" : \"session state\"}, no conversation text). \\`sessionpipe sink add ${url} --tier 2\\` sends transcripts too.`,\n );\n },\n folders,\n mode,\n name: flag(\"--name\") ?? existing?.name ?? cfg.machine ?? os.hostname(),\n out,\n });\n const c = readControl()!;\n out(` Folders sessions may run in: ${c.folders.join(\", \")}`);\n out(\n ` Mode: ${c.mode} (${c.mode === \"safe\" ? \"nothing that needs approval runs unattended\" : \"Claude Code's auto mode\"})`,\n );\n let cli = path.join(distDir, \"cli.js\");\n try {\n cli = realpathSync(cli);\n } catch {}\n if (argv.includes(\"--no-service\"))\n out(\" Daemon: not installed as a service (--no-service); run `sessionpipe control run` yourself\");\n else out(` Daemon: ${installService({ node: stableNode(process.execPath), cli })}`);\n return;\n }\n case \"mode\": {\n const want = argv[2];\n if (want !== \"auto\" && want !== \"safe\") {\n const c = readControl();\n return out(` mode: ${c?.mode ?? \"not set up\"}\\n usage: sessionpipe control mode auto|safe\\n${MODE_TEXT}`);\n }\n const c = readControl();\n if (!c) return out(\" control isn't set up on this machine: run `sessionpipe control pair <receiver>` first\");\n c.mode = want;\n writeControl(c);\n // The running daemon reads control.json again within seconds; the next run uses it.\n return out(\n ` \u2713 Sessions you message now run in ${want} mode${want === \"auto\" ? \" (Claude Code's auto mode decides what's safe)\" : \" (only what each folder's settings already allow)\"}.`,\n );\n }\n case \"keys\": {\n const c = readControl();\n if (argv[2] === \"remove\" && argv[3]) {\n const n = removeKey(argv[3]);\n return out(n ? ` removed ${n} key(s)` : \" no such key\");\n }\n if (!c?.receivers.length)\n return out(\" control isn't paired on this machine (`sessionpipe control pair <receiver>`)\");\n for (const r of c.receivers) {\n out(` ${r.url} \u00B7 machine ${r.machine}`);\n for (const k of r.keys)\n out(` ${k.id.slice(0, 16)}\u2026 ${k.alg === -7 ? \"ES256\" : \"RS256\"} added ${k.added_at.slice(0, 10)}`);\n }\n return;\n }\n case \"off\": {\n const c = await off({ out, ...(argv[2] ? { url: argv[2] } : {}) });\n if (c && !c.receivers.length) uninstallService();\n return;\n }\n case \"status\": {\n const r = await ask(socketPath(stateDir()), { op: \"status\" }, 2000);\n if (r?.op !== \"status\") return out(\" the control daemon isn't running\");\n return out(JSON.stringify(r.status, null, 2));\n }\n case \"run\":\n return runDaemon(out, distDir);\n default:\n return out(CONTROL_HELP);\n }\n}\n\n/** The harnesses set up on this machine, whose hooks an update re-arms. */\nexport function enabledHarnesses(harnesses: Record<string, { enabled?: boolean }>): string[] {\n return Object.entries(harnesses)\n .filter(([, h]) => h?.enabled !== false)\n .map(([n]) => n)\n .filter((n) => /^[a-z][a-z0-9-]{0,40}$/.test(n));\n}\n\nasync function runDaemon(out: (s?: string) => void, distDir: string): Promise<void> {\n const cfg = readControl();\n if (!cfg?.receivers.length) {\n out(\"control isn't paired on this machine; nothing to do (`sessionpipe control pair <receiver>`)\");\n return;\n }\n const log = (s: string) => out(`${new Date().toISOString()} ${s}`);\n let claude: { bin: string; caps: ReturnType<typeof detectCaps>; sig: string } | null = null;\n const claudeNow = () => {\n const bin = findClaude();\n if (!bin) return null;\n const sig = `${bin}:${existsSync(bin) ? realpathSync(bin) : \"\"}`;\n if (claude?.sig !== sig) claude = { bin, caps: detectCaps(bin), sig };\n return claude;\n };\n const sdk = await loadSdk({ claudeBin: findClaude(), env: process.env, log });\n let updater: AutoUpdater | null = null;\n const d = new ControlDaemon(cfg, controlState(), socketPath(stateDir()), {\n now: Date.now,\n fetch,\n log,\n claudeDirs: () => claudeDirs(),\n claude: claudeNow,\n run: runClaude,\n sdk,\n login: async (configDir) => {\n const c = claudeNow();\n return c ? claudeLogin(c.bin, configDir) : { loggedIn: null };\n },\n token: (r) => (r.token_in ? secretGet(r.token_in, controlAccount(r.machine)) : null),\n onRestart: () => updater?.restartWhenIdle() ?? false,\n updateStatus: () => (updater ? updater.record() : null),\n // Two daemons started at once and the other one holds the socket: leave it to it.\n onLostSocket: () => process.exit(0),\n });\n try {\n await d.start();\n } catch (e) {\n if (!(e instanceof DaemonRunning)) throw e;\n // Exit 0: no service manager restarts a daemon that stepped aside on purpose.\n log(`${e.message}; this one exits`);\n process.exit(0);\n }\n // A sink whose token lives in a keychain can't send from a hook's worker that runs\n // where the keychain is locked (a session started over ssh). This daemon runs in the\n // person's own session, so it drains what those workers left, once a minute.\n const drain = setInterval(() => {\n const sinks = readConfig().sinks.filter((s) => s.token_in && !s.paused);\n if (sinks.length) void flush(stateDir(), sinks, new Outbox(stateDir())).catch(() => {});\n }, 60_000);\n drain.unref();\n watchFile(controlFile(), { interval: 5000 }, () => {\n const next = readControl();\n if (next) d.reload(next);\n });\n let stopping = false;\n const bye = async () => {\n if (stopping) return;\n stopping = true;\n updater?.stop();\n await d.stop();\n process.exit(0);\n };\n const signals = [\"SIGTERM\", \"SIGINT\"] as const;\n for (const sig of signals) process.on(sig, bye);\n\n // Restart onto the code now on disk. The daemon is stopped first (its socket closed,\n // its long-polls ended), so two never poll at once.\n const restart = async (_from: string, to: string): Promise<void> => {\n stopping = true;\n updater?.stop();\n clearInterval(drain);\n unwatchFile(controlFile());\n for (const sig of signals) process.off(sig, bye);\n await d.stop();\n const via = restartVia({ env: process.env, platform: process.platform, pid: process.pid, ppid: process.ppid });\n if (via) {\n log(`exiting ${UPDATE_EXIT} so ${via === \"supervisor\" ? \"the supervising sessionpipe\" : via} starts ${to}`);\n process.exit(UPDATE_EXIT);\n }\n // Nobody restarts this process: it stays, as the new daemon's parent.\n let cli = path.join(distDir, \"cli.js\");\n try {\n cli = realpathSync(cli);\n } catch {}\n log(`no service manager restarts this daemon: pid ${process.pid} now runs ${to} as its child`);\n const sup = supervise({ node: process.execPath, args: [cli, \"control\", \"run\"], env: process.env, log });\n for (const sig of [...signals, \"SIGHUP\"] as const) process.on(sig, () => sup.stop(sig));\n };\n updater = new AutoUpdater({\n now: Date.now,\n log,\n version: VERSION,\n file: updateFile(),\n off: () => autoUpdateOff({ env: process.env, config: readConfig(), distDir }),\n latest: () => latestVersion(fetch),\n installed: () => installedVersion({ node: process.execPath, distDir }),\n install: (v) =>\n installVersion(v, { node: process.execPath, distDir, harnesses: enabledHarnesses(readConfig().harnesses) }),\n daemon: d,\n restart,\n });\n updater.start();\n}\n\nexport async function waitMain(argv: string[], out: (s?: string) => void): Promise<void> {\n const i = argv.indexOf(\"--session\");\n const session = waitSession(i >= 0 ? argv[i + 1] : undefined);\n if (!session) {\n out(\"sessionpipe wait: which session? Pass --session <harness>:<id> (Claude Code sets CLAUDE_CODE_SESSION_ID).\");\n process.exitCode = 2;\n return;\n }\n out(await waitForMessage(session));\n}\n\n/** Give a sink the key a receiver handed over at pairing. A sink for the receiver that\n * has a key keeps it (\"kept\"); one without a key gets this one (\"filled\"); otherwise a\n * new sink at `tier` (\"added\"). */\nexport function adoptSinkToken(url: string, token: string, tier: Tier, file?: string): \"kept\" | \"filled\" | \"added\" {\n const now = file ? readConfig(file) : readConfig();\n const same = now.sinks.find((x) => x.url.replace(/\\/$/, \"\") === url);\n if (same && (same.token || same.token_in)) return \"kept\";\n if (same) same.token = token;\n else now.sinks.push({ name: new URL(url).host, url, tier, pii: false, token });\n if (file) writeConfig(now, file);\n else writeConfig(now);\n return same ? \"filled\" : \"added\";\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The control daemon (spec/CONTROL.md): one process per computer. It holds one\n// long-poll per paired receiver, verifies every command itself against the keys\n// enrolled at this terminal, and delivers each one the cheapest way the session\n// allows \u2014 to a parked waiter, at the session's next Stop, to a session it holds\n// through the Agent SDK, or by a headless resume or fork \u2014 then acks how.\n//\n// A receiver can queue a message; it can never make this process run one.\nimport { existsSync, mkdirSync, realpathSync, statSync, unlinkSync } from \"node:fs\";\nimport net from \"node:net\";\nimport path from \"node:path\";\nimport { claudeControl, redactSecrets } from \"@sessionpipe/core\";\nimport { type ControlCommand, parseSessionRef, verifyCommand } from \"@sessionpipe/core/control\";\nimport { ask, type LocalReply, type LocalRequest } from \"./local.js\";\nimport { awaitAnswer, transcriptEnd } from \"./reply.js\";\nimport { type DeliveryMode, frame, frameStart, IN_PLACE_ANSWER, kindPath, routePrompt } from \"./route.js\";\nimport {\n type Ack,\n AckOutbox,\n type ControlConfig,\n type DaemonState,\n NonceStore,\n type PairedReceiver,\n readState,\n writeControl,\n writeState,\n} from \"./store.js\";\nimport { AnswerStream } from \"./stream.js\";\n\nconst {\n claudeEnv,\n findTranscript,\n isUuid,\n JOB_TIMEOUT_MS,\n liveProcess,\n loginHint,\n modeFlags,\n parseResult,\n recentlyWritten,\n sessionFolder,\n} = claudeControl;\ntype Caps = claudeControl.Caps;\ntype RunResult = claudeControl.RunResult;\ntype Login = claudeControl.Login;\n\ndeclare const __SESSIONPIPE_VERSION__: string;\nconst VERSION = typeof __SESSIONPIPE_VERSION__ === \"string\" ? __SESSIONPIPE_VERSION__ : \"0.0.0\";\n\nconst MAX_REPLY = 20_000;\nconst HELLO_EVERY_MS = 10 * 60_000;\n/** A message waiting for a Stop that never comes goes another way after this. */\nconst TURN_FALLBACK_MS = 30 * 60_000;\n/** How long the daemon follows a session's turn for the answer to an in-place\n * message before acking it delivered without one. */\nconst ANSWER_WAIT_MS = 30 * 60_000;\n/** How long a Stop hook may take to be answered. */\nconst RECENT_ACKS_MS = 25 * 3600_000;\n/** Events that prove a pending permission prompt was resolved some other way. */\nconst CLOSES_ATTENTION = new Set([\n \"PostToolUse\",\n \"PostToolUseFailure\",\n \"Stop\",\n \"StopFailure\",\n \"UserPromptSubmit\",\n \"SessionEnd\",\n]);\n\n/** The message as the receiver carried it (control.json). */\nexport interface Carried {\n id: string;\n cmd: string;\n csig?: string | null;\n grant?: { str: string; cred: string; ad: string; cd: string; sig: string } | null;\n confirm?: { cred: string; ad: string; cd: string; sig: string } | null;\n at: string;\n expires_at: string;\n}\n\n/** A session the Agent SDK holds for the daemon (sdk.ts; a fake in tests). */\nexport interface SdkSession {\n /** Deliver one message; resolves with the agent's reply when the turn ends. */\n send(text: string): Promise<{ reply: string; error?: string }>;\n interrupt(): Promise<void>;\n close(): void;\n readonly busy: boolean;\n readonly lastUsed: number;\n}\nexport interface SdkHost {\n start(o: {\n session: string;\n cwd: string;\n mode: \"safe\" | \"auto\";\n configDir?: string;\n allowedTools?: string[];\n }): SdkSession;\n}\n\nexport interface DaemonDeps {\n now: () => number;\n fetch: typeof fetch;\n log: (line: string) => void;\n claudeDirs: () => string[];\n claude: () => { bin: string; caps: Caps } | null;\n run: (\n bin: string,\n args: string[],\n o: { cwd: string; env: NodeJS.ProcessEnv; timeoutMs?: number; onLine?: (line: string) => void },\n ) => Promise<RunResult>;\n sdk?: SdkHost | null;\n /** How long to follow a live session's turn for an in-place answer (tests shorten it). */\n answerWaitMs?: number;\n /** Close an SDK session idle this long (a held session costs ~300 MB). */\n sdkIdleMs?: number;\n env?: NodeJS.ProcessEnv;\n /** Is Claude Code signed in for this account, as this process sees it? Asked before\n * a headless run, so a login the daemon can't read (a macOS keychain with nobody at\n * the screen) fails with what to do, not with Claude Code's \"please run /login\". */\n login?: (configDir?: string) => Promise<Login>;\n /** Read a receiver's machine token again: it may live in a keychain that was\n * locked when the daemon started and has unlocked since. */\n token?: (r: PairedReceiver) => string | null;\n platform?: NodeJS.Platform;\n /** `sessionpipe update` installed a new copy: restart onto it once idle. True when\n * accepted (autoupdate.ts). */\n onRestart?: () => boolean;\n /** The updater's view, for `control status`. */\n updateStatus?: () => unknown;\n /** Another daemon took the socket path: this one has stopped and should exit. */\n onLostSocket?: () => void;\n}\n\n/** Another daemon already answers on the socket: this one must not start. */\nexport class DaemonRunning extends Error {\n constructor(readonly other: { pid?: number; version?: string }) {\n super(\n `another control daemon already serves this machine (${other.pid ? `pid ${other.pid}, ` : \"\"}sessionpipe ${other.version ?? \"?\"})`,\n );\n }\n}\n\ninterface TurnPending {\n receiver: PairedReceiver;\n msgId: string;\n text: string;\n session: string;\n queuedAt: number;\n}\n\ninterface Live {\n midTurn: boolean;\n /** The Stop hook just delivered a block: the next Stop event continues the turn. */\n continued: boolean;\n waiter: net.Socket | null;\n turnQueue: TurnPending[];\n attentions: Map<string, net.Socket>;\n cwd?: string;\n transcript?: string;\n lastEvent: number;\n}\n\nexport interface Status {\n version: string;\n pid: number;\n name: string;\n receivers: {\n url: string;\n machine: string;\n keys: number;\n polling: boolean;\n last_poll: number | null;\n last_error: string | null;\n }[];\n waiting: string[];\n mid_turn: string[];\n attentions: { session: string; id: string }[];\n sdk: string[];\n nonces: number;\n acks_pending: number;\n delivered: Record<string, number>;\n /** Null when the daemon could restart now (nothing in hand); otherwise what it holds. */\n busy: string | null;\n update?: unknown;\n}\n\n/** The machine's own caps (CONTROL.md \u00A76 `start`): every command is the owner's,\n * signed, but a burst of them must not start a crowd of agents. A start beyond the\n * caps is refused `start_limit`; a headless run beyond `headless` waits its turn. */\n/** What a receiver may let its sessions use without asking (CONTROL.md \u00A76): its own MCP\n * servers, by name \u2014 never a built-in tool. The receiver is where the message came\n * from, so answering it there (publishing a page, replying) is the job; anything else\n * still needs the person's approval rule. */\nexport function sessionToolsFrom(v: unknown): string[] {\n if (!Array.isArray(v)) return [];\n return [\n ...new Set(v.filter((t): t is string => typeof t === \"string\" && /^mcp__[A-Za-z0-9_-]{1,64}$/.test(t))),\n ].slice(0, 8);\n}\n\nexport const LIMITS = { startConcurrent: 2, startPerHour: 10, headless: 3 } as const;\n\nexport class ControlDaemon {\n private server: net.Server | null = null;\n private readonly live = new Map<string, Live>();\n private readonly sdkSessions = new Map<string, SdkSession>();\n private readonly nonces: NonceStore;\n private readonly acks: AckOutbox;\n private readonly recentAcks = new Map<string, { ack: Ack; at: number }>();\n private readonly inflight = new Set<string>();\n private readonly queues = new Map<string, Promise<unknown>>();\n private readonly lastEnd = new Map<string, number>();\n private state: DaemonState;\n private running = false;\n private readonly polling = new Map<string, { last: number | null; error: string | null; on: boolean }>();\n private readonly delivered: Record<string, number> = {};\n private helloTimer: NodeJS.Timeout | null = null;\n private helloSoon: NodeJS.Timeout | null = null;\n private readonly aborts = new Set<AbortController>();\n /** Per receiver: the MCP servers its sessions may use unattended (its well-known). */\n private readonly sessionTools = new Map<string, string[]>();\n /** Sessions a run of the daemon's own is working on right now (a start, a resume):\n * a message for one waits for that run and resumes it \u2014 never a copy, which would\n * set two agents on one task (2026-10-02: a \"just merge when ready\" sent while the\n * start still ran forked a second agent that raced the first toward main). */\n private readonly ownRuns = new Map<string, number>();\n private startsRunning = 0;\n private startTimes: number[] = [];\n private procs = 0;\n private readonly procWaiters: (() => void)[] = [];\n /** configDir \u2192 the last login answer and when (a yes is kept 10 minutes, a no 30 s). */\n private readonly logins = new Map<string, { at: number; login: Login }>();\n /** Intake paused for an update: the long-polls end and wait for this. */\n private paused: { until: Promise<void>; go: () => void } | null = null;\n /** Poll answers whose messages are being read and handed out. */\n private receiving = 0;\n /** The socket file this daemon created (dev:ino): stop() removes only that one, and a\n * different file at the path means another daemon took over. */\n private sockId: string | null = null;\n private ownTimer: NodeJS.Timeout | null = null;\n /** Every open local connection: stop() ends them, or the server's close would wait\n * on a client that never says anything. */\n private readonly conns = new Set<net.Socket>();\n\n constructor(\n private cfg: ControlConfig,\n private readonly dir: string,\n private readonly sock: string,\n private readonly deps: DaemonDeps,\n ) {\n this.nonces = new NonceStore(path.join(dir, \"nonces.jsonl\"), deps.now);\n this.acks = new AckOutbox(path.join(dir, \"acks.jsonl\"));\n this.state = readState(path.join(dir, \"state.json\"));\n }\n\n // --- lifecycle ------------------------------------------------------------------\n\n async start(): Promise<void> {\n this.running = true;\n mkdirSync(this.dir, { recursive: true, mode: 0o700 });\n await this.listen();\n for (const r of this.cfg.receivers) void this.pollLoop(r);\n this.helloTimer = setInterval(() => void this.helloAll(), HELLO_EVERY_MS);\n this.helloTimer.unref();\n void this.helloAll();\n void this.flushAcks();\n const idle = setInterval(() => this.closeIdleSdk(), 60_000);\n idle.unref();\n if (this.sockId) {\n this.ownTimer = setInterval(() => void this.checkSocket(), 10_000);\n this.ownTimer.unref();\n }\n this.deps.log(\n `control daemon ${VERSION} up \u00B7 pid ${process.pid} \u00B7 ${this.cfg.receivers.length} receiver(s) \u00B7 socket ${this.sock}`,\n );\n }\n\n /** `leaveSocket`: the socket path is another daemon's now. Closing a Unix-socket\n * server makes Node unlink its path whoever holds it, so this one's server is left\n * open for the process's exit to drop. */\n async stop(o: { leaveSocket?: boolean } = {}): Promise<void> {\n this.running = false;\n this.paused?.go();\n for (const a of this.aborts) a.abort();\n if (this.helloTimer) clearInterval(this.helloTimer);\n if (this.helloSoon) clearTimeout(this.helloSoon);\n if (this.ownTimer) clearInterval(this.ownTimer);\n for (const s of this.sdkSessions.values()) s.close();\n for (const l of this.live.values()) {\n l.waiter?.destroy();\n for (const a of l.attentions.values()) a.destroy();\n }\n for (const c of this.conns) c.destroy();\n if (o.leaveSocket) {\n this.sockId = null;\n return;\n }\n await new Promise<void>((r) => (this.server ? this.server.close(() => r()) : r()));\n this.server = null;\n // Only the socket file this daemon made: after a hand-over the path is someone else's.\n if (process.platform !== \"win32\" && this.sockId && socketId(this.sock) === this.sockId)\n try {\n unlinkSync(this.sock);\n } catch {}\n this.sockId = null;\n }\n\n /** Null when nothing is in hand, so a restart would interrupt nothing; otherwise what\n * is. Parked waiters don't count: a waiter reconnects in silence (CONTROL.md \u00A78). A\n * session someone is working in mid-turn does (a restart forgets it is mid-turn, so a\n * message to it would fork rather than wait for its Stop), unless it has been silent\n * for ten minutes: a session killed mid-turn never sends its Stop. */\n busy(): string | null {\n if (this.inflight.size) return `${this.inflight.size} message(s) in hand`;\n if (this.procs || this.ownRuns.size) return \"a headless Claude Code run\";\n if (this.startsRunning) return \"a session starting\";\n for (const s of this.sdkSessions.values()) if (s.busy) return \"an Agent SDK session mid-turn\";\n for (const l of this.live.values()) if (l.attentions.size) return \"a permission prompt waiting for an answer\";\n const now = this.deps.now();\n for (const l of this.live.values())\n if (l.midTurn && now - l.lastEvent < 10 * 60_000) return \"a session on this machine mid-turn\";\n if (this.receiving) return \"messages just received\";\n if (this.flushing) return \"acks being sent\";\n return null;\n }\n\n /** Stop taking messages: every long-poll ends now and waits for resumeIntake(). The\n * receiver keeps what arrives meanwhile; the local socket keeps answering. */\n pauseIntake(): void {\n if (this.paused) return;\n let go!: () => void;\n const until = new Promise<void>((r) => {\n go = r;\n });\n this.paused = { until, go };\n for (const a of this.aborts) a.abort();\n }\n\n resumeIntake(): void {\n const p = this.paused;\n this.paused = null;\n p?.go();\n }\n\n /** The socket path still holds this daemon's file. Gone: listen again. Replaced:\n * another daemon took over (two started at once), so this one steps aside. */\n private async checkSocket(): Promise<void> {\n if (!this.running || !this.sockId) return;\n const now = socketId(this.sock);\n if (now === this.sockId) return;\n if (now === null) {\n // Someone deleted the file. The old server keeps the connections it has (closing\n // it would wait on parked waiters, and unlink the path again); a new one takes it.\n this.deps.log(`the socket ${this.sock} vanished; listening again`);\n this.server?.unref();\n this.server = null;\n try {\n await this.listen();\n } catch (e) {\n this.deps.log(`couldn't listen again: ${String((e as Error)?.message || e)}`);\n }\n return;\n }\n this.deps.log(\"another control daemon took over the socket; this one stops\");\n await this.stop({ leaveSocket: true });\n this.deps.onLostSocket?.();\n }\n\n reload(cfg: ControlConfig): void {\n const known = new Set(this.cfg.receivers.map((r) => r.control + r.machine));\n this.cfg = cfg;\n for (const r of cfg.receivers) if (!known.has(r.control + r.machine)) void this.pollLoop(r);\n }\n\n status(): Status {\n return {\n version: VERSION,\n pid: process.pid,\n name: this.cfg.name,\n receivers: this.cfg.receivers.map((r) => {\n const p = this.polling.get(r.control + r.machine);\n return {\n url: r.url,\n machine: r.machine,\n keys: r.keys.length,\n polling: !!p?.on,\n last_poll: p?.last ?? null,\n last_error: p?.error ?? null,\n };\n }),\n waiting: [...this.live].filter(([, l]) => l.waiter).map(([k]) => k),\n mid_turn: [...this.live].filter(([, l]) => l.midTurn).map(([k]) => k),\n attentions: [...this.live].flatMap(([k, l]) => [...l.attentions.keys()].map((id) => ({ session: k, id }))),\n sdk: [...this.sdkSessions.keys()],\n nonces: this.nonces.size,\n acks_pending: this.acks.all().length,\n delivered: { ...this.delivered },\n busy: this.busy(),\n ...(this.deps.updateStatus ? { update: this.deps.updateStatus() } : {}),\n };\n }\n\n // --- the local socket -----------------------------------------------------------\n\n /** One daemon per machine: a daemon that answers on the socket keeps it, and this\n * one doesn't start. A socket file nobody answers on is a dead daemon's; it goes. */\n private async listen(): Promise<void> {\n const other = await ask(this.sock, { op: \"status\" }, 1500);\n if (other?.op === \"status\") throw new DaemonRunning((other.status ?? {}) as { pid?: number; version?: string });\n if (process.platform !== \"win32\") {\n try {\n if (existsSync(this.sock)) unlinkSync(this.sock);\n } catch {}\n }\n this.server = net.createServer((s) => this.onConn(s));\n await new Promise<void>((resolve, reject) => {\n this.server!.once(\"error\", reject);\n this.server!.listen(this.sock, () => resolve());\n });\n if (process.platform !== \"win32\") this.sockId = socketId(this.sock);\n }\n\n private onConn(s: net.Socket): void {\n let buf = \"\";\n let handled = false;\n this.conns.add(s);\n s.on(\"close\", () => this.conns.delete(s));\n s.on(\"error\", () => {});\n s.on(\"data\", (d) => {\n if (handled) return;\n buf += d.toString(\"utf8\");\n if (buf.length > 64 * 1024) return s.destroy();\n const i = buf.indexOf(\"\\n\");\n if (i < 0) return;\n handled = true;\n let req: LocalRequest;\n try {\n req = JSON.parse(buf.slice(0, i)) as LocalRequest;\n } catch {\n return s.destroy();\n }\n this.onRequest(req, s);\n });\n }\n\n private reply(s: net.Socket, r: LocalReply): void {\n try {\n s.end(`${JSON.stringify(r)}\\n`);\n } catch {}\n }\n\n private liveOf(session: string): Live {\n let l = this.live.get(session);\n if (!l) {\n l = {\n midTurn: false,\n continued: false,\n waiter: null,\n turnQueue: [],\n attentions: new Map(),\n lastEvent: this.deps.now(),\n };\n this.live.set(session, l);\n }\n return l;\n }\n\n private onRequest(req: LocalRequest, s: net.Socket): void {\n switch (req.op) {\n case \"status\":\n this.reply(s, { op: \"status\", status: this.status() });\n return;\n case \"wait\": {\n if (!parseSessionRef(req.session)) {\n this.reply(s, { op: \"none\" });\n return;\n }\n const l = this.liveOf(req.session);\n if (l.waiter && l.waiter !== s) this.reply(l.waiter, { op: \"replaced\" });\n l.waiter = s;\n s.on(\"close\", () => {\n if (l.waiter === s) {\n l.waiter = null;\n this.scheduleHello();\n }\n });\n this.scheduleHello();\n return;\n }\n case \"stop\": {\n const l = this.liveOf(req.session);\n l.lastEvent = this.deps.now();\n const p = this.takeTurn(l);\n if (!p) {\n this.reply(s, { op: \"none\" });\n return;\n }\n l.continued = true;\n const from = this.answerFrom(req.session);\n this.reply(s, { op: \"block\", reason: `${frame(p.text, p.receiver.url)}\\n\\n${IN_PLACE_ANSWER}`, id: p.msgId });\n this.followAnswer(p.receiver, p.msgId, \"turn\", req.session, from, p.queuedAt);\n return;\n }\n case \"permission\": {\n const l = this.liveOf(req.session);\n const prev = l.attentions.get(req.attention);\n if (prev && prev !== s) this.reply(prev, { op: \"none\" });\n l.attentions.set(req.attention, s);\n s.on(\"close\", () => {\n if (l.attentions.get(req.attention) === s) l.attentions.delete(req.attention);\n });\n return;\n }\n case \"event\":\n this.onEvent(req);\n this.reply(s, { op: \"ok\" });\n return;\n case \"restart\":\n this.reply(s, this.deps.onRestart?.() ? { op: \"ok\" } : { op: \"none\" });\n return;\n default:\n s.destroy();\n }\n }\n\n /** A queued turn message that hasn't expired. */\n private takeTurn(l: Live): TurnPending | null {\n while (l.turnQueue.length) {\n const p = l.turnQueue.shift()!;\n if (!this.inflight.has(p.msgId)) continue;\n return p;\n }\n return null;\n }\n\n private onEvent(e: Extract<LocalRequest, { op: \"event\" }>): void {\n const l = this.liveOf(e.session);\n l.lastEvent = this.deps.now();\n if (e.cwd) l.cwd = e.cwd;\n if (e.transcript) l.transcript = e.transcript;\n if (CLOSES_ATTENTION.has(e.event) && l.attentions.size) {\n for (const s of l.attentions.values()) this.reply(s, { op: \"none\" });\n l.attentions.clear();\n }\n if (e.event === \"UserPromptSubmit\" || e.event === \"SessionStart\") {\n if (e.event === \"UserPromptSubmit\") l.midTurn = true;\n return;\n }\n if (e.event === \"Stop\" && l.continued) {\n l.continued = false;\n return;\n }\n if (e.event === \"Stop\" || e.event === \"StopFailure\" || e.event === \"SessionEnd\") {\n l.midTurn = false;\n l.continued = false;\n // A message queued for a Stop that came and went without taking it (it\n // arrived after the hook asked, or the turn failed) goes another way.\n const left = l.turnQueue.splice(0);\n for (const p of left) if (this.inflight.has(p.msgId)) void this.reroute(p);\n }\n }\n\n // --- receivers ------------------------------------------------------------------\n\n private async pollLoop(first: PairedReceiver): Promise<void> {\n const key = first.control + first.machine;\n const st = { last: null as number | null, error: null as string | null, on: true };\n this.polling.set(key, st);\n let backoff = 0;\n let downSince = 0;\n // A deploy takes the receiver away for seconds, not minutes: retry soon, capped at\n // 15 s (one request per machine), with jitter so every machine a deploy dropped\n // doesn't come back in the same instant. The old 60 s / 5 min steps left a\n // machine blind for minutes after a 30-second outage.\n const steps = [1000, 2000, 5000, 10_000, 15_000];\n const pause = (n: number) => (steps[Math.min(n, steps.length - 1)] as number) * (0.75 + Math.random() * 0.5);\n for (;;) {\n // The current record every round: `control pair` may have added a key since.\n const r = this.cfg.receivers.find((x) => x.control + x.machine === key);\n if (!this.running || !r) break;\n if (this.paused) {\n await this.paused.until;\n continue;\n }\n if (!r.token) {\n // Its token lives in a keychain this process can't read yet (locked, or nobody\n // logged in): ask again every 30 s rather than poll with no bearer.\n const t = this.deps.token?.(r) ?? null;\n if (t) {\n r.token = t;\n this.deps.log(`${r.url}: machine token readable again`);\n } else {\n if (!st.error?.startsWith(\"can't read\"))\n this.deps.log(`${r.url}: can't read this machine's token from ${r.token_in ?? \"its store\"}; retrying`);\n st.error = `can't read this machine's token from ${r.token_in ?? \"its store\"} (locked?); retrying every 30 s`;\n await new Promise((res) => setTimeout(res, 30_000));\n continue;\n }\n }\n const ctl = new AbortController();\n this.aborts.add(ctl);\n // A poll held past wait + 10 s is a dead connection (a laptop that slept, a\n // network that changed): give up on it and ask again.\n const t = setTimeout(() => ctl.abort(), 35_000);\n try {\n const u = new URL(r.control);\n u.searchParams.set(\"machine\", r.machine);\n u.searchParams.set(\"wait\", \"25\");\n const asked = this.deps.now();\n const res = await this.deps.fetch(u, { headers: { authorization: `Bearer ${r.token}` }, signal: ctl.signal });\n st.last = this.deps.now();\n if (downSince && res.status < 500) {\n // Timed to when this poll was sent: a long-poll that reconnected is then held\n // up to `wait` before it answers.\n this.deps.log(`${r.url}: back after ${Math.round((asked - downSince) / 1000)} s (${backoff} failed tries)`);\n downSince = 0;\n }\n if (res.status === 401) {\n st.error = \"the receiver no longer knows this machine (401); run `sessionpipe control pair` again\";\n this.deps.log(`${r.url}: ${st.error}`);\n break;\n }\n if (res.status === 200) {\n let fresh = 0;\n this.receiving++;\n try {\n const body = (await res.json()) as { messages?: Carried[] };\n // Looked up again: a key may have been added while this poll was parked.\n const cur = this.cfg.receivers.find((x) => x.control + x.machine === key) ?? r;\n // Not awaited: a headless turn can run for half an hour, and the next\n // message (for another session, or a permission answer) must not wait\n // behind it. handle() orders what must be ordered (one session's prompts).\n for (const m of body.messages ?? []) {\n if (m && !this.inflight.has(m.id)) fresh++;\n void this.handle(cur, m).catch((e) =>\n this.deps.log(`handle ${String(m?.id).slice(-8)}: ${String((e as Error)?.message || e)}`),\n );\n }\n } finally {\n this.receiving--;\n }\n // Only messages already in hand (a receiver that ignores `taken`): don't\n // turn the long-poll into a spin.\n if (!fresh) await sleep(2000);\n st.error = null;\n backoff = 0;\n } else if (res.status === 204) {\n st.error = null;\n backoff = 0;\n } else {\n st.error = `HTTP ${res.status}`;\n downSince ||= this.deps.now();\n await sleep(pause(backoff++));\n }\n } catch (e) {\n if (!this.running) break;\n // Paused for an update: the abort was ours, not the network's.\n if (this.paused) continue;\n st.error = String((e as Error)?.message || e).slice(0, 120);\n downSince ||= this.deps.now();\n await sleep(pause(backoff++));\n } finally {\n clearTimeout(t);\n this.aborts.delete(ctl);\n }\n }\n st.on = false;\n }\n\n private scheduleHello(): void {\n if (this.helloSoon) return;\n this.helloSoon = setTimeout(() => {\n this.helloSoon = null;\n void this.helloAll();\n }, 1500);\n this.helloSoon.unref();\n }\n\n /** Read each receiver's well-known for its session tools (at start, then with every hello). */\n private async refreshSessionTools(): Promise<void> {\n for (const r of this.cfg.receivers) {\n try {\n const res = await this.deps.fetch(`${r.url.replace(/\\/$/, \"\")}/.well-known/sessionpipe`, {\n signal: AbortSignal.timeout(8000),\n });\n if (!res.ok) continue;\n const wk = (await res.json()) as { control?: { session_tools?: unknown } };\n const tools = sessionToolsFrom(wk.control?.session_tools);\n const key = r.control + r.machine;\n if (JSON.stringify(tools) !== JSON.stringify(this.sessionTools.get(key) ?? []))\n this.deps.log(\n `${r.url}: sessions it messages may use ${tools.length ? tools.join(\", \") : \"nothing extra\"} without asking`,\n );\n this.sessionTools.set(key, tools);\n } catch {}\n }\n }\n\n private allowedFor(r: PairedReceiver): string[] {\n return this.sessionTools.get(r.control + r.machine) ?? [];\n }\n\n private async helloAll(): Promise<void> {\n void this.refreshSessionTools();\n const waiting = [...this.live].filter(([, l]) => l.waiter).map(([k]) => k);\n const modes: DeliveryMode[] = [\"waiter\", \"turn\", \"resume\", \"fork\", ...(this.deps.sdk ? ([\"sdk\"] as const) : [])];\n for (const r of this.cfg.receivers) {\n const body = {\n name: this.cfg.name,\n harnesses: [\"claude-code\"],\n modes,\n keys: r.keys.map((k) => k.id),\n version: VERSION,\n waiting,\n folders: this.cfg.folders,\n mode: this.cfg.mode,\n };\n await this.post(r, \"/hello\", body).catch(() => {});\n }\n }\n\n private async post(r: PairedReceiver, sub: string, body: unknown): Promise<Response> {\n const ctl = new AbortController();\n const t = setTimeout(() => ctl.abort(), 15_000);\n try {\n return await this.deps.fetch(`${r.control.replace(/\\/$/, \"\")}${sub}`, {\n method: \"POST\",\n headers: { authorization: `Bearer ${r.token}`, \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: ctl.signal,\n });\n } finally {\n clearTimeout(t);\n }\n }\n\n // --- acks -----------------------------------------------------------------------\n\n private finish(r: PairedReceiver, id: string, a: Omit<Ack, \"receiver\" | \"id\" | \"at\">, since?: number): void {\n const ack: Ack = { receiver: r.control + r.machine, id, at: new Date(this.deps.now()).toISOString(), ...a };\n if (ack.reply) ack.reply = redactSecrets(ack.reply).slice(0, MAX_REPLY);\n if (ack.detail) ack.detail = redactSecrets(ack.detail).slice(0, 500);\n if (a.outcome !== \"taken\") {\n this.inflight.delete(id);\n this.recentAcks.set(id, { ack, at: this.deps.now() });\n this.delivered[a.mode ?? a.outcome] = (this.delivered[a.mode ?? a.outcome] ?? 0) + 1;\n this.deps.log(\n `ack ${id.slice(-8)} ${a.outcome}${a.mode ? ` via ${a.mode}` : \"\"}${a.code ? ` (${a.code})` : \"\"}${since ? ` send\u2192${a.outcome} ${this.deps.now() - since} ms` : \"\"}`,\n );\n }\n this.acks.add(ack);\n void this.flushAcks();\n }\n\n private flushing = false;\n private async flushAcks(): Promise<void> {\n if (this.flushing) return;\n this.flushing = true;\n try {\n for (let round = 0; round < 5; round++) {\n const all = this.acks.all();\n if (!all.length) return;\n const left: Ack[] = [];\n for (const r of this.cfg.receivers) {\n const mine = all.filter((a) => a.receiver === r.control + r.machine);\n if (!mine.length) continue;\n const acks = mine.map(({ receiver: _r, ...a }) => a);\n const ok = await this.post(r, \"/ack\", { acks })\n .then((res) => res.status >= 200 && res.status < 300)\n .catch(() => false);\n if (!ok) left.push(...mine);\n }\n // Acks for a receiver no longer paired are dropped.\n const now = this.acks.all();\n const added = now.slice(all.length);\n this.acks.keep([...left, ...added]);\n if (!left.length && !added.length) return;\n if (left.length) await sleep(2000 * (round + 1));\n }\n } finally {\n this.flushing = false;\n }\n }\n\n // --- one message ----------------------------------------------------------------\n\n async handle(r: PairedReceiver, m: Carried): Promise<void> {\n if (!m || typeof m.id !== \"string\") return;\n if (this.inflight.has(m.id)) return; // redelivered while we work on it\n const prior = this.recentAcks.get(m.id);\n if (prior && this.deps.now() - prior.at < RECENT_ACKS_MS) {\n this.acks.add(prior.ack);\n void this.flushAcks();\n return;\n }\n // In hand from here, before anything is awaited: a redelivery that arrives while\n // this one verifies must not verify too and come back `replay`. Every path below\n // ends in finish(), which lets go of it.\n this.inflight.add(m.id);\n const sent = Date.parse(m.at) || this.deps.now();\n if (Date.parse(m.expires_at) <= this.deps.now()) return this.finish(r, m.id, { outcome: \"expired\" });\n const v = await verifyCommand(\n { cmd: m.cmd, csig: m.csig ?? null, grant: m.grant ?? null, confirm: m.confirm ?? null },\n { machine: r.machine, rpId: r.rpId, trusted: r.keys, now: this.deps.now(), seenNonce: this.nonces.seen },\n );\n if (!v.ok) {\n this.deps.log(`refused ${m.id.slice(-8)}: ${v.code} \u2014 ${v.why}`);\n return this.finish(r, m.id, { outcome: \"refused\", code: v.code, detail: v.why });\n }\n const cmd = v.cmd;\n // A device this machine already trusts vouched for a new one (CONTROL.md \u00A72): the\n // signature just verified against an enrolled key, so the new key joins the store.\n if (cmd.kind === \"key.add\") return this.addKey(r, m.id, cmd, sent);\n const ref = parseSessionRef(cmd.session)!;\n const kp = kindPath(cmd.kind, ref.harness);\n if (typeof kp === \"object\") return this.finish(r, m.id, { outcome: \"unsupported\", detail: kp.unsupported });\n try {\n if (kp === \"start\") return await this.startSession(r, m.id, cmd, sent);\n let place = this.place(cmd.session);\n // A session the daemon is still starting may have no transcript yet: wait for\n // that run on the session's queue, then place it again.\n if (\"refused\" in place && this.ownRuns.has(ref.id)) {\n this.finish(r, m.id, { outcome: \"taken\" });\n await this.serial(ref.id, async () => {});\n place = this.place(cmd.session);\n }\n if (\"refused\" in place)\n return this.finish(r, m.id, { outcome: \"refused\", code: place.refused, detail: place.why });\n if (kp === \"permission\") return this.permission(r, m.id, cmd, sent);\n if (kp === \"cancel\") return await this.cancel(r, m.id, cmd, sent);\n // One session's prompts in the order they came, each routed only once the one\n // before it has landed (a second message to a session the first one forked\n // goes to the copy). Other sessions don't wait.\n return await this.serial(`deliver:${cmd.session}`, async () => {\n // Read again: the message before this one may have moved the session (a fork).\n const now = this.place(cmd.session);\n if (\"refused\" in now) return this.finish(r, m.id, { outcome: \"refused\", code: now.refused, detail: now.why });\n return this.prompt(r, m.id, cmd, now, sent);\n });\n } catch (e) {\n this.finish(r, m.id, { outcome: \"failed\", detail: String((e as Error)?.message || e) });\n }\n }\n\n /** Where the session lives, and whether its folder is allowed \u2014 read from the\n * session's own transcript (Claude Code) or the hooks' cwd, never the command. */\n private place(\n session: string,\n ): { refused: string; why: string } | { folder: string; transcript: ReturnType<typeof findTranscript> } {\n const ref = parseSessionRef(session)!;\n if (ref.harness === \"claude-code\") {\n const target = this.state.copies[ref.id] ?? ref.id;\n const t = findTranscript(target, this.deps.claudeDirs()) ?? findTranscript(ref.id, this.deps.claudeDirs());\n if (!t) return { refused: \"no_session\", why: `no Claude Code session ${ref.id.slice(0, 8)} on this machine` };\n const folder = sessionFolder(t);\n const ok = folder && this.allowed(folder);\n if (!ok) return { refused: \"folder\", why: \"that session's folder isn't one this machine allows\" };\n return { folder: ok, transcript: t };\n }\n const cwd = this.live.get(session)?.cwd;\n const ok = cwd && this.allowed(cwd);\n if (!ok) return { refused: cwd ? \"folder\" : \"no_session\", why: \"no allowed folder known for that session\" };\n return { folder: ok, transcript: null };\n }\n\n private allowed(dir: string): string | null {\n if (!path.isAbsolute(dir)) return null;\n let r: string;\n try {\n r = realpathSync.native(dir);\n if (!statSync(r).isDirectory()) return null;\n } catch {\n return null;\n }\n for (const f of this.cfg.folders) {\n let rf = f;\n try {\n rf = realpathSync.native(f);\n } catch {}\n if (r === rf || r.startsWith(rf.endsWith(path.sep) ? rf : rf + path.sep)) return r;\n }\n return null;\n }\n\n private permission(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number) {\n const l = this.live.get(cmd.session);\n const hook = l?.attentions.get(cmd.for as string);\n if (!hook) {\n // Nothing is ever auto-allowed: an allow needs a prompt open right now.\n if (cmd.decision === \"allow\")\n return this.finish(r, id, {\n outcome: \"refused\",\n code: \"no_attention\",\n detail: \"no permission prompt open for that id\",\n });\n this.finish(r, id, { outcome: \"expired\", detail: \"the prompt was already answered or closed\" });\n return;\n }\n l!.attentions.delete(cmd.for as string);\n this.reply(hook, {\n op: \"decision\",\n behavior: cmd.decision as \"allow\" | \"deny\",\n ...(cmd.note ? { message: cmd.note } : {}),\n id,\n });\n this.finish(r, id, { outcome: \"delivered\", mode: \"turn\" }, sent);\n }\n\n private async cancel(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number): Promise<void> {\n const ref = parseSessionRef(cmd.session)!;\n const held = this.sdkSessions.get(ref.id);\n if (!held)\n return this.finish(r, id, {\n outcome: \"unsupported\",\n detail: \"no cancel path for a session the daemon doesn't hold\",\n });\n await held.interrupt();\n this.finish(r, id, { outcome: \"delivered\", mode: \"sdk\" }, sent);\n }\n\n private view(session: string, transcript: ReturnType<typeof findTranscript>) {\n const ref = parseSessionRef(session)!;\n const l = this.live.get(session);\n const claude = ref.harness === \"claude-code\" ? this.deps.claude() : null;\n const target = this.state.copies[ref.id] ?? ref.id;\n const t = transcript;\n // The daemon's own run holding it is not \"someone else's live process\": the message\n // queues behind that run (serial per session) and resumes it.\n const live =\n !this.ownRuns.has(target) &&\n !!t &&\n (liveProcess(target, t.configDir) || recentlyWritten(t.file, this.lastEnd.get(target), this.deps.now()));\n return {\n harness: ref.harness,\n sdk: this.sdkSessions.has(ref.id),\n waiter: !!l?.waiter && !l.waiter.destroyed,\n midTurn: !!l?.midTurn,\n live,\n known: !!t,\n canFork: !!claude?.caps.fork,\n api: false,\n };\n }\n\n private async prompt(\n r: PairedReceiver,\n id: string,\n cmd: ControlCommand,\n place: { folder: string; transcript: ReturnType<typeof findTranscript> },\n sent: number,\n ): Promise<void> {\n const route = routePrompt(this.view(cmd.session, place.transcript));\n if (\"unsupported\" in route) return this.finish(r, id, { outcome: \"unsupported\", detail: route.unsupported });\n if (\"refused\" in route) return this.finish(r, id, { outcome: \"refused\", code: route.refused });\n const ref = parseSessionRef(cmd.session)!;\n const text = cmd.text as string;\n switch (route.mode) {\n case \"waiter\": {\n const l = this.live.get(cmd.session)!;\n const w = l.waiter!;\n l.waiter = null;\n const from = this.answerFrom(cmd.session);\n this.reply(w, { op: \"message\", text: frame(text, r.url), id });\n this.scheduleHello();\n return this.followAnswer(r, id, \"waiter\", cmd.session, from, sent);\n }\n case \"turn\": {\n const l = this.liveOf(cmd.session);\n const p: TurnPending = { receiver: r, msgId: id, text, session: cmd.session, queuedAt: sent };\n l.turnQueue.push(p);\n // It waits for the session's Stop: the receiver must not keep handing it back.\n this.finish(r, id, { outcome: \"taken\" });\n const t = setTimeout(() => {\n if (this.inflight.has(id) && l.turnQueue.includes(p)) {\n l.turnQueue.splice(l.turnQueue.indexOf(p), 1);\n void this.reroute(p);\n }\n }, TURN_FALLBACK_MS);\n t.unref();\n return;\n }\n case \"sdk\": {\n const s = this.sdkSessions.get(ref.id)!;\n this.finish(r, id, { outcome: \"taken\" });\n const out = await s.send(frame(text, r.url));\n return this.finish(\n r,\n id,\n out.error\n ? { outcome: \"failed\", detail: out.error }\n : { outcome: \"delivered\", mode: \"sdk\", reply: out.reply },\n sent,\n );\n }\n case \"resume\":\n case \"fork\":\n return this.headless(r, id, cmd, place, route.mode, sent);\n case \"api\":\n return this.finish(r, id, { outcome: \"unsupported\", detail: \"no input API wired for this harness\" });\n }\n }\n\n /** A turn message whose Stop never took it: route again, now that it isn't mid-turn. */\n private async reroute(p: TurnPending): Promise<void> {\n const l = this.liveOf(p.session);\n l.midTurn = false;\n const place = this.place(p.session);\n if (\"refused\" in place) return this.finish(p.receiver, p.msgId, { outcome: \"refused\", code: place.refused });\n const cmd = { kind: \"prompt\", session: p.session, text: p.text } as ControlCommand;\n this.inflight.delete(p.msgId);\n this.inflight.add(p.msgId);\n await this.prompt(p.receiver, p.msgId, cmd, place, p.queuedAt).catch((e) =>\n this.finish(p.receiver, p.msgId, { outcome: \"failed\", detail: String((e as Error)?.message || e) }),\n );\n }\n\n /** Jobs for one session (and its copy) run one at a time, in order. */\n private serial<T>(key: string, task: () => Promise<T>): Promise<T> {\n const prev = this.queues.get(key) ?? Promise.resolve();\n const next = prev.then(task, task);\n this.queues.set(\n key,\n next.catch(() => {}),\n );\n return next;\n }\n\n /** Null when Claude Code is signed in for this account (or can't say); otherwise what\n * to tell the person. */\n private async loginProblem(configDir?: string): Promise<string | null> {\n if (!this.deps.login) return null;\n const key = configDir ?? \"\";\n const now = this.deps.now();\n const hit = this.logins.get(key);\n let login = hit && now - hit.at < (hit.login.loggedIn === false ? 30_000 : 600_000) ? hit.login : null;\n if (!login) {\n login = await this.deps.login(configDir).catch((): Login => ({ loggedIn: null }));\n this.logins.set(key, { at: now, login });\n }\n if (login.loggedIn !== false) return null;\n this.deps.log(`claude isn't signed in for ${configDir ?? \"the default account\"} as the daemon sees it`);\n return loginHint(configDir, this.deps.platform ?? process.platform);\n }\n\n private async headless(\n r: PairedReceiver,\n id: string,\n cmd: ControlCommand,\n place: { folder: string; transcript: ReturnType<typeof findTranscript> },\n mode: \"resume\" | \"fork\",\n sent: number,\n ): Promise<void> {\n const claude = this.deps.claude();\n if (!claude)\n return this.finish(r, id, { outcome: \"failed\", detail: \"Claude Code isn't installed on this machine\" });\n const mf = modeFlags(this.cfg.mode, claude.caps);\n if (\"error\" in mf) return this.finish(r, id, { outcome: \"refused\", code: \"mode\", detail: mf.error });\n const signedOut = await this.loginProblem(place.transcript?.configDir);\n if (signedOut) return this.finish(r, id, { outcome: \"failed\", detail: signedOut });\n const ref = parseSessionRef(cmd.session)!;\n this.finish(r, id, { outcome: \"taken\" });\n await this.serial(ref.id, async () => {\n const target = this.state.copies[ref.id] ?? ref.id;\n const resume = mode === \"fork\" ? [\"--resume\", target, \"--fork-session\"] : [\"--resume\", target];\n const allow = this.allowedFor(r);\n const args = [\n \"-p\",\n ...this.outputArgs(claude.caps),\n ...mf.args,\n ...(allow.length ? [`--allowedTools=${allow.join(\",\")}`] : []),\n ...resume,\n frame(cmd.text as string, r.url),\n ];\n this.deps.log(`${id.slice(-8)}: claude -p ${[...mf.args, ...resume].join(\" \")} in ${place.folder}`);\n const stream = this.answerStream(r, id);\n const res = await this.owning(target, () =>\n this.slot(() =>\n this.deps.run(claude.bin, args, {\n cwd: place.folder,\n env: claudeEnv(place.transcript?.configDir, this.deps.env),\n timeoutMs: JOB_TIMEOUT_MS,\n ...(claude.caps.stream ? { onLine: (l: string) => stream.feed(l) } : {}),\n }),\n ),\n );\n stream.close();\n this.lastEnd.set(target, this.deps.now());\n const out = this.outcome(res);\n if (\"failed\" in out) return this.finish(r, id, { outcome: \"failed\", detail: out.failed });\n const ran = isUuid(out.session) ? out.session : target;\n if (mode === \"fork\" && ran !== target) {\n this.state.copies[ref.id] = ran;\n writeState(path.join(this.dir, \"state.json\"), this.state);\n this.lastEnd.set(ran, this.deps.now());\n }\n this.finish(\n r,\n id,\n { outcome: \"delivered\", mode, reply: out.reply, ...(ran !== ref.id ? { session: `claude-code:${ran}` } : {}) },\n sent,\n );\n });\n }\n\n private outcome(res: RunResult): { failed: string } | { reply: string; session?: string } {\n if (res.error) return { failed: `couldn't start Claude Code: ${res.error}` };\n if (res.timedOut) return { failed: \"Claude Code was still working after 30 minutes, so it was stopped\" };\n if (res.tooBig) return { failed: \"Claude Code's answer was too large to read\" };\n const j = parseResult(res.stdout);\n if (!j) {\n const why = String(res.stderr || \"\")\n .trim()\n .split(\"\\n\")\n .slice(-3)\n .join(\" \");\n return {\n failed: `Claude Code exited (${res.signal || `code ${res.code}`}) without an answer${why ? `: ${why}` : \"\"}`,\n };\n }\n if (j.is_error) return { failed: String(j.result || j.subtype || \"Claude Code reported an error\") };\n const denials = Array.isArray(j.permission_denials) ? j.permission_denials : [];\n const names = [...new Set(denials.map((d) => d?.tool_name).filter((n): n is string => typeof n === \"string\"))];\n const tail = denials.length\n ? `\\n\\n(Not allowed on this machine, since nobody was there to approve: ${names.join(\", \") || `${denials.length} action(s)`}.)`\n : \"\";\n const text =\n typeof j.result === \"string\" && j.result.trim() ? j.result : \"(Claude Code finished without a written reply.)\";\n return { reply: text + tail, ...(typeof j.session_id === \"string\" ? { session: j.session_id } : {}) };\n }\n\n private addKey(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number) {\n const k = cmd.key!;\n const name = typeof cmd.name === \"string\" ? cmd.name.trim().slice(0, 80) : undefined;\n const rec = this.cfg.receivers.find((x) => x.control === r.control && x.machine === r.machine) ?? r;\n if (rec.keys.some((x) => x.id === k.id))\n return this.finish(r, id, { outcome: \"delivered\", detail: \"that device was already trusted\" }, sent);\n rec.keys.push({\n id: k.id,\n alg: k.alg,\n spki: k.spki,\n ...(name ? { name } : {}),\n added_at: new Date(this.deps.now()).toISOString(),\n });\n try {\n writeControl(this.cfg, this.deps.env);\n } catch (e) {\n rec.keys = rec.keys.filter((x) => x.id !== k.id);\n return this.finish(r, id, {\n outcome: \"failed\",\n detail: `couldn't save the key: ${String((e as Error)?.message || e)}`,\n });\n }\n this.deps.log(\n `trusted a new device${name ? ` (${name})` : \"\"} on ${r.url}: ${k.id.slice(0, 12)}\u2026, vouched for by a key it already trusted`,\n );\n this.finish(r, id, { outcome: \"delivered\", detail: `trusted ${name || \"a new device\"}` }, sent);\n }\n\n /** Where the session's transcript ends right now: its answer starts after this. */\n private answerFrom(session: string): { file: string; offset: number } | null {\n const ref = parseSessionRef(session);\n if (!ref || ref.harness !== \"claude-code\") return null;\n const t = findTranscript(this.state.copies[ref.id] ?? ref.id, this.deps.claudeDirs());\n return t ? { file: t.file, offset: transcriptEnd(t.file) } : null;\n }\n\n /** A message handed to a live session (a waiter, a Stop block) is `taken` now; the\n * session answers in its own turn, which the daemon reads from the transcript and\n * sends back as the final ack's `reply` \u2014 so the person sees the answer where they\n * asked. A turn that doesn't end within ANSWER_WAIT_MS is acked delivered without. */\n private followAnswer(\n r: PairedReceiver,\n id: string,\n mode: \"waiter\" | \"turn\",\n session: string,\n from: { file: string; offset: number } | null,\n sent: number,\n ): void {\n this.deps.log(`${id.slice(-8)}: in ${session.slice(0, 24)} via ${mode} ${this.deps.now() - sent} ms after send`);\n this.finish(r, id, { outcome: \"taken\" });\n const stream = this.answerStream(r, id);\n void (async () => {\n const answer = from\n ? await awaitAnswer(from.file, from.offset, {\n timeoutMs: this.deps.answerWaitMs ?? ANSWER_WAIT_MS,\n now: this.deps.now,\n onText: (t) => stream.set(t),\n })\n : null;\n stream.close();\n this.finish(r, id, { outcome: \"delivered\", mode, ...(answer ? { reply: answer } : {}) }, sent);\n })().catch((e) => this.finish(r, id, { outcome: \"delivered\", mode, detail: String((e as Error)?.message || e) }));\n }\n\n /** The answer so far, sent as a `progress` ack: whole, with a rising seq, at most\n * one in flight. Fire-and-forget \u2014 the final ack carries everything. */\n private answerStream(r: PairedReceiver, id: string): AnswerStream {\n return new AnswerStream(async (text, seq) => {\n await this.post(r, \"/ack\", {\n acks: [\n {\n id,\n outcome: \"progress\",\n at: new Date(this.deps.now()).toISOString(),\n seq,\n reply: redactSecrets(text).slice(0, MAX_REPLY),\n },\n ],\n });\n });\n }\n\n /** How a headless run prints: streamed where this Claude Code can, else one JSON at the end. */\n private outputArgs(caps: { stream?: boolean }): string[] {\n return caps.stream\n ? [\"--output-format\", \"stream-json\", \"--verbose\", \"--include-partial-messages\"]\n : [\"--output-format\", \"json\"];\n }\n\n /** Mark a session as held by one of the daemon's runs while `fn` runs. */\n private async owning<T>(session: string, fn: () => Promise<T>): Promise<T> {\n this.ownRuns.set(session, (this.ownRuns.get(session) ?? 0) + 1);\n try {\n return await fn();\n } finally {\n const n = (this.ownRuns.get(session) ?? 1) - 1;\n if (n > 0) this.ownRuns.set(session, n);\n else this.ownRuns.delete(session);\n }\n }\n\n private limits() {\n const l = this.cfg.limits ?? {};\n const n = (v: unknown, d: number) => (typeof v === \"number\" && Number.isInteger(v) && v >= 0 ? v : d);\n return {\n startConcurrent: n(l.start_concurrent, LIMITS.startConcurrent),\n startPerHour: n(l.start_per_hour, LIMITS.startPerHour),\n headless: Math.max(1, n(l.headless, LIMITS.headless)),\n };\n }\n\n /** One headless Claude Code process at a time per slot; the rest wait in order. */\n private async slot<T>(fn: () => Promise<T>): Promise<T> {\n while (this.procs >= this.limits().headless) await new Promise<void>((r) => this.procWaiters.push(r));\n this.procs++;\n try {\n return await fn();\n } finally {\n this.procs--;\n this.procWaiters.shift()?.();\n }\n }\n\n private async startSession(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number): Promise<void> {\n const lim = this.limits();\n const now = this.deps.now();\n this.startTimes = this.startTimes.filter((t) => now - t < 3_600_000);\n if (this.startsRunning >= lim.startConcurrent || this.startTimes.length >= lim.startPerHour) {\n const detail =\n this.startsRunning >= lim.startConcurrent\n ? `this machine is already starting ${this.startsRunning} new session(s); it starts at most ${lim.startConcurrent} at once`\n : `this machine started ${this.startTimes.length} new sessions in the last hour, its limit`;\n this.deps.log(`refused ${id.slice(-8)}: start_limit \u2014 ${detail}`);\n return this.finish(r, id, { outcome: \"refused\", code: \"start_limit\", detail });\n }\n this.startsRunning++;\n this.startTimes.push(now);\n const sid = parseSessionRef(cmd.session)!.id;\n try {\n // On the session's own queue, and held as the daemon's own: a message sent while\n // the start still runs waits for it and resumes the session, never forks it.\n await this.serial(sid, () => this.owning(sid, () => this.startOne(r, id, cmd, sent)));\n } finally {\n this.startsRunning--;\n }\n }\n\n private async startOne(r: PairedReceiver, id: string, cmd: ControlCommand, sent: number): Promise<void> {\n const ref = parseSessionRef(cmd.session)!;\n const cwd = this.allowed(cmd.cwd as string);\n if (!cwd)\n return this.finish(r, id, {\n outcome: \"refused\",\n code: \"folder\",\n detail: \"that folder isn't one this machine allows\",\n });\n if (findTranscript(ref.id, this.deps.claudeDirs()) || this.sdkSessions.has(ref.id))\n return this.finish(r, id, {\n outcome: \"refused\",\n code: \"bad_session\",\n detail: \"that new session's id is already taken\",\n });\n const signedOut = await this.loginProblem(this.deps.env?.CLAUDE_CONFIG_DIR);\n if (signedOut) return this.finish(r, id, { outcome: \"failed\", detail: signedOut });\n this.finish(r, id, { outcome: \"taken\" });\n if (this.deps.sdk) {\n const sdk = this.deps.sdk;\n const out = await this.slot(async () => {\n const s = sdk.start({ session: ref.id, cwd, mode: this.cfg.mode, allowedTools: this.allowedFor(r) });\n this.sdkSessions.set(ref.id, s);\n return s.send(frameStart(cmd.text as string, r.url));\n });\n return this.finish(\n r,\n id,\n out.error ? { outcome: \"failed\", detail: out.error } : { outcome: \"delivered\", mode: \"sdk\", reply: out.reply },\n sent,\n );\n }\n const claude = this.deps.claude();\n if (!claude)\n return this.finish(r, id, { outcome: \"failed\", detail: \"Claude Code isn't installed on this machine\" });\n const mf = modeFlags(this.cfg.mode, claude.caps);\n if (\"error\" in mf) return this.finish(r, id, { outcome: \"refused\", code: \"mode\", detail: mf.error });\n const stream = this.answerStream(r, id);\n const res = await this.slot(() =>\n this.deps.run(\n claude.bin,\n [\n \"-p\",\n ...this.outputArgs(claude.caps),\n ...mf.args,\n ...(this.allowedFor(r).length ? [`--allowedTools=${this.allowedFor(r).join(\",\")}`] : []),\n \"--session-id\",\n ref.id,\n frameStart(cmd.text as string, r.url),\n ],\n {\n cwd,\n env: claudeEnv(undefined, this.deps.env),\n timeoutMs: JOB_TIMEOUT_MS,\n ...(claude.caps.stream ? { onLine: (l: string) => stream.feed(l) } : {}),\n },\n ),\n );\n stream.close();\n // The transcript this run just wrote is ours: the next message must not read it as a\n // live session (a fork instead of a resume).\n this.lastEnd.set(ref.id, this.deps.now());\n const out = this.outcome(res);\n if (\"failed\" in out) return this.finish(r, id, { outcome: \"failed\", detail: out.failed });\n this.finish(r, id, { outcome: \"delivered\", mode: \"resume\", reply: out.reply }, sent);\n }\n\n private closeIdleSdk(): void {\n const idle = this.deps.sdkIdleMs ?? 10 * 60_000;\n for (const [id, s] of this.sdkSessions)\n if (!s.busy && this.deps.now() - s.lastUsed > idle) {\n s.close();\n this.sdkSessions.delete(id);\n this.deps.log(\n `sdk session ${id.slice(0, 8)} closed after ${Math.round(idle / 60_000)} min idle (it resumes on the next message)`,\n );\n }\n }\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms).unref?.());\n\n/** dev:ino of the file at `p`, or null when there is none. */\nfunction socketId(p: string): string | null {\n try {\n const st = statSync(p);\n return `${st.dev}:${st.ino}`;\n } catch {\n return null;\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The answer to a message delivered in place (spec/CONTROL.md \u00A76 `prompt`). A waiter or\n// a Stop block hands the message to the live session, which answers in its own turn;\n// the daemon reads that turn from the session's own transcript and sends it back as the\n// ack's `reply`, so the person sees the answer where they asked. Only the bytes the\n// transcript gained after the delivery are read: a long session's file is never parsed\n// whole, and nothing from before the message can be mistaken for its answer.\nimport { closeSync, openSync, readSync, statSync } from \"node:fs\";\n\n/** The transcript's size now: where its answer will start. */\nexport function transcriptEnd(file: string): number {\n try {\n return statSync(file).size;\n } catch {\n return 0;\n }\n}\n\n/** Claude Code records after the delivery \u2192 the turn's answer once the turn ended\n * (an assistant record with `stop_reason: \"end_turn\"`), else null. The answer is the\n * turn's assistant text, in order; sidechains (subagents) are not the session's words. */\nexport function answerIn(lines: string[]): { done: boolean; text: string } {\n const parts: string[] = [];\n for (const line of lines) {\n let j: {\n type?: string;\n isSidechain?: boolean;\n message?: { stop_reason?: string; content?: unknown };\n };\n try {\n j = JSON.parse(line);\n } catch {\n continue;\n }\n if (j.type !== \"assistant\" || j.isSidechain) continue;\n const content = j.message?.content;\n if (Array.isArray(content))\n for (const c of content as { type?: string; text?: unknown }[])\n if (c?.type === \"text\" && typeof c.text === \"string\" && c.text.trim()) parts.push(c.text.trim());\n if (j.message?.stop_reason === \"end_turn\") return { done: true, text: parts.join(\"\\n\\n\") };\n }\n return { done: false, text: parts.join(\"\\n\\n\") };\n}\n\n/** Wait for the turn that follows a delivery to end, reading the transcript from\n * `from` (its size at delivery). Resolves the answer, or null when the turn doesn't\n * end within `timeoutMs` (an interrupted turn, a session closed mid-answer). */\nexport async function awaitAnswer(\n file: string,\n from: number,\n o: {\n timeoutMs: number;\n pollMs?: number;\n now?: () => number;\n sleep?: (ms: number) => Promise<void>;\n /** The turn's text so far, each time it grows (for the progress ack). */\n onText?: (text: string) => void;\n },\n): Promise<string | null> {\n const now = o.now ?? Date.now;\n const sleep = o.sleep ?? ((ms: number) => new Promise<void>((r) => setTimeout(r, ms).unref?.()));\n const until = now() + o.timeoutMs;\n let offset = from;\n let partial = \"\";\n const lines: string[] = [];\n while (now() < until) {\n const size = transcriptEnd(file);\n if (size < offset) return null; // rewritten under us: nothing we can trust\n if (size > offset) {\n const fd = openSync(file, \"r\");\n try {\n const buf = Buffer.alloc(Math.min(size - offset, 4 * 1024 * 1024));\n const n = readSync(fd, buf, 0, buf.length, offset);\n offset += n;\n const chunk = partial + buf.subarray(0, n).toString(\"utf8\");\n const cut = chunk.lastIndexOf(\"\\n\");\n partial = cut < 0 ? chunk : chunk.slice(cut + 1);\n if (cut >= 0) lines.push(...chunk.slice(0, cut).split(\"\\n\").filter(Boolean));\n } finally {\n closeSync(fd);\n }\n const a = answerIn(lines);\n if (a.done) return a.text || null;\n if (a.text) o.onText?.(a.text);\n }\n await sleep(o.pollMs ?? 500);\n }\n return null;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The routing rule (spec/CONTROL.md \u00A76): the first delivery mode that fits, top to\n// bottom. Pure, so every branch is a unit test.\nimport type { ControlKind } from \"@sessionpipe/core/control\";\n\nexport type DeliveryMode = \"sdk\" | \"waiter\" | \"turn\" | \"api\" | \"resume\" | \"fork\";\n\nexport interface SessionView {\n harness: string;\n /** The daemon holds this session through the Agent SDK right now. */\n sdk: boolean;\n /** A `sessionpipe wait` for it is parked on the socket. */\n waiter: boolean;\n /** Between a turn's start and its Stop (the Stop hook will ask). */\n midTurn: boolean;\n /** A live process holds the session (registry entry or a fresh transcript write). */\n live: boolean;\n /** The transcript exists on this machine. */\n known: boolean;\n /** This Claude Code can copy a session (`--fork-session`). */\n canFork: boolean;\n /** The harness has an input API (OpenCode, Codex app-server) \u2014 none is wired yet. */\n api: boolean;\n}\n\nexport type Route = { mode: DeliveryMode } | { unsupported: string } | { refused: \"no_session\" };\n\n/** Where a prompt (or a start) goes. Never two writers on one transcript: a live\n * session gets a fork, never a resume. */\nexport function routePrompt(s: SessionView): Route {\n if (s.sdk) return { mode: \"sdk\" };\n if (s.waiter) return { mode: \"waiter\" };\n if (s.midTurn) return { mode: \"turn\" };\n if (s.api) return { mode: \"api\" };\n if (s.harness !== \"claude-code\") return { unsupported: `no idle delivery for ${s.harness} yet` };\n if (!s.known) return { refused: \"no_session\" };\n if (!s.live) return { mode: \"resume\" };\n if (s.canFork) return { mode: \"fork\" };\n return { unsupported: \"the session is open and this Claude Code can't copy it (no --fork-session)\" };\n}\n\n/** How each kind is delivered, before the session's state is looked at. */\nexport function kindPath(\n kind: ControlKind,\n harness: string,\n): \"prompt\" | \"permission\" | \"cancel\" | \"start\" | { unsupported: string } {\n switch (kind) {\n case \"prompt\":\n return \"prompt\";\n case \"permission.answer\":\n return harness === \"gemini-cli\" ? { unsupported: \"Gemini CLI has no permission answer channel\" } : \"permission\";\n case \"cancel\":\n return \"cancel\";\n case \"start\":\n return harness === \"claude-code\" ? \"start\" : { unsupported: `can't start a ${harness} session` };\n default:\n return { unsupported: `unknown kind ${String(kind)}` };\n }\n}\n\n/** The framed text a session receives (CONTROL.md \u00A76): the model and the person can\n * tell where it came from. */\n/** Said with every message that reaches a live session: the answer goes back by\n * itself (the daemon reads it from the transcript), so the model never invents a\n * command to reply with (a real session tried \\`sessionpipe send\\`, 2026-10-01). */\nexport const IN_PLACE_ANSWER =\n \"Answer it right here, as you would answer the person at the keyboard: your reply is sent back to them automatically. Don't run a command or call a tool just to send it.\";\n\nexport function frame(text: string, receiver: string): string {\n let host = receiver;\n try {\n host = new URL(receiver).host;\n } catch {}\n return `Message via ${host} (sessionpipe control, signed on the sender's device):\\n\\n${text}`;\n}\n\n/** A new session's first message: the person's words first, where they come from after.\n * Claude Code names a session from the start of its first message, so a header in front\n * named every started session \"Message via spacesheep.dev (sessionpipe control, s\u2026\"\n * (2026-10-02). In a new session there is no one else's conversation to tell it apart\n * from, so the source line can follow the ask. */\nexport function frameStart(text: string, receiver: string): string {\n let host = receiver;\n try {\n host = new URL(receiver).host;\n } catch {}\n return `${text}\\n\\n(Sent via ${host} with sessionpipe control, signed on the sender's device.)`;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The answer as it is written (spec/CONTROL.md \u00A710, the `progress` ack). A headless run\n// streams Claude Code's output (`--output-format stream-json --include-partial-\n// messages`) and a live session's transcript grows message by message; either way the\n// daemon sends the receiver the answer SO FAR, whole, with a rising seq. Reliability\n// comes from that shape, not from delivery: a progress ack is fire-and-forget, a lost\n// one is covered by the next, and the final `delivered` ack always carries the full\n// answer. At most one is in flight, at most one every `everyMs`.\n\n/** One stream-json line \u2192 text to append, or a message boundary (a new assistant\n * message after a tool step: its text starts a new paragraph). */\nexport function streamJsonPiece(line: string): { text?: string; boundary?: boolean } | null {\n let j: {\n type?: string;\n parent_tool_use_id?: unknown;\n event?: { type?: string; delta?: { type?: string; text?: unknown } };\n };\n try {\n j = JSON.parse(line);\n } catch {\n return null;\n }\n if (j.type !== \"stream_event\" || !j.event) return null;\n // A subagent's stream (a Task tool's) is not the session's answer.\n if (j.parent_tool_use_id) return null;\n const e = j.event;\n if (e.type === \"content_block_delta\" && e.delta?.type === \"text_delta\" && typeof e.delta.text === \"string\")\n return { text: e.delta.text };\n if (e.type === \"message_start\") return { boundary: true };\n return null;\n}\n\nexport class AnswerStream {\n private text = \"\";\n private sent = \"\";\n private seq = 0;\n private timer: NodeJS.Timeout | null = null;\n private inFlight = false;\n private closed = false;\n\n constructor(\n private readonly send: (text: string, seq: number) => Promise<void>,\n private readonly everyMs = 400,\n ) {}\n\n /** A stream-json line from a headless run. */\n feed(line: string): void {\n const p = streamJsonPiece(line);\n if (!p) return;\n if (p.boundary) {\n if (this.text && !this.text.endsWith(\"\\n\\n\")) this.text += \"\\n\\n\";\n return;\n }\n if (p.text) {\n this.text += p.text;\n this.schedule();\n }\n }\n\n /** The whole answer so far (a live session's transcript). */\n set(text: string): void {\n if (text === this.text) return;\n this.text = text;\n this.schedule();\n }\n\n /** No more progress: the final ack follows. */\n close(): void {\n this.closed = true;\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n }\n\n private schedule(): void {\n if (this.closed || this.timer || this.inFlight) return;\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.flush();\n }, this.everyMs);\n this.timer.unref?.();\n }\n\n private async flush(): Promise<void> {\n const t = this.text.trim();\n if (this.closed || !t || t === this.sent) return;\n this.inFlight = true;\n this.sent = t;\n try {\n await this.send(t, ++this.seq);\n } catch {\n // Best effort: the next one, or the final ack, carries everything.\n } finally {\n this.inFlight = false;\n }\n if (this.text.trim() !== this.sent) this.schedule();\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// `sessionpipe control pair <receiver>`: a key enters this machine's trust store only\n// from this terminal (spec/CONTROL.md \u00A72). The receiver hands back a passkey and a\n// proof over sha256(\"sessionpipe.pair:<machine>:<code>\"); the key is trusted only once\n// the proof verifies here. Also the service files (launchd / systemd) that keep the\n// daemon running, and `control off`.\nimport { execFileSync } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport { existsSync, mkdirSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { type TrustedKey, verifyEnrollment } from \"@sessionpipe/core/control\";\nimport {\n type ControlConfig,\n controlState,\n dropControlSecret,\n type PairedReceiver,\n readControl,\n writeControl,\n} from \"./store.js\";\n\ndeclare const __SESSIONPIPE_VERSION__: string;\nconst VERSION = typeof __SESSIONPIPE_VERSION__ === \"string\" ? __SESSIONPIPE_VERSION__ : \"0.0.0\";\n\nexport interface PairOptions {\n url: string;\n /** The person's sink token for this receiver (from `sink add`, or --token). Null:\n * open pairing, where the receiver offers it \u2014 the person approves a link and that\n * is the whole setup (CONTROL.md \u00A72). */\n token: string | null;\n folders: string[];\n mode: \"safe\" | \"auto\";\n name: string;\n out: (s: string) => void;\n fetch?: typeof fetch;\n sleep?: (ms: number) => Promise<void>;\n env?: NodeJS.ProcessEnv;\n /** Called with a sessions key the receiver handed over at pairing. */\n addSink?: (token: string) => void;\n}\n\nasync function json(r: Response): Promise<Record<string, unknown>> {\n try {\n return (await r.json()) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\nexport async function discover(\n url: string,\n f: typeof fetch,\n): Promise<{ control: string; rpId: string; open: boolean; events: string | null }> {\n const base = url.replace(/\\/$/, \"\");\n const r = await f(`${base}/.well-known/sessionpipe`);\n if (!r.ok) throw new Error(`${base} has no sessionpipe well-known file (HTTP ${r.status})`);\n const wk = (await r.json()) as {\n capabilities?: string[];\n endpoints?: { control?: string; events?: string };\n control?: { signing?: { rp_id?: string }; open_pairing?: boolean };\n };\n if (!wk.capabilities?.includes(\"control\") || !wk.endpoints?.control || !wk.control?.signing?.rp_id)\n throw new Error(`${base} doesn't serve control yet (its well-known file lists no control.signing)`);\n const abs = (ep: string) => (/^https?:\\/\\//.test(ep) ? ep : base + ep);\n return {\n control: abs(wk.endpoints.control),\n rpId: wk.control.signing.rp_id,\n open: wk.control.open_pairing === true,\n events: wk.endpoints.events ? abs(wk.endpoints.events) : null,\n };\n}\n\n/** Pair (or add a key to) this machine with one receiver. Returns the saved config. */\nexport async function pair(o: PairOptions): Promise<ControlConfig> {\n const f = o.fetch ?? fetch;\n const sleep = o.sleep ?? ((ms: number) => new Promise((r) => setTimeout(r, ms)));\n const { control, rpId, open } = await discover(o.url, f);\n if (!o.token && !open)\n throw new Error(\n `${o.url} needs a key to pair: add it as a sink first (\\`sessionpipe sink add ${o.url} --token \u2026\\`) or pass --token.`,\n );\n // Open pairing: a secret only this terminal knows. The receiver keeps its hash, and\n // the status poll that hands over the machine's token must present it \u2014 so the link,\n // which the person opens elsewhere, is not a credential by itself.\n const pollKey = o.token ? null : randomBytes(32).toString(\"base64url\");\n const cfg: ControlConfig = readControl(o.env) ?? { name: o.name, folders: [], mode: o.mode, receivers: [] };\n cfg.name = o.name || cfg.name;\n cfg.mode = o.mode;\n cfg.folders = [...new Set([...cfg.folders, ...o.folders.map((d) => path.resolve(d))])];\n const existing = cfg.receivers.find((r) => r.control === control);\n const auth = { authorization: `Bearer ${o.token ?? pollKey}`, \"content-type\": \"application/json\" };\n const started = await f(`${control}/pair`, {\n method: \"POST\",\n headers: o.token ? auth : { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n ...(pollKey ? { poll_key: pollKey } : {}),\n ...(existing ? { machine: existing.machine } : {}),\n name: cfg.name,\n harnesses: [\"claude-code\"],\n modes: [\"waiter\", \"turn\", \"resume\", \"fork\"],\n version: VERSION,\n folders: cfg.folders,\n mode: cfg.mode,\n }),\n });\n const s = await json(started);\n if (started.status !== 201 && started.status !== 200)\n throw new Error(\n `the receiver refused to start pairing (HTTP ${started.status}${s.reason ? `: ${String(s.reason)}` : \"\"})`,\n );\n const machine = String(s.machine);\n const code = String(s.code);\n o.out(\"\");\n const digits = String(s.check);\n const spaced = /^\\d{6}$/.test(digits) ? `${digits.slice(0, 3)} ${digits.slice(3)}` : digits;\n // The approval happens on whatever device holds the person's passkey, which is\n // rarely the machine being paired (a server may have no screen at all): say so, or\n // the \"Touch ID\" line reads as \"do it here\" (2026-10-02, four machines, one headless).\n const host = new URL(o.url).host;\n o.out(` On any phone or computer where you're signed in to ${host} (it doesn't have to be this one),`);\n if (pollKey) {\n // Open pairing: one address for everyone, and the digits are what the person types.\n o.out(` open ${String(s.url)} and enter: ${spaced}`);\n o.out(\" then approve with that device's passkey (Touch ID, Face ID, a security key).\");\n o.out(\" Pairing several machines? Run this on each one: every machine shows its own digits.\");\n } else {\n o.out(\" open this link and approve with that device's passkey (Touch ID, Face ID, a security key):\");\n o.out(` ${String(s.url)}`);\n o.out(` The page shows these digits too: ${digits}`);\n }\n o.out(\"\");\n const until = Date.parse(String(s.expires_at)) || Date.now() + 10 * 60_000;\n for (;;) {\n if (Date.now() > until) throw new Error(\"the pairing link expired; run `sessionpipe control pair` again\");\n await sleep(2000);\n const r = await f(`${control}/pair?code=${encodeURIComponent(code)}`, { headers: auth }).catch(() => null);\n if (!r) continue;\n if (r.status === 404) throw new Error(\"the receiver lost the pairing; run `sessionpipe control pair` again\");\n const p = await json(r);\n if (p.status === \"expired\") throw new Error(\"the pairing link expired; run `sessionpipe control pair` again\");\n if (p.status !== \"paired\") continue;\n const key = p.key as TrustedKey;\n const proof = p.proof as { cred: string; ad: string; cd: string; sig: string };\n const v = await verifyEnrollment({ machine, code, key, proof, rpId });\n if (!v.ok) throw new Error(`the receiver's key didn't prove itself (${v.why}); nothing was trusted`);\n const token = existing?.token || (typeof p.token === \"string\" ? p.token : \"\");\n if (!token) throw new Error(\"the receiver didn't hand this machine its token\");\n const rec: PairedReceiver = existing ?? {\n url: o.url.replace(/\\/$/, \"\"),\n control,\n rpId,\n machine,\n token,\n keys: [],\n paired_at: new Date().toISOString(),\n };\n if (!rec.keys.some((k) => k.id === key.id)) rec.keys.push({ ...key, added_at: new Date().toISOString() });\n if (!existing) cfg.receivers.push(rec);\n writeControl(cfg, o.env);\n o.out(` \u2713 Paired with ${rec.url} as ${machine} \u00B7 ${rec.keys.length} key(s) trusted on this machine`);\n // Whose passkey this machine now trusts: with open pairing, whoever approved the link.\n if (typeof p.account === \"string\")\n o.out(` Approved by ${p.account}. If that isn't you, run \\`sessionpipe control off\\` now.`);\n // The receiver may hand over a sessions-only key for the events lane, so its session\n // board shows this machine without a second step.\n if (typeof p.sink_token === \"string\" && o.addSink) o.addSink(p.sink_token);\n return cfg;\n }\n}\n\n/** `control off [<receiver>]`: tell the receiver, forget its token and keys. */\nexport async function off(o: {\n url?: string;\n out: (s: string) => void;\n fetch?: typeof fetch;\n env?: NodeJS.ProcessEnv;\n}) {\n const f = o.fetch ?? fetch;\n const cfg = readControl(o.env);\n if (!cfg) return o.out(\" control isn't set up on this machine\");\n const gone = cfg.receivers.filter((r) => !o.url || r.url === o.url.replace(/\\/$/, \"\"));\n for (const r of gone) {\n await f(`${r.control}/off`, { method: \"POST\", headers: { authorization: `Bearer ${r.token}` } }).catch(() => null);\n dropControlSecret(r);\n o.out(` removed ${r.url} (${r.machine}, ${r.keys.length} key(s))`);\n }\n cfg.receivers = cfg.receivers.filter((r) => !gone.includes(r));\n writeControl(cfg, o.env);\n return cfg;\n}\n\nexport function removeKey(id: string, env?: NodeJS.ProcessEnv): number {\n const cfg = readControl(env);\n if (!cfg) return 0;\n let n = 0;\n for (const r of cfg.receivers) {\n const before = r.keys.length;\n r.keys = r.keys.filter((k) => k.id !== id && !k.id.startsWith(id));\n n += before - r.keys.length;\n }\n writeControl(cfg, env);\n return n;\n}\n\n// --- the service -------------------------------------------------------------------\n\nconst LABEL = \"org.sessionpipe.control\";\nconst UNIT = \"sessionpipe-control.service\";\n\n/** Both files restart the daemon when it exits non-zero; an update exits UPDATE_EXIT\n * (75, autoupdate.ts) to come back on the new code. SESSIONPIPE_SERVICE tells the\n * daemon which manager that is (files from before it are recognized without it). */\nexport function serviceFiles(o: { node: string; cli: string; logDir: string; home?: string }) {\n const home = o.home ?? os.homedir();\n const xml = (s: string) => s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key><string>${LABEL}</string>\n <key>ProgramArguments</key>\n <array><string>${xml(o.node)}</string><string>${xml(o.cli)}</string><string>control</string><string>run</string></array>\n <key>EnvironmentVariables</key><dict><key>SESSIONPIPE_SERVICE</key><string>launchd</string></dict>\n <key>RunAtLoad</key><true/>\n <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>\n <key>ProcessType</key><string>Background</string>\n <key>StandardOutPath</key><string>${xml(path.join(o.logDir, \"daemon.log\"))}</string>\n <key>StandardErrorPath</key><string>${xml(path.join(o.logDir, \"daemon.log\"))}</string>\n</dict>\n</plist>\n`;\n const q = (s: string) => `\"${s.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/%/g, \"%%\")}\"`;\n const unit = `[Unit]\nDescription=sessionpipe control daemon (signed messages to your coding sessions)\nAfter=network-online.target\n\n[Service]\nExecStart=${q(o.node)} ${q(o.cli)} control run\nEnvironment=SESSIONPIPE_SERVICE=systemd\nRestart=on-failure\nRestartForceExitStatus=75\nRestartSec=5\n\n[Install]\nWantedBy=default.target\n`;\n return {\n plist: { file: path.join(home, \"Library\", \"LaunchAgents\", `${LABEL}.plist`), body: plist },\n unit: { file: path.join(home, \".config\", \"systemd\", \"user\", UNIT), body: unit },\n };\n}\n\nexport type Exec = (cmd: string, args: string[]) => string;\nconst execQuiet: Exec = (cmd, args) =>\n execFileSync(cmd, args, { encoding: \"utf8\", stdio: [\"ignore\", \"pipe\", \"ignore\"], timeout: 15_000 });\n\n/** A systemd user service stops when its person's last login ends \u2014 closing the ssh\n * session to a lab workstation or a cloud machine stopped the daemon with it \u2014 unless\n * the user lingers. `loginctl enable-linger` for yourself needs no root on systemd's\n * default policy; where it does, say the one command that does it. */\nexport function ensureLinger(user: string, exec: Exec = execQuiet): { on: boolean; note: string } {\n const lingering = () => {\n try {\n return /^Linger=yes/m.test(exec(\"loginctl\", [\"show-user\", user, \"--property=Linger\"]));\n } catch {\n return false;\n }\n };\n if (lingering()) return { on: true, note: \"it keeps running after you log out (linger was already on)\" };\n try {\n exec(\"loginctl\", [\"enable-linger\", user]);\n } catch {}\n if (lingering()) return { on: true, note: \"it keeps running after you log out (turned linger on)\" };\n return {\n on: false,\n note: `it stops when you log out: run \\`sudo loginctl enable-linger ${user}\\` once to keep it running`,\n };\n}\n\n/** Write and start the service for this platform. Returns what it did, in words. */\nexport function installService(o: {\n node: string;\n cli: string;\n env?: NodeJS.ProcessEnv;\n exec?: Exec;\n platform?: NodeJS.Platform;\n}): string {\n const logDir = controlState(o.env);\n mkdirSync(logDir, { recursive: true, mode: 0o700 });\n const f = serviceFiles({ node: o.node, cli: o.cli, logDir });\n const run = o.exec ?? execQuiet;\n const platform = o.platform ?? process.platform;\n if (platform === \"darwin\") {\n mkdirSync(path.dirname(f.plist.file), { recursive: true });\n writeFileSync(f.plist.file, f.plist.body);\n const uid = String(process.getuid?.() ?? \"\");\n for (const d of [\"gui\", \"user\"])\n try {\n run(\"launchctl\", [\"bootout\", `${d}/${uid}/${LABEL}`]);\n } catch {}\n try {\n run(\"launchctl\", [\"bootstrap\", `gui/${uid}`, f.plist.file]);\n return `launchd agent ${LABEL} (log: ${path.join(logDir, \"daemon.log\")})`;\n } catch {}\n // No one logged in at the screen (an ssh session to a Mac mini): the gui domain\n // doesn't exist. The user domain runs it now; after a restart it starts again at\n // the next login at the screen.\n run(\"launchctl\", [\"bootstrap\", `user/${uid}`, f.plist.file]);\n return `launchd agent ${LABEL} in the background domain, since nobody is logged in at this Mac's screen; after a restart it starts again when someone logs in there (log: ${path.join(logDir, \"daemon.log\")})`;\n }\n if (platform === \"linux\") {\n mkdirSync(path.dirname(f.unit.file), { recursive: true });\n writeFileSync(f.unit.file, f.unit.body);\n try {\n run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n run(\"systemctl\", [\"--user\", \"enable\", \"--now\", UNIT]);\n } catch {\n return `wrote ${f.unit.file}, but systemd --user isn't reachable here; run \\`sessionpipe control run\\` yourself (tmux, screen)`;\n }\n const linger = ensureLinger(os.userInfo().username, run);\n return `systemd user unit ${UNIT}; ${linger.note} (journalctl --user -u ${UNIT})`;\n }\n return \"no service manager for this platform yet; run `sessionpipe control run` yourself\";\n}\n\nexport function uninstallService(env?: NodeJS.ProcessEnv): void {\n const f = serviceFiles({ node: \"\", cli: \"\", logDir: controlState(env) });\n const run = (cmd: string, args: string[]) => {\n try {\n execFileSync(cmd, args, { stdio: \"ignore\", timeout: 15_000 });\n } catch {}\n };\n if (process.platform === \"darwin\" && existsSync(f.plist.file)) {\n run(\"launchctl\", [\"bootout\", `gui/${process.getuid?.() ?? \"\"}/${LABEL}`]);\n run(\"launchctl\", [\"bootout\", `user/${process.getuid?.() ?? \"\"}/${LABEL}`]);\n unlinkSync(f.plist.file);\n }\n if (process.platform === \"linux\" && existsSync(f.unit.file)) {\n run(\"systemctl\", [\"--user\", \"disable\", \"--now\", UNIT]);\n unlinkSync(f.unit.file);\n run(\"systemctl\", [\"--user\", \"daemon-reload\"]);\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The `sdk` delivery mode (spec/CONTROL.md \u00A76): a session the daemon starts itself\n// through the Claude Agent SDK's streaming input, and keeps while it is in use, so\n// the next message lands in the same process with no cold start. Optional: the SDK\n// is a large package with its own binary, so sessionpipe does not depend on it. When\n// it can be imported (installed beside sessionpipe, or SESSIONPIPE_AGENT_SDK names\n// it), `start` goes through it; otherwise `start` is a headless `claude -p`.\n//\n// Measured (P1 spike 4, Claude Code 2.1.286): first token 1.5 s cold, 1.1 s warm;\n// zero turns while idle; but ~300 MB resident per held session, so the daemon\n// closes one that has been idle for ten minutes and a later message resumes it.\nimport type { SdkHost, SdkSession } from \"./daemon.js\";\n\ntype SdkQuery = AsyncIterable<{ type: string; subtype?: string; result?: unknown; is_error?: boolean }> & {\n interrupt(): Promise<void>;\n close(): void;\n};\ntype QueryFn = (p: { prompt: AsyncIterable<unknown>; options: Record<string, unknown> }) => SdkQuery;\n\nexport async function loadSdk(o: {\n claudeBin: string | null;\n env?: NodeJS.ProcessEnv;\n log: (s: string) => void;\n}): Promise<SdkHost | null> {\n const spec = o.env?.SESSIONPIPE_AGENT_SDK || \"@anthropic-ai/claude-agent-sdk\";\n let query: QueryFn;\n try {\n const mod = (await import(/* @vite-ignore */ spec)) as { query?: QueryFn };\n if (typeof mod.query !== \"function\") return null;\n query = mod.query;\n } catch {\n return null;\n }\n o.log(`Agent SDK found (${spec}): new sessions start in place`);\n return {\n start({\n session,\n cwd,\n mode,\n allowedTools,\n }: {\n session: string;\n cwd: string;\n mode: \"safe\" | \"auto\";\n configDir?: string;\n allowedTools?: string[];\n }): SdkSession {\n const queue: unknown[] = [];\n let wake: (() => void) | null = null;\n let closed = false;\n async function* input() {\n while (!closed) {\n while (queue.length) yield queue.shift();\n await new Promise<void>((r) => {\n wake = r;\n });\n }\n }\n const q = query({\n prompt: input(),\n options: {\n sessionId: session,\n cwd,\n permissionMode: mode === \"auto\" ? \"auto\" : \"dontAsk\",\n ...(allowedTools?.length ? { allowedTools } : {}),\n ...(o.claudeBin ? { pathToClaudeCodeExecutable: o.claudeBin } : {}),\n env: { ...(o.env ?? process.env), SESSIONPIPE_CONTROL_JOB: \"1\" },\n },\n });\n const waiting: { resolve: (v: { reply: string; error?: string }) => void }[] = [];\n let busy = false;\n let lastUsed = Date.now();\n void (async () => {\n try {\n for await (const m of q) {\n if (m.type !== \"result\") continue;\n busy = waiting.length > 1;\n lastUsed = Date.now();\n const w = waiting.shift();\n const text =\n typeof m.result === \"string\" && m.result.trim() ? m.result : \"(finished without a written reply)\";\n w?.resolve(m.is_error ? { reply: \"\", error: text } : { reply: text });\n }\n } catch (e) {\n for (const w of waiting.splice(0)) w.resolve({ reply: \"\", error: String((e as Error)?.message || e) });\n }\n })();\n return {\n send(text: string) {\n busy = true;\n lastUsed = Date.now();\n return new Promise((resolve) => {\n waiting.push({ resolve });\n queue.push({ type: \"user\", message: { role: \"user\", content: text }, parent_tool_use_id: null });\n wake?.();\n });\n },\n interrupt: () => q.interrupt(),\n close() {\n closed = true;\n wake?.();\n try {\n q.close();\n } catch {}\n },\n get busy() {\n return busy;\n },\n get lastUsed() {\n return lastUsed;\n },\n };\n },\n };\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// `sessionpipe wait` (spec/CONTROL.md \u00A78): run by a session as a BACKGROUND command.\n// It blocks on the daemon's local socket \u2014 no network, no polling, no output \u2014 until\n// a verified message for this session arrives, prints it and exits 0; the harness\n// then wakes the session with it. If the daemon restarts, it reconnects in silence.\nimport { stateDir } from \"@sessionpipe/core\";\nimport { parseSessionRef } from \"@sessionpipe/core/control\";\nimport { ask, socketPath } from \"./local.js\";\n\nexport const RE_ARM =\n \"(Answer it right here, as you would answer the person at the keyboard: your reply is sent back to them automatically, so don't run a command or call a tool just to send it. Then, without mentioning it, start `sessionpipe wait` again as a background command, with the longest timeout your harness allows, to keep receiving messages.)\";\n\n/** The session to wait for: --session, else the harness's own env. */\nexport function waitSession(flag: string | undefined, env: NodeJS.ProcessEnv = process.env): string | null {\n if (flag) return parseSessionRef(flag) ? flag : null;\n if (env.CLAUDE_CODE_SESSION_ID) return `claude-code:${env.CLAUDE_CODE_SESSION_ID}`;\n if (env.CODEX_SESSION_ID) return `codex:${env.CODEX_SESSION_ID}`;\n return null;\n}\n\nexport async function waitForMessage(\n session: string,\n o: { env?: NodeJS.ProcessEnv; retryMs?: number } = {},\n): Promise<string> {\n const sock = socketPath(stateDir(o.env), o.env);\n for (;;) {\n // No timeout of our own: the harness's background deadline is the only clock.\n const r = await ask(sock, { op: \"wait\", session, pid: process.pid }, 2 ** 31 - 1);\n if (r?.op === \"message\") return `${r.text}\\n\\n${RE_ARM}`;\n if (r?.op === \"replaced\")\n return \"(Another `sessionpipe wait` for this session took over; this one stopped. Nothing to do.)\";\n await new Promise((res) => setTimeout(res, o.retryMs ?? 1000));\n }\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// The hook's own home, outside every npm prefix: a copy of hook.js and worker.js and a\n// small sh launcher, which is what the harnesses run. A hook entry that named node and\n// hook.js by their install paths died with them \u2014 `nvm uninstall`, a Volta or asdf\n// switch, a moved npm prefix \u2014 and the harness said nothing; the machine just stopped\n// reporting. The launcher runs the node sessionpipe was installed with and, once that\n// one is gone, any node on PATH. Windows keeps the direct entry (it has no sh).\n// ~/.local/share/sessionpipe/ SESSIONPIPE_DATA, else $XDG_DATA_HOME/sessionpipe\nimport { accessSync, chmodSync, constants, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { AG_STALE_PRETOOL } from \"@sessionpipe/core\";\n\nexport const LAUNCHER = \"sessionpipe-hook\";\nconst COPIED = [\"worker.js\", \"hook.js\"] as const;\n\nexport function dataDir(env: NodeJS.ProcessEnv = process.env): string {\n if (env.SESSIONPIPE_DATA) return path.resolve(env.SESSIONPIPE_DATA);\n return path.join(env.XDG_DATA_HOME || path.join(os.homedir(), \".local\", \"share\"), \"sessionpipe\");\n}\nexport const launcherPath = (env: NodeJS.ProcessEnv = process.env): string => path.join(dataDir(env), LAUNCHER);\nexport const usesLauncher = (platform: NodeJS.Platform = process.platform): boolean => platform !== \"win32\";\n\nconst sq = (s: string): string => `'${s.replace(/'/g, `'\\\\''`)}'`;\n\n/** The launcher, in sh. No node at all prints what Antigravity needs and exits 0: the\n * hook must stay invisible to the harness whatever is missing (and a PreToolUse entry\n * an older install left must not turn into a silent deny). */\nexport function launcherScript(node: string, hook: string, version: string): string {\n return `#!/bin/sh\n# sessionpipe ${version} hook launcher, written by \\`sessionpipe install\\`. Harnesses run\n# this; it runs hook.js beside it with the node sessionpipe was installed with, or with\n# any node on PATH once that one is gone (an nvm uninstall, a Homebrew upgrade).\nn=${sq(node)}\n[ -x \"$n\" ] || n=$(command -v node) || { [ \"$1\" = antigravity ] && if [ \"$2\" = PreToolUse ]; then echo ${sq(AG_STALE_PRETOOL.trim())}; else echo '{}'; fi; exit 0; }\nexec \"$n\" ${sq(hook)} \"$@\"\n`;\n}\n\nfunction writeIfChanged(file: string, body: Buffer | string, mode: number): boolean {\n try {\n const cur = readFileSync(file);\n if (cur.equals(Buffer.isBuffer(body) ? body : Buffer.from(body))) {\n chmodSync(file, mode);\n return false;\n }\n } catch {}\n // A hook may start while this runs: write beside it and rename, never half a file.\n const tmp = `${file}.${process.pid}.tmp`;\n writeFileSync(tmp, body, { mode });\n renameSync(tmp, file);\n chmodSync(file, mode);\n return true;\n}\n\n/** Copy the hook and worker out of the npm install and (re)write the launcher. The\n * worker goes first, so a hook that starts mid-copy never spawns a missing one. */\nexport function installLauncher(o: { distDir: string; node: string; version: string; env?: NodeJS.ProcessEnv }): {\n launcher: string;\n changed: boolean;\n} {\n const dir = dataDir(o.env);\n mkdirSync(dir, { recursive: true, mode: 0o755 });\n let changed = false;\n for (const f of COPIED)\n changed = writeIfChanged(path.join(dir, f), readFileSync(path.join(o.distDir, f)), 0o644) || changed;\n const launcher = path.join(dir, LAUNCHER);\n changed = writeIfChanged(launcher, launcherScript(o.node, path.join(dir, \"hook.js\"), o.version), 0o755) || changed;\n return { launcher, changed };\n}\n\nexport function removeLauncher(env: NodeJS.ProcessEnv = process.env): void {\n for (const f of [LAUNCHER, ...COPIED]) rmSync(path.join(dataDir(env), f), { force: true });\n}\n\nexport interface LauncherState {\n file: string;\n present: boolean;\n /** The node the launcher names, and whether it can still run. */\n node: string | null;\n nodeOk: boolean;\n version: string | null;\n problems: string[];\n}\n\n/** What `doctor` says about the launcher. */\nexport function launcherState(version: string, env: NodeJS.ProcessEnv = process.env): LauncherState {\n const file = launcherPath(env);\n let text = \"\";\n try {\n text = readFileSync(file, \"utf8\");\n } catch {\n return {\n file,\n present: false,\n node: null,\n nodeOk: false,\n version: null,\n problems: [\"the hook launcher is missing; run `sessionpipe install` again\"],\n };\n }\n const node = /^n='((?:[^']|'\\\\'')*)'$/m.exec(text)?.[1]?.replace(/'\\\\''/g, \"'\") ?? null;\n const v = /^# sessionpipe (\\S+) hook launcher/m.exec(text)?.[1] ?? null;\n let nodeOk = false;\n try {\n if (node) {\n accessSync(node, constants.X_OK);\n nodeOk = true;\n }\n } catch {}\n const problems: string[] = [];\n if (!nodeOk)\n problems.push(\n `the node the hook launcher names (${node ?? \"?\"}) is gone; it falls back to the node on PATH. \\`sessionpipe install\\` points it at this one.`,\n );\n for (const f of COPIED)\n try {\n accessSync(path.join(path.dirname(file), f), constants.R_OK);\n } catch {\n problems.push(`${f} is missing beside the hook launcher; run \\`sessionpipe install\\` again`);\n }\n if (v && v !== version)\n problems.push(\n `the hooks run sessionpipe ${v}, this is ${version}; run \\`sessionpipe install\\` to bring them up to date`,\n );\n return { file, present: true, node, nodeOk, version: v, problems };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["execFileSync", "spawnSync", "readdirSync", "readFileSync", "realpathSync", "rmSync", "statSync", "unlinkSync", "os", "path", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "statSync", "unlinkSync", "writeFileSync", "path", "path", "tail", "cap", "out", "path", "cmd", "settings", "entry", "path", "path", "cmd", "out", "existsSync", "mkdirSync", "writeFileSync", "unlinkSync", "readFileSync", "state", "readdirSync", "statSync", "tail", "execFileSync", "existsSync", "readdirSync", "readFileSync", "statSync", "path", "args", "out", "NAME", "out", "path", "readdirSync", "existsSync", "validTool", "cmd", "prune", "readFileSync", "state", "has", "pid", "execFileSync", "statSync", "tail", "ask", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "writeFileSync", "path", "OURS", "tail", "NAME", "OPTS", "eventsFor", "path", "hooksFile", "configFile", "validTool", "endReason", "cmd", "readFileSync", "mkdirSync", "writeFileSync", "OURS", "readdirSync", "existsSync", "out", "id", "r", "prune", "tail", "execFileSync", "existsSync", "readFileSync", "path", "NAME", "OPTS", "path", "validTool", "eventsFor", "readFileSync", "execFileSync", "existsSync", "cmd", "state", "prune", "out", "tail", "execFileSync", "closeSync", "openSync", "readdirSync", "readFileSync", "readSync", "statSync", "os", "path", "help", "flag", "out", "args", "cap", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "path", "readFileSync", "mkdirSync", "path", "writeFileSync", "existsSync", "out", "closeSync", "existsSync", "mkdirSync", "openSync", "readdirSync", "readFileSync", "readSync", "statSync", "unlinkSync", "writeFileSync", "path", "path", "readFileSync", "mkdirSync", "writeFileSync", "existsSync", "out", "readdirSync", "statSync", "openSync", "readSync", "closeSync", "unlinkSync", "sink", "createHash", "out", "out", "out", "out", "appendFileSync", "mkdirSync", "path", "path", "flag", "spawn", "readFileSync", "path", "spawn", "accessSync", "constants", "existsSync", "realpathSync", "path", "execFileSync", "realpathSync", "os", "path", "appendFileSync", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "renameSync", "statSync", "unlinkSync", "writeFileSync", "os", "path", "os", "path", "state", "createHash", "createHash", "randomBytes", "cmd", "args", "createHash", "randomBytes", "state", "existsSync", "mkdirSync", "path", "writeFileSync", "state", "mkdirSync", "path", "statSync", "renameSync", "appendFileSync", "readFileSync", "writeFileSync", "out", "os", "sink", "state", "path", "realpathSync", "distDir", "out", "execFileSync", "path", "os", "parse", "distDir", "path", "existsSync", "accessSync", "constants", "realpathSync", "cmd", "spawn", "appendFileSync", "chmodSync", "closeSync", "existsSync", "mkdirSync", "openSync", "readFileSync", "renameSync", "writeFileSync", "path", "UUID_RE", "out", "has", "cmd", "path", "mkdirSync", "writeFileSync", "renameSync", "chmodSync", "readFileSync", "openSync", "appendFileSync", "closeSync", "existsSync", "path", "readFileSync", "off", "ms", "spawn", "existsSync", "realpathSync", "os", "path", "existsSync", "mkdirSync", "realpathSync", "statSync", "unlinkSync", "net", "path", "closeSync", "openSync", "readSync", "statSync", "sleep", "claudeEnv", "findTranscript", "isUuid", "JOB_TIMEOUT_MS", "liveProcess", "loginHint", "modeFlags", "parseResult", "recentlyWritten", "sessionFolder", "VERSION", "path", "mkdirSync", "unlinkSync", "existsSync", "net", "t", "sleep", "cmd", "ok", "realpathSync", "statSync", "out", "args", "tail", "execFileSync", "randomBytes", "existsSync", "mkdirSync", "unlinkSync", "writeFileSync", "os", "path", "VERSION", "sleep", "randomBytes", "path", "LABEL", "UNIT", "os", "cmd", "args", "execFileSync", "mkdirSync", "writeFileSync", "existsSync", "unlinkSync", "flag", "claudeLogin", "detectCaps", "findClaude", "runClaude", "out", "distDir", "flag", "sink", "os", "path", "realpathSync", "c", "log", "existsSync", "accessSync", "chmodSync", "constants", "mkdirSync", "readFileSync", "renameSync", "writeFileSync", "os", "path", "path", "os", "readFileSync", "chmodSync", "writeFileSync", "renameSync", "mkdirSync", "accessSync", "constants", "path", "realpathSync", "os", "statSync", "sink", "readdirSync", "spawnSync", "rmSync", "readFileSync", "execFileSync", "w", "unlinkSync"]
|
|
7
7
|
}
|