sessionpipe 0.6.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -5
- package/dist/cli.d.ts +11 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3331 -1371
- package/dist/cli.js.map +4 -4
- package/dist/connect.d.ts.map +1 -1
- package/dist/control/aliases.d.ts +15 -0
- package/dist/control/aliases.d.ts.map +1 -0
- package/dist/control/autoupdate.d.ts.map +1 -1
- package/dist/control/cli.d.ts +8 -1
- package/dist/control/cli.d.ts.map +1 -1
- package/dist/control/daemon.d.ts +65 -10
- package/dist/control/daemon.d.ts.map +1 -1
- package/dist/control/files.d.ts +33 -0
- package/dist/control/files.d.ts.map +1 -0
- package/dist/control/pair.d.ts +9 -0
- package/dist/control/pair.d.ts.map +1 -1
- package/dist/control/route.d.ts +5 -2
- package/dist/control/route.d.ts.map +1 -1
- package/dist/control/store.d.ts.map +1 -1
- package/dist/control/stream.d.ts.map +1 -1
- package/dist/help.d.ts +3 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/hook.d.ts +9 -1
- package/dist/hook.d.ts.map +1 -1
- package/dist/hook.js +184 -158
- package/dist/hook.js.map +3 -3
- package/dist/http-sink.d.ts +3 -0
- package/dist/http-sink.d.ts.map +1 -1
- package/dist/index.js +943 -220
- package/dist/index.js.map +4 -4
- package/dist/launcher.d.ts.map +1 -1
- package/dist/run.d.ts +70 -8
- package/dist/run.d.ts.map +1 -1
- package/dist/runtime.d.ts +5 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/secrets.d.ts.map +1 -1
- package/dist/update.d.ts +3 -2
- package/dist/update.d.ts.map +1 -1
- package/dist/worker.d.ts +3 -1
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +1021 -259
- package/dist/worker.js.map +4 -4
- package/package.json +5 -4
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/
|
|
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", "
|
|
3
|
+
"sources": ["../src/cli.ts", "../../core/src/adapters/antigravity.ts", "../../core/src/paths.ts", "../../core/src/readers/files.ts", "../../core/src/adapters/codex-rollout.ts", "../../core/src/readers/transcripts.ts", "../../core/src/adapters/claude-shaped.ts", "../../core/src/adapters/antigravity-control.ts", "../../core/src/adapters/headless.ts", "../../core/src/adapters/claude-code.ts", "../../core/src/readers/git.ts", "../../core/src/adapters/claude-code-control.ts", "../../core/src/adapters/codex.ts", "../../core/src/adapters/codex-config.ts", "../../core/src/adapters/codex-control.ts", "../../core/src/adapters/devin.ts", "../../core/src/readers/sqlite.ts", "../../core/src/adapters/gemini-cli.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/short-id.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/launcher.ts", "../src/run.ts", "../src/control/aliases.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/files.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/help.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 {\n existsSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n realpathSync,\n rmSync,\n statSync,\n unlinkSync,\n} 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 type { Status } from \"./control/daemon.js\";\nimport { ask, socketPath } from \"./control/local.js\";\nimport { moveControlSecrets, pairedCount, readControl, writeControl } from \"./control/store.js\";\nimport { commandHelp } from \"./help.js\";\nimport { installLauncher, launcherPath, launcherState, removeLauncher, usesLauncher } from \"./launcher.js\";\nimport { buildSinks, drain, factsState, flush, jobsDir, runJob, VERSION } from \"./run.js\";\nimport { assertSetupVersion, 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\nconst print = (s = \"\"): void => {\n process.stdout.write(`${s}\\n`);\n};\n// One command per process: `main` sets these for the run, every command reads them.\nlet args: string[] = [];\nlet out: (s?: string) => void = print;\nlet state = \"\";\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 distDir = path.dirname(fileURLToPath(import.meta.url));\n\nexport interface Io {\n /** One line of output. */\n out: (s?: string) => void;\n /** What a failed command says, then `exit(1)`. */\n err: (s: string) => void;\n exit: (code: number) => void;\n}\n\n/** Run one command: `argv` is what follows `sessionpipe`; `io` is this process by default. */\nexport async function main(\n argv: string[],\n io: Io = { out: print, err: (s) => void process.stderr.write(s), exit: (c) => process.exit(c) },\n): Promise<void> {\n args = argv;\n out = io.out;\n state = stateDir();\n try {\n await command(args[0] ?? \"help\");\n } catch (e) {\n io.err(`sessionpipe: ${(e as Error).message}\\n`);\n io.exit(1);\n }\n}\n\n/** Is this file the process entrypoint? By real path: npm's bin link to it counts. */\nexport function isEntrypoint(argv1: string | undefined, url: string): boolean {\n try {\n return !!argv1 && realpathSync(argv1) === fileURLToPath(url);\n } catch {\n return false;\n }\n}\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 command(cmd: string): Promise<void> {\n // Help wins over every command and argument, before any command can do work.\n if (has(\"--help\") || has(\"-h\")) {\n const usage = commandHelp(\n args,\n ADAPTERS.map((a) => a.name),\n );\n return usage ? out(usage) : help();\n }\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\nUsage:\n sessionpipe connect <receiver> [--machine NAME] [--rename-machine] [--allow-downgrade] [--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 --devin] [--machine NAME] [--rename-machine] [--allow-downgrade] [--backfill DAYS] [--sink URL --tier N]\n sessionpipe uninstall [--claude-code --codex --gemini-cli --antigravity --devin | --all] [--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 [--json] | 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\n/** --machine names a first install. A repeat setup must not split sessions from control. */\nfunction setupConfig(): Config {\n const cfg = readConfig();\n const requested = flag(\"--machine\");\n if ((has(\"--machine\") || has(\"--rename-machine\")) && (!requested || requested.startsWith(\"-\")))\n throw new Error(\"--machine NAME is required when naming or renaming a machine\");\n const machine = requested?.slice(0, 80);\n const control = readControl();\n const hooksName = existsSync(configFile()) ? machineName(cfg, os.hostname()) : undefined;\n // A daemon paired as `<host>.local` (what `control pair` did before 0.9.0 on a Mac) is\n // this machine under the hooks' name, `<host>`: that name keeps a receiver's sessions\n // in one place, and the daemon is renamed to it below, which costs nothing since\n // receivers key a pairing by id. A daemon named on purpose keeps its name.\n const pairedName =\n control && hooksName && machineName({} as Config, control.name) === hooksName ? hooksName : control?.name;\n const current = cfg.machine || pairedName || hooksName;\n if (current && machine && machine !== current && !has(\"--rename-machine\")) {\n out(\n ` Keeping configured machine name ${current}; ignoring --machine ${machine}. Use --rename-machine with --machine NAME for an explicit rename.`,\n );\n cfg.machine = current;\n } else {\n const name = machine || current || machineName(cfg, os.hostname());\n // The daemon goes by the same name as the hooks, or a receiver shows one machine\n // twice. An explicit rename renames the paired daemon too: control.json carries the\n // name, the daemon re-reads it and says it in its next hello (receivers key machines\n // by id, so the pairing holds). receivers[].machine is that id, not the name.\n if (control && control.name !== name && (machine || name === pairedName)) {\n writeControl({ ...control, name });\n out(` Renamed the control daemon ${control.name} \u2192 ${name}; its next hello tells each receiver.`);\n }\n cfg.machine = name;\n }\n return cfg;\n}\n\nasync function install(): Promise<void> {\n const cfg = setupConfig();\n if (viaNpx(distDir)) return rerunGlobally(args, out, { allowDowngrade: has(\"--allow-downgrade\") });\n assertSetupVersion(has(\"--allow-downgrade\"));\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, Devin). 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 === \"devin\" && !reports.some((r) => r.skipped))\n out(\n \" note: Devin ignores a hooks file whole if it holds one event name it doesn't know; run `/hooks` in `devin` to see what loaded.\",\n );\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] [--rename-machine] [--allow-downgrade] [--tier 0-3] [--mode safe|auto] [--folder DIR]\u2026 [--no-service]\",\n );\n const cfg = setupConfig();\n if (viaNpx(distDir)) return rerunGlobally(args, out, { allowDowngrade: has(\"--allow-downgrade\") });\n assertSetupVersion(has(\"--allow-downgrade\"));\n const url = (/^https?:\\/\\//.test(raw) ? raw : `https://${raw}`).replace(/\\/$/, \"\");\n const host = new URL(url).host;\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, Devin): 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\n/** The one env var that moves a harness's config off the real home (`antigravity`\n * lives under Gemini CLI's). A harness with none (null) can never be isolated. */\nconst AWAY_FROM_HOME: Record<string, string | null> = {\n \"claude-code\": \"CLAUDE_CONFIG_DIR\",\n codex: \"CODEX_HOME\",\n \"gemini-cli\": \"GEMINI_CLI_HOME\",\n antigravity: \"GEMINI_CLI_HOME\",\n devin: \"XDG_CONFIG_HOME\",\n};\n/** Harnesses this process would read out of the real home although SESSIONPIPE_CONFIG\n * or SESSIONPIPE_STATE say \"not this machine\". Setting those is how a test or an agent\n * sandboxes sessionpipe \u2014 but they only cover sessionpipe's own files, so an\n * all-harnesses uninstall under them still empties the live hooks files (measured\n * twice on a reporting machine, 8 Oct 2026: six config files rewritten, every `status`\n * row `missing`). */\nfunction unisolated(): string[] {\n if (!process.env.SESSIONPIPE_CONFIG && !process.env.SESSIONPIPE_STATE) return [];\n return ADAPTERS.filter((a) => {\n const v = AWAY_FROM_HOME[a.name];\n return v === null || (typeof v === \"string\" && !process.env[v]);\n }).map((a) => a.name);\n}\n\nfunction uninstall(): void {\n // `install` has had a per-harness selector all along; uninstall taking every harness\n // with no way to say otherwise is how one harness's test strips the other four.\n const named = ADAPTERS.filter((a) => has(`--${a.name}`));\n const all = !named.length;\n if (all && !has(\"--all\")) {\n const exposed = unisolated();\n if (exposed.length) {\n out(\n ` ! Refusing an uninstall of every harness: SESSIONPIPE_CONFIG/SESSIONPIPE_STATE point away from this machine, but ${exposed.join(\", \")} still resolve from ${tilde(os.homedir())}.`,\n );\n out(` Nothing was changed. Name what to remove (${exposed.map((n) => `--${n}`).join(\" \")}),`);\n out(\" pass --all if you do mean every harness on this machine, or unset SESSIONPIPE_CONFIG/SESSIONPIPE_STATE.\");\n process.exitCode = 2;\n return;\n }\n }\n const cfg = readConfig();\n for (const a of all ? ADAPTERS : named) {\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 // The launcher is shared: removing it while another harness still has hook entries\n // would leave that harness running a path that is gone.\n if (all && usesLauncher()) removeLauncher();\n if (!all) {\n out(` Still installed: ${Object.keys(cfg.harnesses).join(\", \") || \"nothing\"}.`);\n return;\n }\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 drain(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), undefined, { force: true });\n for (const [k, v] of Object.entries(d)) out(` ${k}: ${v} event${v === 1 ? \"\" : \"s\"} delivered`);\n}\n\ntype ControlHealth = {\n running: boolean;\n receivers: (Pick<Status[\"receivers\"][number], \"url\" | \"polling\" | \"last_poll\" | \"last_error\"> & {\n last_poll_age_ms: number | null;\n })[];\n};\n\nasync function controlHealth(): Promise<ControlHealth | null> {\n if (!pairedCount()) return null;\n const reply = await ask(socketPath(state), { op: \"status\" }, 1500);\n if (reply?.op !== \"status\") return { running: false, receivers: [] };\n const status = reply.status as Status;\n return {\n running: true,\n receivers: status.receivers.map((r) => ({\n url: r.url,\n polling: r.polling,\n last_poll: r.last_poll,\n last_error: r.last_error,\n // An older daemon has no age field. Its last_poll still exposes a loop\n // that stopped long ago, and polling=false catches the terminal 401.\n last_poll_age_ms: r.last_poll_age_ms ?? (r.last_poll === null ? null : Math.max(0, Date.now() - r.last_poll)),\n })),\n };\n}\n\nfunction controlLines(control: ControlHealth | null): void {\n if (!control) {\n out(\" control: not paired\");\n return;\n }\n if (!control.running) {\n out(\" control: daemon not running or not responding; polling: no\");\n return;\n }\n for (const r of control.receivers) {\n const age = r.last_poll_age_ms === null ? \"unknown\" : `${Math.floor(r.last_poll_age_ms / 60_000)} minutes`;\n out(\n ` control: ${r.url} \u00B7 polling: ${r.polling ? \"yes\" : \"no\"} \u00B7 last successful poll: ${r.last_poll === null ? `never (${age} since start)` : `${age} ago`} \u00B7 last error: ${r.last_error ?? \"none\"}`,\n );\n }\n}\n\nasync function status(): Promise<void> {\n const cfg = readConfig();\n const hc = hookCommand();\n const json = has(\"--json\");\n const harnesses: Record<string, { file: string; state: string; note?: string }[]> = {};\n const sinks = [];\n if (!json) 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 const installed = a.installed(hc, process.env, { lean: isLean(cfg) });\n harnesses[a.name] = installed.map((r) => ({\n file: tilde(r.file),\n state: r.state,\n ...(r.note ? { note: r.note } : {}),\n }));\n if (!json)\n for (const r of installed)\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 (!json && !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 sinks.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 pending_sessions: pending,\n });\n if (!json)\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 control = await controlHealth();\n if (!json) controlLines(control);\n const update = updateState(cfg);\n if (!json) out(` update: ${updateLine(update, Date.now())}`);\n const t = timing();\n if (!json && 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 let jobs = 0;\n try {\n jobs = readdirSync(jobsDir(state)).filter((n) => n.endsWith(\".json\")).length;\n } catch {}\n if (json)\n out(\n JSON.stringify(\n {\n version: VERSION,\n machine: machineName(cfg, os.hostname()),\n state,\n config: configFile(),\n harnesses,\n sinks,\n timing: t,\n control,\n update,\n jobs,\n },\n null,\n 2,\n ),\n );\n else if (jobs) out(` jobs: ${jobs} waiting`);\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 // `?? 0` satisfies noUncheckedIndexedAccess: the index is clamped to the last of `runs` entries.\n const q = (p: number) =>\n Math.round(/* v8 ignore next */ 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 // `?? 0` satisfies noUncheckedIndexedAccess: the index is clamped to the last of a non-empty list.\n const q = (p: number) =>\n Math.round(/* v8 ignore next */ 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 health = await controlHealth();\n report.control = health;\n if (health && !health.running)\n warnings.push(\"the control daemon is not running or not responding; polling is stopped\");\n for (const r of health?.receivers ?? []) {\n // A normal long-poll takes 25 s (35 s deadline). Allow one minute at startup\n // and between responses, but report a stopped/backing-off loop immediately.\n if (!r.polling || (r.last_poll_age_ms !== null && r.last_poll_age_ms >= 60_000)) {\n const age =\n r.last_poll_age_ms === null\n ? \"never polled\"\n : `not polled for ${Math.floor(r.last_poll_age_ms / 60_000)} minutes`;\n warnings.push(\n `${r.url}: the daemon has ${age}: ${r.last_error ?? (r.polling ? \"no successful poll response\" : \"polling stopped\")}`,\n );\n }\n }\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 controlLines(health);\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 \"turn.progress\":\n detail = `#${d.turn} ${String(d.assistant ?? \"\").length} chars so far`;\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\n// The process entrypoint (`node dist/cli.js`, or npm's bin link to it) runs the command;\n// an import of this module runs nothing.\nif (isEntrypoint(process.argv[1], import.meta.url)) {\n process.stdout.on(\"error\", (e: NodeJS.ErrnoException) => {\n if (e.code === \"EPIPE\") process.exit(0);\n });\n void main(process.argv.slice(2));\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 { homeDir } 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 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(homeDir(), \".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 // A stdin that is JSON but not an object (`null`, a number) is no payload.\n const j: unknown = input.stdin ? JSON.parse(input.stdin) : {};\n if (j && typeof j === \"object\" && !Array.isArray(j)) s = j 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): 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 env: process.env,\n });\n },\n\n backfill(sinceMs, env = process.env): BackfillRow[] {\n const rows: BackfillRow[] = [];\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: [], 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; gitFolder?: { folderUri?: unknown } }[] } };\n try {\n j = JSON.parse(readFileSync(path.join(dir, n), \"utf8\"));\n } catch {\n continue;\n }\n const folders: string[] = [];\n // A resource is one of the kinds in Antigravity's project.proto: a plain folder is\n // `{ folderUri }`, a git checkout `{ gitFolder: { folderUri, defaultBranch, allowWrite } }`\n // (what 2.23.1 writes for a folder under git); google3 and remote resources name no folder.\n for (const r of j?.projectResources?.resources ?? []) {\n const f = agPath(r?.folderUri ?? r?.gitFolder?.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[]; 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] as string) : 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\n/** The home directory, read when asked: a test that sets HOME after importing core\n * (or a process whose HOME changes) gets the new one, never one cached at load. */\nexport const homeDir = (): string => 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(homeDir(), \"AppData\", \"Roaming\"), \"sessionpipe\", \"config.json\");\n return path.join(env.XDG_CONFIG_HOME || path.join(homeDir(), \".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(homeDir(), \"AppData\", \"Local\"), \"sessionpipe\");\n return path.join(env.XDG_STATE_HOME || path.join(homeDir(), \".local\", \"state\"), \"sessionpipe\");\n}\n\n/** `~` for the home directory, as the session block writes paths. */\nexport function tilde(p: string, home: string = homeDir()): 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\n/** A thread another thread started \u2014 a subagent, a review \u2014 names a `source.subagent`\n * in its own metadata (the rollout's first record). A fork the person made carries\n * only `forked_from_id`, and is a session of its own. */\nexport function codexSubagent(meta: Record<string, unknown> | null | undefined): boolean {\n if (meta?.type !== \"session_meta\") return false;\n const p = meta.payload as { source?: { subagent?: unknown } } | undefined;\n return !!p?.source?.subagent;\n}\n\n/** A fork starts with its own metadata, then replays the parent's history. Only\n * an event naming the new thread establishes where its own records begin. */\nexport function codexReplayBoundary(meta: Record<string, unknown> | null | undefined) {\n if (meta?.type !== \"session_meta\") return undefined;\n const p = meta.payload as { id?: unknown; forked_from_id?: unknown; source?: { subagent?: unknown } } | undefined;\n if (!p || (!p.forked_from_id && !p.source?.subagent)) return undefined;\n return (record: Record<string, unknown> | null) =>\n typeof p.id === \"string\" &&\n !!p.id &&\n record?.type === \"event_msg\" &&\n (record.payload as { thread_id?: unknown } | undefined)?.thread_id === p.id;\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 { codexReplayBoundary } from \"../adapters/codex-rollout.js\";\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 const out: TranscriptRead = {\n turns: turns.map((t) => ({ user: t.user, assistant: t.assistant, at: t.at, endLine: t.endLine })),\n line,\n };\n if (cur && !cur.assistant && cur.user) out.open = { user: cur.user, at: cur.at };\n return out;\n}\n\n/** Injected context the person never typed: <tag>\u2026</tag> wrappers (the tag may carry\n * attributes, as Claude Code's `<cross-session-message from=\"\u2026\">` does), HTML comments,\n * slash-command expansions. */\nexport const isInjected = (text: string): boolean =>\n (/^<[a-z_-]+(?:\\s[^>]*)?>/i.test(text) && /<\\/[a-z_-]+>\\s*$/i.test(text)) ||\n /^<!--\\s/.test(text) ||\n /^<command-/.test(text);\n\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};\n/** The line after the last whole one. A trailing line that does not parse has no\n * newline yet (a write in progress): the cursor stops before it, or the prompt in\n * it would never be read. */\nconst endOf = (lines: string[]) => {\n const last = lines[lines.length - 1];\n if (last === undefined) return 0;\n return last === \"\" || parse(last) === null ? lines.length - 1 : lines.length;\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/** A message the person sent while a turn was running, absorbed by that turn. Claude Code\n * writes it as an attachment, never as a `user` record: {type:\"attachment\",\n * attachment:{type:\"queued_command\", prompt, commandMode:\"prompt\", origin:{kind:\"human\"}}}.\n * Task notifications and other sessions' messages share the record with another\n * `commandMode` or `origin.kind`; older versions wrote no origin. */\nconst queuedPrompt = (a: unknown): string => {\n if (!a || typeof a !== \"object\") return \"\";\n const q = a as { type?: unknown; commandMode?: unknown; origin?: { kind?: string }; prompt?: unknown };\n if (q.type !== \"queued_command\" || (q.commandMode ?? \"prompt\") !== \"prompt\") return \"\";\n if (q.origin?.kind && q.origin.kind !== \"human\") return \"\";\n return textParts(q.prompt, [\"text\"]).trim();\n};\n\n/** Claude Code / Droid: {type:\"user\"|\"assistant\", message:{content}, timestamp, isMeta, isSidechain, origin},\n * plus the person's mid-turn messages (queuedPrompt). */\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 (\n j.type === \"user\" &&\n (j.isMeta || j.isCompactSummary || j.repeatsCompactSummary || (origin?.kind && origin.kind !== \"human\"))\n )\n 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 } else if (j.type === \"attachment\") {\n const text = queuedPrompt(j.attachment);\n if (text && !isInjected(text)) msgs.push({ role: \"user\", text, at, line: i });\n }\n }\n return pairTurns(msgs, endOf(lines));\n}\n\n/** What Codex writes into a session as a \"user\" message that the person never typed:\n * `<environment_context>` and the like, and the AGENTS.md it read (`# AGENTS.md\n * instructions for <folder>` followed by `<INSTRUCTIONS>`). */\nexport function codexInjected(text: string): boolean {\n return /^<[a-z_-]+>/i.test(text) || /^# AGENTS\\.md instructions\\b/i.test(text);\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 const boundary = codexReplayBoundary(parse(lines.find((line) => line.trim()) ?? \"\"));\n // Find the boundary from the header even when resuming inside the replay.\n // Keep absolute line numbers: the delivery cursor refers to the original file.\n const start = boundary ? lines.findIndex((line) => boundary(parse(line))) : 0;\n if (start < 0) return pairTurns(msgs, endOf(lines));\n for (let i = Math.max(from, start); 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 (codexInjected(text)) continue; // Codex's own injections, not the person's words\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] as string) : 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 writeFileSync(file, formatJson(settings, f));\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// Antigravity (Google) \u2014 control delivery (spec/CONTROL.md \u00A76). Its CLI, `agy`, as the\n// control daemon needs it: which `agy` to run, one headless turn (`agy -p \u2026 --output-\n// format stream-json`, and `--conversation <id>` for the next message), and its stream\n// read as it arrives. agy picks a new conversation's id itself (the `init` line) and\n// starts a fresh one for an id it doesn't know, so the daemon names it after the\n// command that started it (CONTROL.md \u00A76 `start`). No transcript records the folder, so\n// the daemon keeps that too. Shapes measured on agy 1.2.16, 2026-10-04.\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { deniedNote, findBinary, jobEnv, type Mode, type Reading, type RunResult, runFailure } from \"./headless.js\";\n\nconst LABEL = \"Antigravity\";\n\n/** The `agy` to run: SESSIONPIPE_AGY, else on PATH, else where its installer puts it. */\nexport function findAgy(env: NodeJS.ProcessEnv = process.env, home = os.homedir()): string | null {\n return findBinary({\n override: env.SESSIONPIPE_AGY,\n names: process.platform === \"win32\" ? [\"agy.exe\", \"agy.cmd\"] : [\"agy\"],\n env,\n dirs: [path.join(home, \".local\", \"bin\"), \"/opt/homebrew/bin\", \"/usr/local/bin\"],\n });\n}\n\n/** Permission flags for the machine's mode. Safe: none \u2014 agy denies every tool call\n * nobody is there to approve, and says which. Auto: `--mode accept-edits`. Never\n * `--dangerously-skip-permissions`: no path here writes it. */\nexport function agyModeFlags(mode: Mode): string[] {\n return mode === \"auto\" ? [\"--mode\", \"accept-edits\"] : [];\n}\n\n/** One headless turn in the folder it is spawned in. A message that starts with a dash\n * would read as a flag after `-p`; a leading space keeps it the prompt. */\nexport function agyArgs(o: { mode: Mode; prompt: string; resume?: string }): string[] {\n const prompt = o.prompt.startsWith(\"-\") ? ` ${o.prompt}` : o.prompt;\n return [\n ...(o.resume ? [\"--conversation\", o.resume] : []),\n \"-p\",\n prompt,\n \"--output-format\",\n \"stream-json\",\n ...agyModeFlags(o.mode),\n ];\n}\n\n/** The env a headless turn runs with. */\nexport const agyEnv = (env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv => jobEnv(env);\n\nexport interface AgyResult {\n status: string;\n response: string;\n error: string;\n denied: unknown[];\n}\n\n/** One stream-json line, as much of it as the daemon uses. */\nexport interface AgyPiece {\n /** The conversation's id, which agy chose (`init`, then every step and the result). */\n session?: string;\n /** Text an `agent_response` step wrote, and which step it belongs to. */\n delta?: { step: number; text: string };\n /** The final `result`. */\n result?: AgyResult;\n /** An `error_message` step's words: the reason only if the run then fails. */\n note?: string;\n}\n\nexport function agyLine(line: string): AgyPiece | null {\n let j: Record<string, unknown>;\n try {\n j = JSON.parse(line);\n } catch {\n return null;\n }\n if (!j || typeof j !== \"object\") return null;\n const str = (v: unknown) => (typeof v === \"string\" ? v : \"\");\n const out: AgyPiece = {};\n if (j.event === \"init\") {\n if (str(j.conversation_id)) out.session = str(j.conversation_id);\n } else if (j.event === \"step_update\") {\n const s = (j.step_update ?? {}) as Record<string, unknown>;\n if (str(s.conversation_id)) out.session = str(s.conversation_id);\n if (s.step_type === \"agent_response\" && str(s.text_delta))\n out.delta = { step: Number(s.step_index ?? 0), text: str(s.text_delta) };\n if (s.step_type === \"error_message\") {\n const why = str(s.text_delta) || str(s.error) || str(s.message);\n if (why) out.note = why;\n }\n } else if (j.event === \"result\") {\n const r = (j.result ?? {}) as Record<string, unknown>;\n if (str(r.conversation_id)) out.session = str(r.conversation_id);\n out.result = {\n status: str(r.status),\n response: str(r.response),\n error: str(r.error),\n denied: Array.isArray(r.denied_actions) ? r.denied_actions : [],\n };\n } else return null;\n return Object.keys(out).length ? out : null;\n}\n\n/** What agy names a denied action by, whatever shape the entry has. */\nfunction deniedName(d: unknown): string | null {\n if (typeof d === \"string\") return d.slice(0, 80);\n if (!d || typeof d !== \"object\") return null;\n const o = d as Record<string, unknown>;\n for (const k of [\"tool_name\", \"toolName\", \"name\", \"tool\", \"action\", \"type\"])\n if (typeof o[k] === \"string\" && o[k]) return (o[k] as string).slice(0, 80);\n return null;\n}\n\n/** An `AGY_ERROR: {\u2026}` agy may end stderr with, in words. */\nexport function agyError(stderr: string | undefined): string {\n const s = String(stderr || \"\");\n const i = s.lastIndexOf(\"AGY_ERROR:\");\n if (i < 0) return \"\";\n const raw = s.slice(i + \"AGY_ERROR:\".length).trim();\n try {\n const j = JSON.parse(raw) as Record<string, unknown>;\n for (const k of [\"message\", \"error\", \"detail\"]) if (typeof j[k] === \"string\" && j[k]) return j[k] as string;\n } catch {}\n return (raw.split(\"\\n\")[0] as string).slice(0, 300);\n}\n\n/** An agy run read as it streams: the answer is the agent_response steps' text, and the\n * result's `response` once it comes. */\nexport class AgyReading implements Reading {\n session: string | null = null;\n lines = 0;\n private buf = \"\";\n private step: number | null = null;\n private result: AgyResult | null = null;\n private note: string | null = null;\n\n get text(): string {\n return this.buf;\n }\n\n feed(line: string): boolean {\n this.lines++;\n const p = agyLine(line);\n if (!p) return false;\n if (p.session && !this.session) this.session = p.session;\n if (p.note) this.note = p.note;\n if (p.result) this.result = p.result;\n if (!p.delta) return false;\n // A new response step after a tool step starts a new paragraph.\n if (this.step !== null && p.delta.step !== this.step && this.buf && !this.buf.endsWith(\"\\n\\n\")) this.buf += \"\\n\\n\";\n this.step = p.delta.step;\n this.buf += p.delta.text;\n return true;\n }\n\n outcome(res: RunResult): { failed: string } | { reply: string } {\n const broke = runFailure(LABEL, res);\n if (broke) return { failed: broke };\n const r = this.result;\n if (!r) {\n const why = agyError(res.stderr) || this.note || \"\";\n return {\n failed: `Antigravity exited (${res.signal || `code ${res.code}`}) without an answer${why ? `: ${why}` : \"\"}`,\n };\n }\n if (r.status !== \"SUCCESS\")\n return { failed: r.error || agyError(res.stderr) || this.note || \"Antigravity reported an error\" };\n const names = [...new Set(r.denied.map(deniedName).filter((n): n is string => !!n))];\n const text = r.response.trim()\n ? r.response.trim()\n : this.buf.trim() || \"(Antigravity finished without a written reply.)\";\n return { reply: text + deniedNote(names, r.denied.length) };\n }\n}\n\nexport const reading = (): AgyReading => new AgyReading();\n", "// SPDX-License-Identifier: Apache-2.0\n// One headless agent turn as a child process (spec/CONTROL.md \u00A76): the spawner the\n// control daemon runs every harness through, and the shape each harness's reading of\n// its own output takes. Which binary, which flags and how the answer is read are the\n// harness's own (`<harness>-control.ts`); what is the same for all of them is here.\nimport { spawn } from \"node:child_process\";\nimport { accessSync, constants, statSync } from \"node:fs\";\nimport path from \"node:path\";\n\n/** A headless turn still running after this is stopped. */\nexport const JOB_TIMEOUT_MS = 30 * 60_000;\nconst OUT_CAP = 1024 * 1024;\n\nexport type Mode = \"safe\" | \"auto\";\n\nexport function 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\n/** A harness's CLI: the override the person set (`SESSIONPIPE_<NAME>`), else the first\n * of `names` on PATH, else the first of `dirs` that holds one. A launchd or systemd\n * service starts with a short PATH, so the installers' own folders are looked in too. */\nexport function findBinary(o: {\n override?: string | undefined;\n names: string[];\n dirs: string[];\n env?: NodeJS.ProcessEnv;\n}): string | null {\n if (o.override && isExe(o.override)) return o.override;\n for (const d of String(o.env?.PATH || \"\").split(path.delimiter)) {\n if (!d || !path.isAbsolute(d)) continue;\n for (const n of o.names) if (isExe(path.join(d, n))) return path.join(d, n);\n }\n for (const d of o.dirs) for (const n of o.names) if (isExe(path.join(d, n))) return path.join(d, n);\n return null;\n}\n\n/** The env every headless turn runs with: SESSIONPIPE_CONTROL_JOB tells the turn's own\n * hooks that the daemon runs it, so its Stop hook never takes a message meant for a\n * person's session (cli/src/hook.ts). */\nexport function jobEnv(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {\n return { ...env, SESSIONPIPE_CONTROL_JOB: \"1\" };\n}\n\n/** Whether a harness is signed in, in its own words. `loggedIn: null` means it can't\n * say (too old, 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 the harness names it. */\n method?: string;\n subscription?: string;\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\nexport interface RunOptions {\n cwd: string;\n env: NodeJS.ProcessEnv;\n timeoutMs?: number;\n /** Streaming: each stdout line as it arrives. Only the lines `keep` names are kept\n * for the RunResult (none by default), so a long stream never hits the cap. */\n onLine?: (line: string) => void;\n keep?: (line: string) => boolean;\n}\n\n/** Run one headless turn in its own process group, stdin closed (Codex waits on an open\n * one), holding at most 1 MB of stdout. */\nexport function runHeadless(bin: string, args: string[], o: RunOptions): 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 const keep = (line: string) => {\n if (!o.keep?.(line)) return;\n out = [Buffer.from(line)];\n outLen = line.length;\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() as string;\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n o.onLine(line);\n } catch {}\n keep(line);\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 the harness 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 keep(partial);\n partial = \"\";\n }\n finish(result(code, signal));\n });\n });\n}\n\n/** A harness's output read as it streams: the session it names, the answer so far, and\n * the outcome once the process is gone. One per run. */\nexport interface Reading {\n /** One stdout line. True when the answer so far changed. */\n feed(line: string): boolean;\n /** The session id the harness revealed (it picks its own), or null so far. */\n readonly session: string | null;\n /** The answer so far, whole. */\n readonly text: string;\n /** How many lines were fed. */\n readonly lines: number;\n outcome(res: RunResult): { failed: string } | { reply: string };\n}\n\n/** The last few lines a harness wrote to stderr, on one line. */\nexport function stderrTail(stderr: string | undefined, n = 3): string {\n return String(stderr || \"\")\n .trim()\n .split(\"\\n\")\n .slice(-n)\n .join(\" \")\n .trim();\n}\n\n/** What a run that wasn't there to ask says about the actions it was refused. */\nexport function deniedNote(names: string[], count: number): string {\n if (!count) return \"\";\n return `\\n\\n(Not allowed on this machine, since nobody was there to approve: ${names.join(\", \") || `${count} action(s)`}.)`;\n}\n\n/** A process that failed before or without its answer, in words. */\nexport function runFailure(label: string, res: RunResult): string | null {\n if (res.error) return `couldn't start ${label}: ${res.error}`;\n if (res.timedOut) return `${label} was still working after 30 minutes, so it was stopped`;\n return null;\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 (its id; its email only for control's pair and hello).\n// 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 { homeDir } 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 type { HarnessAccount } from \"../types.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 || homeDir()): 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 // A stdin that is JSON but not an object (`null`, a number) is no payload.\n const j: unknown = input.stdin ? JSON.parse(input.stdin) : {};\n if (j && typeof j === \"object\" && !Array.isArray(j)) s = j as Record<string, unknown>;\n } catch {}\n const id = (s.session_id ?? s.sessionId) as string | undefined;\n if (!id) return null;\n if (notClaudeCode(String(id), s)) 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 // The prompt, for the turn's first turn.progress: the transcript may not hold it\n // yet when the worker runs. Never an event field of its own (tier 2 carries it).\n if (event === \"UserPromptSubmit\" && typeof s.prompt === \"string\") hints.prompt = s.prompt;\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}\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n/** Another harness reading this settings file, not Claude Code. Several harnesses\n * import `~/.claude/settings.json` hooks, so our entries there can be run by a tool\n * that has its own adapter: it would arrive under the wrong name, with ids that mean\n * nothing to a Claude Code reader. Every Claude Code payload names a transcript and a\n * UUID session (all 21 recorded fixtures do); a payload with neither is somebody else's. */\nexport function notClaudeCode(id: string, s: Record<string, unknown>): boolean {\n return typeof s.transcript_path !== \"string\" && !UUID.test(id);\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 EMAIL_RE = /^[^@\\s]{1,64}@[^@\\s]{1,189}$/;\n/** Who a config dir is signed in as, from its .claude.json (the default dir keeps it\n * at ~/.claude.json): the account id, and the email it signs in with. */\nfunction claudeLogin(dir: string, home = homeDir()): { id: string; email?: string } | null {\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 for (const f of files) {\n try {\n const a = (\n JSON.parse(readFileSync(f, \"utf8\")) as { oauthAccount?: { accountUuid?: unknown; emailAddress?: unknown } }\n ).oauthAccount;\n if (typeof a?.accountUuid === \"string\" && a.accountUuid) {\n const email = typeof a.emailAddress === \"string\" && EMAIL_RE.test(a.emailAddress) ? a.emailAddress : undefined;\n return { id: a.accountUuid.slice(0, 128), ...(email ? { email } : {}) };\n }\n } catch {}\n }\n return null;\n}\nconst accountCache = new Map<string, string | null>();\n/** The account id for `session.account_id`: never the email. Events go to every sink,\n * a team board included; the email reaches only a receiver the person paired with,\n * in control's pair and hello (claudeAccounts). */\nfunction claudeAccount(dir: string): string | null {\n const hit = accountCache.get(dir);\n if (hit !== undefined) return hit;\n const acct = claudeLogin(dir)?.id ?? null;\n accountCache.set(dir, acct);\n return acct;\n}\n/** Every account signed in across these config dirs, read fresh (a person signs in to\n * another account without restarting anything), for control's pair and hello. */\nexport function claudeAccounts(dirs: string[], home = homeDir()): HarnessAccount[] {\n const out: HarnessAccount[] = [];\n for (const d of dirs) {\n const l = claudeLogin(d, home);\n if (!l) continue;\n const seen = out.find((a) => a.id === l.id);\n if (!seen) out.push({ harness: NAME, ...l });\n else if (!seen.email && l.email) seen.email = l.email;\n }\n return out;\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 // The ssh forms first: the `git@` they are known by is what the credential strip removes.\n const ssh = /^(?:ssh:\\/\\/)?git@([^:/]+)[:/](.+?)(?:\\.git)?$/.exec(url);\n if (ssh) return `${ssh[1]}/${ssh[2]}`;\n return url\n .replace(/\\/\\/[^/@]*@/, \"//\")\n .replace(/^https?:\\/\\//, \"\")\n .replace(/\\.git$/, \"\");\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 } from \"node:child_process\";\nimport { closeSync, openSync, readdirSync, readFileSync, readSync, statSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport {\n isExe,\n JOB_TIMEOUT_MS,\n type Login,\n type Mode,\n type RunOptions,\n type RunResult,\n runHeadless,\n} from \"./headless.js\";\n\nexport { JOB_TIMEOUT_MS, type Login, type Mode, type RunResult };\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;\n/** A transcript someone else wrote this recently is in use. */\nconst LIVE_WRITE_MS = 90_000;\n\n/** Dotted versions by number, a missing part as 0: 1.9.0 < 1.10 = 1.10.0. */\nexport const 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 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\n/** Run one headless turn (headless.ts). Streaming (`--output-format stream-json`), only\n * the `result` line is kept for the RunResult unless the caller says otherwise. */\nexport function runClaude(bin: string, args: string[], o: RunOptions): Promise<RunResult> {\n return runHeadless(bin, args, { ...o, keep: o.keep ?? ((line) => line.includes('\"type\":\"result\"')) });\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// 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 { homeDir } from \"../paths.js\";\nimport { ends, parseLines, recentFiles, scanLines } from \"../readers/files.js\";\nimport { codexInjected, readCodex } from \"../readers/transcripts.js\";\nimport { installClaudeShaped, installedClaudeShaped, uninstallClaudeShaped } from \"./claude-shaped.js\";\nimport * as toml from \"./codex-config.js\";\nimport { codexReplayBoundary, codexSubagent } from \"./codex-rollout.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(homeDir(), \".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 write(toml.replaceNotify(text, n, `notify = ${toml.withPreviousRaw(n.raw, argv)}`));\n return { file, changed: true, note: \"chained after Codex Computer Use (--previous-notify)\" };\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 writeFileSync(file, toml.replaceNotify(text, n, `notify = ${toml.stripPreviousRaw(n.raw)}`));\n return { file, changed: true };\n }\n return { file, changed: false };\n}\n\n/** The rollout file of one thread: `<CODEX_HOME>/sessions/YYYY/MM/DD/rollout-<time>-<thread\n * id>.jsonl`, newest day first. Null for an id that isn't a thread id's shape, so a\n * short or odd one never matches some other session's file. */\nexport function findRollout(threadId: string, env: NodeJS.ProcessEnv = process.env): string | null {\n if (!/^[A-Za-z0-9-]{8,128}$/.test(threadId)) return 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(`-${threadId}.jsonl`)) {\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\n/** A rollout's first record, its own session_meta. About 50 KB (it carries the base\n * instructions), so it is read on its own rather than from a sampled head. */\nfunction rolloutMeta(file: string): Record<string, unknown> | null {\n return scanLines(file, (line) => parseLines([line])[0] ?? {});\n}\n\n/** A rollout named for a thread other than `id` (`rollout-<time>-<thread id>.jsonl`).\n * A name of any other shape says nothing, so it is not taken for another thread's. */\nfunction ofAnotherThread(file: string, id: string): boolean {\n const m = /-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\.jsonl(?:\\.zst)?$/i.exec(file);\n return !!m?.[1] && m[1].toLowerCase() !== id.toLowerCase();\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 const j: unknown = raw ? JSON.parse(raw) : {};\n if (j && typeof j === \"object\" && !Array.isArray(j)) s = j 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 // Notify names the thread whose turn ended. Without a rollout it is an ephemeral\n // thread, kept nowhere (the hooks' `transcript_path: null` below). A subagent's\n // thread belongs to its parent, whose hooks already report it: SubagentStart and\n // SubagentStop name it as `agent_id`. Neither is a session of its own.\n const file = findRollout(String(id), input.env as NodeJS.ProcessEnv);\n if (!file || codexSubagent(rolloutMeta(file))) 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 transcript: file,\n };\n return r;\n }\n try {\n // A stdin that is JSON but not an object (`null`, a number) is no payload.\n const j: unknown = input.stdin ? JSON.parse(input.stdin) : {};\n if (j && typeof j === \"object\" && !Array.isArray(j)) s = j as Record<string, unknown>;\n } catch {}\n const id = s.session_id as string | undefined;\n if (!id) return null;\n // `transcript_path: null` is an ephemeral thread (recorded on codex-cli 0.160.0):\n // Codex Desktop's own background threads (ambient suggestions and their safety\n // review) and `codex exec --ephemeral`. Codex keeps nothing of one, so there is no\n // session to name, read or resume.\n if (s.transcript_path === null) 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 // Inside a subagent Codex sends the parent's session_id with the subagent's own\n // rollout (its SubagentStart, its tool calls): that file is not this session's.\n if (typeof s.transcript_path === \"string\" && !ofAnotherThread(s.transcript_path, String(id)))\n 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 // A subagent's rollout is part of its parent's session, as in fromHook's notify.\n if (codexSubagent(rolloutMeta(f))) 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. A fork's replay is not its ask. */\nexport function codexFacts(file: string): SessionFacts {\n const { head, tail } = ends(file, 128 * 1024, 64 * 1024);\n let H = parseLines(head);\n let T = parseLines(tail);\n const out: SessionFacts = {};\n const meta = H.find((j) => j.type === \"session_meta\" && j.payload);\n const boundary = codexReplayBoundary(meta);\n if (meta?.payload) {\n const p = meta.payload as {\n cwd?: string;\n cli_version?: string;\n git?: { branch?: string; repository_url?: string };\n };\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 if (boundary) {\n const h = H.findIndex(boundary);\n const t = T.findIndex(boundary);\n H = h < 0 ? [] : H.slice(h);\n // The samples can overlap, so trim each one at the boundary independently.\n // If both miss it, scan the gap before trusting the tail: it could still be\n // parent replay. Stop as soon as the boundary is found, without loading the file.\n const found =\n h >= 0 ||\n t >= 0 ||\n scanLines(file, (line) => (boundary(parseLines([line])[0] ?? null) ? true : null), Number.POSITIVE_INFINITY);\n T = t >= 0 ? T.slice(t) : found ? T : [];\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 || codexInjected(text)) continue;\n const line = text.split(\"\\n\")[0] as string; // trimmed, so its first line is its first non-blank one\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 = (boundary && meta ? [meta, ...H, ...T] : 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 const raw = m[1] as string;\n return { raw, argv: parseArgv(raw), index: m.index, length: m[0].length, misplaced: false, other: !OURS.test(raw) };\n }\n const k = NOTIFY_KEY.exec(head);\n if (k) {\n const rest = head.slice(k.index).split(\"\\n\")[0] as string;\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) {\n const raw = t[1] as string;\n if (OURS.test(raw))\n return { raw, argv: parseArgv(raw), index: at + t.index, length: t[0].length, misplaced: true, 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 notify line `n` (as readNotify found it in `text`) replaced by `line`. */\nexport function replaceNotify(text: string, n: Notify, line: string): string {\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// Codex CLI (OpenAI) \u2014 control delivery (spec/CONTROL.md \u00A76). Codex on this machine,\n// as the control daemon needs it: which `codex` to run, with which sandbox flags, one\n// headless turn (`codex exec --json` for a new session, `codex exec resume --json <id>`\n// for the next message), and its JSONL output read as it streams. Codex picks a new\n// session's id itself (the first line, `thread.started`), so the daemon names it after\n// the command that started it (CONTROL.md \u00A76 `start`). Shapes measured on codex-cli\n// 0.160.0, 2026-10-04.\nimport { execFile } from \"node:child_process\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport {\n findBinary,\n jobEnv,\n type Login,\n type Mode,\n type Reading,\n type RunResult,\n runFailure,\n stderrTail,\n} from \"./headless.js\";\n\nexport { codexFacts, findRollout } from \"./codex.js\";\n\nconst LABEL = \"Codex\";\n\n/** The `codex` to run: SESSIONPIPE_CODEX, else on PATH, else beside the node running\n * this (an `npm install -g` there) or where the installers put it. */\nexport function findCodex(\n env: NodeJS.ProcessEnv = process.env,\n home = os.homedir(),\n nodeDir = path.dirname(process.execPath),\n): string | null {\n return findBinary({\n override: env.SESSIONPIPE_CODEX,\n names: process.platform === \"win32\" ? [\"codex.exe\", \"codex.cmd\"] : [\"codex\"],\n env,\n dirs: [nodeDir, path.join(home, \".local\", \"bin\"), \"/opt/homebrew/bin\", \"/usr/local/bin\"],\n });\n}\n\n/** Sandbox flags for the machine's mode. Safe: workspace-write, and nothing escalates\n * unattended (exec never asks). Auto: approval requests go through Codex's own\n * automatic review. Never `--dangerously-bypass-approvals-and-sandbox` or\n * `--dangerously-bypass-hook-trust`: no path here writes them. */\nexport function codexModeFlags(mode: Mode, resume = false): string[] {\n // `codex exec resume` takes neither `-s` nor `--approve-for-me` (0.160: \"unexpected\n // argument\"), so a resume says the same thing as config overrides, which it does take.\n if (resume)\n return mode === \"auto\"\n ? [\n \"-c\",\n 'sandbox_mode=\"workspace-write\"',\n \"-c\",\n 'approval_policy=\"on-request\"',\n \"-c\",\n 'approvals_reviewer=\"auto_review\"',\n ]\n : [\"-c\", 'sandbox_mode=\"workspace-write\"'];\n return mode === \"auto\" ? [\"--approve-for-me\"] : [\"-s\", \"workspace-write\"];\n}\n\n/** One headless turn. A new session runs in `cwd` (`-C`); a resume names the thread.\n * The prompt goes after `--`, so a message that starts with a dash is never a flag. */\nexport function codexArgs(o: { mode: Mode; prompt: string; cwd?: string; resume?: string }): string[] {\n const common = [\"--json\", \"--skip-git-repo-check\"];\n if (o.resume) return [\"exec\", \"resume\", ...common, ...codexModeFlags(o.mode, true), \"--\", o.resume, o.prompt];\n return [\"exec\", ...common, ...(o.cwd ? [\"-C\", o.cwd] : []), ...codexModeFlags(o.mode), \"--\", o.prompt];\n}\n\n/** The env a headless turn runs with. */\nexport const codexEnv = (env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv => jobEnv(env);\n\nexport const LOGIN_HINT = \"Codex isn't signed in on this machine: run `codex login --device-auth` there.\";\n\n/** Whether Codex can run as this process: CODEX_API_KEY in the env is enough; else\n * `codex login status` (exit 0 signed in, exit 1 \"Not logged in\"). Anything else \u2014\n * it didn't run, it timed out \u2014 is null, never a reason to refuse. */\nexport function codexLogin(bin: string, env: NodeJS.ProcessEnv = process.env): Promise<Login> {\n if (env.CODEX_API_KEY) return Promise.resolve({ loggedIn: true, method: \"api key\" });\n return new Promise((resolve) => {\n execFile(\n bin,\n [\"login\", \"status\"],\n { encoding: \"utf8\", timeout: 20_000, env: codexEnv(env), maxBuffer: 256 * 1024 },\n (err) => {\n if (!err) return resolve({ loggedIn: true });\n const code = (err as { code?: unknown }).code;\n resolve(code === 1 ? { loggedIn: false } : { loggedIn: null });\n },\n );\n });\n}\n\n/** One `--json` line, as much of it as the daemon uses. */\nexport interface CodexPiece {\n /** `thread.started`: the session's id, which Codex chose. */\n session?: string;\n /** A finished `agent_message`: one part of the answer. */\n message?: string;\n /** `turn.completed` (or `turn.failed`). */\n done?: boolean;\n /** `turn.failed`: why. */\n failed?: string;\n /** A top-level `error` (\"Reconnecting... 2/5\"): transient, the reason only if the run then fails. */\n note?: string;\n /** An `error` item: a warning Codex printed and carried on after (hook trust, a clamped timeout). */\n warning?: string;\n}\n\nexport function codexLine(line: string): CodexPiece | null {\n let j: {\n type?: unknown;\n thread_id?: unknown;\n message?: unknown;\n item?: { type?: unknown; text?: unknown; message?: unknown };\n error?: { message?: unknown };\n };\n try {\n j = JSON.parse(line);\n } catch {\n return null;\n }\n if (!j || typeof j !== \"object\") return null;\n const str = (v: unknown) => (typeof v === \"string\" ? v : \"\");\n switch (j.type) {\n case \"thread.started\":\n return str(j.thread_id) ? { session: str(j.thread_id) } : null;\n case \"item.completed\": {\n const it = j.item;\n if (it?.type === \"agent_message\" && str(it.text)) return { message: str(it.text) };\n if (it?.type === \"error\" && str(it.message)) return { warning: str(it.message) };\n return null;\n }\n case \"turn.completed\":\n return { done: true };\n case \"turn.failed\":\n return { done: true, failed: str(j.error?.message) || \"Codex reported an error\" };\n case \"error\":\n return str(j.message) ? { note: str(j.message) } : null;\n default:\n return null;\n }\n}\n\n/** A Codex run read as it streams: the answer is its finished agent messages. */\nexport class CodexReading implements Reading {\n session: string | null = null;\n lines = 0;\n readonly warnings: string[] = [];\n private readonly messages: string[] = [];\n private done = false;\n private failed: string | null = null;\n private note: string | null = null;\n\n get text(): string {\n return this.messages.join(\"\\n\\n\");\n }\n\n feed(line: string): boolean {\n this.lines++;\n const p = codexLine(line);\n if (!p) return false;\n if (p.session && !this.session) this.session = p.session;\n if (p.note) this.note = p.note;\n if (p.warning && this.warnings.length < 20) this.warnings.push(p.warning);\n if (p.failed) this.failed = p.failed;\n if (p.done) this.done = true;\n if (p.message?.trim()) {\n this.messages.push(p.message.trim());\n return true;\n }\n return false;\n }\n\n /** A failure is `turn.failed`, or a run that exits non-zero having said nothing; an\n * `error` item before a turn that then succeeds is only a warning. */\n outcome(res: RunResult): { failed: string } | { reply: string } {\n const broke = runFailure(LABEL, res);\n if (broke) return { failed: broke };\n if (this.failed) return { failed: this.failed };\n if (this.done || res.code === 0 || this.messages.length)\n return { reply: this.text || \"(Codex finished without a written reply.)\" };\n const why = this.note || codexStderr(res.stderr) || this.warnings.at(-1) || \"\";\n return { failed: `Codex exited (${res.signal || `code ${res.code}`}) without an answer${why ? `: ${why}` : \"\"}` };\n }\n}\n\n/** stderr's tail without the line Codex prints even with stdin closed. */\nfunction codexStderr(stderr: string | undefined): string {\n return stderrTail(\n String(stderr || \"\")\n .split(\"\\n\")\n .filter((l) => !/^Reading additional input from stdin/.test(l.trim()))\n .join(\"\\n\"),\n );\n}\n\nexport const reading = (): CodexReading => new CodexReading();\n", "// SPDX-License-Identifier: Apache-2.0\n// Devin CLI (Cognition) \u2014 docs: https://docs.devin.ai/cli/extensibility/hooks/overview\n// Config: the `hooks` key of the user config file \u2014 `~/.config/devin/config.json`\n// (`$XDG_CONFIG_HOME/devin/config.json` when that is set), `%APPDATA%\\devin\\config.json`\n// on Windows. Claude-shaped, matcher a REGEX on the tool name, timeouts in SECONDS.\n// That file is the only user-level location Devin reads hooks from; `hooks.v1.json` is\n// project-level only.\n//\n// Devin accepts exactly eight event names and rejects the WHOLE file on one it does not\n// know (\"unknown variant `Notification`, expected one of \u2026\"), which silently disables\n// every hook in it. DEVIN_EVENTS is that set, and nothing else may be added to it.\n//\n// The payload carries no `cwd`, no `transcript_path` and no `model`: the folder comes\n// from DEVIN_PROJECT_DIR in the hook's environment, and the transcript, the model, the\n// title and the times come from Devin's own session store \u2014 one SQLite file under the\n// data directory, read only, through readers/sqlite.ts. A session's transcript is\n// addressed as \"<database>#<session id>\", because readTranscript is given a file.\n//\n// stdout stays empty for every event: Devin reads a decision from stdout, and silence\n// plus exit 0 is \"carry on\" (printing nothing, printing `{}`, exiting 1 and blowing the\n// timeout were all measured as non-blocking; only exit 2 or an explicit\n// {\"decision\":\"block\"} blocks a tool).\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readlinkSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { homeDir } from \"../paths.js\";\nimport { querySqlite } from \"../readers/sqlite.js\";\nimport { pairTurns } from \"../readers/transcripts.js\";\nimport { installClaudeShaped, installedClaudeShaped, readJson, uninstallClaudeShaped } from \"./claude-shaped.js\";\nimport type {\n Adapter,\n BackfillRow,\n HookInput,\n HookResult,\n InstallOptions,\n SessionFacts,\n TranscriptRead,\n} from \"./types.js\";\n\nconst NAME = \"devin\";\n/** The eight event names Devin accepts. One it does not know makes it drop the whole\n * hooks file, so this list is exact, not a superset \u2014 see devin.test.ts. */\nexport const DEVIN_EVENTS = [\n \"SessionStart\",\n \"UserPromptSubmit\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PermissionRequest\",\n \"Stop\",\n \"PostCompaction\",\n \"SessionEnd\",\n] as const;\nconst OPTS = { matcherFor: (e: string) => (/Tool|Permission/.test(e) ? \"\" : undefined), timeout: 5 };\nconst eventsFor = (lean?: boolean) => (lean ? DEVIN_EVENTS.filter((e) => e !== \"PreToolUse\") : [...DEVIN_EVENTS]);\nconst INSTALL_NOTE =\n \"Devin drops a whole hooks file on one event name it doesn't know; `/hooks` in `devin` lists what loaded\";\nconst CLAUDE_NOTE =\n \"Devin also reads ~/.claude/settings.json hooks (read_config_from.claude); a Claude-only event name there makes it ignore that file whole\";\n\nconst deadFileNote = (bad: string) =>\n `Devin loads NO hooks from this file: \"${bad}\" is not one of its event names and it rejects the file whole \u2014 remove that key (\\`/hooks\\` in \\`devin\\` lists what loaded)`;\n\n/** The first `hooks` key in the file that Devin does not accept, if there is one.\n * One such key disables every hook in the file, ours and any other tool's. */\nexport function foreignEvent(file: string): string | undefined {\n const hooks = readJson(file).hooks;\n if (!hooks || typeof hooks !== \"object\" || Array.isArray(hooks)) return undefined;\n const ok = DEVIN_EVENTS as readonly string[];\n return Object.keys(hooks).find((k) => !ok.includes(k));\n}\n\nconst homeOf = (env: NodeJS.ProcessEnv) => env.HOME || homeDir();\nconst appData = (env: NodeJS.ProcessEnv) => env.APPDATA || path.join(homeOf(env), \"AppData\", \"Roaming\");\n/** `~/.config/devin`, `$XDG_CONFIG_HOME/devin`, or `%APPDATA%\\devin`. */\nexport const devinConfigDir = (env: NodeJS.ProcessEnv = process.env): string =>\n process.platform === \"win32\"\n ? path.join(appData(env), \"devin\")\n : path.join(env.XDG_CONFIG_HOME || path.join(homeOf(env), \".config\"), \"devin\");\nconst configFile = (env: NodeJS.ProcessEnv) => path.join(devinConfigDir(env), \"config.json\");\n/** `~/.local/share/devin/cli`, `$XDG_DATA_HOME/devin/cli`, or `%APPDATA%\\devin\\cli`. */\nexport const devinDataDir = (env: NodeJS.ProcessEnv = process.env): string =>\n process.platform === \"win32\"\n ? path.join(appData(env), \"devin\", \"cli\")\n : path.join(env.XDG_DATA_HOME || path.join(homeOf(env), \".local\", \"share\"), \"devin\", \"cli\");\nconst sessionsDb = (env: NodeJS.ProcessEnv) => path.join(devinDataDir(env), \"sessions.db\");\n\nconst SESSION_ID = /^[A-Za-z0-9._:-]{1,128}$/;\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\";\nconst pickSource = (v: unknown): string =>\n typeof v === \"string\" && [\"startup\", \"resume\", \"clear\", \"compact\", \"fork\"].includes(v) ? v : \"unknown\";\nfunction errText(v: unknown): string | undefined {\n if (typeof v === \"string\" && v) return v.slice(0, 2000);\n if (v && typeof v === \"object\") {\n const e = v as { message?: unknown; error?: unknown };\n if (typeof e.message === \"string\" && e.message) return e.message.slice(0, 2000);\n if (typeof e.error === \"string\" && e.error) return e.error.slice(0, 2000);\n }\n return undefined;\n}\nconst cut = (s: string, n: number): string => (s.length > n ? `${s.slice(0, n).replace(/\\s+\\S*$/, \"\")}\u2026` : s);\n\nexport const devin: Adapter = {\n name: NAME,\n events: DEVIN_EVENTS,\n detect: (env = process.env) => existsSync(devinConfigDir(env)) || existsSync(devinDataDir(env)),\n configFiles: (env = process.env) => [configFile(env)],\n install: (cmd, env = process.env, opts: InstallOptions = {}) => {\n const file = configFile(env);\n const r = installClaudeShaped(file, NAME, eventsFor(opts.lean), cmd, OPTS);\n if (r.skipped) return [r];\n const bad = foreignEvent(file);\n return [{ ...r, note: bad ? deadFileNote(bad) : INSTALL_NOTE }];\n },\n uninstall: (env = process.env, opts: InstallOptions = {}) => [\n uninstallClaudeShaped(configFile(env), DEVIN_EVENTS, { created: opts.created?.includes(configFile(env)) }),\n ],\n installed: (cmd, env = process.env, opts: InstallOptions = {}) => {\n const file = configFile(env);\n const state = installedClaudeShaped(file, NAME, eventsFor(opts.lean), cmd, OPTS);\n // Our entries can be present and current and still report nothing: one event name\n // Devin does not know makes it drop the whole file, ours with it. `status` has to\n // say so, or it tells the person reporting is on while it is dead.\n const bad = state === \"missing\" ? undefined : foreignEvent(file);\n return [{ file, state: bad ? \"inactive\" : state, note: bad ? deadFileNote(bad) : CLAUDE_NOTE }];\n },\n\n fromHook(input: HookInput): HookResult | null {\n const event = input.argv[1] ?? \"\";\n let s: Record<string, unknown> = {};\n try {\n // A stdin that is JSON but not an object (`null`, a number) is no payload.\n const j: unknown = input.stdin ? JSON.parse(input.stdin) : {};\n if (j && typeof j === \"object\" && !Array.isArray(j)) s = j as Record<string, unknown>;\n } catch {}\n const id = typeof s.session_id === \"string\" ? s.session_id : \"\";\n if (!id) return null;\n // Nothing in the payload names the folder; DEVIN_PROJECT_DIR is the only thing that does.\n const session: HookResult[\"session\"] = { id, cwd: input.env.DEVIN_PROJECT_DIR ?? input.cwd };\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 // Every recorded payload has an object here, but the field is free-form: a Devin\n // version or an MCP-style tool could send a bare string, and then there is no\n // `success` and no `output` to read \u2014 the whole value IS the output.\n const response =\n s.tool_response && typeof s.tool_response === \"object\" && !Array.isArray(s.tool_response)\n ? (s.tool_response as { success?: unknown; output?: unknown; error?: unknown })\n : undefined;\n // The same prompt must always name the same attention (CONTROL.md \u00A76). Devin's\n // PermissionRequest does carry tool_use_id; the hash is the fallback for one that\n // doesn't, and is the bytes ADAPTERS.md's common conventions prescribe.\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) }));\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 // Devin is the one harness that says so outright: tool_response.success.\n if (tool)\n events.push(\n ev(\"tool.ended\", {\n tool,\n call_id,\n turn_id,\n // `ok` is required on tool.ended (PROTOCOL.md \u00A7events), so a response\n // that carries no success flag at all reads as \"nothing said it failed\".\n ok: response?.success !== false,\n error: errText(response?.error),\n input: s.tool_input,\n output: response ? response.output : s.tool_response,\n }),\n );\n break;\n case \"PermissionRequest\":\n events.push(ev(\"attention.needed\", { attention_id: call_id ?? permissionId(), kind: \"permission\", tool }));\n break;\n case \"Stop\":\n events.push(ev(\"turn.ended\", { turn_id, reason: \"stop\" }));\n break;\n case \"PostCompaction\":\n // Devin has no pre-compaction event; the payload carries only the summary.\n events.push(ev(\"context.compacted\", { trigger: \"auto\" }));\n break;\n case \"SessionEnd\":\n events.push(ev(\"session.ended\", { reason: endReason(s.reason) }));\n break;\n default:\n return null;\n }\n return {\n session,\n events,\n hints: {},\n transcript: transcriptRef(sessionsDb(input.env as NodeJS.ProcessEnv), id),\n };\n },\n\n readTranscript(file, fromLine) {\n const ref = splitRef(file);\n if (!ref) return { turns: [], line: fromLine };\n return readDevinChain(ref.db, ref.session, fromLine);\n },\n\n facts(session, transcript, _hints, _state, env = process.env): SessionFacts {\n const out: SessionFacts = {};\n const version = devinVersion(env);\n if (version) out.harness_version = version;\n const account = devinAccount(env);\n if (account) out.account_id = account;\n const ref = splitRef(transcript) ?? { db: sessionsDb(env), session: session.id };\n if (!SESSION_ID.test(ref.session)) return out;\n const rows = querySqlite(ref.db, SESSION_SQL, [ref.session]);\n const row = rows?.[0];\n if (!row) return out;\n Object.assign(out, sessionFacts(row));\n return out;\n },\n\n backfill(sinceMs, env = process.env): BackfillRow[] {\n const rows = querySqlite(sessionsDb(env), BACKFILL_SQL, [\"text\", Math.floor(sinceMs / 1000)]);\n if (!rows) return [];\n const out: BackfillRow[] = [];\n for (const row of rows) {\n const id = String(row.id); // text, the query says\n if (!SESSION_ID.test(id)) continue;\n const { started_at, last_at, ...rest } = sessionFacts(row);\n if (!started_at || !last_at) continue;\n out.push({ session: { id, ...rest }, started_at, last_at });\n }\n return out;\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// --- the session store ---------------------------------------------------------------\n\n/** `<database>#<session id>`: readTranscript is given a file, and Devin keeps every\n * session in one database, so the session has to ride in the string. */\nexport const transcriptRef = (db: string, session: string): string => `${db}#${session}`;\nexport function splitRef(ref: string | undefined): { db: string; session: string } | null {\n if (!ref) return null;\n const at = ref.lastIndexOf(\"#\");\n if (at <= 0) return null;\n const db = ref.slice(0, at);\n const session = ref.slice(at + 1);\n return db && SESSION_ID.test(session) ? { db, session } : null;\n}\n\n/** `message_nodes` is a forest: it keeps abandoned branches too (27 nodes for a\n * two-turn session). The transcript is the one chain that ends at\n * `sessions.main_chain_id`, walked up through `parent_node_id` \u2014 never every node. */\n/** The walk stops at the cursor (`m.node_id >= ?`): everything below it has been read\n * already, and without that bound every Stop pulled `chat_message` for every ancestor\n * \u2014 the root of a real chain carries a 17 kB system prompt and four more system\n * blocks, re-read on every event, and past 32 MB the child and CLI engines give up\n * and return nothing. The cap keeps the NEWEST rows (`DESC`), re-sorted below: an\n * ascending cap would have kept the oldest and delivered no new turn ever again. */\nconst CHAIN_LIMIT = 4000;\nexport const CHAIN_SQL = `WITH RECURSIVE chain(node_id, parent_node_id, chat_message, created_at) AS (\n SELECT node_id, parent_node_id, chat_message, created_at FROM message_nodes\n WHERE session_id = ? AND node_id = (SELECT main_chain_id FROM sessions WHERE id = ?)\n UNION ALL\n SELECT m.node_id, m.parent_node_id, m.chat_message, m.created_at FROM message_nodes m\n JOIN chain c ON m.node_id = c.parent_node_id AND m.session_id = ? AND m.node_id >= ?\n)\nSELECT node_id, chat_message, created_at FROM chain ORDER BY node_id DESC LIMIT ${CHAIN_LIMIT}`;\n\n/** Times are unix SECONDS in this store. The first ask comes from `prompt_history`,\n * because `sessions.title` holds whatever the titler last produced \u2014 a backticked\n * command, or a raw `functions.Shell:0{\u2026}` mid-turn. */\nconst SESSION_FIELDS = `s.model, s.working_directory, s.created_at, s.last_activity_at,\n (SELECT p.content FROM prompt_history p WHERE p.session_id = s.id AND p.is_shell = 0\n ORDER BY p.timestamp ASC, p.id ASC LIMIT 1) AS first_ask`;\nconst SESSION_SQL = `SELECT ${SESSION_FIELDS} FROM sessions s WHERE s.id = ? LIMIT 1`;\n// typeof(id) = 'text' (the literal rides as a parameter: the CLI engine takes no quote\n// in the SQL): an id a session ref could carry. A blob id comes back from the sqlite3\n// CLI as a string shaped by its version, so the database says what it is.\nconst BACKFILL_SQL = `SELECT s.id, ${SESSION_FIELDS} FROM sessions s\n WHERE s.hidden = 0 AND typeof(s.id) = ? AND s.last_activity_at >= ?\n ORDER BY s.last_activity_at DESC LIMIT 500`;\n\nfunction sessionFacts(row: Record<string, unknown>): SessionFacts {\n const out: SessionFacts = {};\n if (typeof row.model === \"string\" && row.model) out.model = row.model;\n if (typeof row.working_directory === \"string\" && path.isAbsolute(row.working_directory))\n out.cwd = row.working_directory;\n const started = Number(row.created_at);\n const last = Number(row.last_activity_at);\n if (Number.isFinite(started) && started > 0) out.started_at = Math.round(started * 1000);\n if (Number.isFinite(last) && last > 0) out.last_at = Math.round(last * 1000);\n if (typeof row.first_ask === \"string\") {\n const line = row.first_ask.split(\"\\n\").find((l) => l.trim()) ?? \"\";\n if (line.trim()) {\n out.title = cut(line.trim(), 80);\n out.title_source = \"first-ask\";\n }\n }\n return out;\n}\n\ninterface ChatMessage {\n role?: unknown;\n content?: unknown;\n metadata?: { is_user_input?: unknown; created_at?: unknown } | null;\n}\n\n/** The canonical chain as turns. `node_id` is the cursor: it rises along the chain and\n * is stable across a resume, so a later read starts where the last one stopped.\n * `role: \"system\"` is Cognition's own prompt (and the skills manifest, and the\n * generated system_info block), never the person's words \u2014 it is skipped at every\n * tier, as is `role: \"tool\"`. */\nexport function readDevinChain(db: string, session: string, fromLine: number): TranscriptRead {\n if (!SESSION_ID.test(session)) return { turns: [], line: fromLine };\n const floor = Number.isFinite(fromLine) && fromLine > 0 ? Math.floor(fromLine) : 0;\n const rows = querySqlite(db, CHAIN_SQL, [session, session, session, floor]);\n if (!rows?.length) return { turns: [], line: fromLine };\n const msgs: { role: \"user\" | \"assistant\"; text: string; at: number; line: number }[] = [];\n let end = fromLine;\n for (const row of rows) {\n const node = Number(row.node_id);\n if (!Number.isFinite(node)) continue;\n if (node + 1 > end) end = node + 1;\n if (node < fromLine) continue;\n let j: ChatMessage;\n try {\n j = JSON.parse(String(row.chat_message ?? \"\")) as ChatMessage;\n } catch {\n continue;\n }\n const text = typeof j.content === \"string\" ? j.content.trim() : \"\";\n if (!text) continue;\n // The message's own time, not the row's. `message_nodes.created_at` is when the row\n // batch was last WRITTEN: Devin rewrites it on every save of the chain, so every\n // node of a chain usually carries one identical value, and it is not even monotonic\n // along the chain. Measured on a live store 2026-10-08: a two-turn session had all\n // four of its chain nodes at 23:33:10 while their own `metadata.created_at` read\n // 23:32:29, :34, 23:33:08 and :10 (turn 1 reported 41 s late, both turns at the same\n // instant); one node's row time was rewritten 12 s later between two reads; and a\n // descendant's row time was 27 s EARLIER than its ancestor's. The column is only the\n // fallback for a row whose message has no time of its own.\n const secs = Number(row.created_at);\n const at =\n Date.parse(String(j.metadata?.created_at ?? \"\")) ||\n (Number.isFinite(secs) && secs > 0 ? Math.round(secs * 1000) : 0) ||\n Date.now();\n if (j.role === \"user\" && j.metadata?.is_user_input === true) msgs.push({ role: \"user\", text, at, line: node });\n else if (j.role === \"assistant\") msgs.push({ role: \"assistant\", text, at, line: node });\n }\n // The rows come newest first (the cap keeps the newest); a transcript runs the other way.\n msgs.sort((a, b) => a.line - b.line);\n return pairTurns(msgs, end);\n}\n\n/** `<data dir>/_versions/current` is a symlink to the running version's folder. */\nexport function devinVersion(env: NodeJS.ProcessEnv = process.env): string | undefined {\n try {\n const target = readlinkSync(path.join(devinDataDir(env), \"_versions\", \"current\"));\n const name = path.basename(target);\n return /^[0-9][0-9A-Za-z.+-]{0,63}$/.test(name) ? name : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The organisation the CLI is signed in to, from the user config \u2014 the only account id\n * Devin keeps in a plain local file. Never the email, and never credentials.toml. */\nexport function devinAccount(env: NodeJS.ProcessEnv = process.env): string | undefined {\n const d = readJson(configFile(env)).devin as { org_id?: unknown } | undefined;\n const id = d && typeof d === \"object\" ? d.org_id : undefined;\n return typeof id === \"string\" && /^[A-Za-z0-9_.:-]{1,128}$/.test(id) ? id : undefined;\n}\n", "// SPDX-License-Identifier: Apache-2.0\n// Read-only SQLite, for a harness that keeps its sessions in a database instead of a\n// JSONL file. Three ways in, tried in order, because `node:sqlite` does not exist on\n// Node 20 (the floor this package builds for) and is behind --experimental-sqlite on\n// 22.5\u201322.12:\n// \"node\" in this process, through createRequire \u2014 no static import, so the bundle\n// still loads on a Node without the module;\n// \"child\" one `node --experimental-sqlite -e \u2026` run through execFileSync: no shell,\n// arguments passed as argv, a short timeout;\n// \"cli\" the `sqlite3` binary, when it is on PATH and every parameter is a plain\n// scalar that can be written as a literal.\n// Every path opens the file read-only, is bounded in time, and returns null instead of\n// throwing: a database that is busy, missing, locked or unreadable costs the caller\n// nothing but an empty read.\nimport { execFileSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\n\nexport type SqliteParam = string | number;\nexport type SqliteRow = Record<string, unknown>;\nexport type SqliteEngine = \"auto\" | \"node\" | \"child\" | \"cli\";\n\nexport interface SqliteOptions {\n /** Busy timeout and the child's wall clock, in ms (default 2000). */\n timeoutMs?: number;\n /** Force one way in; \"auto\" tries node, then child, then cli (default). */\n engine?: SqliteEngine;\n /** Largest reply a child or the CLI may print (default 32 MB). */\n maxBuffer?: number;\n}\n\ninterface Statement {\n all(...params: SqliteParam[]): unknown[];\n}\ninterface Db {\n prepare(sql: string): Statement;\n exec(sql: string): void;\n close(): void;\n}\ntype DbCtor = new (path: string, options?: Record<string, unknown>) => Db;\n\n/** `node:sqlite` is still experimental, and Node says so on stderr the first time it is\n * used. A reader has no business writing to a harness's terminal, so that one warning\n * is swallowed while the module is loaded and used \u2014 nothing else is, and the original\n * emitter is back before this returns. (The child path passes --no-warnings instead.)\n * Exported for its test: Node emits that warning once per process. */\nexport function quiet<T>(fn: () => T): T {\n const original = process.emitWarning;\n try {\n process.emitWarning = ((warning: unknown, ...rest: unknown[]) => {\n const kind = typeof rest[0] === \"string\" ? rest[0] : (rest[0] as { type?: string } | undefined)?.type;\n if (kind === \"ExperimentalWarning\" && /sqlite/i.test(String(warning))) return;\n (original as (...a: unknown[]) => void).call(process, warning, ...rest);\n }) as typeof process.emitWarning;\n return fn();\n } finally {\n process.emitWarning = original;\n }\n}\n\nlet ctorCache: DbCtor | null | undefined;\n/** `node:sqlite` if this Node has it; null if it does not (Node 20, or 22.x unflagged). */\nfunction dbCtor(): DbCtor | null {\n if (ctorCache !== undefined) return ctorCache;\n ctorCache = null;\n try {\n const req = createRequire(import.meta.url);\n const m = quiet(() => req(\"node:sqlite\")) as { DatabaseSync?: unknown };\n if (typeof m?.DatabaseSync === \"function\") ctorCache = m.DatabaseSync as DbCtor;\n } catch {}\n return ctorCache;\n}\n\n/** SQLite gives back strings, numbers, null, BigInt and Uint8Array; the protocol takes JSON. */\nfunction plain(row: unknown): SqliteRow | null {\n if (!row || typeof row !== \"object\") return null;\n const out: SqliteRow = {};\n for (const [k, v] of Object.entries(row as SqliteRow)) {\n if (typeof v === \"bigint\") out[k] = Number(v);\n else if (v instanceof Uint8Array) out[k] = null;\n else out[k] = v;\n }\n return out;\n}\nconst rows = (v: unknown): SqliteRow[] | null => {\n if (!Array.isArray(v)) return null;\n const out: SqliteRow[] = [];\n for (const r of v) {\n const p = plain(r);\n if (p) out.push(p);\n }\n return out;\n};\n\nfunction viaNode(file: string, sql: string, params: SqliteParam[], o: Required<SqliteOptions>): SqliteRow[] | null {\n const C = dbCtor();\n if (!C) return null;\n let db: Db;\n try {\n db = quiet(() => new C(file, { readOnly: true, timeout: o.timeoutMs }));\n } catch {\n return null;\n }\n try {\n try {\n db.exec(`PRAGMA busy_timeout = ${Math.round(o.timeoutMs)}`);\n } catch {}\n return quiet(() => rows(db.prepare(sql).all(...params)));\n } catch {\n return null;\n } finally {\n try {\n db.close();\n } catch {}\n }\n}\n\n/** Runs in a child Node, with the file, the SQL, the parameters and the timeout as argv. */\nconst CHILD = `const { DatabaseSync } = require(\"node:sqlite\");\nconst [, file, sql, params, ms] = process.argv;\nconst db = new DatabaseSync(file, { readOnly: true, timeout: Number(ms) });\ntry { db.exec(\"PRAGMA busy_timeout = \" + Number(ms)); } catch {}\nconst out = db.prepare(sql).all(...JSON.parse(params));\ndb.close();\nprocess.stdout.write(JSON.stringify(out));`;\n\nfunction viaChild(file: string, sql: string, params: SqliteParam[], o: Required<SqliteOptions>): SqliteRow[] | null {\n try {\n const out = execFileSync(\n process.execPath,\n [\"--experimental-sqlite\", \"--no-warnings\", \"-e\", CHILD, file, sql, JSON.stringify(params), String(o.timeoutMs)],\n {\n encoding: \"utf8\",\n timeout: o.timeoutMs + 3000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n maxBuffer: o.maxBuffer,\n windowsHide: true,\n },\n );\n return rows(JSON.parse(out || \"null\"));\n } catch {\n return null;\n }\n}\n\n/** A parameter safe to write into SQL as a literal: no quote, no backslash, no newline. */\nconst SAFE = /^[A-Za-z0-9 ._:@/+-]{0,256}$/;\nexport function inlineParams(sql: string, params: SqliteParam[]): string | null {\n if (sql.includes(\"'\")) return null; // a literal in the SQL would make the `?` count a guess\n const holes = sql.split(\"?\").length - 1;\n if (holes !== params.length) return null;\n let i = 0;\n let bad = false;\n const out = sql.replace(/\\?/g, () => {\n const p = params[i++];\n if (typeof p === \"number\") {\n if (!Number.isFinite(p)) {\n bad = true;\n return \"NULL\";\n }\n return String(p);\n }\n if (typeof p !== \"string\" || !SAFE.test(p)) {\n bad = true;\n return \"NULL\";\n }\n return `'${p}'`;\n });\n return bad ? null : out;\n}\n\nfunction viaCli(file: string, sql: string, params: SqliteParam[], o: Required<SqliteOptions>): SqliteRow[] | null {\n const text = inlineParams(sql, params);\n if (!text) return null;\n try {\n const out = execFileSync(\"sqlite3\", [\"-readonly\", \"-json\", file, text], {\n encoding: \"utf8\",\n timeout: o.timeoutMs + 3000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n maxBuffer: o.maxBuffer,\n windowsHide: true,\n }).trim();\n if (!out) return [];\n return rows(JSON.parse(out));\n } catch {\n return null;\n }\n}\n\n/** One read-only query. Null means \"could not read it\", never an exception. */\nexport function querySqlite(\n file: string,\n sql: string,\n params: SqliteParam[] = [],\n opts: SqliteOptions = {},\n): SqliteRow[] | null {\n const o: Required<SqliteOptions> = {\n timeoutMs: opts.timeoutMs ?? 2000,\n engine: opts.engine ?? \"auto\",\n maxBuffer: opts.maxBuffer ?? 32 * 1024 * 1024,\n };\n if (!file) return null;\n try {\n if (!existsSync(file)) return null;\n } catch {\n return null;\n }\n const ways =\n o.engine === \"auto\"\n ? ([viaNode, viaChild, viaCli] as const)\n : o.engine === \"node\"\n ? ([viaNode] as const)\n : o.engine === \"child\"\n ? ([viaChild] as const)\n : ([viaCli] as const);\n for (const way of ways) {\n const r = way(file, sql, params, o);\n if (r) return r;\n }\n return null;\n}\n\n/** Is `node:sqlite` in this process? (Tests skip what they cannot set up.) */\nexport const sqliteInProcess = (): boolean => dbCtor() !== null;\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 { homeDir } 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(homeDir(), \".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 // A stdin that is JSON but not an object (`null`, a number) is no payload.\n const j: unknown = input.stdin ? JSON.parse(input.stdin) : {};\n if (j && typeof j === \"object\" && !Array.isArray(j)) s = j 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\")[0] as string; // trimmed, so its first line is its first non-blank one\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// 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 { findAgy } from \"./antigravity-control.js\";\nimport { claudeCode } from \"./claude-code.js\";\nimport { findClaude } from \"./claude-code-control.js\";\nimport { codex } from \"./codex.js\";\nimport { findCodex } from \"./codex-control.js\";\nimport { devin } from \"./devin.js\";\nimport { geminiCli } from \"./gemini-cli.js\";\nimport type { Adapter } from \"./types.js\";\n\nexport const ADAPTERS: readonly Adapter[] = [claudeCode, codex, geminiCli, antigravity, devin];\nexport const adapterByName = (name: string): Adapter | undefined => ADAPTERS.find((a) => a.name === name);\nexport { AG_STALE_PRETOOL, antigravityAnswer } from \"./antigravity.js\";\nexport * as antigravityControl from \"./antigravity-control.js\";\nexport { claudeAccounts, claudeDirs, notClaudeCode } from \"./claude-code.js\";\nexport * as claudeControl from \"./claude-code-control.js\";\nexport * as codexControl from \"./codex-control.js\";\nexport { DEVIN_EVENTS, devinConfigDir, devinDataDir, readDevinChain } from \"./devin.js\";\nexport {\n deniedNote,\n JOB_TIMEOUT_MS,\n jobEnv,\n type Login,\n type Reading,\n type RunOptions,\n type RunResult,\n runHeadless,\n} from \"./headless.js\";\n\n/** The harnesses a control daemon here can drive headlessly (CONTROL.md \u00A76): each whose\n * CLI is installed on this machine. What `control pair` and every hello advertise. */\nexport function drivableHarnesses(env: NodeJS.ProcessEnv = process.env): string[] {\n return [\n ...(findClaude(env) ? [\"claude-code\"] : []),\n ...(findCodex(env) ? [\"codex\"] : []),\n ...(findAgy(env) ? [\"antigravity\"] : []),\n ];\n}\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, devin, 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] as number) + 1;\n if (v < 32) {\n lastRand[i] = v;\n break;\n }\n lastRand[i] = 0;\n }\n } else {\n lastTime = now;\n lastRand = Array.from(randomBytes(16), (b) => b % 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\nconst READ_CHUNK = 1024 * 1024;\nconst READ_MAX = 8 * 1024 * 1024;\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 = -1;\n try {\n const t = readFileSync(f, \"utf8\").trim();\n if (/^\\d+$/.test(t)) n = Number(t);\n } catch {}\n // A missing or unreadable counter (a crash between truncate and write leaves it\n // empty) with an existing outbox: recover from the file's last line.\n if (n < 0) n = this.lastSeqInFile(ref) + 1;\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 string) 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. A read\n * takes READ_CHUNK bytes at a time, not the rest of the file: a session file grows\n * to tens of MB and a drain takes it in batches of 50. It reads on until the batch\n * is full or the file ends, so lines that parse to nothing never stop a drain; one\n * line longer than the chunk gets a larger one, up to READ_MAX. */\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 events: Event[] = [];\n let offset = from;\n let chunk = READ_CHUNK;\n while (events.length < maxEvents && offset < size) {\n const buf = Buffer.alloc(Math.min(size - offset, chunk));\n const n = readSync(fd, buf, 0, buf.length, offset);\n const text = buf.subarray(0, n).toString(\"utf8\");\n let pos = 0;\n let used = 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 used += Buffer.byteLength(line, \"utf8\") + 1;\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as Event);\n } catch {}\n }\n offset += used;\n if (used) continue;\n // No whole line in this chunk: a line longer than it, or a write in progress.\n if (offset + n >= size || chunk >= READ_MAX) break;\n chunk *= 2;\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 once the worker that\n * took it is gone (its 15 s deadline ends it without a release), or after 5 min. */\nexport function takeLock(root: string, ref: OutboxRef, staleMs = 5 * 60_000): (() => void) | null {\n return takeNamedLock(root, `${safeId(ref.harness)}-${safeId(ref.session)}`, staleMs);\n}\n\n/** A named lock under <root>/locks, held by one process at a time: the file names\n * its pid. Stale once that process is gone, or after `staleMs`. */\nexport function takeNamedLock(root: string, name: string, 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, `${name}.lock`);\n try {\n if (Date.now() - statSync(f).mtimeMs > staleMs || !processAlive(Number(readFileSync(f, \"utf8\")))) 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\n/** Whether the process a lock or a claimed job names is still running. A pid that\n * can't be read counts as running: the age rule decides then. */\nexport function processAlive(pid: number): boolean {\n if (!Number.isInteger(pid) || pid <= 0) return true;\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n return (e as NodeJS.ErrnoException).code === \"EPERM\";\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] as string;\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]) as string;\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) => `${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 \"turn.progress\": 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 \"turn.progress\": { 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\n/** At most `max` characters, keeping the end: an ellipsis, then the last max \u2212 1. */\nexport function capTail(v: string, max: number): string {\n return v.length > max ? `\u2026${v.slice(v.length - max + 1)}` : 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\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 // A turn still running is read for where it is now: its reply keeps the end.\n if (typeof data.assistant === \"string\")\n data.assistant = event.type === \"turn.progress\" ? capTail(data.assistant, MAX_SIDE) : 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// A session's short id (spec/PROTOCOL.md \u00A73): the first 8 hex digits of\n// sha256(\"sessionpipe.session:\" + harness + \":\" + id). What a person reads in a log\n// line, a notification, a search box; derived, never sent. Not a prefix of the id\n// itself: Codex ids are time-ordered (UUIDv7), and two sessions started in the same\n// minute share their first eight characters.\nimport { createHash } from \"node:crypto\";\n\nexport function shortId(harness: string, id: string): string {\n return createHash(\"sha256\").update(`sessionpipe.session:${harness}:${id}`).digest(\"hex\").slice(0, 8);\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 try {\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 } catch (e) {\n // A closed pipe (`sessionpipe tail | head`): a result, like every other sink.\n return { ok: false, acknowledged: 0, error: String((e as Error).message ?? e), action: \"retry\" };\n }\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 // A resolved path ends with the separator only when it is the root, answered above.\n return d === h || h.startsWith(/* v8 ignore next */ d.endsWith(path.sep) ? d : d + path.sep);\n}\n\n// `parent` is a resolved, non-root folder (isBroad keeps the root out): it never ends with the separator.\nconst inside = (child: string, parent: string): boolean =>\n child !== parent && child.startsWith(/* v8 ignore next */ 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.\n * Setup opts into prereleases when checking whether an installed build is newer. */\nexport function isNewer(a: string, b: string, includePrereleases = false): boolean {\n const x = parse(a);\n if (!x || (!includePrereleases && 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 { readFileSync, realpathSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { launcherState } from \"./launcher.js\";\nimport { VERSION } from \"./run.js\";\nimport { isNewer } from \"./update.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/** Homebrew's default prefix disappears on a node upgrade; use the persistent one. */\nfunction installLocation(): { prefix: string; target: string } {\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 return {\n prefix,\n target: /\\/Cellar\\/node(?:@\\d+)?\\/[^/]+/.test(prefix) ? path.join(os.homedir(), \".local\") : prefix,\n };\n}\n\n/** Refuse before npm, config or hook writes, including hooks left by another prefix. */\nexport function assertSetupVersion(allowDowngrade: boolean, target?: string): void {\n if (allowDowngrade) return;\n const check = (installed: string | null, where: string): void => {\n if (installed && isNewer(installed, VERSION, true))\n throw new Error(\n `refusing to downgrade sessionpipe: ${installed} is installed at ${where}; this command would install ${VERSION}. Use the installed newer CLI, or pass --allow-downgrade to force ${VERSION}.`,\n );\n };\n const hooks = launcherState(VERSION);\n check(hooks.version, hooks.file);\n const prefix = target ?? installLocation().target;\n if (!prefix) return;\n const pkg = path.join(\n prefix,\n ...(process.platform === \"win32\" ? [] : [\"lib\"]),\n \"node_modules\",\n \"sessionpipe\",\n \"package.json\",\n );\n let installed: unknown;\n try {\n installed = (JSON.parse(readFileSync(pkg, \"utf8\")) as { version?: unknown }).version;\n } catch {}\n if (typeof installed === \"string\") check(installed, pkg);\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, setup?: { allowDowngrade: boolean }): void {\n const { prefix, target } = installLocation();\n if (setup) assertSetupVersion(setup.allowDowngrade, target);\n out(` Installing sessionpipe@${VERSION} globally, so hooks and services use a persistent copy\u2026`);\n let bin: string;\n try {\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 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", "// 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 capTail,\n type DeliveryResult,\n type Event,\n type FactsState,\n FileSink,\n filterEvent,\n gitFacts,\n isInjected,\n machineName,\n makeEvent,\n Outbox,\n processAlive,\n readConfig,\n redactDeep,\n type Session,\n type Sink,\n type SinkConfig,\n StdoutSink,\n safeId,\n shortId,\n stateDir,\n type TranscriptRead,\n takeLock,\n takeNamedLock,\n tilde,\n writeConfig,\n} from \"@sessionpipe/core\";\nimport { aliasFile, readAliases, receiverIdOf } from \"./control/aliases.js\";\nimport { ask, socketPath } from \"./control/local.js\";\nimport { HttpSink } from \"./http-sink.js\";\nimport { sinkWithSecrets } from \"./secrets.js\";\n\nasync function tellDaemon(\n state: string,\n job: Job,\n session: string,\n cwd: string | undefined,\n transcript?: string,\n): 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: `${job.harness}:${session}`,\n event: job.event,\n ...(cwd ? { 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 /** How many times the session's lock held this job out (a fresh worker starts for\n * it each time, up to MAX_TRIES; after that a sweep picks it up). */\n tries?: number;\n}\n\nexport const MAX_TRIES = 10;\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/** A job is claimed by renaming its file `<file>.<pid>.running`: of two workers that\n * race for it, one rename wins. The claim stays until the job's events are in the\n * outbox (or it went back to the queue), so a worker its deadline ended mid-run\n * leaves it behind for a sweep to give back (ground rule 4: no event lost). */\nexport function claimJob(file: string): { job: Job; file: string } | null {\n const claimed = `${file}.${process.pid}.running`;\n try {\n renameSync(file, claimed);\n } catch {\n return null;\n }\n try {\n return { job: JSON.parse(readFileSync(claimed, \"utf8\")) as Job, file: claimed };\n } catch {\n releaseJob(claimed);\n return null;\n }\n}\nexport function releaseJob(claimed: string | undefined): void {\n if (!claimed) return;\n try {\n unlinkSync(claimed);\n } catch {}\n}\n\n/** Jobs another worker left behind: a claim whose worker is gone (or older than any\n * worker lives, `abandonedMs`) goes back to the queue, then every queued job older\n * than `olderThanMs` (younger ones belong to the worker their hook just spawned)\n * is claimed and run. Every worker sweeps before it exits. */\nexport async function sweepJobs(state: string, olderThanMs = 3000, limit = 20, abandonedMs = 60_000): Promise<number> {\n const jobs = jobsDir(state);\n let names: string[] = [];\n try {\n names = readdirSync(jobs);\n } catch {\n return 0;\n }\n const queued = names.filter((n) => n.endsWith(\".json\"));\n for (const n of names) {\n const m = /^(.*\\.json)\\.(\\d+)\\.running$/.exec(n);\n if (!m) continue;\n const f = path.join(jobs, n);\n try {\n if (processAlive(Number(m[2])) && Date.now() - statSync(f).mtimeMs < abandonedMs) continue;\n renameSync(f, path.join(jobs, m[1] as string));\n queued.push(m[1] as string);\n } catch {}\n }\n let ran = 0;\n for (const n of queued.sort().slice(0, limit)) {\n const f = path.join(jobs, n);\n try {\n if (Date.now() - statSync(f).mtimeMs < olderThanMs) continue;\n } catch {\n continue;\n }\n const c = claimJob(f);\n if (!c) continue;\n try {\n await runJob(c.job, { state, claimed: c.file });\n } catch {\n } finally {\n releaseJob(c.file);\n }\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/** How often a running turn's words go out again (turn.progress), at most. */\nexport const PROGRESS_MS = 20_000;\n\n/** The turn still running in a transcript read from the delivery cursor: the last\n * turn with a reply so far, or a prompt nothing has answered yet (the hook's own\n * copy when the transcript doesn't hold it yet). `base` is the number the cursor's\n * first turn will get, so a turn keeps the number its turn.transcript will carry.\n * The reply keeps its end when it is long: where the turn is now. */\nexport function openTurn(\n read: TranscriptRead,\n o: { base: number; prompt?: string | undefined; at: number },\n): { turn: number; user: string; assistant: string; at: number } | null {\n const last = read.turns[read.turns.length - 1];\n const fresh = (user: string, at: number) => ({\n turn: o.base + read.turns.length,\n user: user.slice(0, MAX_TURN_SIDE),\n assistant: \"\",\n at,\n });\n if (read.open) return fresh(read.open.user, read.open.at);\n // The prompt the hook just reported, unless the transcript already has its reply.\n // Text the person never typed (a task notification, another session's message) opens\n // no turn: the readers skip it, so that turn would never be delivered, and its\n // reading would stand in for the turn that is running until the next one lands.\n const prompt = o.prompt?.trim();\n if (prompt && !isInjected(prompt) && !(last && last.user.includes(prompt.slice(0, 200)))) return fresh(prompt, o.at);\n if (!last) return null;\n return {\n turn: o.base + read.turns.length - 1,\n user: last.user.slice(0, MAX_TURN_SIDE),\n assistant: capTail(last.assistant, MAX_TURN_SIDE),\n at: last.at,\n };\n}\nconst MAX_TURN_SIDE = 20_000;\n\n/** Run one hook job end to end: events \u2192 outbox \u2192 sinks. Returns what happened.\n * `claimed` is the job file this run holds: released once the events are in the\n * outbox or the job is back in the queue (`requeued` names its new file). */\nexport async function runJob(\n job: Job,\n opts: { state?: string; now?: number; claimed?: string; lockWaitMs?: number } = {},\n): Promise<{ events: Event[]; delivered: Record<string, number>; requeued?: string }> {\n const state = opts.state ?? stateDir();\n const cfg = readConfig();\n const adapter = adapterByName(job.harness);\n // A hooks file can outlive the build that wrote it (an update to a sessionpipe without\n // that adapter, a hand-written entry): without this line the events are dropped in\n // silence, with nothing on the machine to say so.\n if (!adapter) {\n log(state, `${job.harness} ${job.event}: no adapter for harness \"${job.harness}\"; event dropped`);\n return { events: [], delivered: {} };\n }\n const r = adapter.fromHook({ argv: job.argv, stdin: job.stdin, env: { ...process.env, ...job.env }, cwd: job.cwd });\n // The adapter did not claim the payload (another harness ran our entry out of a\n // shared hooks file, an event name it does not map, a payload with no session id).\n // Dropped either way, but never in silence: this is where a wrongly-named event\n // lands, and the log is the only thing on the machine that can say so.\n if (!r || !r.session.id) {\n log(state, `${job.harness} ${job.event}: the ${job.harness} adapter did not claim this payload; event dropped`);\n return { events: [], delivered: {} };\n }\n // A session the control daemon started goes by the id its start command named, not\n // the one the harness picked (CONTROL.md \u00A76 `start`; control/aliases.ts): its events\n // say so, and so does everything below. The adapter's own reading of the session\n // (facts, a remote URL) keeps the harness's id.\n const id =\n receiverIdOf(readAliases(aliasFile(path.join(state, \"control\"))), job.harness, r.session.id) ?? r.session.id;\n const claudeEnd = job.harness === \"claude-code\" && r.events.some((e) => e.type === \"session.ended\");\n // The control daemon learns each session's turn state and folder from its events (a\n // 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 (!claudeEnd) await tellDaemon(state, job, id, r.session.cwd, r.transcript);\n const outbox = new Outbox(state);\n const ref = { harness: job.harness, session: id };\n // Hooks of one session fire close together (parallel subagents, issue #9): poll\n // for the lock, often enough that its siblings can't keep taking it in between,\n // before giving the job back to the queue.\n let release = takeLock(state, ref);\n const lockWait = opts.lockWaitMs ?? LOCK_WAIT_MS;\n for (const until = Date.now() + lockWait; !release && Date.now() < until; ) {\n await new Promise((res) => setTimeout(res, 50));\n release = takeLock(state, ref);\n }\n if (!release) {\n log(state, `${job.harness} ${job.event}: session ${id} locked for ${lockWait / 1000} s, re-queued`);\n const requeued = enqueueJob(state, { ...job, tries: (job.tries ?? 0) + 1 });\n releaseJob(opts.claimed);\n return { events: [], delivered: {}, requeued };\n }\n const events: Event[] = [];\n try {\n const facts = factsState(state);\n const mem = facts.get(job.harness, id);\n // `claude mcp list` fires SessionEnd with a fresh id but no SessionStart or\n // transcript. Check under the session lock, before creating facts or a seq:\n // any existing outbox, facts or transcript is enough to preserve a real end.\n if (\n claudeEnd &&\n !existsSync(outbox.file(ref)) &&\n Object.keys(mem).length === 0 &&\n !(r.transcript && existsSync(r.transcript))\n ) {\n releaseJob(opts.claimed);\n return { events: [], delivered: {} };\n }\n if (claudeEnd) await tellDaemon(state, job, id, r.session.cwd, r.transcript);\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 // The hook's environment, not the worker's: a swept job may be run by a worker\n // another harness's hook spawned, whose env names none of this harness's homes.\n const f = adapter.facts(r.session, r.transcript, r.hints ?? {}, facts, { ...process.env, ...job.env });\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, id, { harness_version });\n facts.save(job.harness, id, { session: { ...(mem.session as object), ...learned } });\n // Antigravity's transcript never says which folder a conversation runs in, and\n // Devin's payload names none either (only DEVIN_PROJECT_DIR in the hook's env);\n // the hooks do. Kept raw (this file is the machine's own, 0600), so the control\n // daemon still knows where to resume it after a restart.\n if (CWD_FROM_HOOKS.has(job.harness) && r.session.cwd && path.isAbsolute(r.session.cwd))\n facts.save(job.harness, id, { cwd: r.session.cwd });\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,\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, id).harness_version as string | undefined) ?? undefined;\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 const wantsTranscript = cfg.sinks.some((s) => !s.paused && Math.min(s.tier, s.max_tier ?? 3) >= 2);\n // Tier 2, while a turn runs: what it has said so far, so a receiver can show a long\n // turn before it ends. On the prompt, then at most every PROGRESS_MS on a tool call,\n // and only when it changed. The cursor stays where it is: turn.transcript still\n // delivers the whole turn when it ends.\n const ending = r.events.some((e) => e.type === \"turn.ended\" || e.type === \"session.ended\");\n const starting = r.events.some((e) => e.type === \"turn.started\");\n // A message sent while a turn runs is absorbed by that turn, and Claude Code reports\n // it as a prompt with the running turn's own id. It is not a new turn: where it\n // belongs is the transcript's to say, so its text is no reading of its own.\n const startedId = r.events.find((e) => e.type === \"turn.started\")?.data.turn_id;\n const absorbed = starting && typeof startedId === \"string\" && facts.get(job.harness, id).open_turn === startedId;\n if (wantsTranscript && r.transcript && !ending && (starting || r.events.some((e) => e.type === \"tool.ended\"))) {\n const cur = facts.get(job.harness, id);\n const at = opts.now ?? job.at;\n if (starting || at - (Number(cur.progress_at) || 0) >= PROGRESS_MS) {\n const p = openTurn(adapter.readTranscript(r.transcript, Number(cur.transcript_line) || 0), {\n base: Number(cur.transcript_turns) || 0,\n prompt: !absorbed && typeof r.hints?.prompt === \"string\" ? r.hints.prompt : undefined,\n at,\n });\n const sig = p && `${p.turn}:${p.user.length}:${p.assistant.length}`;\n if (p && (starting || sig !== cur.progress_sig)) {\n events.push(\n makeEvent(\n { type: \"turn.progress\", harnessEvent: job.event, data: { ...p, at: new Date(p.at).toISOString() } },\n {\n harness: { name: job.harness, ...(version ? { version } : {}) },\n session: { ...session, seq: outbox.nextSeq(ref) },\n now: at,\n },\n ),\n );\n facts.save(job.harness, id, { progress_at: at, progress_sig: sig });\n }\n }\n }\n // The turn running now, by its prompt's id, until it ends (for `absorbed`).\n if (starting && typeof startedId === \"string\" && !absorbed) facts.save(job.harness, id, { open_turn: startedId });\n if (ending) facts.save(job.harness, id, { open_turn: null });\n // Tier 2: after a turn ends, the transcript's new turns become turn.transcript events.\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, 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) facts.save(job.harness, 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 releaseJob(opts.claimed);\n log(\n state,\n `${job.harness} ${job.event}: ${events.map((e) => e.type).join(\",\") || \"nothing\"} (${shortId(job.harness, id)})`,\n );\n } finally {\n release();\n }\n // The session's lock covered the append; the sinks drain without it (the outbox\n // reader leaves a line still being written), so a sibling hook isn't held out for\n // a round trip.\n const delivered = (await drain(state, cfg.sinks, outbox, ref)) ?? {};\n if (Math.random() < 0.02) outbox.prune(cfg.keep_days ?? 30);\n return { events, delivered };\n}\n\n/** One worker drains a machine's sinks at a time (the `flush` lock). Another whose\n * events are in the outbox meanwhile marks that there is more and leaves them to\n * it (null: nothing sent by this one). The one draining looks for the mark after\n * each pass, once it has let the lock go, so events appended during a pass go out\n * in its next pass or with the worker that appended them, never wait for a later\n * hook. Under a flood of hook events this is one uploader sending full batches,\n * not one per event, all refused together (mordast, 2026-10-14: 828 refusals in\n * two minutes, 5 192 jobs queued). */\nexport async function drain(\n state: string,\n sinkConfigs: SinkConfig[],\n outbox: Outbox,\n first?: { harness: string; session: string },\n): Promise<Record<string, number> | null> {\n const more = path.join(state, \"locks\", \"flush.more\");\n let release = takeNamedLock(state, \"flush\");\n if (!release) {\n try {\n writeFileSync(more, \"\", { mode: 0o600 });\n } catch {}\n release = takeNamedLock(state, \"flush\");\n if (!release) return null;\n }\n const delivered: Record<string, number> = {};\n for (;;) {\n try {\n unlinkSync(more);\n } catch {}\n try {\n for (const [k, v] of Object.entries(await flush(state, sinkConfigs, outbox, first)))\n delivered[k] = (delivered[k] ?? 0) + v;\n } finally {\n release();\n }\n if (!existsSync(more)) return delivered;\n release = takeNamedLock(state, \"flush\");\n if (!release) return delivered;\n }\n}\n\n/** HTTP.md \u00A72: a sink that answered 429 isn't tried again before its `retry-after`;\n * one that was unreachable (5xx, a timeout) waits 2 s \u00B7 10 s \u00B7 60 s \u00B7 5 min \u00B7 30 min,\n * then every 30 min. Kept in <state>/backoff/<sink>.json, so every worker on the\n * machine waits, not only the one that was refused. Cleared by the next batch the\n * sink takes. */\nexport interface Backoff {\n until: number;\n failures: number;\n why: string;\n}\nconst BACKOFF_MS = [2_000, 10_000, 60_000, 5 * 60_000, 30 * 60_000];\nconst backoffFile = (state: string, sink: string): string => path.join(state, \"backoff\", `${safeId(sink)}.json`);\nexport function readBackoff(state: string, sink: string): Backoff | null {\n try {\n const b = JSON.parse(readFileSync(backoffFile(state, sink), \"utf8\")) as Backoff;\n return typeof b.until === \"number\" ? b : null;\n } catch {\n return null;\n }\n}\nfunction noteFailure(state: string, sink: string, res: DeliveryResult, prev: Backoff | null): Backoff {\n const failures = (prev?.failures ?? 0) + 1;\n const ladder = BACKOFF_MS[Math.min(failures, BACKOFF_MS.length) - 1] as number;\n const wait = Number.isFinite(res.retryAfterMs) ? (res.retryAfterMs as number) : ladder;\n const b = { until: Date.now() + wait, failures, why: `${res.status ?? \"\"} ${res.error ?? \"\"}`.trim() };\n const f = backoffFile(state, sink);\n try {\n mkdirSync(path.dirname(f), { recursive: true, mode: 0o700 });\n writeFileSync(f, JSON.stringify(b), { mode: 0o600 });\n } catch {}\n return b;\n}\nfunction clearBackoff(state: string, sink: string): void {\n try {\n unlinkSync(backoffFile(state, sink));\n } catch {}\n}\n\n/** How long a job waits for its session's lock before it goes back to the queue. */\nconst LOCK_WAIT_MS = 6000;\n/** Harnesses whose own files do not name the session's folder: the hooks' cwd is kept. */\nconst CWD_FROM_HOOKS = new Set([\"antigravity\", \"devin\"]);\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. The sinks drain at once:\n * the session's lock is held for the slowest round trip, not the sum of them (a\n * verdict's config write is synchronous, so two sinks' never interleave). */\nexport async function flush(\n state: string,\n sinkConfigs: SinkConfig[],\n outbox: Outbox,\n first?: { harness: string; session: string },\n o: { /** Try a sink in backoff anyway (`sessionpipe replay`). */ force?: boolean } = {},\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 const drainSink = async (sink: Sink): Promise<void> => {\n let backoff = readBackoff(state, sink.name);\n if (backoff && !o.force && backoff.until > Date.now()) {\n delivered[sink.name] = 0;\n return;\n }\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 // HTTP.md \u00A72 413: halve the batch and try again; one event too large on its own\n // is dropped and logged. A half that is refused for another reason stops the\n // run like any refusal: the cursor stays, and the halves that went through are\n // sent again next time (the receiver counts them as duplicates).\n const deliver = async (events: Event[]): Promise<DeliveryResult> => {\n const res = await sink.send(events);\n if (res.ok || res.action !== \"split\") return res;\n if (events.length === 1) {\n const e = events[0] as Event;\n log(state, `sink ${sink.name}: 413 ${res.error ?? \"\"} \u2192 event ${e.id} (${e.type}) is too large alone, dropped`);\n return { ok: true, acknowledged: 0, accepted: 0, duplicates: 0, rejected: [{ id: e.id, reason: \"too_large\" }] };\n }\n const half = Math.ceil(events.length / 2);\n const a = await deliver(events.slice(0, half));\n if (!a.ok) return a;\n const b = await deliver(events.slice(half));\n if (!b.ok) return b;\n return {\n ok: true,\n acknowledged: a.acknowledged + b.acknowledged,\n accepted: (a.accepted ?? 0) + (b.accepted ?? 0),\n duplicates: (a.duplicates ?? 0) + (b.duplicates ?? 0),\n rejected: [...(a.rejected ?? []), ...(b.rejected ?? [])],\n };\n };\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 deliver(batch);\n if (!res.ok) {\n const action = res.action ?? \"retry\";\n let wait = \"\";\n if (action === \"retry\") {\n backoff = noteFailure(state, sink.name, res, backoff);\n wait = `, waits ${Math.round((backoff.until - Date.now()) / 1000)} s`;\n }\n log(state, `sink ${sink.name}: ${res.status ?? \"\"} ${res.error ?? \"\"} \u2192 ${action}${wait}`);\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 } else if (backoff) {\n clearBackoff(state, sink.name);\n backoff = null;\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 await Promise.all(sinks.map(drainSink));\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// Sessions the daemon started under the command's name (spec/CONTROL.md \u00A76 `start`).\n// Codex and Antigravity pick a new session's id themselves, but a `start` names the\n// session (`codex:<id>`), and that name is what the person's receiver knows it by. So\n// the moment a run reveals the harness's own id, the daemon records it here:\n//\n// state/control/aliases.json {\"codex:<command's id>\": {\"id\": \"<harness's id>\",\n// \"cwd\": \"<folder>\", \"at\": \"<iso>\"}, \u2026} (0600)\n//\n// and everything the machine reports uses the command's id: the daemon's acks, a later\n// prompt (resumed under the harness's id), and the hook events, which the worker renames\n// before it builds them (run.ts). Small, so it is read whole wherever it is needed.\nimport { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport interface Alias {\n /** The harness's own session id. */\n id: string;\n /** The folder the session runs in (the start's). */\n cwd: string;\n at: string;\n}\nexport type Aliases = Record<string, Alias>;\n\nexport const aliasFile = (controlDir: string): string => path.join(controlDir, \"aliases.json\");\n\nexport function readAliases(file: string): Aliases {\n try {\n const j = JSON.parse(readFileSync(file, \"utf8\")) as unknown;\n if (!j || typeof j !== \"object\" || Array.isArray(j)) return {};\n const out: Aliases = {};\n for (const [k, v] of Object.entries(j as Record<string, unknown>)) {\n const a = v as Partial<Alias> | null;\n if (a && typeof a.id === \"string\" && a.id && typeof a.cwd === \"string\")\n out[k] = { id: a.id, cwd: a.cwd, at: typeof a.at === \"string\" ? a.at : \"\" };\n }\n return out;\n } catch {\n return {};\n }\n}\n\n/** Written whole and renamed into place, 0600 in a 0700 folder. */\nexport function writeAliases(file: string, all: Aliases): void {\n mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });\n const tmp = `${file}.${process.pid}.tmp`;\n writeFileSync(tmp, `${JSON.stringify(all, null, 2)}\\n`, { mode: 0o600 });\n renameSync(tmp, file);\n try {\n chmodSync(file, 0o600);\n } catch {}\n}\n\n/** The command's id a harness's own session goes by, or null when it was never renamed. */\nexport function receiverIdOf(all: Aliases, harness: string, id: string): string | null {\n const prefix = `${harness}:`;\n for (const [k, a] of Object.entries(all)) if (a.id === id && k.startsWith(prefix)) return k.slice(prefix.length);\n return null;\n}\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\n/** HTTP.md \u00A72 429: wait as `retry-after` says, seconds or an HTTP date (RFC 9110\n * \u00A710.2.3); a minute when the header is missing or unreadable. */\nexport function retryAfterMs(header: string | null, now = Date.now()): number {\n if (header === null || header.trim() === \"\") return 60_000;\n const secs = Number(header);\n if (Number.isFinite(secs)) return Math.max(0, secs) * 1000;\n const at = Date.parse(header);\n return Number.isFinite(at) ? Math.max(0, at - now) : 60_000;\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: retryAfterMs(r.headers.get(\"retry-after\")),\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 // From a store, so with a token (sinkWithSecrets is null without one); a sink\n // already in the file never gets here.\n /* v8 ignore else */\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/** Attachments on a `start` (CONTROL.md \u00A73.1): at most this many files, */\nexport const FILES_MAX = 10;\n/** each at most this many bytes, */\nexport const FILE_SIZE_MAX = 26_214_400;\n/** together at most this many, */\nexport const FILES_TOTAL_MAX = 52_428_800;\n/** with a name of at most this many characters (after NFC) */\nexport const FILE_NAME_MAX = 200;\n/** and a media type of at most this many. */\nexport const FILE_TYPE_MAX = 100;\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}\n/** One file attached to a `start`: the bytes live on the receiver, named by their hash. */\nexport interface ControlFile {\n /** The file name the machine writes (NFC). */\n name: string;\n /** Media type, `type/subtype`. */\n type: string;\n /** Bytes. */\n size: number;\n /** SHA-256 of the bytes, base64url without padding (43 characters). */\n sha256: 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 /** start only: files to download, verify and write into the new session's folder. */\n files?: ControlFile[];\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 SHA256_RE = /^[A-Za-z0-9_-]{43}$/;\nconst MEDIA_TYPE_RE = /^[a-z0-9][a-z0-9!#$&^_.+-]*\\/[a-z0-9][a-z0-9!#$&^_.+-]*$/i;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: control characters are exactly what it rejects\nconst BAD_NAME_CHAR_RE = /[/\\\\\\x00-\\x1f\\x7f]/;\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\n/** Equal, compared whole: a mismatch costs the same as a match. */\nexport function 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 as number; // every RSA key has one\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 (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, cwd and files\");\n if (has(\"files\")) {\n const why = filesProblem(c.files);\n if (why) return bad(\"bad_fields\", why);\n }\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 (c.kind !== \"start\" && has(\"files\")) return bad(\"bad_fields\", \"only a start carries files\");\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\n/** Why a start's `files` breaks the rules (CONTROL.md \u00A73.1), or null when it doesn't. */\nexport function filesProblem(files: unknown): string | null {\n if (!Array.isArray(files) || files.length < 1 || files.length > FILES_MAX)\n return `files is a list of 1 to ${FILES_MAX} files`;\n const seen = new Set<string>();\n let total = 0;\n for (const f of files as unknown[]) {\n if (!f || typeof f !== \"object\" || Array.isArray(f)) return \"each file is an object\";\n const { name, type, size, sha256: hash } = f as Record<string, unknown>;\n const why = fileNameProblem(name);\n if (why) return why;\n const key = (name as string).normalize(\"NFC\").toLowerCase();\n if (seen.has(key)) return \"two files have the same name\";\n seen.add(key);\n if (typeof type !== \"string\" || type.length > FILE_TYPE_MAX || !MEDIA_TYPE_RE.test(type))\n return \"a file's type isn't a media type\";\n if (!isNum(size) || !Number.isInteger(size) || size < 1 || size > FILE_SIZE_MAX)\n return `a file is 1 byte to ${FILE_SIZE_MAX / 1_048_576} MiB`;\n total += size;\n if (typeof hash !== \"string\" || !SHA256_RE.test(hash)) return \"a file's sha256 isn't 43 base64url characters\";\n }\n if (total > FILES_TOTAL_MAX) return `the files add up to more than ${FILES_TOTAL_MAX / 1_048_576} MiB`;\n return null;\n}\n\n/** A file name the machine can write inside the session's folder and nowhere else. */\nfunction fileNameProblem(name: unknown): string | null {\n if (typeof name !== \"string\") return \"a file has no name\";\n const n = name.normalize(\"NFC\");\n if (n.length < 1 || n.length > FILE_NAME_MAX) return `a file name is 1 to ${FILE_NAME_MAX} characters`;\n if (BAD_NAME_CHAR_RE.test(n)) return \"a file name has a slash, a backslash or a control character\";\n if (n.startsWith(\".\")) return \"a file name can't start with a dot\";\n return null;\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 | mode | folders | keys | off | run | status` and `sessionpipe wait`.\nimport { existsSync, realpathSync, statSync, unwatchFile, watchFile } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport {\n antigravityControl,\n claudeControl,\n claudeDirs,\n codexControl,\n drivableHarnesses,\n machineName,\n Outbox,\n readConfig,\n stateDir,\n type Tier,\n writeConfig,\n} from \"@sessionpipe/core\";\n\nconst { claudeLogin, detectCaps, findClaude, runClaude } = claudeControl;\n\nimport { isBroad } from \"../connect.js\";\nimport { drain, 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 folders [add|remove DIR\u2026] (where sessions you message may run)\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 (Codex runs with --approve-for-me, Antigravity with --mode accept-edits.)\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. (Codex runs in its workspace-write sandbox and never\n escalates; Antigravity is denied every tool call that would need approval.)`;\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\n/** `control folders add|remove`: the new list, and a line per folder saying what became\n * of it. A folder to add must exist and be a project, never the home folder or above\n * it (pair's rule); folders are compared as real paths, as the daemon compares them. */\nexport function changeFolders(\n folders: string[],\n op: \"add\" | \"remove\",\n dirs: string[],\n home = os.homedir(),\n): { folders: string[]; said: string[] } {\n const real = (d: string) => {\n try {\n return realpathSync.native(d);\n } catch {\n return path.resolve(d);\n }\n };\n const next = [...folders];\n const said: string[] = [];\n for (const d of dirs) {\n const abs = path.resolve(d);\n const at = next.findIndex((f) => real(f) === real(abs));\n if (op === \"remove\") {\n if (at < 0) said.push(` \u00B7 ${abs} wasn't allowed`);\n else said.push(` \u2713 No longer allowed: ${next.splice(at, 1)[0]}`);\n continue;\n }\n let dir = false;\n try {\n dir = statSync(abs).isDirectory();\n } catch {}\n if (!dir) said.push(` \u2717 ${abs} isn't a folder on this machine`);\n else if (isBroad(abs, home))\n said.push(\n ` \u2717 Not allowing all of ${abs}: name a project folder inside it, so a message can't run anywhere you own`,\n );\n else if (at >= 0) said.push(` \u00B7 ${abs} is already allowed`);\n else {\n next.push(abs);\n said.push(` \u2713 Allowed ${abs}`);\n }\n }\n return { folders: next, said };\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 ?? machineName(cfg, 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 \"folders\": {\n // The folders are the machine's own list, so they change here, at its keyboard, as\n // at pairing: no new pairing and no passkey. A message to a session in any other\n // folder is refused (\"that session's folder isn't one this machine allows\").\n const op = argv[2];\n const usage = \" usage: sessionpipe control folders [add|remove <folder>\u2026]\";\n if (op !== undefined && op !== \"add\" && op !== \"remove\") return out(usage);\n const c = readControl();\n if (!c) return out(\" control isn't set up on this machine: run `sessionpipe control pair <receiver>` first\");\n if (op) {\n const dirs = argv.slice(3);\n if (!dirs.length) return out(usage);\n const r = changeFolders(c.folders, op, dirs);\n for (const l of r.said) out(l);\n if (r.folders.join(\"\\n\") !== c.folders.join(\"\\n\")) {\n c.folders = r.folders;\n writeControl(c);\n // The running daemon reads control.json again within seconds and tells the\n // receiver the new list in a hello then.\n out(\" The control daemon uses the new list within seconds.\");\n }\n }\n return out(\n c.folders.length\n ? ` Sessions you message may run in:\\n${c.folders.map((f) => ` ${f}`).join(\"\\n\")}`\n : \" No folder is allowed: a message to a session here is refused until you add one.\",\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 codex: () => codexControl.findCodex(),\n agy: () => antigravityControl.findAgy(),\n codexLogin: (bin) => codexControl.codexLogin(bin),\n harnesses: () => drivableHarnesses(),\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 // Retry pending events even when a session has no more hooks. This also drains\n // what workers with a locked keychain left. The shared drain honours each sink's\n // wait and the machine-wide delivery lock, wherever its token lives.\n const drainTimer = setInterval(() => {\n const sinks = readConfig().sinks.filter((s) => !s.paused);\n if (sinks.length) void drain(stateDir(), sinks, new Outbox(stateDir())).catch(() => {});\n }, 60_000);\n drainTimer.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(drainTimer);\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. Claude Code,\n// Codex (`codex exec`) and Antigravity (`agy`) sessions can be resumed and started\n// headlessly; the Agent SDK, waiters, Stop blocks and forks are Claude Code's.\n//\n// A receiver can queue a message; it can never make this process run one.\nimport { chmodSync, existsSync, mkdirSync, readFileSync, realpathSync, statSync, unlinkSync } from \"node:fs\";\nimport net from \"node:net\";\nimport path from \"node:path\";\nimport {\n antigravityControl,\n claudeAccounts,\n claudeControl,\n codexControl,\n deniedNote,\n type HarnessAccount,\n JOB_TIMEOUT_MS,\n jobEnv,\n type Login,\n type Reading,\n type RunOptions,\n type RunResult,\n redactSecrets,\n safeId,\n shortId,\n} from \"@sessionpipe/core\";\nimport { type ControlCommand, parseSessionRef, verifyCommand } from \"@sessionpipe/core/control\";\nimport { type Alias, type Aliases, aliasFile, readAliases, receiverIdOf, writeAliases } from \"./aliases.js\";\nimport { fetchFiles, withFiles, writeFiles } from \"./files.js\";\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 liveProcess,\n loginHint,\n modeFlags,\n parseResult,\n recentlyWritten,\n sessionFolder,\n} = claudeControl;\ntype Caps = claudeControl.Caps;\ntype Transcript = claudeControl.Transcript;\n\n/** Where a session lives: its folder, and how the harness names it. */\ninterface Placed {\n folder: string;\n /** Claude Code's transcript. */\n transcript: Transcript | null;\n /** Codex / Antigravity: the harness's own id to resume (an alias's, else the command's). */\n target?: string;\n /** Codex: the session's rollout file, whose writes say whether it is in use. */\n file?: string | null;\n}\n\n/** A harness the daemon runs headlessly besides Claude Code (codex-control.ts,\n * antigravity-control.ts). */\ninterface Driver {\n label: string;\n cmd: string;\n bin: () => string | null;\n args: (o: { mode: \"safe\" | \"auto\"; prompt: string; cwd: string; resume?: string }) => string[];\n reading: () => Reading & { warnings?: string[] };\n login?: (bin: string) => Promise<Login>;\n loginHint?: string;\n}\n\n/** A start, read from the command before it is verified: only ever used to order a\n * prompt behind it, never to run anything. */\nfunction startNamed(cmd: unknown): string | null {\n if (typeof cmd !== \"string\" || cmd.length > 64 * 1024 || !cmd.includes('\"start\"')) return null;\n try {\n const c = JSON.parse(cmd) as { kind?: unknown; session?: unknown };\n return c?.kind === \"start\" && typeof c.session === \"string\" ? c.session : null;\n } catch {\n return null;\n }\n}\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 /** Codex CLI's `codex` and Antigravity's `agy` on this machine (null: not installed).\n * Absent: this daemon doesn't drive that harness. */\n codex?: () => string | null;\n agy?: () => string | null;\n /** Is Codex signed in as this process sees it? Asked before a run. */\n codexLogin?: (bin: string) => Promise<Login>;\n /** The harnesses every hello advertises (core's drivableHarnesses); by default, the\n * ones the finders above find. */\n harnesses?: () => string[];\n /** The harness accounts every hello names; by default, those signed in across\n * `claudeDirs`, read again for each hello. */\n accounts?: () => HarnessAccount[];\n run: (bin: string, args: string[], o: RunOptions) => 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 /** How long one of a start's files may take to download (tests shorten it). */\n fileTimeoutMs?: 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\ninterface PollState {\n started: number;\n last: number | null;\n error: string | null;\n on: boolean;\n unauthorized: boolean;\n authBackoff: number;\n wake: (() => void) | null;\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 successful poll; failed responses must not conceal a control outage. */\n last_poll: number | null;\n /** Time since success, or since this loop started if it has never succeeded. */\n last_poll_age_ms: number;\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, PollState>();\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 /** Codex and Antigravity sessions the daemon started, under the start's id (aliases.ts). */\n private aliases: Aliases;\n /** Starts in hand, by the session they name, from the moment they arrive: a prompt\n * for that session that came in the same poll waits for its start rather than\n * finding no session (2026-10-04: a start and a prompt queued back to back). */\n private readonly startsPending = new Map<string, Promise<void>>();\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 this.aliases = readAliases(aliasFile(dir));\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 for (const st of this.polling.values()) st.wake?.();\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 /* v8 ignore next -- Node unlinks a listening Unix socket's path in server.close(), so the file is gone by here; kept for a runtime that doesn't */\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 agent 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(\n `couldn't listen again: ${String(/* v8 ignore next -- listen() throws Errors (net, DaemonRunning) */ (e as Error)?.message || e)}`,\n );\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 const told = JSON.stringify([this.cfg.folders, this.cfg.mode, this.cfg.name]);\n this.cfg = cfg;\n for (const r of cfg.receivers) if (!known.has(r.control + r.machine)) void this.pollLoop(r);\n // `control folders`, `control mode` or a `--rename-machine` changed what a hello says:\n // say it now, so the receiver doesn't wait up to ten minutes for the next one.\n if (this.running && JSON.stringify([cfg.folders, cfg.mode, cfg.name]) !== told) void this.helloAll();\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_poll_age_ms: p ? Math.max(0, this.deps.now() - (p.last ?? p.started)) : 0,\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\") {\n // The socket is this user's alone (CONTROL.md \u00A78: mode 0600), whatever the umask.\n chmodSync(this.sock, 0o600);\n this.sockId = socketId(this.sock);\n }\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 // A worker that read the aliases a moment before a start recorded its session still\n // names the harness's own id; this daemon knows the start's.\n const l = this.liveOf(this.named(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: PollState = {\n started: this.deps.now(),\n last: null,\n error: null,\n on: true,\n unauthorized: false,\n authBackoff: 0,\n wake: null,\n };\n this.polling.set(key, st);\n // Unlike a bare sleep, this wait can end as soon as a hello proves the token\n // works, or the daemon stops. Keep exactly one poll loop per receiver.\n const retry = (ms: number) =>\n new Promise<void>((resolve) => {\n st.on = false;\n if (!this.running) {\n resolve();\n return;\n }\n const timer = setTimeout(() => st.wake?.(), ms);\n timer.unref();\n st.wake = () => {\n clearTimeout(timer);\n st.wake = null;\n resolve();\n };\n });\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 st.on = false;\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 retry(30_000);\n continue;\n }\n }\n const ctl = new AbortController();\n st.on = true;\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 // The request deadline applies to reading the response, never to a retry\n // delay (which can be much longer than a long-poll).\n if (res.status !== 200) clearTimeout(t);\n st.unauthorized = res.status === 401;\n if (downSince && (res.status === 200 || res.status === 204)) {\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 downSince ||= this.deps.now();\n backoff++;\n const delay = Math.min(60_000 * 2 ** st.authBackoff, 30 * 60_000);\n st.authBackoff = Math.min(st.authBackoff + 1, 5);\n await retry(delay);\n continue;\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(\n `handle ${String(m?.id).slice(-8)}: ${String(/* v8 ignore next -- handle() rejects with an Error (the ack file) */ (e as Error)?.message || e)}`,\n ),\n );\n }\n } finally {\n this.receiving--;\n }\n clearTimeout(t);\n st.last = this.deps.now();\n st.error = null;\n st.authBackoff = 0;\n backoff = 0;\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 } else if (res.status === 204) {\n st.last = this.deps.now();\n st.error = null;\n st.authBackoff = 0;\n backoff = 0;\n } else {\n st.error = `HTTP ${res.status}`;\n downSince ||= this.deps.now();\n let delay = pause(backoff++);\n if (res.status === 503) {\n const after = res.headers.get(\"retry-after\");\n const ms = after && /^\\d+$/.test(after) ? Number(after) * 1000 : Date.parse(after ?? \"\") - this.deps.now();\n if (Number.isFinite(ms)) delay = Math.max(delay, ms);\n }\n // Node treats an overflowing timeout as 1 ms; a long Retry-After must\n // not accidentally become a tight loop.\n await retry(Math.min(delay, 2_147_483_647));\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 st.unauthorized = false;\n downSince ||= this.deps.now();\n clearTimeout(t);\n await retry(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 const harnesses = this.harnesses();\n const accounts = this.accounts();\n for (const r of this.cfg.receivers) {\n const body = {\n name: this.cfg.name,\n harnesses,\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 ...(accounts.length ? { accounts } : {}),\n // This daemon takes `files` on a start (an older one would start without them).\n files: true,\n };\n const res = await this.post(r, \"/hello\", body).catch(() => null);\n const st = this.polling.get(r.control + r.machine);\n if (res?.ok && st?.unauthorized) {\n st.unauthorized = false;\n st.authBackoff = 0;\n st.error = null;\n this.deps.log(`${r.url}: hello accepted; retrying control poll now`);\n st.wake?.();\n }\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 // A start is marked now too, before its verification: messages of one poll are\n // handled side by side, and a prompt queued right behind its start may finish\n // verifying first. Marked unverified, it only ever makes such a prompt wait.\n const starting = startNamed(m.cmd);\n let done = (): void => {};\n if (starting) {\n const mine = new Promise<void>((res) => {\n done = res;\n });\n const before = this.startsPending.get(starting);\n const all = before ? Promise.all([before, mine]).then(() => undefined) : mine;\n this.startsPending.set(starting, all);\n void all.then(() => {\n if (this.startsPending.get(starting) === all) this.startsPending.delete(starting);\n });\n }\n try {\n await this.handleVerified(r, m);\n } finally {\n done();\n }\n }\n\n private async handleVerified(r: PairedReceiver, m: Carried): Promise<void> {\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 (or, for Codex and\n // Antigravity, no name) yet: wait for that start, then place it again.\n const starting = kp === \"prompt\" ? this.startsPending.get(cmd.session) : undefined;\n if (\"refused\" in place && (starting || this.ownRuns.has(ref.id))) {\n this.finish(r, m.id, { outcome: \"taken\" });\n await starting;\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, Codex), the folder its start recorded, or\n * the hooks' cwd, never the command. */\n private place(session: string): { refused: string; why: string } | Placed {\n const ref = parseSessionRef(session)!;\n if (ref.harness === \"codex\" || ref.harness === \"antigravity\") return this.placeDriven(session, ref);\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)\n return { refused: \"no_session\", why: `no Claude Code session ${shortId(ref.harness, ref.id)} 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 /** A Codex or Antigravity session: one the daemon started is its alias (the harness's\n * id and the start's folder); one the hooks reported is Codex's rollout (its\n * `session_meta` cwd) or, for Antigravity, the folder its hooks gave. */\n private placeDriven(\n session: string,\n ref: { harness: string; id: string },\n ): { refused: string; why: string } | Placed {\n const a = this.aliasOf(ref.harness, ref.id);\n const target = a?.id ?? ref.id;\n let cwd: string | undefined = a?.cwd || undefined;\n let file: string | null = null;\n if (ref.harness === \"codex\") {\n file = isUuid(target) ? codexControl.findRollout(target, this.deps.env ?? process.env) : null;\n if (!a && !file)\n return { refused: \"no_session\", why: `no Codex session ${shortId(ref.harness, ref.id)} on this machine` };\n cwd ||= file ? codexControl.codexFacts(file).cwd : undefined;\n } else cwd ||= this.live.get(session)?.cwd || this.factsCwd(ref.harness, ref.id);\n if (!cwd)\n return {\n refused: \"no_session\",\n why: `no folder known for ${ref.harness === \"codex\" ? \"Codex\" : \"Antigravity\"} session ${shortId(ref.harness, ref.id)}`,\n };\n const ok = this.allowed(cwd);\n if (!ok) return { refused: \"folder\", why: \"that session's folder isn't one this machine allows\" };\n return { folder: ok, transcript: null, target, file };\n }\n\n /** The folder the worker recorded for a session from its hooks (run.ts, facts). */\n private factsCwd(harness: string, id: string): string | undefined {\n try {\n const f = path.join(path.dirname(this.dir), \"facts\", safeId(harness), `${safeId(id)}.json`);\n const cwd = (JSON.parse(readFileSync(f, \"utf8\")) as { cwd?: unknown }).cwd;\n return typeof cwd === \"string\" && path.isAbsolute(cwd) ? cwd : undefined;\n } catch {\n return undefined;\n }\n }\n\n private aliasOf(harness: string, id: string): Alias | null {\n return this.aliases[`${harness}:${id}`] ?? null;\n }\n\n /** The harness revealed its own id for a session the command named: from now on that\n * is where the command's id leads (aliases.ts). Written before anything else reads it. */\n private setAlias(harness: string, id: string, real: string, cwd: string): void {\n this.aliases = {\n ...this.aliases,\n [`${harness}:${id}`]: { id: real, cwd, at: new Date(this.deps.now()).toISOString() },\n };\n try {\n writeAliases(aliasFile(this.dir), this.aliases);\n } catch (e) {\n this.deps.log(\n `couldn't record ${harness}:${id.slice(0, 8)} \u2192 ${real.slice(0, 8)}: ${String(/* v8 ignore next -- writeAliases throws fs Errors */ (e as Error)?.message || e)}`,\n );\n }\n }\n\n /** `<harness>:<harness's id>` \u2192 `<harness>:<the start's id>` for a session the daemon named. */\n private named(session: string): string {\n const i = session.indexOf(\":\");\n if (i <= 0) return session;\n const harness = session.slice(0, i);\n const as = receiverIdOf(this.aliases, harness, session.slice(i + 1));\n return as ? `${harness}:${as}` : session;\n }\n\n private driver(harness: string): Driver | null {\n if (harness === \"codex\")\n return {\n label: \"Codex\",\n cmd: \"codex\",\n bin: () => this.deps.codex?.() ?? null,\n args: ({ mode, prompt, cwd, resume }) =>\n resume ? codexControl.codexArgs({ mode, prompt, resume }) : codexControl.codexArgs({ mode, prompt, cwd }),\n reading: () => codexControl.reading(),\n ...(this.deps.codexLogin ? { login: this.deps.codexLogin } : {}),\n loginHint: codexControl.LOGIN_HINT,\n };\n /* v8 ignore else -- only a HEADLESS harness gets here (route.ts): Claude Code never asks for a driver */\n if (harness === \"antigravity\")\n return {\n label: \"Antigravity\",\n cmd: \"agy\",\n bin: () => this.deps.agy?.() ?? null,\n args: ({ mode, prompt, resume }) =>\n resume ? antigravityControl.agyArgs({ mode, prompt, resume }) : antigravityControl.agyArgs({ mode, prompt }),\n reading: () => antigravityControl.reading(),\n };\n /* v8 ignore next -- see above */\n return null;\n }\n\n /** Who is signed in here, for hello. A bad .claude.json names nobody, never fails a hello. */\n private accounts(): HarnessAccount[] {\n try {\n return this.deps.accounts ? this.deps.accounts() : claudeAccounts(this.deps.claudeDirs());\n } catch {\n return [];\n }\n }\n\n /** The harnesses this machine can run a message in, for hello. */\n private harnesses(): string[] {\n if (this.deps.harnesses) return this.deps.harnesses();\n return [\n ...(this.deps.claude() ? [\"claude-code\"] : []),\n ...(this.deps.codex?.() ? [\"codex\"] : []),\n ...(this.deps.agy?.() ? [\"antigravity\"] : []),\n ];\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, place: Placed) {\n const ref = parseSessionRef(session)!;\n const l = this.live.get(session);\n if (ref.harness !== \"claude-code\") {\n // Codex: a rollout someone else wrote in the last 90 s is a session in use.\n // Antigravity keeps no file that says so: only the daemon's own run (whose\n // messages wait in line behind it) holds one.\n const live =\n !this.ownRuns.has(ref.id) &&\n !!place.file &&\n recentlyWritten(place.file, this.lastEnd.get(ref.id), this.deps.now());\n return {\n harness: ref.harness,\n sdk: false,\n waiter: !!l?.waiter && !l.waiter.destroyed,\n midTurn: !!l?.midTurn,\n live,\n known: true,\n canFork: false,\n api: false,\n };\n }\n const transcript = place.transcript;\n const claude =\n ref.harness === \"claude-code\"\n ? this.deps.claude()\n : /* v8 ignore next -- every other harness returned above */ 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(r: PairedReceiver, id: string, cmd: ControlCommand, place: Placed, sent: number): Promise<void> {\n const route = routePrompt(this.view(cmd.session, place));\n if (\"unsupported\" in route) return this.finish(r, id, { outcome: \"unsupported\", detail: route.unsupported });\n /* v8 ignore next -- place() already refused a session with no transcript (`known` is never false here) */\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 /* v8 ignore next -- no harness has an input API wired yet (view() says api: false) */\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 const login = this.deps.login;\n if (!login) return null;\n if (await this.signedIn(configDir ?? \"\", () => login(configDir))) 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 /** One harness account's login, asked at most every 10 minutes (30 s after a no). */\n private async signedIn(key: string, ask: () => Promise<Login>): Promise<boolean> {\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 ask().catch((): Login => ({ loggedIn: null }));\n this.logins.set(key, { at: now, login });\n }\n return login.loggedIn !== false;\n }\n\n /** Null when a Codex or Antigravity run may go ahead; otherwise what to tell the person. */\n private async drivenProblem(drv: Driver): Promise<{ bin: string } | { failed: string }> {\n const bin = drv.bin();\n if (!bin) return { failed: `${drv.label} isn't installed on this machine` };\n const login = drv.login;\n if (login && !(await this.signedIn(`${drv.cmd}:`, () => login(bin)))) {\n this.deps.log(`${drv.cmd} isn't signed in as the daemon sees it`);\n return {\n failed:\n /* v8 ignore next -- only Codex has a login check, and it has a hint */ drv.loginHint ??\n `${drv.label} isn't signed in on this machine`,\n };\n }\n return { bin };\n }\n\n /** A Codex or Antigravity session's next message: a headless turn resumed under the\n * harness's own id, after any run of the daemon's own that holds it. */\n private async resumeDriven(r: PairedReceiver, id: string, cmd: ControlCommand, place: Placed, sent: number) {\n const ref = parseSessionRef(cmd.session)!;\n const drv = this.driver(ref.harness)!;\n const ready = await this.drivenProblem(drv);\n if (\"failed\" in ready) return this.finish(r, id, { outcome: \"failed\", detail: ready.failed });\n this.finish(r, id, { outcome: \"taken\" });\n await this.serial(ref.id, async () => {\n // Read again: the start this waited for may have named the session meanwhile.\n /* v8 ignore next -- placeDriven() always names a target; the last fallback is for the type */\n const target = this.aliasOf(ref.harness, ref.id)?.id ?? place.target ?? ref.id;\n const args = drv.args({\n mode: this.cfg.mode,\n prompt: frame(cmd.text as string, r.url),\n cwd: place.folder,\n resume: target,\n });\n this.deps.log(`${id.slice(-8)}: ${drv.cmd} resume ${target.slice(0, 8)} (${this.cfg.mode}) in ${place.folder}`);\n await this.drive(r, id, ref, drv, ready.bin, args, place.folder, sent, target);\n });\n }\n\n /** Run one Codex or Antigravity turn and ack it: `progress` as its answer grows, then\n * `delivered` (mode `resume`) with the reply. The moment the harness names the session\n * \u2014 a start's new one, or a fresh one for an id it didn't know \u2014 the command's id\n * becomes its alias, so the next message resumes it. */\n private async drive(\n r: PairedReceiver,\n id: string,\n ref: { harness: string; id: string },\n drv: Driver,\n bin: string,\n args: string[],\n cwd: string,\n sent: number,\n asked: string | null,\n ): Promise<void> {\n const stream = this.answerStream(r, id);\n const reading = drv.reading();\n let named: string | null = null;\n const name = () => {\n const s = reading.session;\n if (!s || s === named) return;\n named = s;\n if (s !== asked) this.setAlias(ref.harness, ref.id, s, cwd);\n };\n const onLine = (l: string) => {\n if (reading.feed(l)) stream.set(reading.text);\n name();\n };\n const res = await this.owning(ref.id, () =>\n this.slot(() =>\n this.deps.run(bin, args, {\n cwd,\n env: jobEnv(this.deps.env),\n timeoutMs: JOB_TIMEOUT_MS,\n onLine,\n keep: () => false,\n }),\n ),\n );\n // A runner that doesn't stream hands the whole output over at the end.\n if (!reading.lines && res.stdout) for (const l of res.stdout.split(\"\\n\")) if (l.trim()) onLine(l);\n stream.close();\n this.lastEnd.set(ref.id, this.deps.now());\n if (reading.warnings?.length)\n this.deps.log(`${id.slice(-8)}: ${drv.cmd} warned: ${reading.warnings.join(\" \u00B7 \").slice(0, 400)}`);\n const out = reading.outcome(res);\n if (\"failed\" in out) return this.finish(r, id, { outcome: \"failed\", detail: out.failed });\n const moved =\n asked && named && named !== asked\n ? `\\n\\n(${drv.label} didn't find that session on this machine, so this ran in a new one; later messages continue there.)`\n : \"\";\n this.finish(r, id, { outcome: \"delivered\", mode: \"resume\", reply: out.reply + moved }, sent);\n }\n\n private async headless(\n r: PairedReceiver,\n id: string,\n cmd: ControlCommand,\n place: Placed,\n mode: \"resume\" | \"fork\",\n sent: number,\n ): Promise<void> {\n if (parseSessionRef(cmd.session)?.harness !== \"claude-code\") return this.resumeDriven(r, id, cmd, place, sent);\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 = deniedNote(names, denials.length);\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 /* v8 ignore next -- the receiver that handed the message over is in cfg, unless `control off` ran mid-flight */\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(/* v8 ignore next -- writeControl throws fs Errors */ (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) =>\n this.finish(r, id, {\n outcome: \"delivered\",\n mode,\n detail: String(/* v8 ignore next -- awaitAnswer throws fs Errors */ (e as Error)?.message || e),\n }),\n );\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 /* v8 ignore next -- a session being let go of was always held */\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 (ref.harness !== \"claude-code\") return this.startDriven(r, id, cmd, ref, cwd, sent);\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 const text = await this.attached(r, id, cmd, ref, cwd);\n if (text === null) return;\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(text, 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(text, 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 /** A new Codex or Antigravity session: the harness picks its id, and the start's id\n * becomes its name (aliases.ts) as soon as the run says what it picked. */\n private async startDriven(\n r: PairedReceiver,\n id: string,\n cmd: ControlCommand,\n ref: { harness: string; id: string },\n cwd: string,\n sent: number,\n ): Promise<void> {\n const drv = this.driver(ref.harness)!;\n const env = this.deps.env ?? process.env;\n if (\n this.aliasOf(ref.harness, ref.id) ||\n this.live.get(cmd.session)?.cwd ||\n (ref.harness === \"codex\" && isUuid(ref.id) && codexControl.findRollout(ref.id, env))\n )\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 ready = await this.drivenProblem(drv);\n if (\"failed\" in ready) return this.finish(r, id, { outcome: \"failed\", detail: ready.failed });\n this.finish(r, id, { outcome: \"taken\" });\n const text = await this.attached(r, id, cmd, ref, cwd);\n if (text === null) return;\n const args = drv.args({ mode: this.cfg.mode, prompt: frameStart(text, r.url), cwd });\n this.deps.log(\n `${id.slice(-8)}: ${drv.cmd} new session for ${shortId(ref.harness, ref.id)} (${this.cfg.mode}) in ${cwd}`,\n );\n await this.drive(r, id, ref, drv, ready.bin, args, cwd, sent, null);\n }\n\n /** A start's text, with its files (CONTROL.md \u00A76) fetched, checked and written under\n * `cwd` first \u2014 every check in \u00A75 passed and the nonce is recorded by now, so the\n * `taken` ack is out and the download may take its time. Null when a file failed:\n * the command is acked `failed` with code `file`, nothing is kept, no session starts. */\n private async attached(\n r: PairedReceiver,\n id: string,\n cmd: ControlCommand,\n ref: { id: string },\n cwd: string,\n ): Promise<string | null> {\n const text = cmd.text as string;\n if (!cmd.files) return text;\n try {\n const got = await fetchFiles(cmd.files, {\n control: r.control,\n token: r.token,\n fetch: this.deps.fetch,\n timeoutMs: this.deps.fileTimeoutMs,\n });\n const rel = writeFiles(cwd, ref.id, got);\n this.deps.log(`${id.slice(-8)}: ${got.length} file(s) saved in ${cwd}/.sessionpipe/files/${ref.id}`);\n return withFiles(text, got, rel);\n } catch (e) {\n // fetchFiles and writeFiles throw nothing but a FileProblem, and its message is the detail.\n const detail = (e as Error).message;\n this.deps.log(`${id.slice(-8)}: file \u2014 ${detail}`);\n this.finish(r, id, { outcome: \"failed\", code: \"file\", detail });\n return null;\n }\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// Attachments on a `start` (spec/CONTROL.md \u00A73.1, \u00A76): the signed command names each\n// file by its SHA-256; the bytes wait on the receiver. The daemon fetches each one\n// with the machine's token, stops reading past the signed size, checks length and\n// hash, and only then writes it \u2014 under <cwd>/.sessionpipe/files/<session>/, never\n// through a symlink, never over an existing path, mode 0600. Any problem: nothing is\n// kept and the session doesn't start. The same for every harness the daemon starts:\n// the files are in `cwd` before the run, and nothing about them is the harness's.\nimport { createHash } from \"node:crypto\";\nimport { existsSync, lstatSync, mkdirSync, realpathSync, rmSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { ControlFile } from \"@sessionpipe/core/control\";\n\n/** One file's download may take this long (25 MiB on a slow link). */\nexport const FETCH_TIMEOUT_MS = 5 * 60_000;\n\n/** A file could not be fetched, checked or written: the ack's `detail`, code `file`. */\nexport class FileProblem extends Error {}\n\nexport interface Fetched {\n file: ControlFile;\n /** The name as written: NFC. */\n name: string;\n bytes: Uint8Array;\n}\n\nexport interface FetchOptions {\n control: string;\n token: string;\n fetch: typeof fetch;\n /** Per file; tests shorten it. */\n timeoutMs?: number | undefined;\n}\n\nconst b64url = (b: Buffer) => b.toString(\"base64\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\nconst reason = (e: unknown) => (e instanceof Error ? e.message : String(e)).slice(0, 160);\n\n/** Fetch every file, in order, and check each against the signed size and hash.\n * Every failure is a FileProblem naming the file. */\nexport async function fetchFiles(files: ControlFile[], o: FetchOptions): Promise<Fetched[]> {\n const out: Fetched[] = [];\n for (const file of files) {\n let bytes: Uint8Array;\n try {\n bytes = await fetchOne(file, o);\n } catch (e) {\n if (e instanceof FileProblem) throw e;\n throw new FileProblem(`couldn't download ${JSON.stringify(file.name)}: ${reason(e)}`);\n }\n out.push({ file, name: file.name.normalize(\"NFC\"), bytes });\n }\n return out;\n}\n\nasync function fetchOne(f: ControlFile, o: FetchOptions): Promise<Uint8Array> {\n const label = JSON.stringify(f.name);\n const ctl = new AbortController();\n const t = setTimeout(() => ctl.abort(), o.timeoutMs ?? FETCH_TIMEOUT_MS);\n try {\n const res = await o.fetch(`${o.control.replace(/\\/$/, \"\")}/files/${f.sha256}`, {\n headers: { authorization: `Bearer ${o.token}` },\n signal: ctl.signal,\n });\n if (res.status === 404) throw new FileProblem(`${label} isn't on the receiver (never uploaded, or expired)`);\n if (res.status !== 200) throw new FileProblem(`couldn't download ${label}: HTTP ${res.status}`);\n // A declared length past the signed size: not a byte of it is read.\n if (Number(res.headers.get(\"content-length\")) > f.size) throw tooLong(label, f);\n const buf = new Uint8Array(f.size);\n let got = 0;\n const reader = res.body!.getReader();\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n // Past the signed size: stop reading, whatever the receiver keeps sending.\n if (got + value.length > f.size) throw tooLong(label, f);\n buf.set(value, got);\n got += value.length;\n }\n if (got !== f.size) throw new FileProblem(`${label} is ${got} bytes, not its signed ${f.size}`);\n const hash = b64url(createHash(\"sha256\").update(buf).digest());\n if (hash !== f.sha256) throw new FileProblem(`${label} doesn't match its signed hash: it was changed`);\n return buf;\n } finally {\n clearTimeout(t);\n // Done or failed: whatever the receiver is still sending is cut off here.\n ctl.abort();\n }\n}\n\nconst tooLong = (label: string, f: ControlFile) =>\n new FileProblem(`${label} is larger than its signed size (${f.size} bytes)`);\n\n/** A directory that must be real (not a symlink) \u2014 made when absent. Anything else in\n * the way (a file of that name) fails the mkdir, and the files with it. */\nfunction realDir(p: string, why: string): void {\n mkdirSync(p, { recursive: true, mode: 0o700 });\n if (lstatSync(p).isSymbolicLink()) throw new FileProblem(`${why} is a symlink`);\n}\n\n/**\n * Write the checked files to <cwd>/.sessionpipe/files/<session>/ and answer their\n * paths relative to cwd. `cwd` is already resolved (realpath) and allowed.\n * On any problem everything written here is removed and FileProblem thrown.\n */\nexport function writeFiles(cwd: string, session: string, files: Fetched[]): string[] {\n const top = path.join(cwd, \".sessionpipe\");\n const parent = path.join(top, \"files\");\n const dir = path.join(parent, session);\n let made = false;\n try {\n realDir(top, \".sessionpipe\");\n // The folder ignores itself, so a repository never picks it up.\n const ignore = path.join(top, \".gitignore\");\n if (!existsSync(ignore)) writeFileSync(ignore, \"*\\n\", { flag: \"wx\", mode: 0o600 });\n realDir(parent, \".sessionpipe/files\");\n if (existsSync(dir)) throw new FileProblem(`.sessionpipe/files/${session} already exists`);\n mkdirSync(dir, { mode: 0o700 });\n made = true;\n // Every parent between cwd and here is a real directory right now.\n if (realpathSync.native(dir) !== dir) throw new FileProblem(\".sessionpipe leads outside the session's folder\");\n const rel: string[] = [];\n for (const f of files) {\n // wx: exclusive create, which also refuses to open through a symlink.\n writeFileSync(path.join(dir, f.name), f.bytes, { flag: \"wx\", mode: 0o600 });\n rel.push(`.sessionpipe/files/${session}/${f.name}`);\n }\n return rel;\n } catch (e) {\n if (made) rmSync(dir, { recursive: true, force: true });\n if (e instanceof FileProblem) throw e;\n throw new FileProblem(`couldn't save the files: ${reason(e)}`);\n }\n}\n\n/** 183402 \u2192 \"179 KB\", 1258291 \u2192 \"1.2 MB\" (units of 1024). */\nexport function humanSize(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1_048_576) return `${Math.round(n / 1024)} KB`;\n return `${(n / 1_048_576).toFixed(1)} MB`;\n}\n\n/** The command's text followed by the list of files the session can read. */\nexport function withFiles(text: string, files: Fetched[], rel: string[]): string {\n const lines = files.map((f, i) => `- ${rel[i]} (${f.file.type}, ${humanSize(f.file.size)})`);\n return `${text}\\n\\nAttached files (saved in this folder):\\n${lines.join(\"\\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 (Codex, Antigravity: the session was placed). */\n known: boolean;\n /** This Claude Code can copy a session (`--fork-session`); no other harness can. */\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/** The harnesses the daemon can run a turn of by itself: resume an idle session, start a\n * new one (`claude -p`, `codex exec`, `agy -p`). */\nexport const HEADLESS = new Set([\"claude-code\", \"codex\", \"antigravity\"]);\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 (!HEADLESS.has(s.harness)) 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 {\n unsupported:\n s.harness === \"claude-code\"\n ? \"the session is open and this Claude Code can't copy it (no --fork-session)\"\n : `the session is open in ${s.harness} right now, and a ${s.harness} session can't be copied: send it again once it has been idle a couple of minutes`,\n };\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\"\n ? { unsupported: \"Gemini CLI has no permission answer channel\" }\n : harness === \"devin\"\n ? { unsupported: \"Devin has no permission answer channel\" }\n : \"permission\";\n case \"cancel\":\n return \"cancel\";\n case \"start\":\n return HEADLESS.has(harness) ? \"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 { claudeAccounts, claudeDirs, drivableHarnesses, type HarnessAccount } from \"@sessionpipe/core\";\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 /** The harnesses this machine can run a message in (default: those installed here). */\n harnesses?: string[];\n /** The harness accounts signed in here (default: every Claude Code config dir's). */\n accounts?: HarnessAccount[];\n /** How long expired codes are renewed for (default RENEW_FOR_MS). */\n renewFor?: number;\n}\n\n/** How long `control pair` keeps asking for fresh codes when nobody approves one. */\nexport const RENEW_FOR_MS = 60 * 60_000;\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 let accounts = o.accounts;\n if (!accounts)\n try {\n const e = o.env ?? process.env;\n accounts = claudeAccounts(claudeDirs(e), e.HOME);\n } catch {\n accounts = [];\n }\n const auth = { authorization: `Bearer ${o.token ?? pollKey}`, \"content-type\": \"application/json\" };\n const hello = {\n ...(pollKey ? { poll_key: pollKey } : {}),\n name: cfg.name,\n harnesses: o.harnesses ?? drivableHarnesses(o.env ?? process.env),\n modes: [\"waiter\", \"turn\", \"resume\", \"fork\"],\n version: VERSION,\n folders: cfg.folders,\n mode: cfg.mode,\n ...(accounts.length ? { accounts } : {}),\n // This daemon takes `files` on a start (an older one would start without them).\n files: true,\n };\n /** One pairing code from the receiver. `machine` names the row a previous code\n * made, so a renewal adds no second machine. */\n const start = async (machine: string | undefined) => {\n const started = await f(`${control}/pair`, {\n method: \"POST\",\n headers: o.token ? auth : { \"content-type\": \"application/json\" },\n body: JSON.stringify({ ...hello, ...(machine ? { machine } : {}) }),\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 return {\n machine: String(s.machine),\n code: String(s.code),\n url: String(s.url),\n check: String(s.check),\n until: Date.parse(String(s.expires_at)) || Date.now() + 10 * 60_000,\n };\n };\n const host = new URL(o.url).host;\n const announce = (p: { url: string; check: string; until: number }) => {\n const spaced = /^\\d{6}$/.test(p.check) ? `${p.check.slice(0, 3)} ${p.check.slice(3)}` : p.check;\n o.out(\"\");\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 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 ${p.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(` ${p.url}`);\n o.out(` The page shows these digits too: ${p.check}`);\n }\n const mins = Math.max(1, Math.round((p.until - Date.now()) / 60_000));\n o.out(` This code is good for ${mins} minute${mins === 1 ? \"\" : \"s\"}; if it runs out, a fresh one appears here.`);\n o.out(\"\");\n };\n // A code lives ten minutes on the receiver. A person approving three headless\n // machines from a phone ran out of them (2026-10-08). A code nobody approved in time\n // is renewed from this terminal, with fresh digits, for up to RENEW_FOR_MS: the old\n // code is dead on the receiver, so no code lives longer than it did.\n const renewUntil = Date.now() + (o.renewFor ?? RENEW_FOR_MS);\n let cur = await start(existing?.machine);\n announce(cur);\n for (;;) {\n await sleep(2000);\n let p: Record<string, unknown> = {};\n let expired = Date.now() > cur.until;\n if (!expired) {\n const r = await f(`${control}/pair?code=${encodeURIComponent(cur.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 p = await json(r);\n if (p.status === \"expired\") expired = true;\n else if (p.status !== \"paired\") continue;\n }\n if (expired) {\n if (Date.now() >= renewUntil) throw new Error(\"the pairing link expired; run `sessionpipe control pair` again\");\n // A keyed pairing keeps the machine row its first code made; an open one starts\n // clean under the same poll key (the receiver names the machine at approval).\n cur = await start(o.token ? cur.machine : existing?.machine);\n o.out(\" Nobody approved that code before it expired. Here is a fresh one; the old digits no longer work.\");\n announce(cur);\n continue;\n }\n const { machine, code } = cur;\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 const named = accounts.flatMap((a) => (a.email ? [a.email] : []));\n if (named.length)\n o.out(` Its session board names your Claude Code account${named.length > 1 ? \"s\" : \"\"}: ${named.join(\", \")}`);\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// Usage is data: asking for it must never enter a command's implementation. The site's\n// docs page reads the same table, so a command's usage is written in one place.\nexport function usageTable(harnesses: readonly string[]): Record<string, string> {\n return {\n connect:\n \"connect <receiver> [--machine NAME] [--rename-machine] [--allow-downgrade] [--tier 0-3] [--mode safe|auto] [--folder DIR]\u2026 [--no-service]\",\n install: `install [${harnesses.map((h) => `--${h}`).join(\" \")}] [--machine NAME] [--rename-machine] [--allow-downgrade] [--backfill DAYS] [--sink URL --tier N]`,\n sink: \"sink add|list|remove|test (use --help after a subcommand for its options)\",\n \"sink add\": \"sink add <url|file:PATH|stdout> [--tier 0-3] [--token T] [--secret S] [--pii] [--name N]\",\n \"sink list\": \"sink list\",\n \"sink remove\": \"sink remove <name>\",\n \"sink test\": \"sink test <name>\",\n secrets: \"secrets [move keychain|secret-service|file]\",\n \"secrets move\": \"secrets move keychain|secret-service|file\",\n status: \"status [--json]\",\n doctor: \"doctor [--json]\",\n tail: \"tail [--session ID] [--tier 0-3] [--harness NAME] [--all] [--json]\",\n backfill: `backfill [--days 30] [${harnesses.map((h) => `--${h}`).join(\" \")}]`,\n forget: \"forget <harness> <session>\",\n replay: \"replay [--sink NAME] [--from-start]\",\n update: \"update [off|on] (install the latest now; off/on: the daemon's daily update)\",\n \"update off\": \"update off\",\n \"update on\": \"update on\",\n control: \"control pair|mode|status|keys|off|run (use --help after a subcommand for its options)\",\n \"control pair\":\n \"control pair <receiver> [--folder DIR]\u2026 [--mode safe|auto] [--tier 0-3] [--token T] [--name N] [--no-service]\",\n \"control mode\": \"control mode auto|safe\",\n \"control status\": \"control status\",\n \"control keys\": \"control keys [remove <id>]\",\n \"control keys remove\": \"control keys remove <id>\",\n \"control off\": \"control off [<receiver>]\",\n \"control run\": \"control run\",\n wait: \"wait [--session <harness>:<id>]\",\n worker: \"worker <job-file> (internal: process one queued job)\",\n hook: \"hook (internal: harnesses run dist/hook.js directly)\",\n version: \"version (print the installed version)\",\n \"--version\": \"--version (print the installed version)\",\n \"-v\": \"-v (print the installed version)\",\n };\n}\n\nexport function commandHelp(args: string[], harnesses: readonly string[]): string | undefined {\n const usage = usageTable(harnesses);\n for (let n = Math.min(args.length, 3); n > 0; n--) {\n const line = usage[args.slice(0, n).join(\" \")];\n if (line) return `Usage: sessionpipe ${line}\\n\\n -h, --help Show help without running the command.`;\n }\n return undefined;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["execFileSync", "spawnSync", "existsSync", "readdirSync", "readFileSync", "realpathSync", "rmSync", "statSync", "unlinkSync", "os", "path", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "statSync", "unlinkSync", "writeFileSync", "path", "path", "tail", "cap", "out", "out", "path", "settings", "entry", "path", "out", "existsSync", "mkdirSync", "writeFileSync", "unlinkSync", "readFileSync", "rows", "readdirSync", "statSync", "tail", "os", "path", "statSync", "path", "args", "out", "os", "path", "out", "execFileSync", "existsSync", "readdirSync", "readFileSync", "statSync", "path", "args", "out", "NAME", "out", "path", "readdirSync", "existsSync", "validTool", "prune", "readFileSync", "state", "rows", "has", "pid", "execFileSync", "statSync", "tail", "ask", "claudeLogin", "execFileSync", "closeSync", "openSync", "readdirSync", "readFileSync", "readSync", "statSync", "os", "path", "os", "path", "readdirSync", "help", "flag", "out", "args", "claudeLogin", "execFileSync", "statSync", "cap", "openSync", "readSync", "closeSync", "readFileSync", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "writeFileSync", "path", "OURS", "tail", "NAME", "OPTS", "eventsFor", "path", "hooksFile", "configFile", "validTool", "endReason", "readFileSync", "mkdirSync", "writeFileSync", "OURS", "readdirSync", "existsSync", "out", "id", "r", "prune", "rows", "tail", "reading", "execFile", "os", "path", "LABEL", "os", "path", "execFile", "reading", "createHash", "existsSync", "path", "execFileSync", "existsSync", "out", "bad", "NAME", "OPTS", "eventsFor", "bad", "path", "configFile", "validTool", "endReason", "pickSource", "errText", "existsSync", "state", "createHash", "prune", "out", "rows", "execFileSync", "existsSync", "readFileSync", "path", "NAME", "OPTS", "path", "validTool", "eventsFor", "readFileSync", "execFileSync", "existsSync", "state", "prune", "out", "tail", "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", "createHash", "appendFileSync", "mkdirSync", "path", "path", "flag", "spawn", "readFileSync", "path", "spawn", "accessSync", "constants", "existsSync", "realpathSync", "path", "execFileSync", "readFileSync", "realpathSync", "os", "path", "accessSync", "chmodSync", "constants", "mkdirSync", "readFileSync", "renameSync", "writeFileSync", "os", "path", "path", "os", "readFileSync", "chmodSync", "writeFileSync", "renameSync", "mkdirSync", "accessSync", "constants", "appendFileSync", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "renameSync", "statSync", "unlinkSync", "writeFileSync", "os", "path", "chmodSync", "mkdirSync", "readFileSync", "renameSync", "writeFileSync", "path", "out", "os", "path", "state", "createHash", "createHash", "randomBytes", "args", "createHash", "randomBytes", "state", "existsSync", "state", "mkdirSync", "path", "writeFileSync", "unlinkSync", "state", "mkdirSync", "path", "statSync", "renameSync", "appendFileSync", "readFileSync", "writeFileSync", "out", "os", "existsSync", "unlinkSync", "sink", "state", "path", "realpathSync", "distDir", "execFileSync", "path", "os", "installed", "readFileSync", "out", "parse", "distDir", "path", "existsSync", "accessSync", "constants", "realpathSync", "spawn", "appendFileSync", "chmodSync", "closeSync", "existsSync", "mkdirSync", "openSync", "readFileSync", "renameSync", "writeFileSync", "path", "UUID_RE", "out", "has", "path", "mkdirSync", "writeFileSync", "renameSync", "chmodSync", "readFileSync", "cut", "openSync", "appendFileSync", "closeSync", "existsSync", "LABEL", "path", "readFileSync", "off", "ms", "spawn", "existsSync", "realpathSync", "statSync", "os", "path", "chmodSync", "existsSync", "mkdirSync", "readFileSync", "realpathSync", "statSync", "unlinkSync", "net", "path", "createHash", "existsSync", "mkdirSync", "realpathSync", "rmSync", "writeFileSync", "path", "b64url", "out", "closeSync", "openSync", "readSync", "statSync", "sleep", "cut", "claudeEnv", "findTranscript", "isUuid", "liveProcess", "loginHint", "modeFlags", "parseResult", "recentlyWritten", "sessionFolder", "VERSION", "path", "mkdirSync", "unlinkSync", "existsSync", "net", "chmodSync", "t", "sleep", "ok", "readFileSync", "realpathSync", "statSync", "live", "out", "ask", "args", "reading", "tail", "execFileSync", "randomBytes", "existsSync", "mkdirSync", "unlinkSync", "writeFileSync", "os", "path", "VERSION", "sleep", "randomBytes", "path", "LABEL", "UNIT", "os", "args", "execFileSync", "mkdirSync", "writeFileSync", "existsSync", "unlinkSync", "flag", "claudeLogin", "detectCaps", "findClaude", "runClaude", "out", "os", "realpathSync", "path", "statSync", "distDir", "flag", "sink", "c", "log", "existsSync", "args", "path", "realpathSync", "existsSync", "os", "rows", "statSync", "sink", "status", "json", "update", "readdirSync", "spawnSync", "rmSync", "readFileSync", "execFileSync", "w", "unlinkSync"]
|
|
7
7
|
}
|