@mu-crew/mu 3.11.3 → 3.12.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 +1 @@
1
- {"version":3,"sources":["../../extension/mu-pi.ts","../../src/ctl/protocol.ts","../../extension/delegate.ts","../../src/state-dir.ts","../../extension/nudge.ts"],"sourcesContent":["/**\n * mu pi extension: serves the per-agent control socket from inside the\n * agent's interactive pi, so mu gets exact send / status / wait without\n * replacing the TUI or scraping the pane.\n *\n * Inert unless `$MU_CTL_SOCK` is set (mu injects it at spawn). Imports\n * nothing from mu except the protocol, and nothing from pi: the pi API is\n * typed structurally below so pi stays a peer, not a dependency.\n */\nimport {\n chmodSync,\n existsSync,\n linkSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n rmSync,\n statSync,\n} from \"node:fs\";\nimport { connect, createServer, type Server, type Socket } from \"node:net\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n CTL_COMMANDS,\n CTL_OPS,\n CTL_PROTOCOL_VERSION,\n type CtlCommandName,\n type CtlReply,\n type CtlState,\n encode,\n LineDecoder,\n UNKNOWN_OP_PREFIX,\n} from \"../src/ctl/protocol.js\";\nimport {\n type DelegateCtx,\n defaultRunner,\n type MuDelegateApi,\n type MuRunner,\n registerDelegate,\n} from \"./delegate.js\";\nimport {\n type MuNudgeApi,\n parallelSettle,\n registerCloseNudge,\n registerNudge,\n registerRefuteNudge,\n} from \"./nudge.js\";\n\n/** The mu package version, baked in by tsup's `define`; absent when run from source. */\ndeclare const __MU_VERSION__: string | undefined;\nconst EXT_VERSION = typeof __MU_VERSION__ === \"string\" ? __MU_VERSION__ : undefined;\n\n/** The slice of pi's ExtensionContext this extension uses. */\nexport interface MuPiContext extends DelegateCtx {\n /** pi's session manager; only the session file is read. */\n sessionManager?: { getSessionFile(): string | undefined };\n isIdle(): boolean;\n hasPendingMessages(): boolean;\n abort(): void;\n}\n\n/** The slice of pi's ReplacedSessionContext: bound to the NEW session. */\nexport interface MuPiReplacedContext extends MuPiContext {\n sendUserMessage(text: string): Promise<void>;\n}\n\n/** The slice of pi's ExtensionCommandContext (command handlers only). */\nexport interface MuPiCommandContext extends MuPiContext {\n newSession(options?: {\n withSession?: (ctx: MuPiReplacedContext) => Promise<void>;\n }): Promise<{ cancelled: boolean }>;\n reload(): Promise<void>;\n compact(options?: {\n customInstructions?: string;\n onComplete?: (result: unknown) => void;\n onError?: (error: Error) => void;\n }): void;\n}\n\n/** The slice of pi's ExtensionAPI this extension uses. */\nexport interface MuPiApi extends MuDelegateApi {\n on(\n event:\n | \"session_start\"\n | \"session_shutdown\"\n | \"session_before_compact\"\n | \"agent_start\"\n | \"agent_end\"\n | \"agent_settled\"\n | \"message_start\"\n | \"resources_discover\"\n | Parameters<MuNudgeApi[\"on\"]>[0],\n handler: (event: unknown, ctx: MuPiContext) => unknown,\n ): unknown;\n sendUserMessage(\n text: string,\n options?: { deliverAs?: \"steer\" | \"followUp\"; expandPromptTemplates?: boolean },\n ): void | Promise<void>;\n registerCommand(\n name: string,\n options: {\n description: string;\n handler: (args: string, ctx: MuPiCommandContext) => Promise<void>;\n },\n ): void;\n}\n\n/** Internal command behind the `fresh` op: new session + prompt, inside pi. */\nexport const FRESH_COMMAND = \"mu-fresh\";\n/** The extension's own bound on a fresh op that never reaches agent_start. */\nexport const FRESH_TIMEOUT_MS = 30_000;\n/** Internal command behind the `command` op, per session command: `mu-new`, ... */\nexport function commandName(name: CtlCommandName): string {\n return `mu-${name}`;\n}\n/** The extension's own bound on a `command` op that never completes. */\nexport const COMMAND_TIMEOUT_MS = 30_000;\n/** Cap on `lastText` in a wait reply, in UTF-8 bytes (before the marker). */\nexport const LAST_TEXT_MAX_BYTES = 64 * 1024;\nexport const LAST_TEXT_TRUNCATED = \"[truncated, see pane]\";\n/** How long session_start waits for another pi to answer on the socket path. */\nexport const LIVE_PROBE_MS = 500;\n\ntype Reply = CtlReply;\nconst V = CTL_PROTOCOL_VERSION;\n\nfunction fail(error: string): Reply {\n return { v: V, ok: false, error };\n}\n\n/** Best effort: the version of the pi package running this process. */\nfunction detectPiVersion(): string | undefined {\n try {\n const entry = process.argv[1];\n if (!entry) return undefined;\n let dir = dirname(realpathSync(entry));\n for (let i = 0; i < 6; i++) {\n const pkgPath = join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg: unknown = JSON.parse(readFileSync(pkgPath, \"utf8\"));\n if (typeof pkg === \"object\" && pkg !== null) {\n const { name, version } = pkg as { name?: unknown; version?: unknown };\n if (typeof name === \"string\" && /pi/.test(name) && typeof version === \"string\") {\n return version;\n }\n }\n }\n const up = dirname(dir);\n if (up === dir) break;\n dir = up;\n }\n } catch {\n // Unknown version is reported as absent, never as an error.\n }\n return undefined;\n}\n\nfunction str(o: Record<string, unknown>, k: string): string | undefined {\n const x = o[k];\n return typeof x === \"string\" ? x : undefined;\n}\n\nfunction num(o: Record<string, unknown>, k: string): number | undefined {\n const x = o[k];\n return typeof x === \"number\" && Number.isFinite(x) ? x : undefined;\n}\n\n/** A `fresh` op in flight: its prompt and the reply it is waiting to send. */\ntype PendingFresh = {\n text: string;\n /** Set once the new session exists, so its agent_start is the prompt's. */\n armed: boolean;\n settle: (r: Reply) => void;\n};\n\n/** A `command` op in flight: the session command and its pending reply. */\ntype PendingCommand = {\n name: CtlCommandName;\n instructions?: string;\n /** reload: set by the session_start (reason reload) the reload produced. */\n reloaded: boolean;\n settle: (r: Reply) => void;\n};\n\n/**\n * Process-global state, keyed by socket path. pi re-runs this factory\n * for every session (a /new or /mu-fresh replaces the extension runtime),\n * so the socket server, the run counters and an in-flight fresh must\n * outlive any one runtime. Each runtime refreshes `pi` and `handle`.\n */\ntype Shared = {\n server?: Server;\n /** Set by bind(): another pi serves the socket, so this pi is not the agent. */\n nested?: boolean;\n /** Inode of the socket file this process bound; the only file it may unlink. */\n ino?: number;\n conns: Set<Socket>;\n waiters: Set<() => void>;\n state: CtlState;\n since: number;\n runs: number;\n /** Final assistant text of the last settled run; served by `wait`. */\n lastText: string;\n /** Captured on agent_end, published to `lastText` on agent_settled. */\n endText?: string;\n /** Error that ended the last settled run, if any; served by `wait`. */\n lastError?: string;\n endError?: string;\n /** Session file of the last settled run; served by `wait`. */\n sessionFile?: string;\n ctx?: MuPiContext;\n pi: MuPiApi;\n handle: (req: Record<string, unknown>, conn: Socket) => Promise<Reply>;\n fresh?: PendingFresh;\n command?: PendingCommand;\n};\n\nconst SHARED = Symbol.for(\"mu.pi.ctl\");\ntype SharedMap = Map<string, Shared>;\n\nfunction sharedMap(): SharedMap {\n const g = globalThis as { [SHARED]?: SharedMap };\n g[SHARED] ??= new Map();\n return g[SHARED];\n}\n\n/**\n * Text of the last assistant message in an agent_end event's `messages`:\n * its text parts joined, no tool calls or thinking. \"\" when there is none.\n */\nexport function lastAssistantText(event: unknown): string {\n const msgs =\n typeof event === \"object\" && event !== null\n ? (event as { messages?: unknown }).messages\n : undefined;\n if (!Array.isArray(msgs)) return \"\";\n for (let i = msgs.length - 1; i >= 0; i--) {\n const m: unknown = msgs[i];\n if (typeof m !== \"object\" || m === null) continue;\n const { role, content } = m as { role?: unknown; content?: unknown };\n if (role !== \"assistant\") continue;\n if (typeof content === \"string\") return capText(content);\n if (!Array.isArray(content)) return \"\";\n const parts = content.flatMap((c: unknown) => {\n if (typeof c !== \"object\" || c === null) return [];\n const { type, text } = c as { type?: unknown; text?: unknown };\n return type === \"text\" && typeof text === \"string\" ? [text] : [];\n });\n return capText(parts.join(\"\"));\n }\n return \"\";\n}\n\n/** The final assistant message's error, when the run stopped on one\n * (pi's own retries exhausted: overloaded, connection, auth). */\nexport function lastAssistantError(event: unknown): string | undefined {\n const msgs =\n typeof event === \"object\" && event !== null\n ? (event as { messages?: unknown }).messages\n : undefined;\n if (!Array.isArray(msgs)) return undefined;\n for (let i = msgs.length - 1; i >= 0; i--) {\n const m: unknown = msgs[i];\n if (typeof m !== \"object\" || m === null) continue;\n const { role, stopReason, errorMessage } = m as {\n role?: unknown;\n stopReason?: unknown;\n errorMessage?: unknown;\n };\n if (role !== \"assistant\") continue;\n if (stopReason !== \"error\") return undefined;\n return typeof errorMessage === \"string\" && errorMessage !== \"\"\n ? capText(errorMessage)\n : \"unknown error\";\n }\n return undefined;\n}\n\nfunction capText(text: string): string {\n if (Buffer.byteLength(text, \"utf8\") <= LAST_TEXT_MAX_BYTES) return text;\n // Cut on bytes; drop a code point split by the cut.\n const cut = Buffer.from(text, \"utf8\").subarray(0, LAST_TEXT_MAX_BYTES).toString(\"utf8\");\n return `${cut.replace(/\\uFFFD$/, \"\")}\\n${LAST_TEXT_TRUNCATED}`;\n}\n\n/** Inode at `path`, or undefined when there is no file. */\nfunction inodeOf(path: string): number | undefined {\n try {\n return statSync(path).ino;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Whether some process is serving `path`. Refused / missing means a stale\n * file. A connect that neither succeeds nor fails in time counts as live:\n * never steal a socket on a guess.\n */\nfunction socketIsLive(path: string): Promise<boolean> {\n return new Promise((resolve) => {\n const c = connect(path);\n const done = (live: boolean) => {\n clearTimeout(timer);\n c.destroy();\n resolve(live);\n };\n const timer = setTimeout(() => done(true), LIVE_PROBE_MS);\n c.once(\"connect\", () => done(true));\n c.once(\"error\", (e: NodeJS.ErrnoException) =>\n done(e.code !== \"ENOENT\" && e.code !== \"ECONNREFUSED\"),\n );\n });\n}\n\n/** Per-process counter so a rebind never reuses a temp name a closing server owns. */\nlet bindSeq = 0;\n\nfunction reasonOf(event: unknown): string | undefined {\n const r =\n typeof event === \"object\" && event !== null\n ? (event as { reason?: unknown }).reason\n : undefined;\n return typeof r === \"string\" ? r : undefined;\n}\n\n/** The package's `prompts/` dir: two up from dist/extension/, one up from extension/. */\nexport function promptsDir(from: string = import.meta.url): string | undefined {\n let here: string;\n try {\n here = dirname(fileURLToPath(from));\n } catch {\n return undefined;\n }\n for (const up of [\"..\", \"../..\"]) {\n const d = join(here, up, \"prompts\");\n if (existsSync(join(d, \"ultrathink.md\"))) return d;\n }\n return undefined;\n}\n\n/** The recipe slash commands (`/ultrathink`, `/mu-review`, ...): prompt\n * templates shipped in the package, so they upgrade with mu. */\nfunction registerPrompts(pi: MuPiApi): void {\n pi.on(\"resources_discover\", () => {\n const d = promptsDir();\n if (!d) return {};\n const paths = readdirSync(d)\n .filter((f) => f.endsWith(\".md\"))\n .sort()\n .map((f) => join(d, f));\n return { promptPaths: paths };\n });\n}\n\nexport default function muPi(pi: MuPiApi, run: MuRunner = defaultRunner()): void {\n registerDelegate(pi, run);\n registerPrompts(pi);\n // Identity follows the bind: a pi that finds MU_CTL_SOCK served by\n // another pi is nested and gets none of the agent's nudges.\n const nested = serveCtl(pi);\n // The three nudges' settle checks run in parallel, as one handler.\n const settle = parallelSettle(pi);\n registerNudge(settle.api, run, undefined, nested);\n registerCloseNudge(settle.api, run, process.env, nested);\n registerRefuteNudge(settle.api, run, nested);\n settle.flush();\n}\n\n/**\n * Child side: serve `$MU_CTL_SOCK` for the mu that spawned this pi.\n * Returns whether this pi is nested (another pi serves the socket), read\n * from the process-global state so a reloaded runtime sees the decision.\n */\nfunction serveCtl(pi: MuPiApi): () => boolean {\n const sock = process.env.MU_CTL_SOCK;\n if (!sock) return () => false;\n const sockPath: string = sock;\n const piVersion = detectPiVersion();\n\n const map = sharedMap();\n const existing = map.get(sockPath);\n const g: Shared = existing ?? {\n conns: new Set(),\n waiters: new Set(),\n state: \"idle\",\n since: Date.now(),\n runs: 0,\n lastText: \"\",\n pi,\n handle,\n };\n g.pi = pi;\n g.handle = handle;\n map.set(sockPath, g);\n\n const status = () => ({\n state: g.state,\n since: g.since,\n runs: g.runs,\n pending: g.ctx?.hasPendingMessages() ?? false,\n });\n\n const settleFresh = (r: Reply) => {\n const f = g.fresh;\n if (!f) return;\n g.fresh = undefined;\n f.settle(r);\n };\n\n const settleCommand = (r: Reply) => {\n const c = g.command;\n if (!c) return;\n g.command = undefined;\n c.settle(r);\n };\n\n pi.on(\"agent_start\", (_e, c) => {\n g.ctx = c;\n g.state = \"busy\";\n g.since = Date.now();\n // The new session's run started: the fresh prompt landed.\n if (g.fresh?.armed) settleFresh({ v: V, ok: true, ...status() });\n });\n\n // A settled run can span several low-level runs (retry, follow-up):\n // the last agent_end before the settle holds the final answer.\n pi.on(\"agent_end\", (e) => {\n g.endText = lastAssistantText(e);\n g.endError = lastAssistantError(e);\n });\n\n pi.on(\"agent_settled\", (_e, c) => {\n g.ctx = c;\n g.state = \"idle\";\n g.since = Date.now();\n g.runs++;\n g.lastText = g.endText ?? \"\";\n g.endText = undefined;\n g.lastError = g.endError;\n g.endError = undefined;\n try {\n g.sessionFile = c.sessionManager?.getSessionFile();\n } catch {\n g.sessionFile = undefined; // stale ctx: the pointer is a convenience\n }\n for (const w of [...g.waiters]) w();\n });\n\n pi.registerCommand(FRESH_COMMAND, {\n description: \"mu internal: new session + the prompt mu queued (run by mu agent send --fresh)\",\n handler: async (_args, ctx) => {\n const f = g.fresh;\n if (!f) return; // typed by hand: nothing queued\n try {\n const r = await ctx.newSession({\n withSession: async (c) => {\n g.ctx = c;\n f.armed = true;\n await c.sendUserMessage(f.text);\n },\n });\n if (r.cancelled) settleFresh(fail(\"new session was cancelled\"));\n } catch (e) {\n settleFresh(fail(e instanceof Error ? e.message : String(e)));\n }\n // The run finished without an agent_start we saw: still landed.\n settleFresh({ v: V, ok: true, ...status() });\n },\n });\n\n // A compaction we asked for has started: reply now, not after the\n // summary call. Errors before this point (e.g. \"Nothing to compact\")\n // reach the reply through compact's onError.\n pi.on(\"session_before_compact\", () => {\n if (g.command?.name === \"compact\") settleCommand({ v: V, ok: true, ...status() });\n });\n\n /** Run the queued session command `name` with pi's command context. */\n async function runCommand(name: CtlCommandName, ctx: MuPiCommandContext): Promise<void> {\n const c = g.command;\n if (c?.name !== name) return; // typed by hand: nothing queued\n const ok = () => settleCommand({ v: V, ok: true, ...status() });\n const failWith = (e: unknown) =>\n settleCommand(fail(e instanceof Error ? e.message : String(e)));\n try {\n if (name === \"new\") {\n const r = await ctx.newSession();\n if (r.cancelled) settleCommand(fail(\"new session was cancelled\"));\n else ok();\n } else if (name === \"reload\") {\n await ctx.reload();\n // pi's reload returns quietly when it refuses (streaming, compacting).\n if (c.reloaded) ok();\n else settleCommand(fail(\"pi did not reload (busy or compacting)\"));\n } else {\n ctx.compact({\n ...(c.instructions !== undefined ? { customInstructions: c.instructions } : {}),\n onComplete: ok,\n onError: failWith,\n });\n }\n } catch (e) {\n failWith(e);\n }\n }\n\n for (const name of CTL_COMMANDS) {\n pi.registerCommand(commandName(name), {\n description: `mu internal: /${name} requested over the control socket (mu agent send '/${name}')`,\n handler: (_args, ctx) => runCommand(name, ctx),\n });\n }\n\n function command(req: Record<string, unknown>): Promise<Reply> | Reply {\n const name = CTL_COMMANDS.find((n) => n === req.name);\n if (name === undefined) {\n return fail(`command must be one of ${CTL_COMMANDS.join(\", \")}`);\n }\n if (g.fresh || g.command) return fail(\"a fresh send or command is already in progress\");\n const busy = !(g.ctx?.isIdle() ?? g.state === \"idle\");\n if (busy && req.force !== true) return fail(\"busy\");\n const instructions = str(req, \"instructions\");\n return new Promise<Reply>((resolve) => {\n const timer = setTimeout(() => settleCommand(fail(`/${name} timed out`)), COMMAND_TIMEOUT_MS);\n g.command = {\n name,\n ...(instructions !== undefined ? { instructions } : {}),\n reloaded: false,\n settle: (r) => {\n clearTimeout(timer);\n resolve(r);\n },\n };\n Promise.resolve(\n g.pi.sendUserMessage(`/${commandName(name)}`, { expandPromptTemplates: true }),\n ).catch((e: unknown) => settleCommand(fail(e instanceof Error ? e.message : String(e))));\n });\n }\n\n function fresh(req: Record<string, unknown>): Promise<Reply> | Reply {\n const text = str(req, \"text\");\n if (text === undefined) return fail(\"fresh needs a string text\");\n if (g.fresh || g.command) return fail(\"a fresh send or command is already in progress\");\n const busy = !(g.ctx?.isIdle() ?? g.state === \"idle\");\n if (busy && req.force !== true) return fail(\"busy\");\n return new Promise<Reply>((resolve) => {\n const timer = setTimeout(() => settleFresh(fail(\"fresh timed out\")), FRESH_TIMEOUT_MS);\n g.fresh = {\n text,\n armed: false,\n settle: (r) => {\n clearTimeout(timer);\n resolve(r);\n },\n };\n // expandPromptTemplates dispatches extension commands, even mid-run.\n Promise.resolve(\n g.pi.sendUserMessage(`/${FRESH_COMMAND}`, { expandPromptTemplates: true }),\n ).catch((e: unknown) => settleFresh(fail(e instanceof Error ? e.message : String(e))));\n });\n }\n\n async function handle(req: Record<string, unknown>, conn: Socket): Promise<Reply> {\n switch (req.op) {\n case \"hello\":\n return {\n v: V,\n ok: true,\n agent: process.env.MU_AGENT_NAME,\n workstream: process.env.MU_WORKSTREAM,\n piVersion,\n ops: [...CTL_OPS],\n ...(EXT_VERSION !== undefined ? { extVersion: EXT_VERSION } : {}),\n };\n case \"status\":\n return { v: V, ok: true, ...status() };\n case \"send\": {\n const text = str(req, \"text\");\n if (text === undefined) return fail(\"send needs a string text\");\n const mode = req.mode === \"steer\" ? \"steer\" : \"followUp\";\n // Measured before dispatch: `runs` is the caller's wait baseline,\n // and a run this send starts may settle before the reply is read.\n const before = status();\n // A message sent while idle starts a run; options are only for a busy pi.\n if (g.ctx?.isIdle() ?? g.state === \"idle\") await g.pi.sendUserMessage(text);\n else await g.pi.sendUserMessage(text, { deliverAs: mode });\n return { v: V, ok: true, ...before };\n }\n case \"fresh\":\n return fresh(req);\n case \"command\":\n return command(req);\n case \"wait\":\n return wait(num(req, \"afterRuns\"), num(req, \"timeoutMs\"), conn);\n case \"abort\":\n if (!g.ctx) return fail(\"no pi context yet\");\n g.ctx.abort();\n return { v: V, ok: true, state: g.state };\n case \"interrupt\":\n return interrupt(req, conn);\n default:\n return { ...fail(`${UNKNOWN_OP_PREFIX}${String(req.op)}`), ops: [...CTL_OPS] };\n }\n }\n\n /**\n * Abort a busy turn, wait for its settle, then send `text` as a new run.\n * The waiter is registered before the abort, so a settle that lands at\n * once is not missed. `runs` is read after that settle and before the\n * send: the caller's wait baseline for the new run, not the aborted one.\n */\n async function interrupt(req: Record<string, unknown>, conn: Socket): Promise<Reply> {\n const text = str(req, \"text\");\n if (text === undefined) return fail(\"interrupt needs a string text\");\n const wasBusy = !(g.ctx?.isIdle() ?? g.state === \"idle\");\n const { pending } = status();\n if (wasBusy) {\n if (!g.ctx) return fail(\"no pi context yet\");\n const settled = wait(g.runs, num(req, \"timeoutMs\"), conn);\n g.ctx.abort();\n const w = await settled;\n if (!w.ok) return w;\n }\n const before = status();\n await g.pi.sendUserMessage(text);\n return { v: V, ok: true, ...before, pending, wasBusy };\n }\n\n const settledRun = () => ({\n lastText: g.lastText,\n ...(g.lastError !== undefined ? { lastError: g.lastError } : {}),\n ...(g.sessionFile !== undefined ? { sessionFile: g.sessionFile } : {}),\n });\n\n /** Resolve once a run past `afterRuns` has settled (any next settle when omitted). */\n function wait(afterRuns: number | undefined, timeoutMs: number | undefined, conn: Socket) {\n if (afterRuns !== undefined && g.runs > afterRuns && g.state === \"idle\") {\n return Promise.resolve<Reply>({ v: V, ok: true, ...status(), ...settledRun() });\n }\n return new Promise<Reply>((resolve) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const done = (r: Reply) => {\n g.waiters.delete(waiter);\n if (timer) clearTimeout(timer);\n conn.off(\"close\", onClose);\n resolve(r);\n };\n // A settle at or below `afterRuns` is not the run asked for: keep waiting.\n const waiter = () => {\n if (afterRuns !== undefined && g.runs <= afterRuns) return;\n done({ v: V, ok: true, ...status(), ...settledRun() });\n };\n const onClose = () => done(fail(\"client closed\"));\n g.waiters.add(waiter);\n conn.on(\"close\", onClose);\n if (timeoutMs !== undefined) timer = setTimeout(() => done(fail(\"timeout\")), timeoutMs);\n });\n }\n\n /** Created once per process; dispatches to the newest runtime's handle. */\n function onConnection(conn: Socket): void {\n g.conns.add(conn);\n conn.setEncoding(\"utf8\");\n const dec = new LineDecoder();\n let seen = false;\n conn.on(\"close\", () => g.conns.delete(conn));\n conn.on(\"error\", () => {});\n conn.on(\"data\", (chunk: string) => {\n const line = dec.push(chunk)[0];\n if (line === undefined || seen) return;\n seen = true; // one request per connection\n let req: unknown;\n try {\n req = JSON.parse(line);\n } catch {\n conn.end(encode(fail(\"bad json\")));\n return;\n }\n if (typeof req !== \"object\" || req === null) {\n conn.end(encode(fail(\"request must be an object\")));\n return;\n }\n g.handle(req as Record<string, unknown>, conn).then(\n (r) => {\n if (!conn.destroyed) conn.end(encode(r));\n },\n (e: unknown) => {\n if (!conn.destroyed) conn.end(encode(fail(e instanceof Error ? e.message : String(e))));\n },\n );\n });\n }\n\n /**\n * Bind the socket unless another pi already serves it. A nested pi (a\n * probe or `pi -p` run inside an agent's pane) inherits MU_CTL_SOCK; it\n * must leave the agent's socket alone, not unlink and take it.\n */\n async function bind(): Promise<void> {\n mkdirSync(dirname(sockPath), { recursive: true, mode: 0o700 });\n if (await socketIsLive(sockPath)) {\n g.nested = true;\n process.stderr.write(\n `mu: control socket ${sockPath} is served by another pi; nested pi: mu agent features off\\n`,\n );\n return;\n }\n rmSync(sockPath, { force: true });\n // Listen on a private name, then hard-link it into place. libuv unlinks\n // the name a server listened on when it closes, so the public path must\n // never be that name: closing would delete whatever file sits there by\n // then. link() also fails on an existing path, so a racing pi keeps it.\n const tmp = join(dirname(sockPath), `.${process.pid.toString(36)}${(++bindSeq).toString(36)}`);\n rmSync(tmp, { force: true });\n const s = createServer(onConnection);\n await new Promise<void>((resolve, reject) => {\n s.once(\"error\", reject);\n s.listen(tmp, () => {\n s.off(\"error\", reject);\n resolve();\n });\n });\n chmodSync(tmp, 0o600);\n try {\n linkSync(tmp, sockPath);\n } catch (e) {\n s.close();\n if ((e as NodeJS.ErrnoException).code !== \"EEXIST\") throw e;\n g.nested = true;\n process.stderr.write(\n `mu: control socket ${sockPath} was taken by another pi; nested pi: mu agent features off\\n`,\n );\n return;\n } finally {\n rmSync(tmp, { force: true });\n }\n g.server = s;\n g.ino = inodeOf(sockPath);\n g.nested = false;\n }\n\n pi.on(\"session_start\", async (e, c) => {\n g.ctx = c;\n if (reasonOf(e) === \"reload\" && g.command?.name === \"reload\") g.command.reloaded = true;\n const s = g.server;\n if (s) {\n // A new/resumed session keeps the same socket, while the path is ours.\n if (g.ino !== undefined && inodeOf(sockPath) === g.ino) return;\n // Orphaned: the file was deleted or replaced under a live server.\n // Stop accepting on the dead inode (open connections finish) and rebind.\n g.server = undefined;\n g.ino = undefined;\n s.close();\n }\n await bind();\n });\n\n pi.on(\"session_shutdown\", async (e) => {\n // Session replacement (new / resume / fork / reload) keeps the socket\n // and its connections: an in-flight fresh is answered by the next\n // runtime. Only quit (or an unknown reason) tears the server down.\n const reason = reasonOf(e);\n if (reason === \"new\" || reason === \"resume\" || reason === \"fork\" || reason === \"reload\") {\n return;\n }\n const s = g.server;\n const ino = g.ino;\n g.server = undefined;\n g.ino = undefined;\n map.delete(sockPath);\n if (!s) return;\n g.waiters.clear();\n settleFresh(fail(\"pi is shutting down\"));\n settleCommand(fail(\"pi is shutting down\"));\n for (const c of g.conns) c.destroy();\n await new Promise<void>((resolve) => s.close(() => resolve()));\n // Unlink only the file this process bound: another pi may own the path now.\n if (ino !== undefined && inodeOf(sockPath) === ino) rmSync(sockPath, { force: true });\n });\n\n return () => g.nested === true;\n}\n","/**\n * mu control socket protocol: JSON lines over a unix socket, one request\n * per connection. Shared by mu's client and the mu pi extension, so this\n * file imports nothing from mu — the extension loads it standalone.\n */\n\nexport const CTL_PROTOCOL_VERSION = 1;\n\nexport type CtlState = \"busy\" | \"idle\";\n\nexport type CtlRequest =\n | { op: \"hello\" }\n | { op: \"status\" }\n | { op: \"send\"; text: string; mode?: \"steer\" | \"followUp\" }\n | { op: \"wait\"; afterRuns?: number; timeoutMs?: number }\n | { op: \"abort\" }\n /**\n * Make a busy pi act on `text` now: abort the running turn, wait for\n * agent_settled (up to timeoutMs), then send `text` as a new run. Idle:\n * just send. Replies `timeout` and sends nothing when pi does not settle.\n */\n | { op: \"interrupt\"; text: string; timeoutMs?: number }\n /** New session + prompt as one operation. Refused with error \"busy\" unless force. */\n | { op: \"fresh\"; text: string; force?: boolean }\n /**\n * Run one of pi's session commands inside pi (sendUserMessage cannot run\n * built-in slash commands). Refused with error \"busy\" unless force.\n */\n | { op: \"command\"; name: CtlCommandName; instructions?: string; force?: boolean };\n\n/** Session commands the `command` op runs: `/new`, `/reload`, `/compact`. */\nexport const CTL_COMMANDS = [\"new\", \"reload\", \"compact\"] as const;\nexport type CtlCommandName = (typeof CTL_COMMANDS)[number];\n\n/**\n * Every op this protocol defines. The extension reports the ops it serves\n * in its `hello` reply (and in an unknown-op error), so mu can tell an\n * extension loaded by an older pi process from a broken one.\n */\nexport const CTL_OPS = [\n \"hello\",\n \"status\",\n \"send\",\n \"wait\",\n \"abort\",\n \"interrupt\",\n \"fresh\",\n \"command\",\n] as const satisfies readonly CtlRequest[\"op\"][];\n\nexport type CtlStatus = { state: CtlState; since: number; runs: number; pending: boolean };\n\nexport type CtlReply =\n | ({ v: 1; ok: true } & Partial<CtlStatus> & {\n agent?: string;\n workstream?: string;\n piVersion?: string;\n /** hello only: the ops this extension serves. Absent: predates reporting. */\n ops?: string[];\n /** hello only: the mu package version the extension was built from. */\n extVersion?: string;\n /** wait only: text of the settled run's final assistant message (\"\" when none). */\n lastText?: string;\n /** wait only: the error that ended the settled run (retries exhausted). */\n lastError?: string;\n /** wait only: the settled pi's session file, where its full transcript lives. */\n sessionFile?: string;\n /** interrupt only: pi was busy, so the turn was aborted before the send. */\n wasBusy?: boolean;\n })\n | { v: 1; ok: false; error: string; ops?: string[] };\n\n/** Error text of a reply to an op the extension does not serve. */\nexport const UNKNOWN_OP_PREFIX = \"unknown op: \";\n\n/** One frame. JSON.stringify escapes \"\\n\" inside strings, so the frame is one line. */\nexport function encode(msg: object): string {\n return `${JSON.stringify(msg)}\\n`;\n}\n\n/** Splits a stream into lines on \"\\n\" only (never U+2028/U+2029). */\nexport class LineDecoder {\n private buf = \"\";\n\n push(chunk: string): string[] {\n this.buf += chunk;\n const parts = this.buf.split(\"\\n\");\n this.buf = parts.pop() ?? \"\";\n return parts;\n }\n}\n","/**\n * mu pi extension, parent side: the `mu_delegate` tool.\n *\n * A delegate is a scratch agent started for one task. The tool spawns it,\n * hands it the task, returns at once, and posts the answer back into this\n * conversation as a follow-up when the delegate's run settles.\n *\n * Everything is the `mu` CLI (spawn / send / wait --json / read / abort /\n * close): the tool only orders the calls and formats the result, so a\n * shell gets the same delegation (VISION § 1, rule 2). The one\n * thing only an extension can do is the callback into the parent\n * conversation, and that is presentation. No extension-only state: the\n * in-flight set below is the list of `mu agent wait` children this pi owns.\n *\n * Separate from the child side (the control-socket server in mu-pi.ts):\n * that one serves a pi mu spawned; this one runs in a pi that is not.\n */\nimport { execFile } from \"node:child_process\";\nimport { existsSync, mkdirSync, statSync, writeFileSync } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { defaultCacheDir } from \"../src/state-dir.js\";\n\n/** The slice of pi's ExtensionAPI the delegate side uses. */\nexport interface MuDelegateApi {\n registerTool(tool: DelegateTool): void;\n sendMessage(\n message: { customType: string; content: string; display: boolean; details?: unknown },\n options?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },\n ): void | Promise<void>;\n on(\n event: \"session_shutdown\" | \"message_start\" | \"agent_settled\",\n handler: (event: unknown, ctx: DelegateCtx) => unknown,\n ): unknown;\n /** pi's in-process bus between extensions. */\n events: { emit(channel: string, data: unknown): void };\n}\n\n/** The slice of pi's ExtensionContext the delegate side uses. */\nexport interface DelegateCtx {\n hasUI?: boolean;\n cwd?: string;\n ui?: {\n notify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n setStatus?(key: string, text: string | undefined): void;\n };\n}\n\ntype ToolResult = { content: { type: \"text\"; text: string }[]; details: unknown };\n\nexport interface DelegateTool {\n name: string;\n label: string;\n description: string;\n promptSnippet?: string;\n parameters: object;\n execute(\n id: string,\n params: Record<string, unknown>,\n signal?: AbortSignal,\n onUpdate?: unknown,\n ctx?: DelegateCtx,\n ): Promise<ToolResult>;\n}\n\nexport type MuResult = { code: number; stdout: string; stderr: string };\n/** Runs `mu <args>`. The test seam: tests inject a fake. */\nexport type MuRunner = (args: readonly string[], signal?: AbortSignal) => Promise<MuResult>;\n\nexport const DELEGATE_TOOL = \"mu_delegate\";\nexport const DELEGATE_CANCEL_TOOL = \"mu_delegate_cancel\";\nexport const DELEGATE_MESSAGE_TYPE = \"mu-delegate\";\nexport const DELEGATE_WORKSTREAM = \"scratch\";\n/** The footer status key (`ctx.ui.setStatus`), like goal / watchloop. */\nexport const DELEGATE_STATUS_KEY = \"mu-delegate\";\n/**\n * murmur's channel for outstanding background work, as\n * `{ source, count }`. murmur shows the count on this agent's card,\n * renders a stopped agent with work out as `waiting`, and holds back\n * `done` until it is zero: a parent that ended its turn to wait on\n * delegates has not finished. A string, not an import: neither side\n * depends on the other, and with no murmur loaded nobody listens.\n */\nexport const PENDING_CHANNEL = \"murmur:pending\";\n\n/** Footer text: delegates running (pane up), starting (no pane yet),\n * queued, failed, and finished whose answer has not reached this\n * conversation yet (pending); undefined clears the entry. */\nexport function delegateStatus(\n running: number,\n starting = 0,\n queued = 0,\n failed = 0,\n pending = 0,\n): string | undefined {\n const parts: string[] = [];\n if (running > 0) parts.push(`${running} delegate${running === 1 ? \"\" : \"s\"} running`);\n if (starting > 0) parts.push(`${starting} starting`);\n if (queued > 0) parts.push(`${queued} queued`);\n if (failed > 0) parts.push(`${failed} failed`);\n if (pending > 0) parts.push(`${pending} result${pending === 1 ? \"\" : \"s\"} pending`);\n return parts.length > 0 ? parts.join(\", \") : undefined;\n}\n/** Default `mu agent wait --timeout` for a delegate, in seconds. */\nexport const DELEGATE_TIMEOUT_S = 3600;\n/** Default cap on delegates in flight from one pi session. */\nexport const DELEGATE_MAX_DEFAULT = 16;\n/** The queue holds this many caps' worth of calls waiting for a slot. A\n * fan-out (refuters per finding, checkers per claim) issues several\n * caps' worth in one turn; past this, the model is refused. */\nexport const DELEGATE_QUEUE_FACTOR = 4;\n\n/** `MU_DELEGATE_MAX`: a positive integer, else the default. */\nexport function delegateMax(env: NodeJS.ProcessEnv = process.env): number {\n const n = Number(env.MU_DELEGATE_MAX);\n return Number.isInteger(n) && n > 0 ? n : DELEGATE_MAX_DEFAULT;\n}\nconst W = DELEGATE_WORKSTREAM;\n\n/** Registration guards: unmanaged pi, a mux in reach, not switched off. */\nexport function delegateEnabled(env: NodeJS.ProcessEnv = process.env): boolean {\n if (env.MU_MANAGED_AGENT) return false; // no helper-spawns-helper\n if (env.MU_DELEGATE === \"0\") return false;\n if (env.MU_MUX || env.HERDR_ENV === \"1\" || env.TMUX || env.TMUX_PANE) return true;\n return onPath(\"tmux\", env) || onPath(\"herdr\", env);\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction onPath(bin: string, env: NodeJS.ProcessEnv): boolean {\n return (env.PATH ?? \"\").split(delimiter).some((d) => d !== \"\" && existsSync(join(d, bin)));\n}\n\n/** The CLI this extension ships with (dist/cli.js next to dist/extension/), else `mu` on PATH. */\nexport function defaultRunner(): MuRunner {\n let cli: string | undefined;\n try {\n const p = fileURLToPath(new URL(\"../cli.js\", import.meta.url));\n if (existsSync(p)) cli = p;\n } catch {\n // not a file: URL; use PATH\n }\n return (args, signal) =>\n new Promise((resolve) => {\n const [cmd, argv] = cli ? [process.execPath, [cli, ...args]] : [\"mu\", [...args]];\n execFile(\n cmd,\n argv,\n { maxBuffer: 16 * 1024 * 1024, ...(signal ? { signal } : {}) },\n (err, stdout, stderr) => {\n const code = err ? (typeof err.code === \"number\" ? err.code : 1) : 0;\n resolve({ code, stdout: String(stdout), stderr: String(stderr || err?.message || \"\") });\n },\n );\n });\n}\n\n/** One agent row of `mu agent wait --json`, as far as the tool reads it. */\nexport type WaitAgent = {\n outcome?: string;\n lastText?: string;\n lastError?: string;\n /** The delegate's pi session file (mu ≥ 3.11.2 on the delegate side). */\n sessionFile?: string;\n};\n\n/** What happened to the pane after delivery, for the message. */\nexport type PaneFate = { closed: true } | { closed: false; why: string };\n\n/** Extras for the follow-up message; all optional. */\nexport type MessageExtras = {\n /** `mu agent read -n 50` for the outcomes without text. */\n tail?: string;\n attach?: string;\n timeoutS?: number;\n workspace?: string;\n /** How long the delegate ran, in ms. */\n elapsedMs?: number;\n /** The queue handle the caller was given (`queued-3`), if it was queued. */\n queuedAs?: string;\n};\n\n/** `42s`, `3m 05s`, `1h 02m`. */\nexport function formatElapsed(ms: number): string {\n const t = Math.max(0, Math.round(ms / 1000));\n if (t < 60) return `${t}s`;\n const m = Math.floor(t / 60);\n if (m < 60) return `${m}m ${String(t % 60).padStart(2, \"0\")}s`;\n return `${Math.floor(m / 60)}h ${String(m % 60).padStart(2, \"0\")}m`;\n}\n\n/**\n * The follow-up message for one finished wait. Pure: the CLI already\n * classified the outcome (`mu agent wait --json` → `outcome`); this only\n * words it.\n */\nexport function delegateMessage(\n name: string,\n agent: WaitAgent | undefined,\n pane: PaneFate,\n x: MessageExtras = {},\n): string {\n const timeoutS = x.timeoutS ?? DELEGATE_TIMEOUT_S;\n const who = `Delegate ${W}/${name}${x.queuedAs ? ` (queued as ${x.queuedAs})` : \"\"}`;\n const took = x.elapsedMs !== undefined ? ` after ${formatElapsed(x.elapsedMs)}` : \"\";\n const fate = pane.closed ? \"Pane closed.\" : `Pane kept (${pane.why}).`;\n const look = [\n x.attach ? `Attach: ${x.attach}` : undefined,\n `Read: mu agent read ${name} -n 50 -w ${W}`,\n ].filter((v) => v !== undefined);\n const tailBlock = x.tail?.trim() ? `\\n\\nPane tail:\\n${x.tail.trimEnd()}` : \"\";\n const ws = x.workspace ? ` Workspace: ${x.workspace}` : \"\";\n switch (agent?.outcome) {\n case \"done\":\n return `${who} finished${took}. ${fate}${ws}\\n\\n${agent.lastText ?? \"\"}`;\n case \"empty\":\n return `${who} finished${took} without a text answer. ${fate}${ws}${tailBlock}`;\n case \"error\":\n return [\n `${who} stopped on an API error${took}, after pi's own retries: ${(agent.lastError ?? \"unknown error\").replace(/[.\\s]+$/, \"\")}. ${fate}${ws}`,\n \"Decide: re-issue the call, or record the check as UNVERIFIED.\",\n ...look,\n `Close: mu agent close ${name} -w ${W}`,\n ].join(\"\\n\");\n case \"died\":\n return `${who} died${took} before answering. ${fate}${ws}${tailBlock}`;\n case \"timeout\":\n case \"pending\":\n return [\n `${who} is still running after ${timeoutS}s; stopped waiting, so its answer will not arrive here. ${fate}${ws}`,\n ...look,\n `Wait again: mu agent wait ${name} -w ${W} --json`,\n ].join(\"\\n\");\n default:\n return `${who}: mu agent wait gave no result. ${fate}${ws}${tailBlock}`;\n }\n}\n\n/** A finished delegate whose answer an aborted run dropped from pi's queue. */\nexport type DroppedAnswer = {\n name: string;\n outcome?: string;\n elapsedMs?: number;\n /** The local copy of the follow-up message, if writing it worked. */\n copy?: string;\n sessionFile?: string;\n};\n\n/** Where dropped answers are copied: `<mu cache dir>/delegate-answers`.\n * Cache, not state: the delegate's pi session file keeps the answer. */\nexport function droppedAnswersDir(): string {\n return join(defaultCacheDir(), \"delegate-answers\");\n}\n\n/**\n * The note left in the conversation when Escape drops queued answers:\n * one line per delegate, pointing at the local copy and the delegate's\n * own session file. Pure.\n */\nexport function droppedNote(dropped: readonly DroppedAnswer[]): string {\n const n = dropped.length;\n const lines = dropped.map((d) => {\n const how = [\n d.outcome ?? \"no result\",\n d.elapsedMs !== undefined ? formatElapsed(d.elapsedMs) : undefined,\n ]\n .filter((x) => x !== undefined)\n .join(\", \");\n const where = [\n d.copy ? `answer: ${d.copy}` : undefined,\n d.sessionFile ? `session: ${d.sessionFile}` : undefined,\n ].filter((x) => x !== undefined);\n if (where.length === 0) where.push(`read: mu agent read ${d.name} -n 50 -w ${W}`);\n return `- ${W}/${d.name} (${how}) ${where.join(\" · \")}`;\n });\n return [\n `The interrupt dropped ${n} delegate answer${n === 1 ? \"\" : \"s\"} before ${n === 1 ? \"it\" : \"they\"} arrived:`,\n ...lines,\n \"The answer file holds the message that would have arrived; in a session file the answer is the last assistant message.\",\n ].join(\"\\n\");\n}\n\n/** Where a delegate's answer is recorded: a task, resolved by `mu task show`. */\nexport type RecordTarget = { workstream: string; task: string };\n\n/** Cap on a recorded note, in chars. */\nexport const RECORD_NOTE_MAX = 4000;\n/** Without a VERDICT line, this much of the answer's end is recorded. */\nexport const RECORD_FALLBACK_TAIL = 1500;\n\nconst VERDICT_LINE = /^[\\s>*_`-]*VERDICT:/;\nconst EVIDENCE_LINE = /^[\\s>*_`-]*EVIDENCE:/;\n\n/**\n * The note a delegate's answer leaves on the task it judged. Pure. A done\n * answer keeps its last `VERDICT:` line and every `EVIDENCE:` line after\n * it (else its tail, marked NO VERDICT LINE); any other outcome records\n * the gap.\n */\nexport function recordNote(\n label: string,\n name: string,\n outcome: string | undefined,\n lastText: string | undefined,\n elapsedMs: number,\n): string {\n if (outcome !== \"done\" || !lastText?.trim())\n return `REFUTER ${label}: no verdict (${outcome === \"done\" ? \"empty\" : (outcome ?? \"no result\")})`;\n const lines = lastText.trimEnd().split(\"\\n\");\n let at = -1;\n for (let i = lines.length - 1; i >= 0 && at < 0; i--)\n if (VERDICT_LINE.test(lines[i] ?? \"\")) at = i;\n const body =\n at >= 0\n ? [lines[at] ?? \"\", ...lines.slice(at + 1).filter((l) => EVIDENCE_LINE.test(l))].join(\"\\n\")\n : `NO VERDICT LINE: ${lastText.trimEnd().slice(-RECORD_FALLBACK_TAIL)}`;\n const note = `REFUTER ${label} (${name}, ${formatElapsed(elapsedMs)}):\\n${body}`;\n const mark = \"\\n[truncated]\";\n return note.length <= RECORD_NOTE_MAX\n ? note\n : note.slice(0, RECORD_NOTE_MAX - mark.length) + mark;\n}\n\n/** A label → agent-name stem: lowercase, [a-z0-9-], ≤ 20 chars. */\nexport function labelStem(label: unknown): string | undefined {\n if (typeof label !== \"string\") return undefined;\n const stem = label\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 20)\n .replace(/-+$/, \"\");\n return stem || undefined;\n}\n\n/** Model values that need no shell quoting inside a `--command` string. */\nconst MODEL_BARE_RE = /^[A-Za-z0-9._:/@+=-]+$/;\n\n/**\n * Forgive the usual slips in a `model` value: surrounding quotes or\n * backticks, a pasted `--model ` / `--model=` prefix, stray whitespace.\n * Anything else (brackets as in `gpt-6.1-sol[1m]`, odd provider ids) is\n * kept and shell-quoted by `modelCommand`, so pi gets to judge the id.\n * Returns undefined for an empty value or one with inner whitespace,\n * which no model id has.\n */\nexport function normalizeModel(raw: unknown): string | undefined {\n if (typeof raw !== \"string\") return undefined;\n let m = raw.trim();\n for (let prev = \"\"; prev !== m; ) {\n prev = m;\n m = m\n .replace(/^--model(?:=|\\s+)/, \"\")\n .replace(/^([\"'`])(.*)\\1$/s, \"$2\")\n .trim();\n }\n return m && !/\\s/.test(m) ? m : undefined;\n}\n\nfunction shellArg(s: string): string {\n return MODEL_BARE_RE.test(s) ? s : `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\n/**\n * The command a delegate with `model` runs: the cli key's command\n * (`$MU_<KEY>_COMMAND`, else the key itself, as `resolveCliCommand` in\n * src/agents/spawn.ts does) plus `--model <model>`. Inlined: the extension\n * bundles standalone and spawn.ts pulls in the DB.\n */\nexport function modelCommand(\n cli: string,\n model: string,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n const override = env[`MU_${cli.toUpperCase().replace(/-/g, \"_\")}_COMMAND`];\n const base = override && override.trim() !== \"\" ? override.trim() : cli;\n return `${base} --model ${shellArg(model)}`;\n}\n\n/**\n * One delegate this pi waits on. `cancelling` is set while a cancel's abort\n * is in flight: the abort itself settles the run, so a wait resolving then\n * is parked in `parked` instead of delivered, and delivered after all if\n * the abort fails.\n */\ntype Inflight = {\n abort: AbortController;\n record?: { target: RecordTarget; label: string };\n cancelling: boolean;\n parked?: () => Promise<void>;\n};\n\n/** A call past the cap, waiting for a slot. Its delegate name is picked\n * at spawn, so the queue hands out its own handle (`queued-3`). */\ntype Queued = {\n handle: string;\n params: Record<string, unknown>;\n ctx: DelegateCtx | undefined;\n record?: RecordTarget;\n};\n\nexport function registerDelegate(pi: MuDelegateApi, run: MuRunner = defaultRunner()): void {\n if (!delegateEnabled()) return;\n const inflight = new Map<string, Inflight>();\n /** Calls past the cap check whose delegate is not yet in `inflight`. */\n let starting = 0;\n /** Calls past the cap, FIFO, at most `DELEGATE_QUEUE_FACTOR * delegateMax()` long. */\n const queue: Queued[] = [];\n let queueSeq = 0;\n /** Delegates that settled on an error, pane kept: counted in the footer\n * until the model closes or re-issues them (no call to action). */\n const failed = new Set<string>();\n /** Delegates that finished whose follow-up has not entered the\n * conversation: being delivered, or queued behind a running turn.\n * Keyed by a per-delivery id carried in the message's details, and\n * cleared on that message's message_start. `queued` says whether\n * pi.sendMessage has returned, i.e. the message sits in pi's queue;\n * the rest is what an interrupt needs to point at the answer. */\n const arriving = new Map<\n number,\n { queued: boolean; name: string; content?: string } & Omit<DroppedAnswer, \"copy\">\n >();\n let deliverySeq = 0;\n // The ctx of the latest tool call: answers settle outside any call, so\n // the footer is refreshed through the last ctx pi handed us.\n let ui: DelegateCtx[\"ui\"];\n let lastPending = 0;\n /** Running, starting and queued: every delegate whose answer is still\n * to come back here. Failed panes have answered, so they do not count. */\n const reportPending = () => {\n const count = inflight.size + starting + queue.length;\n if (count === lastPending) return;\n lastPending = count;\n try {\n pi.events.emit(PENDING_CHANNEL, { source: DELEGATE_TOOL, count });\n } catch {\n // a listener's fault must not cost a delegate its answer\n }\n };\n // Every change to the counts already refreshes the footer, so the\n // report rides along rather than being a second set of call sites.\n const showStatus = () => {\n reportPending();\n try {\n ui?.setStatus?.(\n DELEGATE_STATUS_KEY,\n delegateStatus(inflight.size, starting, queue.length, failed.size, arriving.size),\n );\n } catch {\n // stale ctx after a session switch: the footer is decoration\n }\n };\n const track = (ctx: DelegateCtx | undefined) => {\n if (ctx?.hasUI !== false && ctx?.ui) ui = ctx.ui;\n };\n /** The follow-up for `delivery` is in pi's queue now. */\n const markQueued = (delivery: number) => {\n const a = arriving.get(delivery);\n if (a) a.queued = true;\n };\n /** Copy a dropped answer under the mu cache dir; undefined if that fails. */\n const saveCopy = (name: string, content: string): string | undefined => {\n try {\n const dir = droppedAnswersDir();\n mkdirSync(dir, { recursive: true });\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const path = join(dir, `${stamp}_${name}.md`);\n writeFileSync(path, `${content}\\n`);\n return path;\n } catch {\n return undefined;\n }\n };\n /** Drop a delegate from the in-flight set, start the next queued call\n * into the freed slot, and refresh the footer. */\n const forget = (name: string) => {\n inflight.delete(name);\n drain();\n showStatus();\n };\n /** Start queued calls while there is a free slot. A queued call's tool\n * call has already returned, so a failed start becomes a follow-up. */\n function drain(): void {\n while (queue.length > 0 && inflight.size + starting < delegateMax()) {\n const q = queue.shift();\n if (!q) break;\n starting++; // held until start() takes over the slot\n void start(q.params, undefined, q.ctx, q.handle, q.record).then(\n () => {},\n (e: unknown) => {\n void Promise.resolve(\n pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content: `Queued delegate ${q.handle} could not start: ${e instanceof Error ? e.message : String(e)}`,\n display: true,\n details: { name: q.handle, workstream: W, outcome: null, closed: false },\n },\n { deliverAs: \"followUp\", triggerTurn: true },\n ),\n ).catch(() => {});\n },\n );\n }\n }\n\n const mu = run;\n const json = (r: MuResult): Record<string, unknown> | undefined => {\n try {\n const v: unknown = JSON.parse(r.stdout);\n return typeof v === \"object\" && v !== null ? (v as Record<string, unknown>) : undefined;\n } catch {\n return undefined;\n }\n };\n const failure = (what: string, r: MuResult) =>\n new Error(`${what} failed (exit ${r.code}): ${(r.stderr || r.stdout).trim()}`);\n\n /** A failed delegate whose pane is gone (closed from bash) leaves the\n * footer. Off the call's path: only a footer count rides on it. */\n function pruneFailed(): void {\n if (failed.size === 0) return;\n void mu([\"agent\", \"list\", \"-w\", W, \"--json\"]).then((r) => {\n const agents = json(r)?.agents;\n if (!Array.isArray(agents)) return;\n const taken = new Set(agents.map((a: unknown) => (a as { name?: unknown }).name));\n for (const f of [...failed]) if (!taken.has(f)) failed.delete(f);\n showStatus();\n });\n }\n\n /**\n * Spawn the delegate and send it the task in ONE mu call (`spawn\n * --next-free --send`): mu picks the free name under its spawn lock, so\n * parallel calls get distinct names with no `agent list` first. Returns\n * the name and the send's `runs`, the exact wait baseline.\n */\n async function spawn(\n params: Record<string, unknown>,\n text: string,\n cwd: string | undefined,\n signal?: AbortSignal,\n ): Promise<{ name: string; runs: number; attach?: string; workspace?: string }> {\n signal?.throwIfAborted();\n pruneFailed();\n const stem = labelStem(params.label);\n // A label names the delegate (delegate-review, then delegate-review-2);\n // without one it is numbered (delegate-1, delegate-2).\n const base = stem ? `delegate-${stem}` : \"delegate-1\";\n const args = [\"agent\", \"spawn\", base, \"-w\", W, \"--next-free\", \"--send\", text, \"--json\"];\n if (params.workspace === true) args.push(\"--workspace\");\n else if (cwd) args.push(\"--cwd\", cwd);\n const cli = typeof params.cli === \"string\" && params.cli ? params.cli : undefined;\n if (cli) args.push(\"--cli\", cli);\n if (typeof params.model === \"string\" && params.model)\n args.push(\"--command\", modelCommand(cli ?? \"pi\", params.model));\n const r = await mu(args);\n const out = json(r);\n const spawned = (out?.agent as { name?: unknown } | undefined)?.name;\n // No agent in the reply: the spawn itself failed, nothing is up.\n if (typeof spawned !== \"string\") throw failure(\"mu agent spawn\", r);\n const name = spawned;\n if (signal?.aborted) {\n // The user cancelled while the pane came up: take it down again.\n await mu([\"agent\", \"close\", name, \"-w\", W]);\n signal.throwIfAborted();\n }\n if (out?.ctl !== \"ok\") {\n throw new Error(\n `${W}/${name} spawned but its control socket is ${String(out?.ctl)}, so its answer cannot come back. Pane kept; close it with: mu agent close ${name} -w ${W}`,\n );\n }\n const sent = out.send as { ok?: unknown; runs?: unknown; message?: unknown } | undefined;\n if (sent?.ok !== true) {\n // Nothing reached it: the pane is just an idle pi. Take it down.\n const c = await mu([\"agent\", \"close\", name, \"-w\", W]);\n const pane =\n c.code === 0 ? \"Pane closed.\" : `Pane kept; close it with: mu agent close ${name} -w ${W}`;\n const why = typeof sent?.message === \"string\" ? sent.message : (r.stderr || r.stdout).trim();\n throw new Error(`mu agent send to ${W}/${name} failed (exit ${r.code}): ${why}. ${pane}`);\n }\n const steps = Array.isArray(out.nextSteps) ? out.nextSteps : [];\n const attach = steps\n .map((s: unknown) => s as { intent?: unknown; command?: unknown })\n .find((s) => s.intent === \"Attach the pane\")?.command;\n const wsPath = (out.workspace as { path?: unknown } | null | undefined)?.path;\n return {\n name,\n // A pi just spawned has settled no run, so 0 is exact when an older\n // extension's reply carries no runs.\n runs: typeof sent.runs === \"number\" ? sent.runs : 0,\n ...(typeof attach === \"string\" ? { attach } : {}),\n ...(typeof wsPath === \"string\" ? { workspace: wsPath } : {}),\n };\n }\n\n /** The note label: the caller's label, else the delegate's name. */\n const recordLabel = (params: Record<string, unknown>, name: string) =>\n typeof params.label === \"string\" && params.label.trim() ? params.label.trim() : name;\n\n /** Check `record` names a real task, before anything spawns. */\n async function resolveRecord(raw: unknown): Promise<RecordTarget | undefined> {\n if (raw === undefined) return undefined;\n const r = raw as { task?: unknown; workstream?: unknown } | null;\n const task = typeof r?.task === \"string\" ? r.task.trim() : \"\";\n if (!task) throw new Error(\"mu_delegate: record.task must name a task\");\n const ws = typeof r?.workstream === \"string\" ? r.workstream.trim() : \"\";\n // Without a workstream, mu resolves it as any verb does (<ws>/<task>, $MU_SESSION, tmux).\n const shown = await mu([\"task\", \"show\", task, ...(ws ? [\"-w\", ws] : []), \"--json\"]);\n const out = json(shown);\n const t = out?.task as { name?: unknown; workstreamName?: unknown } | undefined;\n if (shown.code !== 0 || typeof t?.name !== \"string\" || typeof t.workstreamName !== \"string\") {\n const why =\n typeof out?.message === \"string\" ? out.message : (shown.stderr || shown.stdout).trim();\n throw new Error(\n `mu_delegate: record task ${ws ? `${ws}/` : \"\"}${task} not found (exit ${shown.code}): ${why}. Nothing spawned.`,\n );\n }\n return { workstream: t.workstreamName, task: t.name };\n }\n\n /** Write one note on the record task; the follow-up's line about it. */\n async function writeRecord(rec: RecordTarget, name: string, text: string): Promise<string> {\n const where = `${rec.workstream}/${rec.task}`;\n try {\n const r = await mu([\"task\", \"note\", rec.task, \"-w\", rec.workstream, \"--author\", name, text]);\n if (r.code === 0) return `Recorded on ${where} as a note.`;\n return `Recording on ${where} failed (exit ${r.code}): ${(r.stderr || r.stdout).trim()}. Record it yourself.`;\n } catch (e) {\n return `Recording on ${where} failed: ${e instanceof Error ? e.message : String(e)}. Record it yourself.`;\n }\n }\n\n async function deliver(\n name: string,\n wait: MuResult,\n keep: boolean,\n extras: MessageExtras,\n delivery: number,\n record?: { target: RecordTarget; label: string },\n ) {\n const agent = (json(wait)?.agents as WaitAgent[] | undefined)?.[0];\n const outcome = agent?.outcome;\n const tail =\n outcome === \"done\" || outcome === \"timeout\" || outcome === \"pending\" || outcome === \"error\"\n ? undefined\n : (await mu([\"agent\", \"read\", name, \"-n\", \"50\", \"-w\", W])).stdout;\n // Close only after a clean finish: a died or timed-out pane is evidence.\n let pane: PaneFate = { closed: false, why: \"keep: true\" };\n if (outcome !== \"done\" && outcome !== \"empty\")\n pane = { closed: false, why: \"kept as evidence\" };\n else if (!keep) {\n const c = await mu([\"agent\", \"close\", name, \"-w\", W]);\n pane =\n c.code === 0\n ? { closed: true }\n : { closed: false, why: `close refused: ${(c.stderr || c.stdout).trim()}` };\n }\n if (outcome === \"error\" && !pane.closed) {\n failed.add(name);\n showStatus();\n }\n const recorded = record\n ? await writeRecord(\n record.target,\n name,\n recordNote(record.label, name, outcome, agent?.lastText, extras.elapsedMs ?? 0),\n )\n : undefined;\n const message = delegateMessage(name, agent, pane, { ...extras, ...(tail ? { tail } : {}) });\n const content = recorded ? `${message}\\n\\n${recorded}` : message;\n const a = arriving.get(delivery);\n if (a)\n Object.assign(a, {\n content,\n ...(outcome ? { outcome } : {}),\n ...(extras.elapsedMs !== undefined ? { elapsedMs: extras.elapsedMs } : {}),\n ...(agent?.sessionFile ? { sessionFile: agent.sessionFile } : {}),\n });\n await pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content,\n display: true,\n details: {\n name,\n workstream: W,\n outcome: outcome ?? null,\n closed: pane.closed,\n answer: outcome === \"done\" ? (agent?.lastText ?? null) : null,\n elapsedMs: extras.elapsedMs ?? null,\n workspace: extras.workspace ?? null,\n delivery,\n },\n },\n { deliverAs: \"followUp\", triggerTurn: true },\n );\n }\n\n /** Spawn, send, and watch one delegate. The caller holds one\n * `starting` slot; it is released once the delegate is in `inflight`\n * (or on failure). Returns the tool result text. */\n async function start(\n params: Record<string, unknown>,\n signal: AbortSignal | undefined,\n ctx: DelegateCtx | undefined,\n queuedAs?: string,\n record?: RecordTarget,\n ): Promise<ToolResult> {\n let slotHeld = true;\n const freeSlot = () => {\n if (slotHeld) {\n starting--;\n showStatus();\n }\n slotHeld = false;\n };\n showStatus(); // the footer moves at once, before the pane exists\n try {\n const task = typeof params.task === \"string\" ? params.task.trim() : \"\";\n const brief = typeof params.brief === \"string\" ? params.brief.trim() : \"\";\n const keep = params.keep === true;\n const t = params.timeout;\n if (t !== undefined && !(typeof t === \"number\" && Number.isFinite(t) && t > 0))\n throw new Error(\n `mu_delegate: timeout must be a positive number of seconds (got ${JSON.stringify(t)})`,\n );\n const timeoutS = typeof t === \"number\" ? Math.ceil(t) : DELEGATE_TIMEOUT_S;\n // Without --cwd the pane inherits the mux session's start dir (wherever\n // the FIRST scratch spawn ran), and a missing dir silently becomes\n // $HOME: pin it to the caller's and check it exists.\n let cwd: string | undefined;\n if (params.workspace !== true) {\n cwd =\n typeof params.cwd === \"string\" && params.cwd ? params.cwd : (ctx?.cwd ?? process.cwd());\n if (!isDir(cwd)) throw new Error(`mu_delegate: cwd ${cwd} is not a directory`);\n }\n const { name, runs, attach, workspace } = await spawn(\n params,\n brief ? `${brief}\\n\\n${task}` : task,\n cwd,\n signal,\n );\n const entry: Inflight = {\n abort: new AbortController(),\n cancelling: false,\n ...(record ? { record: { target: record, label: recordLabel(params, name) } } : {}),\n };\n inflight.set(name, entry);\n freeSlot(); // now counted in inflight\n showStatus();\n const started = Date.now();\n // The send's `runs` is pi's count before this prompt: waiting past it\n // catches the run even if it settled before this wait started.\n const waiting = mu(\n [\n \"agent\",\n \"wait\",\n name,\n \"-w\",\n W,\n \"--json\",\n \"--timeout\",\n String(timeoutS),\n \"--after-runs\",\n String(runs),\n ],\n entry.abort.signal,\n );\n const settle = async (r: MuResult) => {\n const delivery = ++deliverySeq;\n arriving.set(delivery, { queued: false, name });\n forget(name);\n try {\n await deliver(\n name,\n r,\n keep,\n {\n timeoutS,\n elapsedMs: Date.now() - started,\n ...(queuedAs ? { queuedAs } : {}),\n ...(attach ? { attach } : {}),\n ...(workspace ? { workspace } : {}),\n },\n delivery,\n entry.record,\n );\n markQueued(delivery);\n } catch (e) {\n // A throw here would be an unhandled rejection and a lost answer.\n const content = `Delegate ${W}/${name} settled, but delivering its answer failed: ${e instanceof Error ? e.message : String(e)}. Read it with: mu agent read ${name} -n 50 -w ${W}`;\n const a = arriving.get(delivery);\n if (a) a.content = content;\n await Promise.resolve(\n pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content,\n display: true,\n details: { name, workstream: W, outcome: null, closed: false, delivery },\n },\n { deliverAs: \"followUp\", triggerTurn: true },\n ),\n ).then(\n () => markQueued(delivery),\n () => {\n // Nothing will arrive: stop counting it.\n arriving.delete(delivery);\n showStatus();\n },\n );\n }\n };\n void waiting.then(async (r) => {\n if (inflight.get(name) !== entry) return; // cancelled or shut down\n if (entry.cancelling) entry.parked = () => settle(r);\n else await settle(r);\n });\n const lines = [\n `Delegated to ${W}/${name}. Its answer arrives as a follow-up message when it finishes; do not wait or poll.`,\n workspace ? `Workspace: ${workspace}` : undefined,\n attach ? `Attach: ${attach}` : undefined,\n `Cancel: ${DELEGATE_CANCEL_TOOL} { name: \"${name}\" }`,\n ].filter((x) => x !== undefined);\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n details: {\n name,\n workstream: W,\n attach: attach ?? null,\n workspace: workspace ?? null,\n keep,\n },\n };\n } finally {\n // A start that threw frees its slot here, and a call queued while it\n // was starting must take that slot: drain whether queued or direct.\n freeSlot();\n drain();\n }\n }\n\n pi.registerTool({\n name: DELEGATE_TOOL,\n label: \"mu delegate\",\n description: `Subagent: run one self-contained task in a fresh pi agent (its own mux pane in mu's ${W} workstream) while you keep working. Use it whenever you would reach for a subagent: research, a review, a draft, an investigation, or a refuter of a claim, plan or fix before you act on it; call it several times to fan out in parallel (at most ${delegateMax()} run at once; up to ${DELEGATE_QUEUE_FACTOR * delegateMax()} more are queued and start as slots free). The subagent starts with no context, in your working directory: put everything it needs in task. The call returns at once and the answer arrives later as a follow-up message: carry on with other work, or end your turn if your next step needs the answer (the follow-up resumes you). The pane closes after a clean finish; keep: true leaves it open. When the check judges a mu task, set record so its verdict lands on that task; leave it out when there is no task.`,\n promptSnippet:\n \"Subagent: delegate a self-contained task to a background pi agent; its answer arrives later as a follow-up\",\n parameters: {\n type: \"object\",\n properties: {\n task: { type: \"string\", description: \"The complete task, with all context it needs\" },\n label: {\n type: \"string\",\n description:\n \"Short label naming the delegate, e.g. 'review' → delegate-review. Use one per subtask when fanning out.\",\n },\n brief: {\n type: \"string\",\n description:\n \"Optional standing role or rules, sent before the task, e.g. 'You are a reviewer; read only.' The rules are instructions, not enforced. The job itself goes in task.\",\n },\n cwd: {\n type: \"string\",\n description:\n \"Working directory for the delegate (default: yours; ignored with workspace)\",\n },\n timeout: {\n type: \"number\",\n exclusiveMinimum: 0,\n description: `Seconds to wait for the answer (default ${DELEGATE_TIMEOUT_S}). On timeout you get a \"still running\" follow-up instead of the answer, and the answer will not arrive later; the subagent keeps running in its pane.`,\n },\n workspace: {\n type: \"boolean\",\n description:\n \"For tasks that edit files: its own VCS checkout (jj workspace / git worktree / sl share) branched from the current commit. The result and follow-up name the path; changes stay there until you merge them. This isolates repository edits only: the subagent runs as you, with your files, environment and network.\",\n },\n cli: {\n type: \"string\",\n description:\n \"Agent CLI key (default pi). Only keys with $MU_<KEY>_COMMAND set in pi's environment exist; to pick a model, use model instead.\",\n },\n model: {\n type: \"string\",\n description:\n \"Model for the subagent, passed to pi as --model (e.g. 'sonnet', '<provider>/<model>:high' copied from `pi --list-models`); appended to the cli's command. Default: the cli's own model. Use it to vary models across a review panel.\",\n },\n keep: {\n type: \"boolean\",\n description: \"Keep the pane after it finishes, to talk to it again\",\n },\n record: {\n type: \"object\",\n description:\n \"When the answer arrives, write its VERDICT/EVIDENCE onto this task as a note (for a check that judges a mu task; omit with no task); task may be <ws>/<task>.\",\n properties: {\n task: { type: \"string\" },\n workstream: { type: \"string\" },\n },\n required: [\"task\"],\n additionalProperties: false,\n },\n },\n required: [\"task\"],\n additionalProperties: false,\n },\n async execute(_id, params, signal, _onUpdate, ctx) {\n track(ctx);\n const task = typeof params.task === \"string\" ? params.task.trim() : \"\";\n if (!task) throw new Error(\"mu_delegate needs a non-empty task\");\n const t = params.timeout;\n if (t !== undefined && !(typeof t === \"number\" && Number.isFinite(t) && t > 0))\n throw new Error(\n `mu_delegate: timeout must be a positive number of seconds (got ${JSON.stringify(t)})`,\n );\n if (params.workspace !== true) {\n const cwd =\n typeof params.cwd === \"string\" && params.cwd ? params.cwd : (ctx?.cwd ?? process.cwd());\n if (!isDir(cwd)) throw new Error(`mu_delegate: cwd ${cwd} is not a directory`);\n }\n if (params.model !== undefined && params.model !== \"\") {\n const m = normalizeModel(params.model);\n if (!m)\n throw new Error(\n `mu_delegate: model must be one pi model id like 'provider/id:thinking', as listed by \\`pi --list-models\\` (got ${JSON.stringify(params.model)}); omit it for the cli's default`,\n );\n params = { ...params, model: m };\n }\n const record = await resolveRecord(params.record);\n // Count slots synchronously, before any await: parallel calls in one\n // turn all run this line before the first spawn returns.\n const max = delegateMax();\n if (inflight.size + starting < max) {\n starting++;\n return start(params, signal, ctx, undefined, record);\n }\n // Full: queue up to DELEGATE_QUEUE_FACTOR caps' worth; past that, refuse.\n if (queue.length >= DELEGATE_QUEUE_FACTOR * max)\n throw new Error(\n `mu_delegate: ${inflight.size + starting} running and ${queue.length} queued (MU_DELEGATE_MAX=${max}). End your turn; issue the rest as answers arrive (each answer resumes you).`,\n );\n const handle = `queued-${++queueSeq}`;\n queue.push({\n handle,\n params: {\n ...params,\n cwd:\n typeof params.cwd === \"string\" && params.cwd ? params.cwd : (ctx?.cwd ?? process.cwd()),\n },\n ctx,\n ...(record ? { record } : {}),\n });\n showStatus();\n return {\n content: [\n {\n type: \"text\",\n text: `Queued as ${handle} (#${queue.length}; ${inflight.size + starting} running, MU_DELEGATE_MAX=${max}). It starts when a slot frees, and its answer arrives as a follow-up message like any delegate's; do not wait or poll. Cancel: ${DELEGATE_CANCEL_TOOL} { name: \"${handle}\" }`,\n },\n ],\n details: { name: handle, workstream: W, queued: true, position: queue.length },\n };\n },\n });\n\n pi.registerTool({\n name: DELEGATE_CANCEL_TOOL,\n label: \"mu delegate cancel\",\n description: `Stop a delegate started by ${DELEGATE_TOOL}: abort its turn and close its pane (keep: true leaves the pane open). No follow-up message is sent for it afterwards.`,\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Delegate name, e.g. delegate-1\" },\n keep: { type: \"boolean\", description: \"Leave the pane open after aborting\" },\n },\n required: [\"name\"],\n additionalProperties: false,\n },\n async execute(_id, params, _signal, _onUpdate, ctx) {\n track(ctx);\n const name = typeof params.name === \"string\" ? params.name : \"\";\n if (!name) throw new Error(\"mu_delegate_cancel needs a name\");\n const qi = queue.findIndex((q) => q.handle === name);\n if (qi >= 0) {\n const [q] = queue.splice(qi, 1);\n showStatus();\n const recorded = q?.record\n ? ` ${await writeRecord(q.record, name, recordNote(recordLabel(q.params, name), name, \"cancelled\", undefined, 0))}`\n : \"\";\n return {\n content: [\n { type: \"text\", text: `Dropped ${name} from the queue; it never started.${recorded}` },\n ],\n details: { name, workstream: W },\n };\n }\n const entry = inflight.get(name);\n if (entry) entry.cancelling = true;\n const ab = await mu([\"agent\", \"abort\", name, \"-w\", W]);\n if (ab.code !== 0) {\n // Not cancelled after all: keep waiting, or deliver what settled meanwhile.\n if (entry) {\n entry.cancelling = false;\n const parked = entry.parked;\n entry.parked = undefined;\n if (parked) void parked();\n }\n throw failure(`mu agent abort ${W}/${name}`, ab);\n }\n if (entry) {\n entry.abort.abort();\n forget(name);\n }\n failed.delete(name);\n let text = `Aborted ${W}/${name}.`;\n if (entry?.record)\n text += ` ${await writeRecord(entry.record.target, name, recordNote(entry.record.label, name, \"cancelled\", undefined, 0))}`;\n if (params.keep === true) text += \" Pane kept.\";\n else {\n const c = await mu([\"agent\", \"close\", name, \"-w\", W]);\n text +=\n c.code === 0\n ? \" Pane closed.\"\n : ` Pane kept: close refused: ${(c.stderr || c.stdout).trim()}`;\n }\n return { content: [{ type: \"text\", text }], details: { name, workstream: W } };\n },\n });\n\n // A follow-up enters the conversation at its message_start: at once\n // when pi is idle, or when the running turn drains its follow-ups.\n pi.on(\"message_start\", (e) => {\n const m = (e as { message?: { role?: unknown; customType?: unknown; details?: unknown } })\n .message;\n if (m?.role !== \"custom\" || m.customType !== DELEGATE_MESSAGE_TYPE) return;\n const id = (m.details as { delivery?: unknown } | undefined)?.delivery;\n if (typeof id === \"number\" && arriving.delete(id)) showStatus();\n });\n\n // Escape clears pi's follow-up queue along with the run: answers that\n // were queued in it never arrive. Stop counting them, copy each to the\n // mu cache dir, and leave one line per answer in the conversation (no\n // turn: the model sees it with the user's next prompt). An answer\n // still being delivered is not in the queue yet and arrives as usual.\n pi.on(\"agent_settled\", (e) => {\n if ((e as { aborted?: unknown }).aborted !== true) return;\n const dropped: DroppedAnswer[] = [];\n for (const [id, a] of arriving) {\n if (!a.queued) continue;\n arriving.delete(id);\n dropped.push({\n name: a.name,\n ...(a.outcome ? { outcome: a.outcome } : {}),\n ...(a.elapsedMs !== undefined ? { elapsedMs: a.elapsedMs } : {}),\n ...(a.sessionFile ? { sessionFile: a.sessionFile } : {}),\n ...(a.content ? { copy: saveCopy(a.name, a.content) } : {}),\n });\n }\n if (dropped.length === 0) return;\n showStatus();\n void Promise.resolve(\n pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content: droppedNote(dropped),\n display: true,\n details: { dropped },\n },\n { triggerTurn: false },\n ),\n ).catch(() => {});\n });\n\n // The watchers die with this runtime (/reload, /new, quit): say which\n // delegates lose their callback, so none is lost silently. The names\n // are also in the tool results, and `mu agent wait` recovers them.\n pi.on(\"session_shutdown\", (_e, ctx) => {\n if (arriving.size > 0) {\n // Answers still being delivered or queued die with this runtime.\n arriving.clear();\n showStatus();\n }\n if (inflight.size === 0 && queue.length === 0) return;\n const names = [...inflight.keys()];\n const never = queue.splice(0).map((q) => q.handle);\n for (const e of inflight.values()) e.abort.abort();\n inflight.clear();\n showStatus();\n ui = undefined;\n const parts: string[] = [];\n if (names.length > 0)\n parts.push(\n `${names.length} delegate${names.length === 1 ? \"\" : \"s\"} still running: ${names.join(\", \")}. Their answers will not come back here; use mu agent wait <name> -w ${W} --json.`,\n );\n if (never.length > 0)\n parts.push(`${never.length} queued, never started: ${never.join(\", \")}. Re-issue them.`);\n const msg = parts.join(\" \");\n if (ctx?.hasUI && ctx.ui) ctx.ui.notify(msg, \"warning\");\n else process.stderr.write(`mu: ${msg}\\n`);\n });\n}\n","// The mu state directory, resolved from builtins only so the CLI\n// bootstrap (src/main.ts) can locate its compile cache before it loads\n// any of the CLI graph. db.ts re-exports defaultStateDir.\n\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join } from \"node:path\";\n\n/**\n * Resolve the canonical mu state directory:\n * MU_STATE_DIR > $XDG_STATE_HOME/mu (absolute only) > ~/.local/state/mu\n */\nexport function defaultStateDir(): string {\n if (process.env.MU_STATE_DIR) return process.env.MU_STATE_DIR;\n return join(xdgStateHome(homedir()), \"mu\");\n}\n\n/**\n * The mu cache directory, `$XDG_CACHE_HOME/mu` (absolute only) else\n * `~/.cache/mu`: files mu can lose at any time, such as copies of data\n * that lives elsewhere too.\n */\nexport function defaultCacheDir(): string {\n const xdg = process.env.XDG_CACHE_HOME;\n return join(xdg !== undefined && isAbsolute(xdg) ? xdg : join(homedir(), \".cache\"), \"mu\");\n}\n\n/** `$XDG_STATE_HOME`, or `<home>/.local/state` when it is unset, empty,\n * or relative: the XDG spec says such a value must be ignored, and a\n * relative one would scatter state across every cwd mu runs in. */\nexport function xdgStateHome(home: string): string {\n const xdg = process.env.XDG_STATE_HOME;\n return xdg !== undefined && isAbsolute(xdg) ? xdg : join(home, \".local\", \"state\");\n}\n","/**\n * mu pi extension: the keep-driving nudge (docs/specs/2026-10-03-keep-driving-nudge.md).\n *\n * An orchestrator that dispatched mu work and then ends its turn while\n * that work is still IN_PROGRESS gets ONE visible message quoting the\n * skill's keep-driving rule, and one continuation. If it stops again,\n * that stop stands. Not a goal loop: no re-check, no counter.\n *\n * Its only read is `mu state --json`, its only write `mu log --kind\n * nudge`; the armed set and fired flag are per-prompt scratch. The rule\n * text lives in skills/mu/SKILL.md between the keep-driving markers.\n *\n * The refute nudge: `mu task claim <id> --for` on a task whose notes\n * carry no line starting `REFUTER `, `VERDICT:` or `REFUTE-EXEMPT:`\n * (read with `mu task notes --json`) gets ONE visible message per prompt\n * listing those tasks. It informs, never continues; `review_*` tasks\n * are exempt (their brief is the fixed reviewer template).\n *\n * Its worker-side twin, the close nudge: a mu-spawned pi worker\n * ($MU_AGENT_NAME + $MU_WORKSTREAM) that settles while it still owns an\n * IN_PROGRESS task is told once to close it or say why not. Same\n * once-per-prompt rule and `MU_NUDGE=0` opt-out.\n *\n * None fire in a nested pi (mu-pi.ts decides at bind); close and refute\n * also skip a pi with no UI (`pi -p`, json), where nobody can answer.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { defaultRunner, type MuRunner } from \"./delegate.js\";\n\nexport const NUDGE_MESSAGE_TYPE = \"mu-keep-driving\";\nexport const NUDGE_LOG_KIND = \"nudge\";\nexport const CLOSE_NUDGE_MESSAGE_TYPE = \"mu-close-task\";\nexport const REFUTE_NUDGE_MESSAGE_TYPE = \"mu-refute-brief\";\nconst MARK_START = \"<!-- mu:keep-driving -->\";\nconst MARK_END = \"<!-- /mu:keep-driving -->\";\n/** Tasks named in the wait hint; the rest are counted, not listed. */\nconst WAIT_HINT_MAX = 8;\n\n/** The slice of pi's ExtensionContext the nudge reads. */\nexport type MuNudgeCtx = { mode?: string; hasUI?: boolean };\n\n/** The slice of pi's ExtensionAPI the nudge uses. */\nexport interface MuNudgeApi {\n on(\n event: \"tool_call\" | \"agent_before_settle\" | \"input\",\n handler: (event: unknown, ctx: MuNudgeCtx) => unknown,\n ): unknown;\n}\n\n/**\n * True while this pi is nested: it inherited a MU_CTL_SOCK another pi\n * serves (a `pi -p` run inside an agent's pane). Read at settle time,\n * since the bind decision lands in session_start, after registration.\n */\nexport type NestedCheck = () => boolean;\nconst notNested: NestedCheck = () => false;\n\n/** No one can answer a nudge: print or json mode. */\nfunction noUI(ctx: MuNudgeCtx | undefined): boolean {\n return ctx?.hasUI === false;\n}\n\n/** `MU_NUDGE=0` turns the nudge off. */\nexport function nudgeEnabled(env: NodeJS.ProcessEnv = process.env): boolean {\n return env.MU_NUDGE !== \"0\";\n}\n\n/** The keep-driving paragraph from SKILL.md, or undefined without the markers. */\nexport function keepDrivingRule(skillMd: string): string | undefined {\n const i = skillMd.indexOf(MARK_START);\n const j = skillMd.indexOf(MARK_END);\n if (i < 0 || j < i) return undefined;\n const text = skillMd.slice(i + MARK_START.length, j).trim();\n return text === \"\" ? undefined : text;\n}\n\n/** SKILL.md next to this file in either layout (source or dist/extension). */\nfunction readSkill(): string | undefined {\n for (const up of [\"..\", \"../..\"]) {\n const p = join(import.meta.dirname ?? \"\", up, \"skills\", \"mu\", \"SKILL.md\");\n if (existsSync(p)) return readFileSync(p, \"utf8\");\n }\n return undefined;\n}\n\n/** Leading `NAME=value` words: env assignments before the command. */\nconst ENV_ASSIGN = /^[A-Za-z_][A-Za-z0-9_]*=/;\n\n/** The args after `mu` when this segment runs mu (after any env\n * assignments), or undefined when it runs something else. */\nfunction muArgs(words: string[]): string[] | undefined {\n let at = 0;\n while (at < words.length && ENV_ASSIGN.test(words[at] ?? \"\")) at++;\n const cmd = words[at];\n if (cmd !== \"mu\" && !cmd?.endsWith(\"/mu\")) return undefined;\n return words.slice(at + 1);\n}\n\n/**\n * The workstreams a bash command dispatches mu work into, or undefined\n * when it dispatches nothing. Dispatch = `mu agent send|spawn`, or\n * `mu task claim <id> --for` (parsed by claimOf, as the refute nudge\n * does). `\"\"` stands for the default workstream (resolved by mu\n * itself: $MU_SESSION, then tmux).\n */\nexport function dispatchedWorkstreams(command: string): string[] | undefined {\n const found = new Set<string>();\n // One mu invocation per shell segment.\n for (const words of shellSegments(command)) {\n const args = muArgs(words);\n if (args === undefined) continue;\n const claim = claimOf(args);\n if (claim !== undefined) {\n if (claim.ws !== \"scratch\") found.add(claim.ws);\n continue;\n }\n if (args[0] !== \"agent\" || (args[1] !== \"send\" && args[1] !== \"spawn\")) continue;\n let ws = \"\";\n for (let k = 2; k < args.length; k++) {\n const w = args[k] ?? \"\";\n if (w === \"-w\" || w === \"--workstream\") ws = args[k + 1] ?? \"\";\n else if (w.startsWith(\"--workstream=\")) ws = w.slice(\"--workstream=\".length);\n }\n if (ws !== \"scratch\") found.add(ws);\n }\n return found.size > 0 ? [...found] : undefined;\n}\n\n/** Claim options that take a value; the task id is the first other positional. */\nconst CLAIM_VALUE_OPTS = new Set([\"--for\", \"-f\", \"-w\", \"--workstream\", \"--evidence\", \"--actor\"]);\n\n/** A heredoc body to skip: lines up to `delim` (leading tabs stripped with `<<-`). */\ntype Heredoc = { delim: string; strip: boolean };\n\n/**\n * The words of each shell segment. Quotes group words and are dropped;\n * `&&`, `||`, `;`, `|` and newlines split segments only outside\n * quotes, so a quoted `--evidence 'a | b'` stays one word. A\n * backslash-newline joins lines, and heredoc bodies are skipped: they\n * are data, not commands. A `<<<` here-string and a `<<` shift inside\n * `(( ))` arithmetic do not start a heredoc. As in bash, `((` is\n * arithmetic only when its matching close is `))`; otherwise it is\n * nested subshells, where `<<` is a heredoc. A `#` that starts a word\n * comments out the rest of the line.\n */\nexport function shellSegments(command: string): string[][] {\n const segs: string[][] = [];\n let words: string[] = [];\n let word: string | undefined;\n const heredocs: Heredoc[] = [];\n /** Index of the closing `)` of the current `(( ))` arithmetic, where `<<` is a shift. */\n let arithEnd = -1;\n const endWord = () => {\n if (word !== undefined) words.push(word);\n word = undefined;\n };\n const endSeg = () => {\n endWord();\n if (words.length > 0) segs.push(words);\n words = [];\n };\n /** Skip the pending heredoc bodies that start after the newline at `i`;\n * returns the index of the last newline consumed. */\n const skipHeredocs = (i: number): number => {\n for (const h of heredocs.splice(0)) {\n while (i < command.length) {\n const eol = command.indexOf(\"\\n\", i + 1);\n const end = eol < 0 ? command.length : eol;\n const line = command.slice(i + 1, end);\n i = end;\n if ((h.strip ? line.replace(/^\\t+/, \"\") : line) === h.delim) break;\n }\n }\n return i;\n };\n for (let i = 0; i < command.length; i++) {\n const c = command[i] ?? \"\";\n if (c === \"'\" || c === '\"') {\n const close = command.indexOf(c, i + 1);\n const end = close < 0 ? command.length : close;\n word = (word ?? \"\") + command.slice(i + 1, end);\n i = end;\n } else if (c === \"\\\\\" && command[i + 1] === \"\\n\") {\n i++; // line continuation: neither a word nor a segment break\n } else if (c === \"\\\\\" && i + 1 < command.length) {\n word = (word ?? \"\") + command[++i];\n } else if (c === \"#\" && word === undefined) {\n const eol = command.indexOf(\"\\n\", i);\n i = (eol < 0 ? command.length : eol) - 1; // a comment: the newline still ends the segment\n } else if (c === \"(\" && command[i + 1] === \"(\" && i > arithEnd) {\n arithEnd = arithmeticEnd(command, i);\n word = `${word ?? \"\"}((`;\n i++;\n } else if (command.startsWith(\"<<<\", i)) {\n endWord(); // a here-string: its word is data on the same line\n i += 2;\n } else if (c === \"<\" && command[i + 1] === \"<\" && i > arithEnd) {\n // `<<[-] DELIM`: the delimiter may be quoted; its body starts on the next line.\n endWord();\n const m = /^<<(-?)[ \\t]*('([^']*)'|\"([^\"]*)\"|[^\\s;&|<>()]+)/.exec(command.slice(i));\n if (!m) {\n i++;\n continue;\n }\n const delim = m[3] ?? m[4] ?? (m[2] ?? \"\").replace(/\\\\/g, \"\");\n heredocs.push({ delim, strip: m[1] === \"-\" });\n i += m[0].length - 1;\n } else if (c === \";\" || c === \"|\" || c === \"\\n\" || (c === \"&\" && command[i + 1] === \"&\")) {\n if (c !== \";\" && c !== \"\\n\" && command[i + 1] === c) i++;\n endSeg();\n if (c === \"\\n\" && heredocs.length > 0) i = skipHeredocs(i);\n } else if (/\\s/.test(c)) {\n endWord();\n } else {\n word = (word ?? \"\") + c;\n }\n }\n endSeg();\n return segs;\n}\n\n/**\n * For the `((` at `open`: the index of the `)` that closes it when the\n * matching close is a `))` pair (arithmetic), else -1 (nested\n * subshells, or unclosed). Bash decides `((` the same way.\n */\nfunction arithmeticEnd(command: string, open: number): number {\n let depth = 0;\n for (let i = open + 2; i < command.length; i++) {\n const c = command[i];\n if (c === \"'\" || c === '\"') {\n const close = command.indexOf(c, i + 1);\n if (close < 0) return -1;\n i = close;\n } else if (c === \"\\\\\") {\n i++;\n } else if (c === \"(\") {\n depth++;\n } else if (c === \")\") {\n if (depth > 0) depth--;\n else return command[i + 1] === \")\" ? i + 1 : -1;\n }\n }\n return -1;\n}\n\n/** The task a `mu task claim <id> --for` dispatches, from the args after\n * `mu`, as `{ ws, id }`; undefined for any other mu command. */\nfunction claimOf(args: string[]): { ws: string; id: string } | undefined {\n if (args[0] !== \"task\" || args[1] !== \"claim\") return undefined;\n let ws = \"\";\n let id: string | undefined;\n let isFor = false;\n for (let k = 2; k < args.length; k++) {\n const w = args[k] ?? \"\";\n const [opt, eq] = w.startsWith(\"--\") && w.includes(\"=\") ? w.split(\"=\", 2) : [w, undefined];\n if (opt === \"--for\" || opt === \"-f\") isFor = true;\n if (opt === \"-w\" || opt === \"--workstream\") ws = eq ?? args[k + 1] ?? \"\";\n if (CLAIM_VALUE_OPTS.has(opt ?? \"\")) {\n if (eq === undefined) k++;\n } else if (id === undefined && !w.startsWith(\"-\")) id = w;\n }\n if (!isFor || id === undefined) return undefined;\n const slash = id.indexOf(\"/\");\n if (slash >= 0) {\n if (ws === \"\") ws = id.slice(0, slash);\n id = id.slice(slash + 1);\n }\n return { ws, id };\n}\n\n/**\n * The tasks a bash command dispatches with `mu task claim <id> --for`,\n * as `{ ws, id }`. `ws` is `\"\"` for the default workstream; a qualified\n * `<ws>/<id>` splits. `scratch` is skipped, like dispatchedWorkstreams.\n */\nexport function dispatchedTasks(command: string): { ws: string; id: string }[] {\n const out: { ws: string; id: string }[] = [];\n for (const words of shellSegments(command)) {\n const args = muArgs(words);\n const claim = args === undefined ? undefined : claimOf(args);\n if (claim !== undefined && claim.ws !== \"scratch\") out.push(claim);\n }\n return out;\n}\n\ntype Card = { workstreamName?: string; inProgress?: { name?: string }[] };\n/** `mu state --json` prints one bare card for one workstream, and\n * `{ workstreams: [...] }` for several (or none named). */\ntype StateJson = Card & { workstreams?: Card[] };\n\n/** IN_PROGRESS task refs per workstream, from `mu state --json`. */\nasync function inProgress(run: MuRunner, workstreams: string[]): Promise<string[] | undefined> {\n const named = workstreams.filter((w) => w !== \"\");\n const args = [\"state\", \"--json\", \"--events\", \"0\"];\n for (const w of named) args.push(\"-w\", w);\n const r = await run(args);\n if (r.code !== 0) return undefined;\n let json: StateJson;\n try {\n json = JSON.parse(r.stdout) as StateJson;\n } catch {\n return undefined;\n }\n const cards = json.workstreams ?? [json];\n const refs: string[] = [];\n for (const ws of cards) {\n for (const t of ws.inProgress ?? []) {\n if (t.name) refs.push(`${ws.workstreamName ?? \"\"}/${t.name}`);\n }\n }\n return refs;\n}\n\n/** The nudge text: the rule verbatim, then the live count and the wait. */\nexport function nudgeText(rule: string, refs: string[]): string {\n const shown = refs.slice(0, WAIT_HINT_MAX).join(\" \");\n const more = refs.length > WAIT_HINT_MAX ? ` (+${refs.length - WAIT_HINT_MAX} more)` : \"\";\n return [\n `[mu] ${rule}`,\n \"\",\n `${refs.length} task(s) IN_PROGRESS. Next: mu task wait ${shown} --first --on-stall exit --json${more}`,\n ].join(\"\\n\");\n}\n\n/** Write a `mu log` breadcrumb without holding the settle for it: the\n * nudge's message does not depend on the log line. */\nfunction breadcrumb(run: MuRunner, args: string[]): void {\n void run(args).catch(() => {});\n}\n\ntype SettleResult = { entries?: unknown[]; continue?: boolean } | undefined;\ntype SettleHandler = (event: unknown, ctx: MuNudgeCtx) => unknown;\n\n/**\n * A view of `pi` whose `agent_before_settle` handlers run in PARALLEL\n * behind one real handler. pi awaits boundary handlers one after the\n * other, and each nudge awaits a mu subprocess, so three nudges held the\n * settle (and every `mu agent wait` on it) for the sum of their calls.\n * The merged result appends every handler's entries to the event's\n * (pi replaces `entries` with each handler's return, so separate\n * handlers dropped all but the last nudge) and continues when any asks.\n * A nudge that throws still reaches pi's extension-error path: after the\n * merged handler, one reporter handler per nudge rethrows that nudge's\n * error, so pi reports each failure (as it did when every nudge was its\n * own handler) while the other nudges' entries are still delivered.\n * Call `flush()` after registering the nudges.\n */\nexport function parallelSettle(pi: MuNudgeApi): { api: MuNudgeApi; flush(): void } {\n const handlers: SettleHandler[] = [];\n const api: MuNudgeApi = {\n on(event, handler) {\n if (event === \"agent_before_settle\") handlers.push(handler);\n else pi.on(event, handler);\n },\n };\n // Errors of the last settle, by handler index; each reporter takes its own.\n let errors: (unknown[] | undefined)[] = [];\n return {\n api,\n flush() {\n if (handlers.length === 0) return;\n pi.on(\"agent_before_settle\", async (event, ctx) => {\n errors = handlers.map(() => undefined);\n const results = await Promise.all(\n handlers.map(async (h, i) => {\n try {\n return (await h(event, ctx)) as SettleResult;\n } catch (err) {\n errors[i] = [err]; // reported by reporter i, after the merge\n return undefined;\n }\n }),\n );\n const fired = results.filter((r) => r !== undefined);\n if (fired.length === 0) return undefined;\n const prior = (event as { entries?: unknown[] } | null)?.entries ?? [];\n return {\n entries: [...prior, ...fired.flatMap((r) => r.entries ?? [])],\n ...(fired.some((r) => r.continue === true) ? { continue: true } : {}),\n };\n });\n handlers.forEach((_, i) => {\n pi.on(\"agent_before_settle\", () => {\n const err = errors[i];\n errors[i] = undefined;\n if (err !== undefined) throw err[0];\n return undefined;\n });\n });\n },\n };\n}\n\nfunction outcomeOf(event: unknown): unknown {\n return typeof event === \"object\" && event !== null\n ? (event as { outcome?: unknown }).outcome\n : undefined;\n}\n\nfunction bashCommand(event: unknown): string | undefined {\n if (typeof event !== \"object\" || event === null) return undefined;\n const e = event as { toolName?: unknown; input?: { command?: unknown } };\n return e.toolName === \"bash\" && typeof e.input?.command === \"string\"\n ? e.input.command\n : undefined;\n}\n\nexport function registerNudge(\n pi: MuNudgeApi,\n run: MuRunner = defaultRunner(),\n skillMd: string | undefined = readSkill(),\n nested: NestedCheck = notNested,\n): void {\n if (!nudgeEnabled()) return;\n const rule = skillMd === undefined ? undefined : keepDrivingRule(skillMd);\n if (rule === undefined) return; // no markers: nothing true to quote\n\n const armed = new Set<string>();\n let fired = false;\n\n pi.on(\"input\", () => {\n armed.clear();\n fired = false;\n });\n\n pi.on(\"tool_call\", (event) => {\n const cmd = bashCommand(event);\n if (cmd === undefined) return;\n for (const ws of dispatchedWorkstreams(cmd) ?? []) armed.add(ws);\n });\n\n pi.on(\"agent_before_settle\", async (event) => {\n if (fired || armed.size === 0 || nested()) return;\n if (outcomeOf(event) !== \"completed\") return; // Esc or an error: stop\n fired = true; // once per prompt, even if the check below fails\n const refs = await inProgress(run, [...armed]);\n if (refs === undefined || refs.length === 0) return;\n const text = nudgeText(rule, refs);\n const logWs = [...armed].find((w) => w !== \"\");\n breadcrumb(run, [\n \"log\",\n ...(logWs ? [\"-w\", logWs] : []),\n \"--kind\",\n NUDGE_LOG_KIND,\n `keep-driving: ${refs.length} in progress`,\n ]);\n return {\n entries: [\n { type: \"custom_message\", customType: NUDGE_MESSAGE_TYPE, content: text, display: true },\n ],\n continue: true,\n };\n });\n}\n\n/** The mu-spawned worker this pi runs as, or undefined outside mu. */\nexport function workerIdentity(\n env: NodeJS.ProcessEnv = process.env,\n): { agent: string; workstream: string } | undefined {\n const agent = env.MU_AGENT_NAME;\n const workstream = env.MU_WORKSTREAM;\n if (!agent || !workstream || workstream === \"scratch\") return undefined;\n return { agent, workstream };\n}\n\n/** IN_PROGRESS task names owned by `agent`, from `mu task owned-by --json`. */\nasync function ownedInProgress(\n run: MuRunner,\n agent: string,\n workstream: string,\n): Promise<string[] | undefined> {\n const r = await run([\"task\", \"owned-by\", agent, \"-w\", workstream, \"--json\"]);\n if (r.code !== 0) return undefined;\n try {\n const json = JSON.parse(r.stdout) as { items?: { name?: string; status?: string }[] };\n return (json.items ?? []).flatMap((t) =>\n t.status === \"IN_PROGRESS\" && t.name ? [t.name] : [],\n );\n } catch {\n return undefined;\n }\n}\n\n/** The close-nudge text: name each task and the two ways out. */\nexport function closeNudgeText(workstream: string, names: string[]): string {\n const close = names\n .map((n) => `mu task close ${n} -w ${workstream} --evidence \"<what you verified>\"`)\n .join(\"\\n \");\n return [\n `[mu] You are stopping while you still own ${names.map((n) => `${workstream}/${n}`).join(\", \")} (IN_PROGRESS).`,\n \"If the work is done and verified, close it now:\",\n ` ${close}`,\n \"If you are blocked or need an answer, say so in one line and stop; the orchestrator will read your pane.\",\n ].join(\"\\n\");\n}\n\nexport function registerCloseNudge(\n pi: MuNudgeApi,\n run: MuRunner = defaultRunner(),\n env: NodeJS.ProcessEnv = process.env,\n nested: NestedCheck = notNested,\n): void {\n if (!nudgeEnabled(env)) return;\n const me = workerIdentity(env);\n if (me === undefined) return;\n let fired = false;\n\n pi.on(\"input\", () => {\n fired = false;\n });\n\n pi.on(\"agent_before_settle\", async (event, ctx) => {\n if (fired || nested() || noUI(ctx)) return; // nested: workerIdentity is the parent's\n if (outcomeOf(event) !== \"completed\") return;\n fired = true;\n const names = await ownedInProgress(run, me.agent, me.workstream);\n if (names === undefined || names.length === 0) return;\n breadcrumb(run, [\n \"log\",\n \"-w\",\n me.workstream,\n \"--kind\",\n NUDGE_LOG_KIND,\n `close: ${me.agent} settled owning ${names.join(\", \")}`,\n ]);\n return {\n entries: [\n {\n type: \"custom_message\",\n customType: CLOSE_NUDGE_MESSAGE_TYPE,\n content: closeNudgeText(me.workstream, names),\n display: true,\n },\n ],\n continue: true,\n };\n });\n}\n\n/** A note counts as a refute decision only when a line starts with a marker. */\nconst REFUTE_MARK = /^(REFUTER |VERDICT:|REFUTE-EXEMPT:)/m;\n\n/** True when the task's notes hold a refute decision; undefined if unreadable. */\nasync function briefRefuted(run: MuRunner, ws: string, id: string): Promise<boolean | undefined> {\n const r = await run([\"task\", \"notes\", id, ...(ws ? [\"-w\", ws] : []), \"--json\"]);\n if (r.code !== 0) return undefined;\n try {\n const json = JSON.parse(r.stdout) as { items?: { content?: string }[] };\n return (json.items ?? []).some((n) => REFUTE_MARK.test(n.content ?? \"\"));\n } catch {\n return undefined;\n }\n}\n\n/** The refute-nudge text: name each task and the two ways out. */\nexport function refuteNudgeText(refs: string[]): string {\n return `[mu] dispatched ${refs.join(\", \")} with an unrefuted brief: refute it (delegate, record) or note REFUTE-EXEMPT: <why>`;\n}\n\nexport function registerRefuteNudge(\n pi: MuNudgeApi,\n run: MuRunner = defaultRunner(),\n nested: NestedCheck = notNested,\n): void {\n if (!nudgeEnabled()) return;\n const armed = new Map<string, { ws: string; id: string }>();\n let fired = false;\n\n pi.on(\"input\", () => {\n armed.clear();\n fired = false;\n });\n\n pi.on(\"tool_call\", (event) => {\n const cmd = bashCommand(event);\n if (cmd === undefined) return;\n for (const t of dispatchedTasks(cmd)) {\n if (!t.id.startsWith(\"review_\")) armed.set(`${t.ws}/${t.id}`, t);\n }\n });\n\n pi.on(\"agent_before_settle\", async (event, ctx) => {\n if (fired || armed.size === 0 || nested() || noUI(ctx)) return;\n if (outcomeOf(event) !== \"completed\") return;\n fired = true;\n // One read per armed task, all at once: the settle waits for the slowest.\n const tasks = [...armed];\n const refuted = await Promise.all(tasks.map(([, t]) => briefRefuted(run, t.ws, t.id)));\n const refs = tasks.flatMap(([ref], i) => (refuted[i] === false ? [ref] : []));\n if (refs.length === 0) return;\n const logWs = [...armed.values()].find((t) => t.ws !== \"\")?.ws;\n breadcrumb(run, [\n \"log\",\n ...(logWs ? [\"-w\", logWs] : []),\n \"--kind\",\n NUDGE_LOG_KIND,\n `refute: ${refs.join(\", \")}`,\n ]);\n return {\n entries: [\n {\n type: \"custom_message\",\n customType: REFUTE_NUDGE_MESSAGE_TYPE,\n content: refuteNudgeText(refs),\n display: true,\n },\n ],\n };\n });\n}\n"],"mappings":"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","names":["existsSync","mkdirSync","readFileSync","statSync","join","fileURLToPath","join","join","existsSync","join","join","existsSync","join","existsSync","readFileSync","statSync","fileURLToPath","mkdirSync"]}
1
+ {"version":3,"sources":["../../extension/mu-pi.ts","../../src/ctl/protocol.ts","../../extension/delegate.ts","../../src/state-dir.ts","../../extension/nudge.ts"],"sourcesContent":["/**\n * mu pi extension: serves the per-agent control socket from inside the\n * agent's interactive pi, so mu gets exact send / status / wait without\n * replacing the TUI or scraping the pane.\n *\n * Inert unless `$MU_CTL_SOCK` is set (mu injects it at spawn). Imports\n * nothing from mu except the protocol, and nothing from pi: the pi API is\n * typed structurally below so pi stays a peer, not a dependency.\n */\nimport {\n chmodSync,\n existsSync,\n linkSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n rmSync,\n statSync,\n} from \"node:fs\";\nimport { connect, createServer, type Server, type Socket } from \"node:net\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n CTL_COMMANDS,\n CTL_OPS,\n CTL_PROTOCOL_VERSION,\n type CtlCommandName,\n type CtlReply,\n type CtlState,\n encode,\n LineDecoder,\n UNKNOWN_OP_PREFIX,\n} from \"../src/ctl/protocol.js\";\nimport {\n type DelegateCtx,\n defaultRunner,\n type MuDelegateApi,\n type MuRunner,\n registerDelegate,\n} from \"./delegate.js\";\nimport {\n type MuNudgeApi,\n parallelSettle,\n registerCloseNudge,\n registerNudge,\n registerRefuteNudge,\n} from \"./nudge.js\";\n\n/** The mu package version, baked in by tsup's `define`; absent when run from source. */\ndeclare const __MU_VERSION__: string | undefined;\nconst EXT_VERSION = typeof __MU_VERSION__ === \"string\" ? __MU_VERSION__ : undefined;\n\n/** The slice of pi's ExtensionContext this extension uses. */\nexport interface MuPiContext extends DelegateCtx {\n /** pi's session manager; only the session file is read. */\n sessionManager?: { getSessionFile(): string | undefined };\n isIdle(): boolean;\n hasPendingMessages(): boolean;\n abort(): void;\n}\n\n/** The slice of pi's ReplacedSessionContext: bound to the NEW session. */\nexport interface MuPiReplacedContext extends MuPiContext {\n sendUserMessage(text: string): Promise<void>;\n}\n\n/** The slice of pi's ExtensionCommandContext (command handlers only). */\nexport interface MuPiCommandContext extends MuPiContext {\n newSession(options?: {\n withSession?: (ctx: MuPiReplacedContext) => Promise<void>;\n }): Promise<{ cancelled: boolean }>;\n reload(): Promise<void>;\n compact(options?: {\n customInstructions?: string;\n onComplete?: (result: unknown) => void;\n onError?: (error: Error) => void;\n }): void;\n}\n\n/** The slice of pi's ExtensionAPI this extension uses. */\nexport interface MuPiApi extends MuDelegateApi {\n on(\n event:\n | \"session_start\"\n | \"session_shutdown\"\n | \"session_before_compact\"\n | \"agent_start\"\n | \"agent_end\"\n | \"agent_settled\"\n | \"message_start\"\n | \"resources_discover\"\n | Parameters<MuNudgeApi[\"on\"]>[0],\n handler: (event: unknown, ctx: MuPiContext) => unknown,\n ): unknown;\n sendUserMessage(\n text: string,\n options?: { deliverAs?: \"steer\" | \"followUp\"; expandPromptTemplates?: boolean },\n ): void | Promise<void>;\n registerCommand(\n name: string,\n options: {\n description: string;\n handler: (args: string, ctx: MuPiCommandContext) => Promise<void>;\n },\n ): void;\n}\n\n/** Internal command behind the `fresh` op: new session + prompt, inside pi. */\nexport const FRESH_COMMAND = \"mu-fresh\";\n/** The extension's own bound on a fresh op that never reaches agent_start. */\nexport const FRESH_TIMEOUT_MS = 30_000;\n/** Internal command behind the `command` op, per session command: `mu-new`, ... */\nexport function commandName(name: CtlCommandName): string {\n return `mu-${name}`;\n}\n/** The extension's own bound on a `command` op that never completes. */\nexport const COMMAND_TIMEOUT_MS = 30_000;\n/** Cap on `lastText` in a wait reply, in UTF-8 bytes (before the marker). */\nexport const LAST_TEXT_MAX_BYTES = 64 * 1024;\nexport const LAST_TEXT_TRUNCATED = \"[truncated, see pane]\";\n/** How long session_start waits for another pi to answer on the socket path. */\nexport const LIVE_PROBE_MS = 500;\n\ntype Reply = CtlReply;\nconst V = CTL_PROTOCOL_VERSION;\n\nfunction fail(error: string): Reply {\n return { v: V, ok: false, error };\n}\n\n/** Best effort: the version of the pi package running this process. */\nfunction detectPiVersion(): string | undefined {\n try {\n const entry = process.argv[1];\n if (!entry) return undefined;\n let dir = dirname(realpathSync(entry));\n for (let i = 0; i < 6; i++) {\n const pkgPath = join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg: unknown = JSON.parse(readFileSync(pkgPath, \"utf8\"));\n if (typeof pkg === \"object\" && pkg !== null) {\n const { name, version } = pkg as { name?: unknown; version?: unknown };\n if (typeof name === \"string\" && /pi/.test(name) && typeof version === \"string\") {\n return version;\n }\n }\n }\n const up = dirname(dir);\n if (up === dir) break;\n dir = up;\n }\n } catch {\n // Unknown version is reported as absent, never as an error.\n }\n return undefined;\n}\n\nfunction str(o: Record<string, unknown>, k: string): string | undefined {\n const x = o[k];\n return typeof x === \"string\" ? x : undefined;\n}\n\nfunction num(o: Record<string, unknown>, k: string): number | undefined {\n const x = o[k];\n return typeof x === \"number\" && Number.isFinite(x) ? x : undefined;\n}\n\n/** A `fresh` op in flight: its prompt and the reply it is waiting to send. */\ntype PendingFresh = {\n text: string;\n /** Set once the new session exists, so its agent_start is the prompt's. */\n armed: boolean;\n settle: (r: Reply) => void;\n};\n\n/** A `command` op in flight: the session command and its pending reply. */\ntype PendingCommand = {\n name: CtlCommandName;\n instructions?: string;\n /** reload: set by the session_start (reason reload) the reload produced. */\n reloaded: boolean;\n settle: (r: Reply) => void;\n};\n\n/**\n * Process-global state, keyed by socket path. pi re-runs this factory\n * for every session (a /new or /mu-fresh replaces the extension runtime),\n * so the socket server, the run counters and an in-flight fresh must\n * outlive any one runtime. Each runtime refreshes `pi` and `handle`.\n */\ntype Shared = {\n server?: Server;\n /** Set by bind(): another pi serves the socket, so this pi is not the agent. */\n nested?: boolean;\n /** Inode of the socket file this process bound; the only file it may unlink. */\n ino?: number;\n conns: Set<Socket>;\n waiters: Set<() => void>;\n state: CtlState;\n since: number;\n runs: number;\n /** Final assistant text of the last settled run; served by `wait`. */\n lastText: string;\n /** Captured on agent_end, published to `lastText` on agent_settled. */\n endText?: string;\n /** Error that ended the last settled run, if any; served by `wait`. */\n lastError?: string;\n endError?: string;\n /** Session file of the last settled run; served by `wait`. */\n sessionFile?: string;\n ctx?: MuPiContext;\n pi: MuPiApi;\n handle: (req: Record<string, unknown>, conn: Socket) => Promise<Reply>;\n fresh?: PendingFresh;\n command?: PendingCommand;\n};\n\nconst SHARED = Symbol.for(\"mu.pi.ctl\");\ntype SharedMap = Map<string, Shared>;\n\nfunction sharedMap(): SharedMap {\n const g = globalThis as { [SHARED]?: SharedMap };\n g[SHARED] ??= new Map();\n return g[SHARED];\n}\n\n/**\n * Text of the last assistant message in an agent_end event's `messages`:\n * its text parts joined, no tool calls or thinking. \"\" when there is none.\n */\nexport function lastAssistantText(event: unknown): string {\n const msgs =\n typeof event === \"object\" && event !== null\n ? (event as { messages?: unknown }).messages\n : undefined;\n if (!Array.isArray(msgs)) return \"\";\n for (let i = msgs.length - 1; i >= 0; i--) {\n const m: unknown = msgs[i];\n if (typeof m !== \"object\" || m === null) continue;\n const { role, content } = m as { role?: unknown; content?: unknown };\n if (role !== \"assistant\") continue;\n if (typeof content === \"string\") return capText(content);\n if (!Array.isArray(content)) return \"\";\n const parts = content.flatMap((c: unknown) => {\n if (typeof c !== \"object\" || c === null) return [];\n const { type, text } = c as { type?: unknown; text?: unknown };\n return type === \"text\" && typeof text === \"string\" ? [text] : [];\n });\n return capText(parts.join(\"\"));\n }\n return \"\";\n}\n\n/** The final assistant message's error, when the run stopped on one\n * (pi's own retries exhausted: overloaded, connection, auth). */\nexport function lastAssistantError(event: unknown): string | undefined {\n const msgs =\n typeof event === \"object\" && event !== null\n ? (event as { messages?: unknown }).messages\n : undefined;\n if (!Array.isArray(msgs)) return undefined;\n for (let i = msgs.length - 1; i >= 0; i--) {\n const m: unknown = msgs[i];\n if (typeof m !== \"object\" || m === null) continue;\n const { role, stopReason, errorMessage } = m as {\n role?: unknown;\n stopReason?: unknown;\n errorMessage?: unknown;\n };\n if (role !== \"assistant\") continue;\n if (stopReason !== \"error\") return undefined;\n return typeof errorMessage === \"string\" && errorMessage !== \"\"\n ? capText(errorMessage)\n : \"unknown error\";\n }\n return undefined;\n}\n\nfunction capText(text: string): string {\n if (Buffer.byteLength(text, \"utf8\") <= LAST_TEXT_MAX_BYTES) return text;\n // Cut on bytes; drop a code point split by the cut.\n const cut = Buffer.from(text, \"utf8\").subarray(0, LAST_TEXT_MAX_BYTES).toString(\"utf8\");\n return `${cut.replace(/\\uFFFD$/, \"\")}\\n${LAST_TEXT_TRUNCATED}`;\n}\n\n/** Inode at `path`, or undefined when there is no file. */\nfunction inodeOf(path: string): number | undefined {\n try {\n return statSync(path).ino;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Whether some process is serving `path`. Refused / missing means a stale\n * file. A connect that neither succeeds nor fails in time counts as live:\n * never steal a socket on a guess.\n */\nfunction socketIsLive(path: string): Promise<boolean> {\n return new Promise((resolve) => {\n const c = connect(path);\n const done = (live: boolean) => {\n clearTimeout(timer);\n c.destroy();\n resolve(live);\n };\n const timer = setTimeout(() => done(true), LIVE_PROBE_MS);\n c.once(\"connect\", () => done(true));\n c.once(\"error\", (e: NodeJS.ErrnoException) =>\n done(e.code !== \"ENOENT\" && e.code !== \"ECONNREFUSED\"),\n );\n });\n}\n\n/** Per-process counter so a rebind never reuses a temp name a closing server owns. */\nlet bindSeq = 0;\n\nfunction reasonOf(event: unknown): string | undefined {\n const r =\n typeof event === \"object\" && event !== null\n ? (event as { reason?: unknown }).reason\n : undefined;\n return typeof r === \"string\" ? r : undefined;\n}\n\n/** The package's `prompts/` dir: two up from dist/extension/, one up from extension/. */\nexport function promptsDir(from: string = import.meta.url): string | undefined {\n let here: string;\n try {\n here = dirname(fileURLToPath(from));\n } catch {\n return undefined;\n }\n for (const up of [\"..\", \"../..\"]) {\n const d = join(here, up, \"prompts\");\n if (existsSync(join(d, \"ultrathink.md\"))) return d;\n }\n return undefined;\n}\n\n/** The recipe slash commands (`/ultrathink`, `/mu-review`, ...): prompt\n * templates shipped in the package, so they upgrade with mu. */\nfunction registerPrompts(pi: MuPiApi): void {\n pi.on(\"resources_discover\", () => {\n const d = promptsDir();\n if (!d) return {};\n const paths = readdirSync(d)\n .filter((f) => f.endsWith(\".md\"))\n .sort()\n .map((f) => join(d, f));\n return { promptPaths: paths };\n });\n}\n\nexport default function muPi(pi: MuPiApi, run: MuRunner = defaultRunner()): void {\n registerDelegate(pi, run);\n registerPrompts(pi);\n // Identity follows the bind: a pi that finds MU_CTL_SOCK served by\n // another pi is nested and gets none of the agent's nudges.\n const nested = serveCtl(pi);\n // The three nudges' settle checks run in parallel, as one handler.\n const settle = parallelSettle(pi);\n registerNudge(settle.api, run, undefined, nested);\n registerCloseNudge(settle.api, run, process.env, nested);\n registerRefuteNudge(settle.api, run, nested);\n settle.flush();\n}\n\n/**\n * Child side: serve `$MU_CTL_SOCK` for the mu that spawned this pi.\n * Returns whether this pi is nested (another pi serves the socket), read\n * from the process-global state so a reloaded runtime sees the decision.\n */\nfunction serveCtl(pi: MuPiApi): () => boolean {\n const sock = process.env.MU_CTL_SOCK;\n if (!sock) return () => false;\n const sockPath: string = sock;\n const piVersion = detectPiVersion();\n\n const map = sharedMap();\n const existing = map.get(sockPath);\n const g: Shared = existing ?? {\n conns: new Set(),\n waiters: new Set(),\n state: \"idle\",\n since: Date.now(),\n runs: 0,\n lastText: \"\",\n pi,\n handle,\n };\n g.pi = pi;\n g.handle = handle;\n map.set(sockPath, g);\n\n const status = () => ({\n state: g.state,\n since: g.since,\n runs: g.runs,\n pending: g.ctx?.hasPendingMessages() ?? false,\n ...sessionFileOf(g.ctx),\n });\n\n const settleFresh = (r: Reply) => {\n const f = g.fresh;\n if (!f) return;\n g.fresh = undefined;\n f.settle(r);\n };\n\n const settleCommand = (r: Reply) => {\n const c = g.command;\n if (!c) return;\n g.command = undefined;\n c.settle(r);\n };\n\n pi.on(\"agent_start\", (_e, c) => {\n g.ctx = c;\n g.state = \"busy\";\n g.since = Date.now();\n // The new session's run started: the fresh prompt landed.\n if (g.fresh?.armed) settleFresh({ v: V, ok: true, ...status() });\n });\n\n // A settled run can span several low-level runs (retry, follow-up):\n // the last agent_end before the settle holds the final answer.\n pi.on(\"agent_end\", (e) => {\n g.endText = lastAssistantText(e);\n g.endError = lastAssistantError(e);\n });\n\n /** The session file of `c`, as a spreadable field; {} when unknown. */\n function sessionFileOf(c: MuPiContext | undefined): { sessionFile?: string } {\n try {\n const f = c?.sessionManager?.getSessionFile();\n return f ? { sessionFile: f } : {};\n } catch {\n return {}; // stale ctx: the pointer is a convenience\n }\n }\n\n pi.on(\"agent_settled\", (_e, c) => {\n g.ctx = c;\n g.state = \"idle\";\n g.since = Date.now();\n g.runs++;\n g.lastText = g.endText ?? \"\";\n g.endText = undefined;\n g.lastError = g.endError;\n g.endError = undefined;\n g.sessionFile = sessionFileOf(c).sessionFile;\n for (const w of [...g.waiters]) w();\n });\n\n pi.registerCommand(FRESH_COMMAND, {\n description: \"mu internal: new session + the prompt mu queued (run by mu agent send --fresh)\",\n handler: async (_args, ctx) => {\n const f = g.fresh;\n if (!f) return; // typed by hand: nothing queued\n try {\n const r = await ctx.newSession({\n withSession: async (c) => {\n g.ctx = c;\n f.armed = true;\n await c.sendUserMessage(f.text);\n },\n });\n if (r.cancelled) settleFresh(fail(\"new session was cancelled\"));\n } catch (e) {\n settleFresh(fail(e instanceof Error ? e.message : String(e)));\n }\n // The run finished without an agent_start we saw: still landed.\n settleFresh({ v: V, ok: true, ...status() });\n },\n });\n\n // A compaction we asked for has started: reply now, not after the\n // summary call. Errors before this point (e.g. \"Nothing to compact\")\n // reach the reply through compact's onError.\n pi.on(\"session_before_compact\", () => {\n if (g.command?.name === \"compact\") settleCommand({ v: V, ok: true, ...status() });\n });\n\n /** Run the queued session command `name` with pi's command context. */\n async function runCommand(name: CtlCommandName, ctx: MuPiCommandContext): Promise<void> {\n const c = g.command;\n if (c?.name !== name) return; // typed by hand: nothing queued\n const ok = () => settleCommand({ v: V, ok: true, ...status() });\n const failWith = (e: unknown) =>\n settleCommand(fail(e instanceof Error ? e.message : String(e)));\n try {\n if (name === \"new\") {\n const r = await ctx.newSession();\n if (r.cancelled) settleCommand(fail(\"new session was cancelled\"));\n else ok();\n } else if (name === \"reload\") {\n await ctx.reload();\n // pi's reload returns quietly when it refuses (streaming, compacting).\n if (c.reloaded) ok();\n else settleCommand(fail(\"pi did not reload (busy or compacting)\"));\n } else {\n ctx.compact({\n ...(c.instructions !== undefined ? { customInstructions: c.instructions } : {}),\n onComplete: ok,\n onError: failWith,\n });\n }\n } catch (e) {\n failWith(e);\n }\n }\n\n for (const name of CTL_COMMANDS) {\n pi.registerCommand(commandName(name), {\n description: `mu internal: /${name} requested over the control socket (mu agent send '/${name}')`,\n handler: (_args, ctx) => runCommand(name, ctx),\n });\n }\n\n function command(req: Record<string, unknown>): Promise<Reply> | Reply {\n const name = CTL_COMMANDS.find((n) => n === req.name);\n if (name === undefined) {\n return fail(`command must be one of ${CTL_COMMANDS.join(\", \")}`);\n }\n if (g.fresh || g.command) return fail(\"a fresh send or command is already in progress\");\n const busy = !(g.ctx?.isIdle() ?? g.state === \"idle\");\n if (busy && req.force !== true) return fail(\"busy\");\n const instructions = str(req, \"instructions\");\n return new Promise<Reply>((resolve) => {\n const timer = setTimeout(() => settleCommand(fail(`/${name} timed out`)), COMMAND_TIMEOUT_MS);\n g.command = {\n name,\n ...(instructions !== undefined ? { instructions } : {}),\n reloaded: false,\n settle: (r) => {\n clearTimeout(timer);\n resolve(r);\n },\n };\n Promise.resolve(\n g.pi.sendUserMessage(`/${commandName(name)}`, { expandPromptTemplates: true }),\n ).catch((e: unknown) => settleCommand(fail(e instanceof Error ? e.message : String(e))));\n });\n }\n\n function fresh(req: Record<string, unknown>): Promise<Reply> | Reply {\n const text = str(req, \"text\");\n if (text === undefined) return fail(\"fresh needs a string text\");\n if (g.fresh || g.command) return fail(\"a fresh send or command is already in progress\");\n const busy = !(g.ctx?.isIdle() ?? g.state === \"idle\");\n if (busy && req.force !== true) return fail(\"busy\");\n return new Promise<Reply>((resolve) => {\n const timer = setTimeout(() => settleFresh(fail(\"fresh timed out\")), FRESH_TIMEOUT_MS);\n g.fresh = {\n text,\n armed: false,\n settle: (r) => {\n clearTimeout(timer);\n resolve(r);\n },\n };\n // expandPromptTemplates dispatches extension commands, even mid-run.\n Promise.resolve(\n g.pi.sendUserMessage(`/${FRESH_COMMAND}`, { expandPromptTemplates: true }),\n ).catch((e: unknown) => settleFresh(fail(e instanceof Error ? e.message : String(e))));\n });\n }\n\n async function handle(req: Record<string, unknown>, conn: Socket): Promise<Reply> {\n switch (req.op) {\n case \"hello\":\n return {\n v: V,\n ok: true,\n agent: process.env.MU_AGENT_NAME,\n workstream: process.env.MU_WORKSTREAM,\n piVersion,\n ops: [...CTL_OPS],\n ...(EXT_VERSION !== undefined ? { extVersion: EXT_VERSION } : {}),\n };\n case \"status\":\n return { v: V, ok: true, ...status() };\n case \"send\": {\n const text = str(req, \"text\");\n if (text === undefined) return fail(\"send needs a string text\");\n const mode = req.mode === \"steer\" ? \"steer\" : \"followUp\";\n // Measured before dispatch: `runs` is the caller's wait baseline,\n // and a run this send starts may settle before the reply is read.\n const before = status();\n // A message sent while idle starts a run; options are only for a busy pi.\n if (g.ctx?.isIdle() ?? g.state === \"idle\") await g.pi.sendUserMessage(text);\n else await g.pi.sendUserMessage(text, { deliverAs: mode });\n return { v: V, ok: true, ...before };\n }\n case \"fresh\":\n return fresh(req);\n case \"command\":\n return command(req);\n case \"wait\":\n return wait(num(req, \"afterRuns\"), num(req, \"timeoutMs\"), conn);\n case \"abort\":\n if (!g.ctx) return fail(\"no pi context yet\");\n g.ctx.abort();\n return { v: V, ok: true, state: g.state };\n case \"interrupt\":\n return interrupt(req, conn);\n default:\n return { ...fail(`${UNKNOWN_OP_PREFIX}${String(req.op)}`), ops: [...CTL_OPS] };\n }\n }\n\n /**\n * Abort a busy turn, wait for its settle, then send `text` as a new run.\n * The waiter is registered before the abort, so a settle that lands at\n * once is not missed. `runs` is read after that settle and before the\n * send: the caller's wait baseline for the new run, not the aborted one.\n */\n async function interrupt(req: Record<string, unknown>, conn: Socket): Promise<Reply> {\n const text = str(req, \"text\");\n if (text === undefined) return fail(\"interrupt needs a string text\");\n const wasBusy = !(g.ctx?.isIdle() ?? g.state === \"idle\");\n const { pending } = status();\n if (wasBusy) {\n if (!g.ctx) return fail(\"no pi context yet\");\n const settled = wait(g.runs, num(req, \"timeoutMs\"), conn);\n g.ctx.abort();\n const w = await settled;\n if (!w.ok) return w;\n }\n const before = status();\n await g.pi.sendUserMessage(text);\n return { v: V, ok: true, ...before, pending, wasBusy };\n }\n\n const settledRun = () => ({\n lastText: g.lastText,\n ...(g.lastError !== undefined ? { lastError: g.lastError } : {}),\n ...(g.sessionFile !== undefined ? { sessionFile: g.sessionFile } : {}),\n });\n\n /** Resolve once a run past `afterRuns` has settled (any next settle when omitted). */\n function wait(afterRuns: number | undefined, timeoutMs: number | undefined, conn: Socket) {\n if (afterRuns !== undefined && g.runs > afterRuns && g.state === \"idle\") {\n return Promise.resolve<Reply>({ v: V, ok: true, ...status(), ...settledRun() });\n }\n return new Promise<Reply>((resolve) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const done = (r: Reply) => {\n g.waiters.delete(waiter);\n if (timer) clearTimeout(timer);\n conn.off(\"close\", onClose);\n resolve(r);\n };\n // A settle at or below `afterRuns` is not the run asked for: keep waiting.\n const waiter = () => {\n if (afterRuns !== undefined && g.runs <= afterRuns) return;\n done({ v: V, ok: true, ...status(), ...settledRun() });\n };\n const onClose = () => done(fail(\"client closed\"));\n g.waiters.add(waiter);\n conn.on(\"close\", onClose);\n if (timeoutMs !== undefined) timer = setTimeout(() => done(fail(\"timeout\")), timeoutMs);\n });\n }\n\n /** Created once per process; dispatches to the newest runtime's handle. */\n function onConnection(conn: Socket): void {\n g.conns.add(conn);\n conn.setEncoding(\"utf8\");\n const dec = new LineDecoder();\n let seen = false;\n conn.on(\"close\", () => g.conns.delete(conn));\n conn.on(\"error\", () => {});\n conn.on(\"data\", (chunk: string) => {\n const line = dec.push(chunk)[0];\n if (line === undefined || seen) return;\n seen = true; // one request per connection\n let req: unknown;\n try {\n req = JSON.parse(line);\n } catch {\n conn.end(encode(fail(\"bad json\")));\n return;\n }\n if (typeof req !== \"object\" || req === null) {\n conn.end(encode(fail(\"request must be an object\")));\n return;\n }\n g.handle(req as Record<string, unknown>, conn).then(\n (r) => {\n if (!conn.destroyed) conn.end(encode(r));\n },\n (e: unknown) => {\n if (!conn.destroyed) conn.end(encode(fail(e instanceof Error ? e.message : String(e))));\n },\n );\n });\n }\n\n /**\n * Bind the socket unless another pi already serves it. A nested pi (a\n * probe or `pi -p` run inside an agent's pane) inherits MU_CTL_SOCK; it\n * must leave the agent's socket alone, not unlink and take it.\n */\n async function bind(): Promise<void> {\n mkdirSync(dirname(sockPath), { recursive: true, mode: 0o700 });\n if (await socketIsLive(sockPath)) {\n g.nested = true;\n process.stderr.write(\n `mu: control socket ${sockPath} is served by another pi; nested pi: mu agent features off\\n`,\n );\n return;\n }\n rmSync(sockPath, { force: true });\n // Listen on a private name, then hard-link it into place. libuv unlinks\n // the name a server listened on when it closes, so the public path must\n // never be that name: closing would delete whatever file sits there by\n // then. link() also fails on an existing path, so a racing pi keeps it.\n const tmp = join(dirname(sockPath), `.${process.pid.toString(36)}${(++bindSeq).toString(36)}`);\n rmSync(tmp, { force: true });\n const s = createServer(onConnection);\n await new Promise<void>((resolve, reject) => {\n s.once(\"error\", reject);\n s.listen(tmp, () => {\n s.off(\"error\", reject);\n resolve();\n });\n });\n chmodSync(tmp, 0o600);\n try {\n linkSync(tmp, sockPath);\n } catch (e) {\n s.close();\n if ((e as NodeJS.ErrnoException).code !== \"EEXIST\") throw e;\n g.nested = true;\n process.stderr.write(\n `mu: control socket ${sockPath} was taken by another pi; nested pi: mu agent features off\\n`,\n );\n return;\n } finally {\n rmSync(tmp, { force: true });\n }\n g.server = s;\n g.ino = inodeOf(sockPath);\n g.nested = false;\n }\n\n pi.on(\"session_start\", async (e, c) => {\n g.ctx = c;\n if (reasonOf(e) === \"reload\" && g.command?.name === \"reload\") g.command.reloaded = true;\n const s = g.server;\n if (s) {\n // A new/resumed session keeps the same socket, while the path is ours.\n if (g.ino !== undefined && inodeOf(sockPath) === g.ino) return;\n // Orphaned: the file was deleted or replaced under a live server.\n // Stop accepting on the dead inode (open connections finish) and rebind.\n g.server = undefined;\n g.ino = undefined;\n s.close();\n }\n await bind();\n });\n\n pi.on(\"session_shutdown\", async (e) => {\n // Session replacement (new / resume / fork / reload) keeps the socket\n // and its connections: an in-flight fresh is answered by the next\n // runtime. Only quit (or an unknown reason) tears the server down.\n const reason = reasonOf(e);\n if (reason === \"new\" || reason === \"resume\" || reason === \"fork\" || reason === \"reload\") {\n return;\n }\n const s = g.server;\n const ino = g.ino;\n g.server = undefined;\n g.ino = undefined;\n map.delete(sockPath);\n if (!s) return;\n g.waiters.clear();\n settleFresh(fail(\"pi is shutting down\"));\n settleCommand(fail(\"pi is shutting down\"));\n for (const c of g.conns) c.destroy();\n await new Promise<void>((resolve) => s.close(() => resolve()));\n // Unlink only the file this process bound: another pi may own the path now.\n if (ino !== undefined && inodeOf(sockPath) === ino) rmSync(sockPath, { force: true });\n });\n\n return () => g.nested === true;\n}\n","/**\n * mu control socket protocol: JSON lines over a unix socket, one request\n * per connection. Shared by mu's client and the mu pi extension, so this\n * file imports nothing from mu — the extension loads it standalone.\n */\n\nexport const CTL_PROTOCOL_VERSION = 1;\n\nexport type CtlState = \"busy\" | \"idle\";\n\nexport type CtlRequest =\n | { op: \"hello\" }\n | { op: \"status\" }\n | { op: \"send\"; text: string; mode?: \"steer\" | \"followUp\" }\n | { op: \"wait\"; afterRuns?: number; timeoutMs?: number }\n | { op: \"abort\" }\n /**\n * Make a busy pi act on `text` now: abort the running turn, wait for\n * agent_settled (up to timeoutMs), then send `text` as a new run. Idle:\n * just send. Replies `timeout` and sends nothing when pi does not settle.\n */\n | { op: \"interrupt\"; text: string; timeoutMs?: number }\n /** New session + prompt as one operation. Refused with error \"busy\" unless force. */\n | { op: \"fresh\"; text: string; force?: boolean }\n /**\n * Run one of pi's session commands inside pi (sendUserMessage cannot run\n * built-in slash commands). Refused with error \"busy\" unless force.\n */\n | { op: \"command\"; name: CtlCommandName; instructions?: string; force?: boolean };\n\n/** Session commands the `command` op runs: `/new`, `/reload`, `/compact`. */\nexport const CTL_COMMANDS = [\"new\", \"reload\", \"compact\"] as const;\nexport type CtlCommandName = (typeof CTL_COMMANDS)[number];\n\n/**\n * Every op this protocol defines. The extension reports the ops it serves\n * in its `hello` reply (and in an unknown-op error), so mu can tell an\n * extension loaded by an older pi process from a broken one.\n */\nexport const CTL_OPS = [\n \"hello\",\n \"status\",\n \"send\",\n \"wait\",\n \"abort\",\n \"interrupt\",\n \"fresh\",\n \"command\",\n] as const satisfies readonly CtlRequest[\"op\"][];\n\nexport type CtlStatus = {\n state: CtlState;\n since: number;\n runs: number;\n pending: boolean;\n /** The pi session file (where the transcript is written); absent for an ephemeral pi or an older extension. */\n sessionFile?: string;\n};\n\nexport type CtlReply =\n | ({ v: 1; ok: true } & Partial<CtlStatus> & {\n agent?: string;\n workstream?: string;\n piVersion?: string;\n /** hello only: the ops this extension serves. Absent: predates reporting. */\n ops?: string[];\n /** hello only: the mu package version the extension was built from. */\n extVersion?: string;\n /** wait only: text of the settled run's final assistant message (\"\" when none). */\n lastText?: string;\n /** wait only: the error that ended the settled run (retries exhausted). */\n lastError?: string;\n /** wait only: the settled pi's session file, where its full transcript lives. */\n sessionFile?: string;\n /** interrupt only: pi was busy, so the turn was aborted before the send. */\n wasBusy?: boolean;\n })\n | { v: 1; ok: false; error: string; ops?: string[] };\n\n/** Error text of a reply to an op the extension does not serve. */\nexport const UNKNOWN_OP_PREFIX = \"unknown op: \";\n\n/** One frame. JSON.stringify escapes \"\\n\" inside strings, so the frame is one line. */\nexport function encode(msg: object): string {\n return `${JSON.stringify(msg)}\\n`;\n}\n\n/** Splits a stream into lines on \"\\n\" only (never U+2028/U+2029). */\nexport class LineDecoder {\n private buf = \"\";\n\n push(chunk: string): string[] {\n this.buf += chunk;\n const parts = this.buf.split(\"\\n\");\n this.buf = parts.pop() ?? \"\";\n return parts;\n }\n}\n","/**\n * mu pi extension, parent side: the `mu_delegate` tool.\n *\n * A delegate is a scratch agent started for one task. The tool spawns it,\n * hands it the task, returns at once, and posts the answer back into this\n * conversation as a follow-up when the delegate's run settles.\n *\n * Everything is the `mu` CLI (spawn / send / wait --json / read / abort /\n * close): the tool only orders the calls and formats the result, so a\n * shell gets the same delegation (VISION § 1, rule 2). The one\n * thing only an extension can do is the callback into the parent\n * conversation, and that is presentation. No extension-only state: the\n * in-flight set below is the list of `mu agent wait` children this pi owns.\n *\n * Separate from the child side (the control-socket server in mu-pi.ts):\n * that one serves a pi mu spawned; this one runs in a pi that is not.\n */\nimport { execFile } from \"node:child_process\";\nimport { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { defaultCacheDir } from \"../src/state-dir.js\";\n\n/** The slice of pi's ExtensionAPI the delegate side uses. */\nexport interface MuDelegateApi {\n registerTool(tool: DelegateTool): void;\n sendMessage(\n message: { customType: string; content: string; display: boolean; details?: unknown },\n options?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },\n ): void | Promise<void>;\n on(\n event: \"session_shutdown\" | \"message_start\" | \"agent_settled\",\n handler: (event: unknown, ctx: DelegateCtx) => unknown,\n ): unknown;\n /** pi's in-process bus between extensions. */\n events: { emit(channel: string, data: unknown): void };\n}\n\n/** The slice of pi's ExtensionContext the delegate side uses. */\nexport interface DelegateCtx {\n hasUI?: boolean;\n cwd?: string;\n ui?: {\n notify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n setStatus?(key: string, text: string | undefined): void;\n };\n}\n\ntype ToolResult = { content: { type: \"text\"; text: string }[]; details: unknown };\n\nexport interface DelegateTool {\n name: string;\n label: string;\n description: string;\n promptSnippet?: string;\n parameters: object;\n execute(\n id: string,\n params: Record<string, unknown>,\n signal?: AbortSignal,\n onUpdate?: unknown,\n ctx?: DelegateCtx,\n ): Promise<ToolResult>;\n}\n\nexport type MuResult = { code: number; stdout: string; stderr: string };\n/** Runs `mu <args>`. The test seam: tests inject a fake. */\nexport type MuRunner = (args: readonly string[], signal?: AbortSignal) => Promise<MuResult>;\n\nexport const DELEGATE_TOOL = \"mu_delegate\";\nexport const DELEGATE_CANCEL_TOOL = \"mu_delegate_cancel\";\nexport const DELEGATE_MESSAGE_TYPE = \"mu-delegate\";\nexport const DELEGATE_WORKSTREAM = \"scratch\";\n/** The footer status key (`ctx.ui.setStatus`), like goal / watchloop. */\nexport const DELEGATE_STATUS_KEY = \"mu-delegate\";\n/**\n * murmur's channel for outstanding background work, as\n * `{ source, count }`. murmur shows the count on this agent's card,\n * renders a stopped agent with work out as `waiting`, and holds back\n * `done` until it is zero: a parent that ended its turn to wait on\n * delegates has not finished. A string, not an import: neither side\n * depends on the other, and with no murmur loaded nobody listens.\n */\nexport const PENDING_CHANNEL = \"murmur:pending\";\n\n/** Footer text: delegates running (pane up), starting (no pane yet),\n * queued, failed, and finished whose answer has not reached this\n * conversation yet (pending); undefined clears the entry. */\nexport function delegateStatus(\n running: number,\n starting = 0,\n queued = 0,\n failed = 0,\n pending = 0,\n): string | undefined {\n const parts: string[] = [];\n if (running > 0) parts.push(`${running} delegate${running === 1 ? \"\" : \"s\"} running`);\n if (starting > 0) parts.push(`${starting} starting`);\n if (queued > 0) parts.push(`${queued} queued`);\n if (failed > 0) parts.push(`${failed} failed`);\n if (pending > 0) parts.push(`${pending} result${pending === 1 ? \"\" : \"s\"} pending`);\n return parts.length > 0 ? parts.join(\", \") : undefined;\n}\n/** Default `mu agent wait --timeout` for a delegate, in seconds. */\nexport const DELEGATE_TIMEOUT_S = 3600;\n/** Default cap on delegates in flight from one pi session. */\nexport const DELEGATE_MAX_DEFAULT = 16;\n/** The queue holds this many caps' worth of calls waiting for a slot. A\n * fan-out (refuters per finding, checkers per claim) issues several\n * caps' worth in one turn; past this, the model is refused. */\nexport const DELEGATE_QUEUE_FACTOR = 4;\n\n/** `MU_DELEGATE_MAX`: a positive integer, else the default. */\nexport function delegateMax(env: NodeJS.ProcessEnv = process.env): number {\n const n = Number(env.MU_DELEGATE_MAX);\n return Number.isInteger(n) && n > 0 ? n : DELEGATE_MAX_DEFAULT;\n}\nconst W = DELEGATE_WORKSTREAM;\n\n/** Registration guards: unmanaged pi, a mux in reach, not switched off. */\nexport function delegateEnabled(env: NodeJS.ProcessEnv = process.env): boolean {\n if (env.MU_MANAGED_AGENT) return false; // no helper-spawns-helper\n if (env.MU_DELEGATE === \"0\") return false;\n if (env.MU_MUX || env.HERDR_ENV === \"1\" || env.TMUX || env.TMUX_PANE) return true;\n return onPath(\"tmux\", env) || onPath(\"herdr\", env);\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction onPath(bin: string, env: NodeJS.ProcessEnv): boolean {\n return (env.PATH ?? \"\").split(delimiter).some((d) => d !== \"\" && existsSync(join(d, bin)));\n}\n\n/** The CLI this extension ships with (dist/cli.js next to dist/extension/), else `mu` on PATH. */\nexport function defaultRunner(): MuRunner {\n let cli: string | undefined;\n try {\n const p = fileURLToPath(new URL(\"../cli.js\", import.meta.url));\n if (existsSync(p)) cli = p;\n } catch {\n // not a file: URL; use PATH\n }\n return (args, signal) =>\n new Promise((resolve) => {\n const [cmd, argv] = cli ? [process.execPath, [cli, ...args]] : [\"mu\", [...args]];\n execFile(\n cmd,\n argv,\n { maxBuffer: 16 * 1024 * 1024, ...(signal ? { signal } : {}) },\n (err, stdout, stderr) => {\n const code = err ? (typeof err.code === \"number\" ? err.code : 1) : 0;\n resolve({ code, stdout: String(stdout), stderr: String(stderr || err?.message || \"\") });\n },\n );\n });\n}\n\n/** One agent row of `mu agent wait --json`, as far as the tool reads it. */\nexport type WaitAgent = {\n outcome?: string;\n lastText?: string;\n lastError?: string;\n /** The delegate's pi session file (mu ≥ 3.11.2 on the delegate side). */\n sessionFile?: string;\n};\n\n/** What happened to the pane after delivery, for the message. */\nexport type PaneFate = { closed: true } | { closed: false; why: string };\n\n/** Extras for the follow-up message; all optional. */\nexport type MessageExtras = {\n /** `mu agent read -n 50` for the outcomes without text. */\n tail?: string;\n attach?: string;\n timeoutS?: number;\n workspace?: string;\n /** How long the delegate ran, in ms. */\n elapsedMs?: number;\n /** The queue handle the caller was given (`queued-3`), if it was queued. */\n queuedAs?: string;\n /** The delegate's pi session file: the full transcript. */\n sessionFile?: string;\n /** A local copy of the delegate's last assistant text so far. */\n partial?: string;\n};\n\n/**\n * Text of the last assistant message in a pi session file (JSONL), or\n * undefined when there is none or the file cannot be read. A delegate\n * that timed out, died or was cancelled has no final answer, but what it\n * wrote so far is here.\n */\nexport function lastAssistantTextIn(sessionFile: string): string | undefined {\n let raw: string;\n try {\n raw = readFileSync(sessionFile, \"utf8\");\n } catch {\n return undefined;\n }\n const lines = raw.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i];\n if (!line?.includes('\"assistant\"')) continue;\n try {\n const e = JSON.parse(line) as { message?: { role?: unknown; content?: unknown } };\n if (e.message?.role !== \"assistant\") continue;\n const c = e.message.content;\n const text =\n typeof c === \"string\"\n ? c\n : Array.isArray(c)\n ? c\n .map((p: unknown) => {\n const q = p as { type?: unknown; text?: unknown };\n return q.type === \"text\" && typeof q.text === \"string\" ? q.text : \"\";\n })\n .join(\"\")\n : \"\";\n if (text.trim()) return text;\n } catch {\n // a torn last line while pi writes: keep looking\n }\n }\n return undefined;\n}\n\n/** Where to look next for a delegate with no final answer: the copy of\n * its partial text and its session file, one line each. */\nfunction evidenceLines(x: { sessionFile?: string; partial?: string }): string[] {\n return [\n x.partial ? `Partial answer so far: ${x.partial}` : undefined,\n x.sessionFile ? `Session: ${x.sessionFile}` : undefined,\n ].filter((v) => v !== undefined);\n}\n\n/** `42s`, `3m 05s`, `1h 02m`. */\nexport function formatElapsed(ms: number): string {\n const t = Math.max(0, Math.round(ms / 1000));\n if (t < 60) return `${t}s`;\n const m = Math.floor(t / 60);\n if (m < 60) return `${m}m ${String(t % 60).padStart(2, \"0\")}s`;\n return `${Math.floor(m / 60)}h ${String(m % 60).padStart(2, \"0\")}m`;\n}\n\n/**\n * The follow-up message for one finished wait. Pure: the CLI already\n * classified the outcome (`mu agent wait --json` → `outcome`); this only\n * words it.\n */\nexport function delegateMessage(\n name: string,\n agent: WaitAgent | undefined,\n pane: PaneFate,\n x: MessageExtras = {},\n): string {\n const timeoutS = x.timeoutS ?? DELEGATE_TIMEOUT_S;\n const who = `Delegate ${W}/${name}${x.queuedAs ? ` (queued as ${x.queuedAs})` : \"\"}`;\n const took = x.elapsedMs !== undefined ? ` after ${formatElapsed(x.elapsedMs)}` : \"\";\n const fate = pane.closed ? \"Pane closed.\" : `Pane kept (${pane.why}).`;\n const look = [\n x.attach ? `Attach: ${x.attach}` : undefined,\n `Read: mu agent read ${name} -n 50 -w ${W}`,\n ].filter((v) => v !== undefined);\n const tailBlock = x.tail?.trim() ? `\\n\\nPane tail:\\n${x.tail.trimEnd()}` : \"\";\n const ws = x.workspace ? ` Workspace: ${x.workspace}` : \"\";\n const ev = evidenceLines(x);\n const evBlock = ev.length > 0 ? `\\n${ev.join(\"\\n\")}` : \"\";\n switch (agent?.outcome) {\n case \"done\":\n return `${who} finished${took}. ${fate}${ws}\\n\\n${agent.lastText ?? \"\"}`;\n case \"empty\":\n return `${who} finished${took} without a text answer. ${fate}${ws}${evBlock}${tailBlock}`;\n case \"error\":\n return [\n `${who} stopped on an API error${took}, after pi's own retries: ${(agent.lastError ?? \"unknown error\").replace(/[.\\s]+$/, \"\")}. ${fate}${ws}`,\n \"Decide: re-issue the call, or record the check as UNVERIFIED.\",\n ...ev,\n ...look,\n `Close: mu agent close ${name} -w ${W}`,\n ].join(\"\\n\");\n case \"died\":\n return `${who} died${took} before answering. ${fate}${ws}${evBlock}${tailBlock}`;\n case \"timeout\":\n case \"pending\":\n return [\n `${who} is still running after ${timeoutS}s; stopped waiting, so its answer will not arrive here. ${fate}${ws}`,\n ...ev,\n ...look,\n `Wait again: mu agent wait ${name} -w ${W} --json`,\n ].join(\"\\n\");\n default:\n return `${who}: mu agent wait gave no result. ${fate}${ws}${evBlock}${tailBlock}`;\n }\n}\n\n/** A finished delegate whose answer an aborted run dropped from pi's queue. */\nexport type DroppedAnswer = {\n name: string;\n outcome?: string;\n elapsedMs?: number;\n /** The local copy of the follow-up message, if writing it worked. */\n copy?: string;\n sessionFile?: string;\n};\n\n/** Where dropped answers are copied: `<mu cache dir>/delegate-answers`.\n * Cache, not state: the delegate's pi session file keeps the answer. */\nexport function droppedAnswersDir(): string {\n return join(defaultCacheDir(), \"delegate-answers\");\n}\n\n/**\n * The note left in the conversation when Escape drops queued answers:\n * one line per delegate, pointing at the local copy and the delegate's\n * own session file. Pure.\n */\nexport function droppedNote(dropped: readonly DroppedAnswer[]): string {\n const n = dropped.length;\n const lines = dropped.map((d) => {\n const how = [\n d.outcome ?? \"no result\",\n d.elapsedMs !== undefined ? formatElapsed(d.elapsedMs) : undefined,\n ]\n .filter((x) => x !== undefined)\n .join(\", \");\n const where = [\n d.copy ? `answer: ${d.copy}` : undefined,\n d.sessionFile ? `session: ${d.sessionFile}` : undefined,\n ].filter((x) => x !== undefined);\n if (where.length === 0) where.push(`read: mu agent read ${d.name} -n 50 -w ${W}`);\n return `- ${W}/${d.name} (${how}) ${where.join(\" · \")}`;\n });\n return [\n `The interrupt dropped ${n} delegate answer${n === 1 ? \"\" : \"s\"} before ${n === 1 ? \"it\" : \"they\"} arrived:`,\n ...lines,\n \"The answer file holds the message that would have arrived; in a session file the answer is the last assistant message.\",\n ].join(\"\\n\");\n}\n\n/** Where a delegate's answer is recorded: a task, resolved by `mu task show`. */\nexport type RecordTarget = { workstream: string; task: string };\n\n/** Cap on a recorded note, in chars. */\nexport const RECORD_NOTE_MAX = 4000;\n/** Without a VERDICT line, this much of the answer's end is recorded. */\nexport const RECORD_FALLBACK_TAIL = 1500;\n\nconst VERDICT_LINE = /^[\\s>*_`-]*VERDICT:/;\nconst EVIDENCE_LINE = /^[\\s>*_`-]*EVIDENCE:/;\n\n/**\n * The note a delegate's answer leaves on the task it judged. Pure. A done\n * answer keeps its last `VERDICT:` line and every `EVIDENCE:` line after\n * it (else its tail, marked NO VERDICT LINE); any other outcome records\n * the gap.\n */\nexport function recordNote(\n label: string,\n name: string,\n outcome: string | undefined,\n lastText: string | undefined,\n elapsedMs: number,\n): string {\n if (outcome !== \"done\" || !lastText?.trim())\n return `REFUTER ${label}: no verdict (${outcome === \"done\" ? \"empty\" : (outcome ?? \"no result\")})`;\n const lines = lastText.trimEnd().split(\"\\n\");\n let at = -1;\n for (let i = lines.length - 1; i >= 0 && at < 0; i--)\n if (VERDICT_LINE.test(lines[i] ?? \"\")) at = i;\n const body =\n at >= 0\n ? [lines[at] ?? \"\", ...lines.slice(at + 1).filter((l) => EVIDENCE_LINE.test(l))].join(\"\\n\")\n : `NO VERDICT LINE: ${lastText.trimEnd().slice(-RECORD_FALLBACK_TAIL)}`;\n const note = `REFUTER ${label} (${name}, ${formatElapsed(elapsedMs)}):\\n${body}`;\n const mark = \"\\n[truncated]\";\n return note.length <= RECORD_NOTE_MAX\n ? note\n : note.slice(0, RECORD_NOTE_MAX - mark.length) + mark;\n}\n\n/** A label → agent-name stem: lowercase, [a-z0-9-], ≤ 20 chars. */\nexport function labelStem(label: unknown): string | undefined {\n if (typeof label !== \"string\") return undefined;\n const stem = label\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 20)\n .replace(/-+$/, \"\");\n return stem || undefined;\n}\n\n/** Model values that need no shell quoting inside a `--command` string. */\nconst MODEL_BARE_RE = /^[A-Za-z0-9._:/@+=-]+$/;\n\n/**\n * Forgive the usual slips in a `model` value: surrounding quotes or\n * backticks, a pasted `--model ` / `--model=` prefix, stray whitespace.\n * Anything else (brackets as in `gpt-6.1-sol[1m]`, odd provider ids) is\n * kept and shell-quoted by `modelCommand`, so pi gets to judge the id.\n * Returns undefined for an empty value or one with inner whitespace,\n * which no model id has.\n */\nexport function normalizeModel(raw: unknown): string | undefined {\n if (typeof raw !== \"string\") return undefined;\n let m = raw.trim();\n for (let prev = \"\"; prev !== m; ) {\n prev = m;\n m = m\n .replace(/^--model(?:=|\\s+)/, \"\")\n .replace(/^([\"'`])(.*)\\1$/s, \"$2\")\n .trim();\n }\n return m && !/\\s/.test(m) ? m : undefined;\n}\n\nfunction shellArg(s: string): string {\n return MODEL_BARE_RE.test(s) ? s : `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\n/**\n * The command a delegate with `model` runs: the cli key's command\n * (`$MU_<KEY>_COMMAND`, else the key itself, as `resolveCliCommand` in\n * src/agents/spawn.ts does) plus `--model <model>`. Inlined: the extension\n * bundles standalone and spawn.ts pulls in the DB.\n */\nexport function modelCommand(\n cli: string,\n model: string,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n const override = env[`MU_${cli.toUpperCase().replace(/-/g, \"_\")}_COMMAND`];\n const base = override && override.trim() !== \"\" ? override.trim() : cli;\n return `${base} --model ${shellArg(model)}`;\n}\n\n/**\n * One delegate this pi waits on. `cancelling` is set while a cancel's abort\n * is in flight: the abort itself settles the run, so a wait resolving then\n * is parked in `parked` instead of delivered, and delivered after all if\n * the abort fails.\n */\ntype Inflight = {\n abort: AbortController;\n /** The delegate's pi session file, reported by the spawn's send. */\n sessionFile?: string;\n record?: { target: RecordTarget; label: string };\n cancelling: boolean;\n parked?: () => Promise<void>;\n};\n\n/** A call past the cap, waiting for a slot. Its delegate name is picked\n * at spawn, so the queue hands out its own handle (`queued-3`). */\ntype Queued = {\n handle: string;\n params: Record<string, unknown>;\n ctx: DelegateCtx | undefined;\n record?: RecordTarget;\n};\n\nexport function registerDelegate(pi: MuDelegateApi, run: MuRunner = defaultRunner()): void {\n if (!delegateEnabled()) return;\n const inflight = new Map<string, Inflight>();\n /** Calls past the cap check whose delegate is not yet in `inflight`. */\n let starting = 0;\n /** Calls past the cap, FIFO, at most `DELEGATE_QUEUE_FACTOR * delegateMax()` long. */\n const queue: Queued[] = [];\n let queueSeq = 0;\n /** Delegates that settled on an error, pane kept: counted in the footer\n * until the model closes or re-issues them (no call to action). */\n const failed = new Set<string>();\n /** Delegates that finished whose follow-up has not entered the\n * conversation: being delivered, or queued behind a running turn.\n * Keyed by a per-delivery id carried in the message's details, and\n * cleared on that message's message_start. `queued` says whether\n * pi.sendMessage has returned, i.e. the message sits in pi's queue;\n * the rest is what an interrupt needs to point at the answer. */\n const arriving = new Map<\n number,\n { queued: boolean; name: string; content?: string } & Omit<DroppedAnswer, \"copy\">\n >();\n let deliverySeq = 0;\n // The ctx of the latest tool call: answers settle outside any call, so\n // the footer is refreshed through the last ctx pi handed us.\n let ui: DelegateCtx[\"ui\"];\n let lastPending = 0;\n /** Running, starting and queued: every delegate whose answer is still\n * to come back here. Failed panes have answered, so they do not count. */\n const reportPending = () => {\n const count = inflight.size + starting + queue.length;\n if (count === lastPending) return;\n lastPending = count;\n try {\n pi.events.emit(PENDING_CHANNEL, { source: DELEGATE_TOOL, count });\n } catch {\n // a listener's fault must not cost a delegate its answer\n }\n };\n // Every change to the counts already refreshes the footer, so the\n // report rides along rather than being a second set of call sites.\n const showStatus = () => {\n reportPending();\n try {\n ui?.setStatus?.(\n DELEGATE_STATUS_KEY,\n delegateStatus(inflight.size, starting, queue.length, failed.size, arriving.size),\n );\n } catch {\n // stale ctx after a session switch: the footer is decoration\n }\n };\n const track = (ctx: DelegateCtx | undefined) => {\n if (ctx?.hasUI !== false && ctx?.ui) ui = ctx.ui;\n };\n /** The follow-up for `delivery` is in pi's queue now. */\n const markQueued = (delivery: number) => {\n const a = arriving.get(delivery);\n if (a) a.queued = true;\n };\n /** Copy a dropped answer under the mu cache dir; undefined if that fails. */\n const saveCopy = (name: string, content: string, kind = \"\"): string | undefined => {\n try {\n const dir = droppedAnswersDir();\n mkdirSync(dir, { recursive: true });\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const path = join(dir, `${stamp}_${name}${kind}.md`);\n writeFileSync(path, `${content}\\n`);\n return path;\n } catch {\n return undefined;\n }\n };\n /** Copy a delegate's last assistant text so far (from its session\n * file) next to the dropped answers; undefined when it wrote none. */\n const partialCopy = (name: string, sessionFile: string): string | undefined => {\n const text = lastAssistantTextIn(sessionFile);\n return text ? saveCopy(name, text, \".partial\") : undefined;\n };\n /** Drop a delegate from the in-flight set, start the next queued call\n * into the freed slot, and refresh the footer. */\n const forget = (name: string) => {\n inflight.delete(name);\n drain();\n showStatus();\n };\n /** Start queued calls while there is a free slot. A queued call's tool\n * call has already returned, so a failed start becomes a follow-up. */\n function drain(): void {\n while (queue.length > 0 && inflight.size + starting < delegateMax()) {\n const q = queue.shift();\n if (!q) break;\n starting++; // held until start() takes over the slot\n void start(q.params, undefined, q.ctx, q.handle, q.record).then(\n () => {},\n (e: unknown) => {\n void Promise.resolve(\n pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content: `Queued delegate ${q.handle} could not start: ${e instanceof Error ? e.message : String(e)}`,\n display: true,\n details: { name: q.handle, workstream: W, outcome: null, closed: false },\n },\n { deliverAs: \"followUp\", triggerTurn: true },\n ),\n ).catch(() => {});\n },\n );\n }\n }\n\n const mu = run;\n const json = (r: MuResult): Record<string, unknown> | undefined => {\n try {\n const v: unknown = JSON.parse(r.stdout);\n return typeof v === \"object\" && v !== null ? (v as Record<string, unknown>) : undefined;\n } catch {\n return undefined;\n }\n };\n const failure = (what: string, r: MuResult) =>\n new Error(`${what} failed (exit ${r.code}): ${(r.stderr || r.stdout).trim()}`);\n\n /** A failed delegate whose pane is gone (closed from bash) leaves the\n * footer. Off the call's path: only a footer count rides on it. */\n function pruneFailed(): void {\n if (failed.size === 0) return;\n void mu([\"agent\", \"list\", \"-w\", W, \"--json\"]).then((r) => {\n const agents = json(r)?.agents;\n if (!Array.isArray(agents)) return;\n const taken = new Set(agents.map((a: unknown) => (a as { name?: unknown }).name));\n for (const f of [...failed]) if (!taken.has(f)) failed.delete(f);\n showStatus();\n });\n }\n\n /**\n * Spawn the delegate and send it the task in ONE mu call (`spawn\n * --next-free --send`): mu picks the free name under its spawn lock, so\n * parallel calls get distinct names with no `agent list` first. Returns\n * the name and the send's `runs`, the exact wait baseline.\n */\n async function spawn(\n params: Record<string, unknown>,\n text: string,\n cwd: string | undefined,\n signal?: AbortSignal,\n ): Promise<{\n name: string;\n runs: number;\n attach?: string;\n workspace?: string;\n sessionFile?: string;\n }> {\n signal?.throwIfAborted();\n pruneFailed();\n const stem = labelStem(params.label);\n // A label names the delegate (delegate-review, then delegate-review-2);\n // without one it is numbered (delegate-1, delegate-2).\n const base = stem ? `delegate-${stem}` : \"delegate-1\";\n const args = [\"agent\", \"spawn\", base, \"-w\", W, \"--next-free\", \"--send\", text, \"--json\"];\n if (params.workspace === true) args.push(\"--workspace\");\n else if (cwd) args.push(\"--cwd\", cwd);\n const cli = typeof params.cli === \"string\" && params.cli ? params.cli : undefined;\n if (cli) args.push(\"--cli\", cli);\n if (typeof params.model === \"string\" && params.model)\n args.push(\"--command\", modelCommand(cli ?? \"pi\", params.model));\n const r = await mu(args);\n const out = json(r);\n const spawned = (out?.agent as { name?: unknown } | undefined)?.name;\n // No agent in the reply: the spawn itself failed, nothing is up.\n if (typeof spawned !== \"string\") throw failure(\"mu agent spawn\", r);\n const name = spawned;\n if (signal?.aborted) {\n // The user cancelled while the pane came up: take it down again.\n await mu([\"agent\", \"close\", name, \"-w\", W]);\n signal.throwIfAborted();\n }\n if (out?.ctl !== \"ok\") {\n throw new Error(\n `${W}/${name} spawned but its control socket is ${String(out?.ctl)}, so its answer cannot come back. Pane kept; close it with: mu agent close ${name} -w ${W}`,\n );\n }\n const sent = out.send as\n | { ok?: unknown; runs?: unknown; message?: unknown; sessionFile?: unknown }\n | undefined;\n if (sent?.ok !== true) {\n // Nothing reached it: the pane is just an idle pi. Take it down.\n const c = await mu([\"agent\", \"close\", name, \"-w\", W]);\n const pane =\n c.code === 0 ? \"Pane closed.\" : `Pane kept; close it with: mu agent close ${name} -w ${W}`;\n const why = typeof sent?.message === \"string\" ? sent.message : (r.stderr || r.stdout).trim();\n throw new Error(`mu agent send to ${W}/${name} failed (exit ${r.code}): ${why}. ${pane}`);\n }\n const steps = Array.isArray(out.nextSteps) ? out.nextSteps : [];\n const attach = steps\n .map((s: unknown) => s as { intent?: unknown; command?: unknown })\n .find((s) => s.intent === \"Attach the pane\")?.command;\n const wsPath = (out.workspace as { path?: unknown } | null | undefined)?.path;\n return {\n name,\n // A pi just spawned has settled no run, so 0 is exact when an older\n // extension's reply carries no runs.\n runs: typeof sent.runs === \"number\" ? sent.runs : 0,\n ...(typeof attach === \"string\" ? { attach } : {}),\n ...(typeof wsPath === \"string\" ? { workspace: wsPath } : {}),\n ...(typeof sent.sessionFile === \"string\" ? { sessionFile: sent.sessionFile } : {}),\n };\n }\n\n /** The note label: the caller's label, else the delegate's name. */\n const recordLabel = (params: Record<string, unknown>, name: string) =>\n typeof params.label === \"string\" && params.label.trim() ? params.label.trim() : name;\n\n /** Check `record` names a real task, before anything spawns. */\n async function resolveRecord(raw: unknown): Promise<RecordTarget | undefined> {\n if (raw === undefined) return undefined;\n const r = raw as { task?: unknown; workstream?: unknown } | null;\n const task = typeof r?.task === \"string\" ? r.task.trim() : \"\";\n if (!task) throw new Error(\"mu_delegate: record.task must name a task\");\n const ws = typeof r?.workstream === \"string\" ? r.workstream.trim() : \"\";\n // Without a workstream, mu resolves it as any verb does (<ws>/<task>, $MU_SESSION, tmux).\n const shown = await mu([\"task\", \"show\", task, ...(ws ? [\"-w\", ws] : []), \"--json\"]);\n const out = json(shown);\n const t = out?.task as { name?: unknown; workstreamName?: unknown } | undefined;\n if (shown.code !== 0 || typeof t?.name !== \"string\" || typeof t.workstreamName !== \"string\") {\n const why =\n typeof out?.message === \"string\" ? out.message : (shown.stderr || shown.stdout).trim();\n throw new Error(\n `mu_delegate: record task ${ws ? `${ws}/` : \"\"}${task} not found (exit ${shown.code}): ${why}. Nothing spawned.`,\n );\n }\n return { workstream: t.workstreamName, task: t.name };\n }\n\n /** Write one note on the record task; the follow-up's line about it. */\n async function writeRecord(rec: RecordTarget, name: string, text: string): Promise<string> {\n const where = `${rec.workstream}/${rec.task}`;\n try {\n const r = await mu([\"task\", \"note\", rec.task, \"-w\", rec.workstream, \"--author\", name, text]);\n if (r.code === 0) return `Recorded on ${where} as a note.`;\n return `Recording on ${where} failed (exit ${r.code}): ${(r.stderr || r.stdout).trim()}. Record it yourself.`;\n } catch (e) {\n return `Recording on ${where} failed: ${e instanceof Error ? e.message : String(e)}. Record it yourself.`;\n }\n }\n\n async function deliver(\n name: string,\n wait: MuResult,\n keep: boolean,\n extras: MessageExtras,\n delivery: number,\n record?: { target: RecordTarget; label: string },\n ) {\n const agent = (json(wait)?.agents as WaitAgent[] | undefined)?.[0];\n const outcome = agent?.outcome;\n const tail =\n outcome === \"done\" || outcome === \"timeout\" || outcome === \"pending\" || outcome === \"error\"\n ? undefined\n : (await mu([\"agent\", \"read\", name, \"-n\", \"50\", \"-w\", W])).stdout;\n // Close only after a clean finish: a died or timed-out pane is evidence.\n let pane: PaneFate = { closed: false, why: \"keep: true\" };\n if (outcome !== \"done\" && outcome !== \"empty\")\n pane = { closed: false, why: \"kept as evidence\" };\n else if (!keep) {\n const c = await mu([\"agent\", \"close\", name, \"-w\", W]);\n pane =\n c.code === 0\n ? { closed: true }\n : { closed: false, why: `close refused: ${(c.stderr || c.stdout).trim()}` };\n }\n if (outcome === \"error\" && !pane.closed) {\n failed.add(name);\n showStatus();\n }\n // No final answer: point at the transcript, and copy what it wrote so far.\n if (outcome !== \"done\") {\n const sessionFile = agent?.sessionFile ?? extras.sessionFile;\n const partial = sessionFile ? partialCopy(name, sessionFile) : undefined;\n extras = {\n ...extras,\n ...(sessionFile ? { sessionFile } : {}),\n ...(partial ? { partial } : {}),\n };\n }\n const recorded = record\n ? await writeRecord(\n record.target,\n name,\n recordNote(record.label, name, outcome, agent?.lastText, extras.elapsedMs ?? 0),\n )\n : undefined;\n const message = delegateMessage(name, agent, pane, { ...extras, ...(tail ? { tail } : {}) });\n const content = recorded ? `${message}\\n\\n${recorded}` : message;\n const a = arriving.get(delivery);\n if (a)\n Object.assign(a, {\n content,\n ...(outcome ? { outcome } : {}),\n ...(extras.elapsedMs !== undefined ? { elapsedMs: extras.elapsedMs } : {}),\n ...(agent?.sessionFile ? { sessionFile: agent.sessionFile } : {}),\n });\n await pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content,\n display: true,\n details: {\n name,\n workstream: W,\n outcome: outcome ?? null,\n closed: pane.closed,\n answer: outcome === \"done\" ? (agent?.lastText ?? null) : null,\n elapsedMs: extras.elapsedMs ?? null,\n workspace: extras.workspace ?? null,\n sessionFile: agent?.sessionFile ?? extras.sessionFile ?? null,\n partial: extras.partial ?? null,\n delivery,\n },\n },\n { deliverAs: \"followUp\", triggerTurn: true },\n );\n }\n\n /** Spawn, send, and watch one delegate. The caller holds one\n * `starting` slot; it is released once the delegate is in `inflight`\n * (or on failure). Returns the tool result text. */\n async function start(\n params: Record<string, unknown>,\n signal: AbortSignal | undefined,\n ctx: DelegateCtx | undefined,\n queuedAs?: string,\n record?: RecordTarget,\n ): Promise<ToolResult> {\n let slotHeld = true;\n const freeSlot = () => {\n if (slotHeld) {\n starting--;\n showStatus();\n }\n slotHeld = false;\n };\n showStatus(); // the footer moves at once, before the pane exists\n try {\n const task = typeof params.task === \"string\" ? params.task.trim() : \"\";\n const brief = typeof params.brief === \"string\" ? params.brief.trim() : \"\";\n const keep = params.keep === true;\n const t = params.timeout;\n if (t !== undefined && !(typeof t === \"number\" && Number.isFinite(t) && t > 0))\n throw new Error(\n `mu_delegate: timeout must be a positive number of seconds (got ${JSON.stringify(t)})`,\n );\n const timeoutS = typeof t === \"number\" ? Math.ceil(t) : DELEGATE_TIMEOUT_S;\n // Without --cwd the pane inherits the mux session's start dir (wherever\n // the FIRST scratch spawn ran), and a missing dir silently becomes\n // $HOME: pin it to the caller's and check it exists.\n let cwd: string | undefined;\n if (params.workspace !== true) {\n cwd =\n typeof params.cwd === \"string\" && params.cwd ? params.cwd : (ctx?.cwd ?? process.cwd());\n if (!isDir(cwd)) throw new Error(`mu_delegate: cwd ${cwd} is not a directory`);\n }\n const { name, runs, attach, workspace, sessionFile } = await spawn(\n params,\n brief ? `${brief}\\n\\n${task}` : task,\n cwd,\n signal,\n );\n const entry: Inflight = {\n abort: new AbortController(),\n cancelling: false,\n ...(sessionFile ? { sessionFile } : {}),\n ...(record ? { record: { target: record, label: recordLabel(params, name) } } : {}),\n };\n inflight.set(name, entry);\n freeSlot(); // now counted in inflight\n showStatus();\n const started = Date.now();\n // The send's `runs` is pi's count before this prompt: waiting past it\n // catches the run even if it settled before this wait started.\n const waiting = mu(\n [\n \"agent\",\n \"wait\",\n name,\n \"-w\",\n W,\n \"--json\",\n \"--timeout\",\n String(timeoutS),\n \"--after-runs\",\n String(runs),\n ],\n entry.abort.signal,\n );\n const settle = async (r: MuResult) => {\n const delivery = ++deliverySeq;\n arriving.set(delivery, { queued: false, name });\n forget(name);\n try {\n await deliver(\n name,\n r,\n keep,\n {\n timeoutS,\n elapsedMs: Date.now() - started,\n ...(queuedAs ? { queuedAs } : {}),\n ...(attach ? { attach } : {}),\n ...(workspace ? { workspace } : {}),\n ...(entry.sessionFile ? { sessionFile: entry.sessionFile } : {}),\n },\n delivery,\n entry.record,\n );\n markQueued(delivery);\n } catch (e) {\n // A throw here would be an unhandled rejection and a lost answer.\n const content = `Delegate ${W}/${name} settled, but delivering its answer failed: ${e instanceof Error ? e.message : String(e)}. Read it with: mu agent read ${name} -n 50 -w ${W}`;\n const a = arriving.get(delivery);\n if (a) a.content = content;\n await Promise.resolve(\n pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content,\n display: true,\n details: { name, workstream: W, outcome: null, closed: false, delivery },\n },\n { deliverAs: \"followUp\", triggerTurn: true },\n ),\n ).then(\n () => markQueued(delivery),\n () => {\n // Nothing will arrive: stop counting it.\n arriving.delete(delivery);\n showStatus();\n },\n );\n }\n };\n void waiting.then(async (r) => {\n if (inflight.get(name) !== entry) return; // cancelled or shut down\n if (entry.cancelling) entry.parked = () => settle(r);\n else await settle(r);\n });\n const lines = [\n `Delegated to ${W}/${name}. Its answer arrives as a follow-up message when it finishes; do not wait or poll.`,\n workspace ? `Workspace: ${workspace}` : undefined,\n attach ? `Attach: ${attach}` : undefined,\n `Cancel: ${DELEGATE_CANCEL_TOOL} { name: \"${name}\" }`,\n ].filter((x) => x !== undefined);\n return {\n content: [{ type: \"text\", text: lines.join(\"\\n\") }],\n details: {\n name,\n workstream: W,\n attach: attach ?? null,\n workspace: workspace ?? null,\n keep,\n },\n };\n } finally {\n // A start that threw frees its slot here, and a call queued while it\n // was starting must take that slot: drain whether queued or direct.\n freeSlot();\n drain();\n }\n }\n\n pi.registerTool({\n name: DELEGATE_TOOL,\n label: \"mu delegate\",\n description: `Subagent: run one self-contained task in a fresh pi agent (its own mux pane in mu's ${W} workstream) while you keep working. Use it whenever you would reach for a subagent: research, a review, a draft, an investigation, or a refuter of a claim, plan or fix before you act on it; call it several times to fan out in parallel (at most ${delegateMax()} run at once; up to ${DELEGATE_QUEUE_FACTOR * delegateMax()} more are queued and start as slots free). The subagent starts with no context, in your working directory: put everything it needs in task. The call returns at once and the answer arrives later as a follow-up message: carry on with other work, or end your turn if your next step needs the answer (the follow-up resumes you). The pane closes after a clean finish; keep: true leaves it open. When the check judges a mu task, set record so its verdict lands on that task; leave it out when there is no task.`,\n promptSnippet:\n \"Subagent: delegate a self-contained task to a background pi agent; its answer arrives later as a follow-up\",\n parameters: {\n type: \"object\",\n properties: {\n task: { type: \"string\", description: \"The complete task, with all context it needs\" },\n label: {\n type: \"string\",\n description:\n \"Short label naming the delegate, e.g. 'review' → delegate-review. Use one per subtask when fanning out.\",\n },\n brief: {\n type: \"string\",\n description:\n \"Optional standing role or rules, sent before the task, e.g. 'You are a reviewer; read only.' The rules are instructions, not enforced. The job itself goes in task.\",\n },\n cwd: {\n type: \"string\",\n description:\n \"Working directory for the delegate (default: yours; ignored with workspace)\",\n },\n timeout: {\n type: \"number\",\n exclusiveMinimum: 0,\n description: `Seconds to wait for the answer (default ${DELEGATE_TIMEOUT_S}). On timeout you get a \"still running\" follow-up instead of the answer, and the answer will not arrive later; the subagent keeps running in its pane.`,\n },\n workspace: {\n type: \"boolean\",\n description:\n \"For tasks that edit files: its own VCS checkout (jj workspace / git worktree / sl share) branched from the current commit. The result and follow-up name the path; changes stay there until you merge them. This isolates repository edits only: the subagent runs as you, with your files, environment and network.\",\n },\n cli: {\n type: \"string\",\n description:\n \"Agent CLI key (default pi). Only keys with $MU_<KEY>_COMMAND set in pi's environment exist; to pick a model, use model instead.\",\n },\n model: {\n type: \"string\",\n description:\n \"Model for the subagent, passed to pi as --model (e.g. 'sonnet', '<provider>/<model>:high' copied from `pi --list-models`); appended to the cli's command. Default: the cli's own model. Use it to vary models across a review panel.\",\n },\n keep: {\n type: \"boolean\",\n description: \"Keep the pane after it finishes, to talk to it again\",\n },\n record: {\n type: \"object\",\n description:\n \"When the answer arrives, write its VERDICT/EVIDENCE onto this task as a note (for a check that judges a mu task; omit with no task); task may be <ws>/<task>.\",\n properties: {\n task: { type: \"string\" },\n workstream: { type: \"string\" },\n },\n required: [\"task\"],\n additionalProperties: false,\n },\n },\n required: [\"task\"],\n additionalProperties: false,\n },\n async execute(_id, params, signal, _onUpdate, ctx) {\n track(ctx);\n const task = typeof params.task === \"string\" ? params.task.trim() : \"\";\n if (!task) throw new Error(\"mu_delegate needs a non-empty task\");\n const t = params.timeout;\n if (t !== undefined && !(typeof t === \"number\" && Number.isFinite(t) && t > 0))\n throw new Error(\n `mu_delegate: timeout must be a positive number of seconds (got ${JSON.stringify(t)})`,\n );\n if (params.workspace !== true) {\n const cwd =\n typeof params.cwd === \"string\" && params.cwd ? params.cwd : (ctx?.cwd ?? process.cwd());\n if (!isDir(cwd)) throw new Error(`mu_delegate: cwd ${cwd} is not a directory`);\n }\n if (params.model !== undefined && params.model !== \"\") {\n const m = normalizeModel(params.model);\n if (!m)\n throw new Error(\n `mu_delegate: model must be one pi model id like 'provider/id:thinking', as listed by \\`pi --list-models\\` (got ${JSON.stringify(params.model)}); omit it for the cli's default`,\n );\n params = { ...params, model: m };\n }\n const record = await resolveRecord(params.record);\n // Count slots synchronously, before any await: parallel calls in one\n // turn all run this line before the first spawn returns.\n const max = delegateMax();\n if (inflight.size + starting < max) {\n starting++;\n return start(params, signal, ctx, undefined, record);\n }\n // Full: queue up to DELEGATE_QUEUE_FACTOR caps' worth; past that, refuse.\n if (queue.length >= DELEGATE_QUEUE_FACTOR * max)\n throw new Error(\n `mu_delegate: ${inflight.size + starting} running and ${queue.length} queued (MU_DELEGATE_MAX=${max}). End your turn; issue the rest as answers arrive (each answer resumes you).`,\n );\n const handle = `queued-${++queueSeq}`;\n queue.push({\n handle,\n params: {\n ...params,\n cwd:\n typeof params.cwd === \"string\" && params.cwd ? params.cwd : (ctx?.cwd ?? process.cwd()),\n },\n ctx,\n ...(record ? { record } : {}),\n });\n showStatus();\n return {\n content: [\n {\n type: \"text\",\n text: `Queued as ${handle} (#${queue.length}; ${inflight.size + starting} running, MU_DELEGATE_MAX=${max}). It starts when a slot frees, and its answer arrives as a follow-up message like any delegate's; do not wait or poll. Cancel: ${DELEGATE_CANCEL_TOOL} { name: \"${handle}\" }`,\n },\n ],\n details: { name: handle, workstream: W, queued: true, position: queue.length },\n };\n },\n });\n\n pi.registerTool({\n name: DELEGATE_CANCEL_TOOL,\n label: \"mu delegate cancel\",\n description: `Stop a delegate started by ${DELEGATE_TOOL}: abort its turn and close its pane (keep: true leaves the pane open). No follow-up message is sent for it afterwards.`,\n parameters: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Delegate name, e.g. delegate-1\" },\n keep: { type: \"boolean\", description: \"Leave the pane open after aborting\" },\n },\n required: [\"name\"],\n additionalProperties: false,\n },\n async execute(_id, params, _signal, _onUpdate, ctx) {\n track(ctx);\n const name = typeof params.name === \"string\" ? params.name : \"\";\n if (!name) throw new Error(\"mu_delegate_cancel needs a name\");\n const qi = queue.findIndex((q) => q.handle === name);\n if (qi >= 0) {\n const [q] = queue.splice(qi, 1);\n showStatus();\n const recorded = q?.record\n ? ` ${await writeRecord(q.record, name, recordNote(recordLabel(q.params, name), name, \"cancelled\", undefined, 0))}`\n : \"\";\n return {\n content: [\n { type: \"text\", text: `Dropped ${name} from the queue; it never started.${recorded}` },\n ],\n details: { name, workstream: W },\n };\n }\n const entry = inflight.get(name);\n if (entry) entry.cancelling = true;\n const ab = await mu([\"agent\", \"abort\", name, \"-w\", W]);\n if (ab.code !== 0) {\n // Not cancelled after all: keep waiting, or deliver what settled meanwhile.\n if (entry) {\n entry.cancelling = false;\n const parked = entry.parked;\n entry.parked = undefined;\n if (parked) void parked();\n }\n throw failure(`mu agent abort ${W}/${name}`, ab);\n }\n if (entry) {\n entry.abort.abort();\n forget(name);\n }\n failed.delete(name);\n let text = `Aborted ${W}/${name}.`;\n // What it wrote before the abort, and its transcript.\n const sessionFile = entry?.sessionFile;\n const partial = sessionFile ? partialCopy(name, sessionFile) : undefined;\n const evidence = evidenceLines({\n ...(sessionFile ? { sessionFile } : {}),\n ...(partial ? { partial } : {}),\n });\n if (entry?.record)\n text += ` ${await writeRecord(entry.record.target, name, recordNote(entry.record.label, name, \"cancelled\", undefined, 0))}`;\n if (params.keep === true) text += \" Pane kept.\";\n else {\n const c = await mu([\"agent\", \"close\", name, \"-w\", W]);\n text +=\n c.code === 0\n ? \" Pane closed.\"\n : ` Pane kept: close refused: ${(c.stderr || c.stdout).trim()}`;\n }\n if (evidence.length > 0) text += `\\n${evidence.join(\"\\n\")}`;\n return { content: [{ type: \"text\", text }], details: { name, workstream: W } };\n },\n });\n\n // A follow-up enters the conversation at its message_start: at once\n // when pi is idle, or when the running turn drains its follow-ups.\n pi.on(\"message_start\", (e) => {\n const m = (e as { message?: { role?: unknown; customType?: unknown; details?: unknown } })\n .message;\n if (m?.role !== \"custom\" || m.customType !== DELEGATE_MESSAGE_TYPE) return;\n const id = (m.details as { delivery?: unknown } | undefined)?.delivery;\n if (typeof id === \"number\" && arriving.delete(id)) showStatus();\n });\n\n // Escape clears pi's follow-up queue along with the run: answers that\n // were queued in it never arrive. Stop counting them, copy each to the\n // mu cache dir, and leave one line per answer in the conversation (no\n // turn: the model sees it with the user's next prompt). An answer\n // still being delivered is not in the queue yet and arrives as usual.\n pi.on(\"agent_settled\", (e) => {\n if ((e as { aborted?: unknown }).aborted !== true) return;\n const dropped: DroppedAnswer[] = [];\n for (const [id, a] of arriving) {\n if (!a.queued) continue;\n arriving.delete(id);\n dropped.push({\n name: a.name,\n ...(a.outcome ? { outcome: a.outcome } : {}),\n ...(a.elapsedMs !== undefined ? { elapsedMs: a.elapsedMs } : {}),\n ...(a.sessionFile ? { sessionFile: a.sessionFile } : {}),\n ...(a.content ? { copy: saveCopy(a.name, a.content) } : {}),\n });\n }\n if (dropped.length === 0) return;\n showStatus();\n void Promise.resolve(\n pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content: droppedNote(dropped),\n display: true,\n details: { dropped },\n },\n { triggerTurn: false },\n ),\n ).catch(() => {});\n });\n\n // The watchers die with this runtime (/reload, /new, quit): say which\n // delegates lose their callback, so none is lost silently. The names\n // are also in the tool results, and `mu agent wait` recovers them.\n pi.on(\"session_shutdown\", (_e, ctx) => {\n if (arriving.size > 0) {\n // Answers still being delivered or queued die with this runtime.\n arriving.clear();\n showStatus();\n }\n if (inflight.size === 0 && queue.length === 0) return;\n const names = [...inflight.keys()];\n const sessions = [...inflight].flatMap(([n, e]) =>\n e.sessionFile ? [`${n}: ${e.sessionFile}`] : [],\n );\n const never = queue.splice(0).map((q) => q.handle);\n for (const e of inflight.values()) e.abort.abort();\n inflight.clear();\n showStatus();\n ui = undefined;\n const parts: string[] = [];\n if (names.length > 0)\n parts.push(\n `${names.length} delegate${names.length === 1 ? \"\" : \"s\"} still running: ${names.join(\", \")}. Their answers will not come back here; use mu agent wait <name> -w ${W} --json.`,\n );\n if (sessions.length > 0) parts.push(`Sessions: ${sessions.join(\"; \")}.`);\n if (never.length > 0)\n parts.push(`${never.length} queued, never started: ${never.join(\", \")}. Re-issue them.`);\n const msg = parts.join(\" \");\n if (ctx?.hasUI && ctx.ui) ctx.ui.notify(msg, \"warning\");\n else process.stderr.write(`mu: ${msg}\\n`);\n });\n}\n","// The mu state directory, resolved from builtins only so the CLI\n// bootstrap (src/main.ts) can locate its compile cache before it loads\n// any of the CLI graph. db.ts re-exports defaultStateDir.\n\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join } from \"node:path\";\n\n/**\n * Resolve the canonical mu state directory:\n * MU_STATE_DIR > $XDG_STATE_HOME/mu (absolute only) > ~/.local/state/mu\n */\nexport function defaultStateDir(): string {\n if (process.env.MU_STATE_DIR) return process.env.MU_STATE_DIR;\n return join(xdgStateHome(homedir()), \"mu\");\n}\n\n/**\n * The mu cache directory, `$XDG_CACHE_HOME/mu` (absolute only) else\n * `~/.cache/mu`: files mu can lose at any time, such as copies of data\n * that lives elsewhere too.\n */\nexport function defaultCacheDir(): string {\n const xdg = process.env.XDG_CACHE_HOME;\n return join(xdg !== undefined && isAbsolute(xdg) ? xdg : join(homedir(), \".cache\"), \"mu\");\n}\n\n/** `$XDG_STATE_HOME`, or `<home>/.local/state` when it is unset, empty,\n * or relative: the XDG spec says such a value must be ignored, and a\n * relative one would scatter state across every cwd mu runs in. */\nexport function xdgStateHome(home: string): string {\n const xdg = process.env.XDG_STATE_HOME;\n return xdg !== undefined && isAbsolute(xdg) ? xdg : join(home, \".local\", \"state\");\n}\n","/**\n * mu pi extension: the keep-driving nudge (docs/specs/2026-10-03-keep-driving-nudge.md).\n *\n * An orchestrator that dispatched mu work and then ends its turn while\n * that work is still IN_PROGRESS gets ONE visible message quoting the\n * skill's keep-driving rule, and one continuation. If it stops again,\n * that stop stands. Not a goal loop: no re-check, no counter.\n *\n * Its only read is `mu state --json`, its only write `mu log --kind\n * nudge`; the armed set and fired flag are per-prompt scratch. The rule\n * text lives in skills/mu/SKILL.md between the keep-driving markers.\n *\n * The refute nudge: `mu task claim <id> --for` on a task whose notes\n * carry no line starting `REFUTER `, `VERDICT:` or `REFUTE-EXEMPT:`\n * (read with `mu task notes --json`) gets ONE visible message per prompt\n * listing those tasks. It informs, never continues; `review_*` tasks\n * are exempt (their brief is the fixed reviewer template).\n *\n * Its worker-side twin, the close nudge: a mu-spawned pi worker\n * ($MU_AGENT_NAME + $MU_WORKSTREAM) that settles while it still owns an\n * IN_PROGRESS task is told once to close it or say why not. Same\n * once-per-prompt rule and `MU_NUDGE=0` opt-out.\n *\n * None fire in a nested pi (mu-pi.ts decides at bind); close and refute\n * also skip a pi with no UI (`pi -p`, json), where nobody can answer.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { defaultRunner, type MuRunner } from \"./delegate.js\";\n\nexport const NUDGE_MESSAGE_TYPE = \"mu-keep-driving\";\nexport const NUDGE_LOG_KIND = \"nudge\";\nexport const CLOSE_NUDGE_MESSAGE_TYPE = \"mu-close-task\";\nexport const REFUTE_NUDGE_MESSAGE_TYPE = \"mu-refute-brief\";\nconst MARK_START = \"<!-- mu:keep-driving -->\";\nconst MARK_END = \"<!-- /mu:keep-driving -->\";\n/** Tasks named in the wait hint; the rest are counted, not listed. */\nconst WAIT_HINT_MAX = 8;\n\n/** The slice of pi's ExtensionContext the nudge reads. */\nexport type MuNudgeCtx = { mode?: string; hasUI?: boolean };\n\n/** The slice of pi's ExtensionAPI the nudge uses. */\nexport interface MuNudgeApi {\n on(\n event: \"tool_call\" | \"agent_before_settle\" | \"input\",\n handler: (event: unknown, ctx: MuNudgeCtx) => unknown,\n ): unknown;\n}\n\n/**\n * True while this pi is nested: it inherited a MU_CTL_SOCK another pi\n * serves (a `pi -p` run inside an agent's pane). Read at settle time,\n * since the bind decision lands in session_start, after registration.\n */\nexport type NestedCheck = () => boolean;\nconst notNested: NestedCheck = () => false;\n\n/** No one can answer a nudge: print or json mode. */\nfunction noUI(ctx: MuNudgeCtx | undefined): boolean {\n return ctx?.hasUI === false;\n}\n\n/** `MU_NUDGE=0` turns the nudge off. */\nexport function nudgeEnabled(env: NodeJS.ProcessEnv = process.env): boolean {\n return env.MU_NUDGE !== \"0\";\n}\n\n/** The keep-driving paragraph from SKILL.md, or undefined without the markers. */\nexport function keepDrivingRule(skillMd: string): string | undefined {\n const i = skillMd.indexOf(MARK_START);\n const j = skillMd.indexOf(MARK_END);\n if (i < 0 || j < i) return undefined;\n const text = skillMd.slice(i + MARK_START.length, j).trim();\n return text === \"\" ? undefined : text;\n}\n\n/** SKILL.md next to this file in either layout (source or dist/extension). */\nfunction readSkill(): string | undefined {\n for (const up of [\"..\", \"../..\"]) {\n const p = join(import.meta.dirname ?? \"\", up, \"skills\", \"mu\", \"SKILL.md\");\n if (existsSync(p)) return readFileSync(p, \"utf8\");\n }\n return undefined;\n}\n\n/** Leading `NAME=value` words: env assignments before the command. */\nconst ENV_ASSIGN = /^[A-Za-z_][A-Za-z0-9_]*=/;\n\n/** The args after `mu` when this segment runs mu (after any env\n * assignments), or undefined when it runs something else. */\nfunction muArgs(words: string[]): string[] | undefined {\n let at = 0;\n while (at < words.length && ENV_ASSIGN.test(words[at] ?? \"\")) at++;\n const cmd = words[at];\n if (cmd !== \"mu\" && !cmd?.endsWith(\"/mu\")) return undefined;\n return words.slice(at + 1);\n}\n\n/**\n * The workstreams a bash command dispatches mu work into, or undefined\n * when it dispatches nothing. Dispatch = `mu agent send|spawn`, or\n * `mu task claim <id> --for` (parsed by claimOf, as the refute nudge\n * does). `\"\"` stands for the default workstream (resolved by mu\n * itself: $MU_SESSION, then tmux).\n */\nexport function dispatchedWorkstreams(command: string): string[] | undefined {\n const found = new Set<string>();\n // One mu invocation per shell segment.\n for (const words of shellSegments(command)) {\n const args = muArgs(words);\n if (args === undefined) continue;\n const claim = claimOf(args);\n if (claim !== undefined) {\n if (claim.ws !== \"scratch\") found.add(claim.ws);\n continue;\n }\n if (args[0] !== \"agent\" || (args[1] !== \"send\" && args[1] !== \"spawn\")) continue;\n let ws = \"\";\n for (let k = 2; k < args.length; k++) {\n const w = args[k] ?? \"\";\n if (w === \"-w\" || w === \"--workstream\") ws = args[k + 1] ?? \"\";\n else if (w.startsWith(\"--workstream=\")) ws = w.slice(\"--workstream=\".length);\n }\n if (ws !== \"scratch\") found.add(ws);\n }\n return found.size > 0 ? [...found] : undefined;\n}\n\n/** Claim options that take a value; the task id is the first other positional. */\nconst CLAIM_VALUE_OPTS = new Set([\"--for\", \"-f\", \"-w\", \"--workstream\", \"--evidence\", \"--actor\"]);\n\n/** A heredoc body to skip: lines up to `delim` (leading tabs stripped with `<<-`). */\ntype Heredoc = { delim: string; strip: boolean };\n\n/**\n * The words of each shell segment. Quotes group words and are dropped;\n * `&&`, `||`, `;`, `|` and newlines split segments only outside\n * quotes, so a quoted `--evidence 'a | b'` stays one word. A\n * backslash-newline joins lines, and heredoc bodies are skipped: they\n * are data, not commands. A `<<<` here-string and a `<<` shift inside\n * `(( ))` arithmetic do not start a heredoc. As in bash, `((` is\n * arithmetic only when its matching close is `))`; otherwise it is\n * nested subshells, where `<<` is a heredoc. A `#` that starts a word\n * comments out the rest of the line.\n */\nexport function shellSegments(command: string): string[][] {\n const segs: string[][] = [];\n let words: string[] = [];\n let word: string | undefined;\n const heredocs: Heredoc[] = [];\n /** Index of the closing `)` of the current `(( ))` arithmetic, where `<<` is a shift. */\n let arithEnd = -1;\n const endWord = () => {\n if (word !== undefined) words.push(word);\n word = undefined;\n };\n const endSeg = () => {\n endWord();\n if (words.length > 0) segs.push(words);\n words = [];\n };\n /** Skip the pending heredoc bodies that start after the newline at `i`;\n * returns the index of the last newline consumed. */\n const skipHeredocs = (i: number): number => {\n for (const h of heredocs.splice(0)) {\n while (i < command.length) {\n const eol = command.indexOf(\"\\n\", i + 1);\n const end = eol < 0 ? command.length : eol;\n const line = command.slice(i + 1, end);\n i = end;\n if ((h.strip ? line.replace(/^\\t+/, \"\") : line) === h.delim) break;\n }\n }\n return i;\n };\n for (let i = 0; i < command.length; i++) {\n const c = command[i] ?? \"\";\n if (c === \"'\" || c === '\"') {\n const close = command.indexOf(c, i + 1);\n const end = close < 0 ? command.length : close;\n word = (word ?? \"\") + command.slice(i + 1, end);\n i = end;\n } else if (c === \"\\\\\" && command[i + 1] === \"\\n\") {\n i++; // line continuation: neither a word nor a segment break\n } else if (c === \"\\\\\" && i + 1 < command.length) {\n word = (word ?? \"\") + command[++i];\n } else if (c === \"#\" && word === undefined) {\n const eol = command.indexOf(\"\\n\", i);\n i = (eol < 0 ? command.length : eol) - 1; // a comment: the newline still ends the segment\n } else if (c === \"(\" && command[i + 1] === \"(\" && i > arithEnd) {\n arithEnd = arithmeticEnd(command, i);\n word = `${word ?? \"\"}((`;\n i++;\n } else if (command.startsWith(\"<<<\", i)) {\n endWord(); // a here-string: its word is data on the same line\n i += 2;\n } else if (c === \"<\" && command[i + 1] === \"<\" && i > arithEnd) {\n // `<<[-] DELIM`: the delimiter may be quoted; its body starts on the next line.\n endWord();\n const m = /^<<(-?)[ \\t]*('([^']*)'|\"([^\"]*)\"|[^\\s;&|<>()]+)/.exec(command.slice(i));\n if (!m) {\n i++;\n continue;\n }\n const delim = m[3] ?? m[4] ?? (m[2] ?? \"\").replace(/\\\\/g, \"\");\n heredocs.push({ delim, strip: m[1] === \"-\" });\n i += m[0].length - 1;\n } else if (c === \";\" || c === \"|\" || c === \"\\n\" || (c === \"&\" && command[i + 1] === \"&\")) {\n if (c !== \";\" && c !== \"\\n\" && command[i + 1] === c) i++;\n endSeg();\n if (c === \"\\n\" && heredocs.length > 0) i = skipHeredocs(i);\n } else if (/\\s/.test(c)) {\n endWord();\n } else {\n word = (word ?? \"\") + c;\n }\n }\n endSeg();\n return segs;\n}\n\n/**\n * For the `((` at `open`: the index of the `)` that closes it when the\n * matching close is a `))` pair (arithmetic), else -1 (nested\n * subshells, or unclosed). Bash decides `((` the same way.\n */\nfunction arithmeticEnd(command: string, open: number): number {\n let depth = 0;\n for (let i = open + 2; i < command.length; i++) {\n const c = command[i];\n if (c === \"'\" || c === '\"') {\n const close = command.indexOf(c, i + 1);\n if (close < 0) return -1;\n i = close;\n } else if (c === \"\\\\\") {\n i++;\n } else if (c === \"(\") {\n depth++;\n } else if (c === \")\") {\n if (depth > 0) depth--;\n else return command[i + 1] === \")\" ? i + 1 : -1;\n }\n }\n return -1;\n}\n\n/** The task a `mu task claim <id> --for` dispatches, from the args after\n * `mu`, as `{ ws, id }`; undefined for any other mu command. */\nfunction claimOf(args: string[]): { ws: string; id: string } | undefined {\n if (args[0] !== \"task\" || args[1] !== \"claim\") return undefined;\n let ws = \"\";\n let id: string | undefined;\n let isFor = false;\n for (let k = 2; k < args.length; k++) {\n const w = args[k] ?? \"\";\n const [opt, eq] = w.startsWith(\"--\") && w.includes(\"=\") ? w.split(\"=\", 2) : [w, undefined];\n if (opt === \"--for\" || opt === \"-f\") isFor = true;\n if (opt === \"-w\" || opt === \"--workstream\") ws = eq ?? args[k + 1] ?? \"\";\n if (CLAIM_VALUE_OPTS.has(opt ?? \"\")) {\n if (eq === undefined) k++;\n } else if (id === undefined && !w.startsWith(\"-\")) id = w;\n }\n if (!isFor || id === undefined) return undefined;\n const slash = id.indexOf(\"/\");\n if (slash >= 0) {\n if (ws === \"\") ws = id.slice(0, slash);\n id = id.slice(slash + 1);\n }\n return { ws, id };\n}\n\n/**\n * The tasks a bash command dispatches with `mu task claim <id> --for`,\n * as `{ ws, id }`. `ws` is `\"\"` for the default workstream; a qualified\n * `<ws>/<id>` splits. `scratch` is skipped, like dispatchedWorkstreams.\n */\nexport function dispatchedTasks(command: string): { ws: string; id: string }[] {\n const out: { ws: string; id: string }[] = [];\n for (const words of shellSegments(command)) {\n const args = muArgs(words);\n const claim = args === undefined ? undefined : claimOf(args);\n if (claim !== undefined && claim.ws !== \"scratch\") out.push(claim);\n }\n return out;\n}\n\ntype Card = { workstreamName?: string; inProgress?: { name?: string }[] };\n/** `mu state --json` prints one bare card for one workstream, and\n * `{ workstreams: [...] }` for several (or none named). */\ntype StateJson = Card & { workstreams?: Card[] };\n\n/** IN_PROGRESS task refs per workstream, from `mu state --json`. */\nasync function inProgress(run: MuRunner, workstreams: string[]): Promise<string[] | undefined> {\n const named = workstreams.filter((w) => w !== \"\");\n const args = [\"state\", \"--json\", \"--events\", \"0\"];\n for (const w of named) args.push(\"-w\", w);\n const r = await run(args);\n if (r.code !== 0) return undefined;\n let json: StateJson;\n try {\n json = JSON.parse(r.stdout) as StateJson;\n } catch {\n return undefined;\n }\n const cards = json.workstreams ?? [json];\n const refs: string[] = [];\n for (const ws of cards) {\n for (const t of ws.inProgress ?? []) {\n if (t.name) refs.push(`${ws.workstreamName ?? \"\"}/${t.name}`);\n }\n }\n return refs;\n}\n\n/** The nudge text: the rule verbatim, then the live count and the wait. */\nexport function nudgeText(rule: string, refs: string[]): string {\n const shown = refs.slice(0, WAIT_HINT_MAX).join(\" \");\n const more = refs.length > WAIT_HINT_MAX ? ` (+${refs.length - WAIT_HINT_MAX} more)` : \"\";\n return [\n `[mu] ${rule}`,\n \"\",\n `${refs.length} task(s) IN_PROGRESS. Next: mu task wait ${shown} --first --on-stall exit --json${more}`,\n ].join(\"\\n\");\n}\n\n/** Write a `mu log` breadcrumb without holding the settle for it: the\n * nudge's message does not depend on the log line. */\nfunction breadcrumb(run: MuRunner, args: string[]): void {\n void run(args).catch(() => {});\n}\n\ntype SettleResult = { entries?: unknown[]; continue?: boolean } | undefined;\ntype SettleHandler = (event: unknown, ctx: MuNudgeCtx) => unknown;\n\n/**\n * A view of `pi` whose `agent_before_settle` handlers run in PARALLEL\n * behind one real handler. pi awaits boundary handlers one after the\n * other, and each nudge awaits a mu subprocess, so three nudges held the\n * settle (and every `mu agent wait` on it) for the sum of their calls.\n * The merged result appends every handler's entries to the event's\n * (pi replaces `entries` with each handler's return, so separate\n * handlers dropped all but the last nudge) and continues when any asks.\n * A nudge that throws still reaches pi's extension-error path: after the\n * merged handler, one reporter handler per nudge rethrows that nudge's\n * error, so pi reports each failure (as it did when every nudge was its\n * own handler) while the other nudges' entries are still delivered.\n * Call `flush()` after registering the nudges.\n */\nexport function parallelSettle(pi: MuNudgeApi): { api: MuNudgeApi; flush(): void } {\n const handlers: SettleHandler[] = [];\n const api: MuNudgeApi = {\n on(event, handler) {\n if (event === \"agent_before_settle\") handlers.push(handler);\n else pi.on(event, handler);\n },\n };\n // Errors of the last settle, by handler index; each reporter takes its own.\n let errors: (unknown[] | undefined)[] = [];\n return {\n api,\n flush() {\n if (handlers.length === 0) return;\n pi.on(\"agent_before_settle\", async (event, ctx) => {\n errors = handlers.map(() => undefined);\n const results = await Promise.all(\n handlers.map(async (h, i) => {\n try {\n return (await h(event, ctx)) as SettleResult;\n } catch (err) {\n errors[i] = [err]; // reported by reporter i, after the merge\n return undefined;\n }\n }),\n );\n const fired = results.filter((r) => r !== undefined);\n if (fired.length === 0) return undefined;\n const prior = (event as { entries?: unknown[] } | null)?.entries ?? [];\n return {\n entries: [...prior, ...fired.flatMap((r) => r.entries ?? [])],\n ...(fired.some((r) => r.continue === true) ? { continue: true } : {}),\n };\n });\n handlers.forEach((_, i) => {\n pi.on(\"agent_before_settle\", () => {\n const err = errors[i];\n errors[i] = undefined;\n if (err !== undefined) throw err[0];\n return undefined;\n });\n });\n },\n };\n}\n\nfunction outcomeOf(event: unknown): unknown {\n return typeof event === \"object\" && event !== null\n ? (event as { outcome?: unknown }).outcome\n : undefined;\n}\n\nfunction bashCommand(event: unknown): string | undefined {\n if (typeof event !== \"object\" || event === null) return undefined;\n const e = event as { toolName?: unknown; input?: { command?: unknown } };\n return e.toolName === \"bash\" && typeof e.input?.command === \"string\"\n ? e.input.command\n : undefined;\n}\n\nexport function registerNudge(\n pi: MuNudgeApi,\n run: MuRunner = defaultRunner(),\n skillMd: string | undefined = readSkill(),\n nested: NestedCheck = notNested,\n): void {\n if (!nudgeEnabled()) return;\n const rule = skillMd === undefined ? undefined : keepDrivingRule(skillMd);\n if (rule === undefined) return; // no markers: nothing true to quote\n\n const armed = new Set<string>();\n let fired = false;\n\n pi.on(\"input\", () => {\n armed.clear();\n fired = false;\n });\n\n pi.on(\"tool_call\", (event) => {\n const cmd = bashCommand(event);\n if (cmd === undefined) return;\n for (const ws of dispatchedWorkstreams(cmd) ?? []) armed.add(ws);\n });\n\n pi.on(\"agent_before_settle\", async (event) => {\n if (fired || armed.size === 0 || nested()) return;\n if (outcomeOf(event) !== \"completed\") return; // Esc or an error: stop\n fired = true; // once per prompt, even if the check below fails\n const refs = await inProgress(run, [...armed]);\n if (refs === undefined || refs.length === 0) return;\n const text = nudgeText(rule, refs);\n const logWs = [...armed].find((w) => w !== \"\");\n breadcrumb(run, [\n \"log\",\n ...(logWs ? [\"-w\", logWs] : []),\n \"--kind\",\n NUDGE_LOG_KIND,\n `keep-driving: ${refs.length} in progress`,\n ]);\n return {\n entries: [\n { type: \"custom_message\", customType: NUDGE_MESSAGE_TYPE, content: text, display: true },\n ],\n continue: true,\n };\n });\n}\n\n/** The mu-spawned worker this pi runs as, or undefined outside mu. */\nexport function workerIdentity(\n env: NodeJS.ProcessEnv = process.env,\n): { agent: string; workstream: string } | undefined {\n const agent = env.MU_AGENT_NAME;\n const workstream = env.MU_WORKSTREAM;\n if (!agent || !workstream || workstream === \"scratch\") return undefined;\n return { agent, workstream };\n}\n\n/** IN_PROGRESS task names owned by `agent`, from `mu task owned-by --json`. */\nasync function ownedInProgress(\n run: MuRunner,\n agent: string,\n workstream: string,\n): Promise<string[] | undefined> {\n const r = await run([\"task\", \"owned-by\", agent, \"-w\", workstream, \"--json\"]);\n if (r.code !== 0) return undefined;\n try {\n const json = JSON.parse(r.stdout) as { items?: { name?: string; status?: string }[] };\n return (json.items ?? []).flatMap((t) =>\n t.status === \"IN_PROGRESS\" && t.name ? [t.name] : [],\n );\n } catch {\n return undefined;\n }\n}\n\n/** The close-nudge text: name each task and the two ways out. */\nexport function closeNudgeText(workstream: string, names: string[]): string {\n const close = names\n .map((n) => `mu task close ${n} -w ${workstream} --evidence \"<what you verified>\"`)\n .join(\"\\n \");\n return [\n `[mu] You are stopping while you still own ${names.map((n) => `${workstream}/${n}`).join(\", \")} (IN_PROGRESS).`,\n \"If the work is done and verified, close it now:\",\n ` ${close}`,\n \"If you are blocked or need an answer, say so in one line and stop; the orchestrator will read your pane.\",\n ].join(\"\\n\");\n}\n\nexport function registerCloseNudge(\n pi: MuNudgeApi,\n run: MuRunner = defaultRunner(),\n env: NodeJS.ProcessEnv = process.env,\n nested: NestedCheck = notNested,\n): void {\n if (!nudgeEnabled(env)) return;\n const me = workerIdentity(env);\n if (me === undefined) return;\n let fired = false;\n\n pi.on(\"input\", () => {\n fired = false;\n });\n\n pi.on(\"agent_before_settle\", async (event, ctx) => {\n if (fired || nested() || noUI(ctx)) return; // nested: workerIdentity is the parent's\n if (outcomeOf(event) !== \"completed\") return;\n fired = true;\n const names = await ownedInProgress(run, me.agent, me.workstream);\n if (names === undefined || names.length === 0) return;\n breadcrumb(run, [\n \"log\",\n \"-w\",\n me.workstream,\n \"--kind\",\n NUDGE_LOG_KIND,\n `close: ${me.agent} settled owning ${names.join(\", \")}`,\n ]);\n return {\n entries: [\n {\n type: \"custom_message\",\n customType: CLOSE_NUDGE_MESSAGE_TYPE,\n content: closeNudgeText(me.workstream, names),\n display: true,\n },\n ],\n continue: true,\n };\n });\n}\n\n/** A note counts as a refute decision only when a line starts with a marker. */\nconst REFUTE_MARK = /^(REFUTER |VERDICT:|REFUTE-EXEMPT:)/m;\n\n/** True when the task's notes hold a refute decision; undefined if unreadable. */\nasync function briefRefuted(run: MuRunner, ws: string, id: string): Promise<boolean | undefined> {\n const r = await run([\"task\", \"notes\", id, ...(ws ? [\"-w\", ws] : []), \"--json\"]);\n if (r.code !== 0) return undefined;\n try {\n const json = JSON.parse(r.stdout) as { items?: { content?: string }[] };\n return (json.items ?? []).some((n) => REFUTE_MARK.test(n.content ?? \"\"));\n } catch {\n return undefined;\n }\n}\n\n/** The refute-nudge text: name each task and the two ways out. */\nexport function refuteNudgeText(refs: string[]): string {\n return `[mu] dispatched ${refs.join(\", \")} with an unrefuted brief: refute it (delegate, record) or note REFUTE-EXEMPT: <why>`;\n}\n\nexport function registerRefuteNudge(\n pi: MuNudgeApi,\n run: MuRunner = defaultRunner(),\n nested: NestedCheck = notNested,\n): void {\n if (!nudgeEnabled()) return;\n const armed = new Map<string, { ws: string; id: string }>();\n let fired = false;\n\n pi.on(\"input\", () => {\n armed.clear();\n fired = false;\n });\n\n pi.on(\"tool_call\", (event) => {\n const cmd = bashCommand(event);\n if (cmd === undefined) return;\n for (const t of dispatchedTasks(cmd)) {\n if (!t.id.startsWith(\"review_\")) armed.set(`${t.ws}/${t.id}`, t);\n }\n });\n\n pi.on(\"agent_before_settle\", async (event, ctx) => {\n if (fired || armed.size === 0 || nested() || noUI(ctx)) return;\n if (outcomeOf(event) !== \"completed\") return;\n fired = true;\n // One read per armed task, all at once: the settle waits for the slowest.\n const tasks = [...armed];\n const refuted = await Promise.all(tasks.map(([, t]) => briefRefuted(run, t.ws, t.id)));\n const refs = tasks.flatMap(([ref], i) => (refuted[i] === false ? [ref] : []));\n if (refs.length === 0) return;\n const logWs = [...armed.values()].find((t) => t.ws !== \"\")?.ws;\n breadcrumb(run, [\n \"log\",\n ...(logWs ? [\"-w\", logWs] : []),\n \"--kind\",\n NUDGE_LOG_KIND,\n `refute: ${refs.join(\", \")}`,\n ]);\n return {\n entries: [\n {\n type: \"custom_message\",\n customType: REFUTE_NUDGE_MESSAGE_TYPE,\n content: refuteNudgeText(refs),\n display: true,\n },\n ],\n };\n });\n}\n"],"mappings":"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","names":["existsSync","mkdirSync","readFileSync","statSync","join","fileURLToPath","join","join","existsSync","readFileSync","join","join","existsSync","readFileSync","join","existsSync","readFileSync","statSync","fileURLToPath","mkdirSync"]}