sessionpipe 0.7.0 → 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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/worker.ts", "../../core/src/adapters/antigravity.ts", "../../core/src/paths.ts", "../../core/src/readers/files.ts", "../../core/src/readers/transcripts.ts", "../../core/src/adapters/claude-shaped.ts", "../../core/src/adapters/claude-code.ts", "../../core/src/readers/git.ts", "../../core/src/adapters/codex.ts", "../../core/src/adapters/codex-config.ts", "../../core/src/adapters/gemini-cli.ts", "../../core/src/adapters/index.ts", "../../core/src/config.ts", "../../core/src/ulid.ts", "../../core/src/events.ts", "../../core/src/outbox.ts", "../../core/src/privacy/pii.ts", "../../core/src/privacy/secrets.ts", "../../core/src/privacy/filter.ts", "../../core/src/sinks/file.ts", "../../core/src/sinks/stdout.ts", "../src/run.ts", "../src/control/aliases.ts", "../src/control/local.ts", "../src/http-sink.ts", "../src/secrets.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n// SPDX-License-Identifier: Apache-2.0\n// The detached worker. `node worker.js <job>`: adapter turns the payload into\n// events; facts are merged; every event is appended to the outbox with its seq;\n// on a turn end the transcript is read from the stored offset for tier-2 sinks;\n// then every sink is flushed from its cursor. Exits within 15 s; a sink that\n// cannot be reached is left for the next worker, which drains the backlog first.\nimport { readFileSync, unlinkSync } from \"node:fs\";\nimport { stateDir } from \"@sessionpipe/core\";\nimport { runJob, sweepJobs } from \"./run.js\";\n\nconst jobFile = process.argv[2];\nif (!jobFile) process.exit(0);\nlet job: Parameters<typeof runJob>[0] | null = null;\ntry {\n job = JSON.parse(readFileSync(jobFile, \"utf8\"));\n} catch {}\ntry {\n unlinkSync(jobFile);\n} catch {}\nif (!job) process.exit(0);\nconst deadline = setTimeout(() => process.exit(0), 15_000);\ndeadline.unref();\nrunJob(job)\n .catch(() => {})\n .then(() => sweepJobs(stateDir()))\n .catch(() => {})\n .finally(() => process.exit(0));\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/** 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 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 (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] ?? \"\") : 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 { codexInjected, 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\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\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 || codexInjected(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// 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 { 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 * as antigravityControl from \"./antigravity-control.js\";\nexport { claudeDirs } from \"./claude-code.js\";\nexport * as claudeControl from \"./claude-code-control.js\";\nexport * as codexControl from \"./codex-control.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, 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// 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 { 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}\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 // 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 // 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 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): 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 ${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, 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, 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; the\n // 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 (job.harness === \"antigravity\" && 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 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, 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 log(state, `${job.harness} ${job.event}: ${events.map((e) => e.type).join(\",\") || \"nothing\"} (${id.slice(0, 8)})`);\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// 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\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"],
5
- "mappings": "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",
6
- "names": ["readFileSync", "unlinkSync", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "statSync", "unlinkSync", "writeFileSync", "path", "path", "cap", "path", "settings", "entry", "path", "path", "existsSync", "mkdirSync", "writeFileSync", "unlinkSync", "readFileSync", "readdirSync", "statSync", "execFileSync", "existsSync", "readdirSync", "readFileSync", "statSync", "path", "NAME", "path", "readdirSync", "existsSync", "validTool", "prune", "readFileSync", "pid", "execFileSync", "statSync", "ask", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "writeFileSync", "path", "OURS", "NAME", "OPTS", "eventsFor", "path", "hooksFile", "configFile", "validTool", "endReason", "readFileSync", "mkdirSync", "writeFileSync", "OURS", "readdirSync", "existsSync", "id", "r", "prune", "execFileSync", "existsSync", "readFileSync", "path", "NAME", "OPTS", "path", "validTool", "eventsFor", "readFileSync", "execFileSync", "existsSync", "prune", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "path", "readFileSync", "mkdirSync", "path", "writeFileSync", "existsSync", "closeSync", "existsSync", "mkdirSync", "openSync", "readdirSync", "readFileSync", "readSync", "statSync", "unlinkSync", "writeFileSync", "path", "path", "readFileSync", "mkdirSync", "writeFileSync", "existsSync", "readdirSync", "statSync", "openSync", "readSync", "closeSync", "unlinkSync", "createHash", "appendFileSync", "mkdirSync", "path", "appendFileSync", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "renameSync", "statSync", "unlinkSync", "writeFileSync", "os", "path", "chmodSync", "mkdirSync", "readFileSync", "renameSync", "writeFileSync", "path", "os", "path", "createHash", "createHash", "randomBytes", "createHash", "job", "existsSync", "job", "mkdirSync", "path", "writeFileSync", "readdirSync", "statSync", "readFileSync", "unlinkSync", "renameSync", "appendFileSync", "os", "path", "readFileSync", "unlinkSync"]
3
+ "sources": ["../src/worker.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/claude-code.ts", "../../core/src/readers/git.ts", "../../core/src/adapters/codex.ts", "../../core/src/adapters/codex-config.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/run.ts", "../src/control/aliases.ts", "../src/control/local.ts", "../src/http-sink.ts", "../src/secrets.ts"],
4
+ "sourcesContent": ["#!/usr/bin/env node\n// SPDX-License-Identifier: Apache-2.0\n// The detached worker. `node worker.js <job>`: the job file is claimed (renamed, so\n// a sweeper racing for it loses); adapter turns the payload into events; facts are\n// merged; every event is appended to the outbox with its seq, and the claim is\n// released; on a turn end the transcript is read from the stored offset for tier-2\n// sinks; then the sinks are drained from their cursors, unless another worker is\n// at it (run.ts drain: this one leaves its events to it). Exits within 15 s: a\n// claim still held then is a job a sweep gives back; a sink that cannot be reached\n// waits as HTTP.md \u00A72 says, for every worker. A job the session's\n// lock held out goes back to the queue, and a fresh worker is started for it (up\n// to MAX_TRIES in a row; then a later worker's sweep picks it up).\nimport { spawn } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\nimport { pathToFileURL } from \"node:url\";\nimport { stateDir } from \"@sessionpipe/core\";\nimport { claimJob, MAX_TRIES, releaseJob, runJob, sweepJobs } from \"./run.js\";\n\n/** One worker run over `argv` as node received it ([node, worker.js, job]). Resolves\n * once the job is done and the sweep is over; the process then exits 0. */\nexport async function workerMain(argv: string[]): Promise<void> {\n const jobFile = argv[2];\n if (!jobFile) return;\n const claimed = claimJob(jobFile);\n if (!claimed) return;\n const deadline = setTimeout(() => process.exit(0), 15_000);\n deadline.unref();\n await runJob(claimed.job, { claimed: claimed.file })\n .then((r) => {\n if (!r.requeued || (claimed.job.tries ?? 0) + 1 >= MAX_TRIES) return;\n const p = spawn(process.execPath, [argv[1] as string, r.requeued], {\n detached: true,\n stdio: \"ignore\",\n windowsHide: true,\n });\n p.unref();\n })\n .catch(() => {})\n .finally(() => releaseJob(claimed.file))\n .then(() => sweepJobs(stateDir()))\n .catch(() => {})\n .finally(() => clearTimeout(deadline));\n}\n\n// Run as `node worker.js <job>`; importing this module runs nothing (real path: see hook.ts).\nif (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href)\n workerMain(process.argv).finally(() => process.exit(0));\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// 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// 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// 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// 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"],
5
+ "mappings": "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",
6
+ "names": ["realpathSync", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "statSync", "unlinkSync", "writeFileSync", "path", "path", "cap", "path", "settings", "entry", "path", "existsSync", "mkdirSync", "writeFileSync", "unlinkSync", "readFileSync", "rows", "readdirSync", "statSync", "execFileSync", "existsSync", "readdirSync", "readFileSync", "statSync", "path", "NAME", "path", "readdirSync", "existsSync", "validTool", "prune", "readFileSync", "rows", "pid", "execFileSync", "statSync", "path", "NAME", "ask", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "writeFileSync", "path", "OURS", "NAME", "OPTS", "eventsFor", "path", "hooksFile", "configFile", "validTool", "endReason", "readFileSync", "mkdirSync", "writeFileSync", "OURS", "readdirSync", "existsSync", "id", "r", "prune", "rows", "createHash", "existsSync", "path", "execFileSync", "existsSync", "NAME", "OPTS", "eventsFor", "path", "configFile", "validTool", "endReason", "pickSource", "errText", "existsSync", "createHash", "prune", "rows", "execFileSync", "existsSync", "readFileSync", "path", "NAME", "OPTS", "path", "validTool", "eventsFor", "readFileSync", "execFileSync", "existsSync", "prune", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "path", "readFileSync", "mkdirSync", "path", "writeFileSync", "existsSync", "closeSync", "existsSync", "mkdirSync", "openSync", "readdirSync", "readFileSync", "readSync", "statSync", "unlinkSync", "writeFileSync", "path", "path", "readFileSync", "mkdirSync", "writeFileSync", "existsSync", "readdirSync", "statSync", "openSync", "readSync", "closeSync", "unlinkSync", "createHash", "createHash", "appendFileSync", "mkdirSync", "path", "appendFileSync", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "renameSync", "statSync", "unlinkSync", "writeFileSync", "os", "path", "chmodSync", "mkdirSync", "readFileSync", "renameSync", "writeFileSync", "path", "os", "path", "createHash", "createHash", "randomBytes", "createHash", "existsSync", "mkdirSync", "path", "writeFileSync", "renameSync", "readFileSync", "unlinkSync", "readdirSync", "statSync", "appendFileSync", "os", "existsSync", "path", "realpathSync"]
7
7
  }