@mu-crew/mu 3.5.0 → 3.6.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.
@@ -581,6 +581,7 @@ import { existsSync as existsSync2, readFileSync } from "fs";
581
581
  import { join as join2 } from "path";
582
582
  var NUDGE_MESSAGE_TYPE = "mu-keep-driving";
583
583
  var NUDGE_LOG_KIND = "nudge";
584
+ var CLOSE_NUDGE_MESSAGE_TYPE = "mu-close-task";
584
585
  var MARK_START = "<!-- mu:keep-driving -->";
585
586
  var MARK_END = "<!-- /mu:keep-driving -->";
586
587
  var WAIT_HINT_MAX = 8;
@@ -704,9 +705,71 @@ function registerNudge(pi, run = defaultRunner(), skillMd = readSkill()) {
704
705
  };
705
706
  });
706
707
  }
708
+ function workerIdentity(env = process.env) {
709
+ const agent = env.MU_AGENT_NAME;
710
+ const workstream = env.MU_WORKSTREAM;
711
+ if (!agent || !workstream || workstream === "scratch") return void 0;
712
+ return { agent, workstream };
713
+ }
714
+ async function ownedInProgress(run, agent, workstream) {
715
+ const r = await run(["task", "owned-by", agent, "-w", workstream, "--json"]);
716
+ if (r.code !== 0) return void 0;
717
+ try {
718
+ const json = JSON.parse(r.stdout);
719
+ return (json.items ?? []).flatMap(
720
+ (t) => t.status === "IN_PROGRESS" && t.name ? [t.name] : []
721
+ );
722
+ } catch {
723
+ return void 0;
724
+ }
725
+ }
726
+ function closeNudgeText(workstream, names) {
727
+ const close = names.map((n) => `mu task close ${n} -w ${workstream} --evidence "<what you verified>"`).join("\n ");
728
+ return [
729
+ `[mu] You are stopping while you still own ${names.map((n) => `${workstream}/${n}`).join(", ")} (IN_PROGRESS).`,
730
+ "If the work is done and verified, close it now:",
731
+ ` ${close}`,
732
+ "If you are blocked or need an answer, say so in one line and stop; the orchestrator will read your pane."
733
+ ].join("\n");
734
+ }
735
+ function registerCloseNudge(pi, run = defaultRunner(), env = process.env) {
736
+ if (!nudgeEnabled(env)) return;
737
+ const me = workerIdentity(env);
738
+ if (me === void 0) return;
739
+ let fired = false;
740
+ pi.on("input", () => {
741
+ fired = false;
742
+ });
743
+ pi.on("agent_before_settle", async (event) => {
744
+ if (fired) return;
745
+ if (outcomeOf(event) !== "completed") return;
746
+ fired = true;
747
+ const names = await ownedInProgress(run, me.agent, me.workstream);
748
+ if (names === void 0 || names.length === 0) return;
749
+ await run([
750
+ "log",
751
+ "-w",
752
+ me.workstream,
753
+ "--kind",
754
+ NUDGE_LOG_KIND,
755
+ `close: ${me.agent} settled owning ${names.join(", ")}`
756
+ ]);
757
+ return {
758
+ entries: [
759
+ {
760
+ type: "custom_message",
761
+ customType: CLOSE_NUDGE_MESSAGE_TYPE,
762
+ content: closeNudgeText(me.workstream, names),
763
+ display: true
764
+ }
765
+ ],
766
+ continue: true
767
+ };
768
+ });
769
+ }
707
770
 
708
771
  // extension/mu-pi.ts
709
- var EXT_VERSION = true ? "3.5.0" : void 0;
772
+ var EXT_VERSION = true ? "3.6.0" : void 0;
710
773
  var FRESH_COMMAND = "mu-fresh";
711
774
  var FRESH_TIMEOUT_MS = 3e4;
712
775
  function commandName(name) {
@@ -849,6 +912,7 @@ function muPi(pi) {
849
912
  registerDelegate(pi);
850
913
  registerPrompts(pi);
851
914
  registerNudge(pi);
915
+ registerCloseNudge(pi);
852
916
  serveCtl(pi);
853
917
  }
854
918
  function serveCtl(pi) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../extension/mu-pi.ts","../../src/ctl/protocol.ts","../../extension/delegate.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 { type DelegateCtx, type MuDelegateApi, registerDelegate } from \"./delegate.js\";\nimport { type MuNudgeApi, registerNudge } 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 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 | \"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 /** 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 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): void {\n registerDelegate(pi);\n registerPrompts(pi);\n registerNudge(pi);\n serveCtl(pi);\n}\n\n/** Child side: serve `$MU_CTL_SOCK` for the mu that spawned this pi. */\nfunction serveCtl(pi: MuPiApi): void {\n const sock = process.env.MU_CTL_SOCK;\n if (!sock) return;\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 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 // 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, state: g.state };\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 default:\n return { ...fail(`${UNKNOWN_OP_PREFIX}${String(req.op)}`), ops: [...CTL_OPS] };\n }\n }\n\n const settledRun = () => ({\n lastText: g.lastText,\n ...(g.lastError !== undefined ? { lastError: g.lastError } : {}),\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 const waiter = () => done({ v: V, ok: true, ...status(), ...settledRun() });\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 process.stderr.write(\n `mu: control socket ${sockPath} is served by another pi; this pi will not take it\\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 process.stderr.write(`mu: control socket ${sockPath} was taken by another pi\\n`);\n return;\n } finally {\n rmSync(tmp, { force: true });\n }\n g.server = s;\n g.ino = inodeOf(sockPath);\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","/**\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\" | \"needs_input\";\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 /** 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 \"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 })\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 (ROADMAP § Pi extension, 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, statSync } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\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(event: \"session_shutdown\", handler: (event: unknown, ctx: DelegateCtx) => unknown): 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 for `n` running delegates; undefined clears the entry. */\n/** Footer text: delegates still spawning (the call returned no pane yet)\n * and delegates whose pane is up and working. */\nexport function delegateStatus(\n running: number,\n starting = 0,\n queued = 0,\n failed = 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 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 = { outcome?: string; lastText?: string; lastError?: string };\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 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/**\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 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};\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 const reserved = new Set<string>();\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),\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 /** 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 reserved.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).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 async function pickName(stem?: string): Promise<string> {\n const r = await mu([\"agent\", \"list\", \"-w\", W, \"--json\"]);\n const agents = json(r)?.agents;\n const taken = new Set(\n Array.isArray(agents)\n ? agents.map((a: unknown) => (a as { name?: unknown }).name).filter((n) => n)\n : [],\n );\n // A failed delegate whose pane is gone (closed from bash) leaves the footer.\n if (Array.isArray(agents)) {\n for (const f of [...failed]) if (!taken.has(f)) failed.delete(f);\n showStatus();\n }\n for (let n = 1; ; n++) {\n // A label names the delegate (delegate-review, then delegate-review-2);\n // without one it is numbered.\n const name = stem\n ? n === 1\n ? `delegate-${stem}`\n : `delegate-${stem}-${n}`\n : `delegate-${n}`;\n if (!taken.has(name) && !reserved.has(name)) {\n reserved.add(name); // sync after the await: parallel calls get distinct names\n return name;\n }\n }\n }\n\n async function spawn(\n params: Record<string, unknown>,\n cwd: string | undefined,\n signal?: AbortSignal,\n ): Promise<{ name: string; attach?: string; workspace?: string }> {\n const stem = labelStem(params.label);\n for (let attempt = 0; ; attempt++) {\n signal?.throwIfAborted();\n const name = await pickName(stem);\n const args = [\"agent\", \"spawn\", name, \"-w\", W, \"--json\"];\n if (params.workspace === true) args.push(\"--workspace\");\n else if (cwd) args.push(\"--cwd\", cwd);\n if (typeof params.cli === \"string\" && params.cli) args.push(\"--cli\", params.cli);\n const r = await mu(args);\n if (signal?.aborted && r.code === 0) {\n // The user cancelled while the pane came up: take it down again.\n reserved.delete(name);\n await mu([\"agent\", \"close\", name, \"-w\", W]);\n signal.throwIfAborted();\n }\n // Another mu took the name between list and spawn: pick again.\n if (r.code !== 0 && /already exists/.test(r.stderr) && attempt < 3) {\n reserved.delete(name);\n continue;\n }\n if (r.code !== 0) {\n reserved.delete(name);\n throw failure(\"mu agent spawn\", r);\n }\n const out = json(r) ?? {};\n if (out.ctl !== \"ok\") {\n reserved.delete(name);\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 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 ...(typeof attach === \"string\" ? { attach } : {}),\n ...(typeof wsPath === \"string\" ? { workspace: wsPath } : {}),\n };\n }\n }\n\n async function deliver(name: string, wait: MuResult, keep: boolean, extras: MessageExtras) {\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 await pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content: delegateMessage(name, agent, pane, { ...extras, ...(tail ? { tail } : {}) }),\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 },\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 ): 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, attach, workspace } = await spawn(params, cwd, signal);\n const entry: Inflight = { abort: new AbortController(), cancelling: false };\n inflight.set(name, entry);\n freeSlot(); // now counted in inflight\n showStatus();\n const started = Date.now();\n // Start the wait alongside the send: it takes its baseline run count\n // at startup and resolves on the first settle past it. A model turn\n // outlasts a mu process start by orders of magnitude.\n const waiting = mu(\n [\"agent\", \"wait\", name, \"-w\", W, \"--json\", \"--timeout\", String(timeoutS)],\n entry.abort.signal,\n );\n const sent = await mu([\"agent\", \"send\", name, brief ? `${brief}\\n\\n${task}` : task, \"-w\", W]);\n if (sent.code !== 0) {\n entry.abort.abort();\n forget(name);\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\n ? \"Pane closed.\"\n : `Pane kept; close it with: mu agent close ${name} -w ${W}`;\n throw new Error(`${failure(`mu agent send to ${W}/${name}`, sent).message}. ${pane}`);\n }\n const settle = async (r: MuResult) => {\n forget(name);\n try {\n await deliver(name, r, keep, {\n timeoutS,\n elapsedMs: Date.now() - started,\n ...(queuedAs ? { queuedAs } : {}),\n ...(attach ? { attach } : {}),\n ...(workspace ? { workspace } : {}),\n });\n } catch (e) {\n // A throw here would be an unhandled rejection and a lost answer.\n await Promise.resolve(\n pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n 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 display: true,\n details: { name, workstream: W, outcome: null, closed: false },\n },\n { deliverAs: \"followUp\", triggerTurn: true },\n ),\n ).catch(() => {});\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 freeSlot();\n if (queuedAs) 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; 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.`,\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). Name a configured key such as 'pi_fast' to run a cheaper model.\",\n },\n keep: {\n type: \"boolean\",\n description: \"Keep the pane after it finishes, to talk to it again\",\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 // 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);\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 });\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 queue.splice(qi, 1);\n showStatus();\n return {\n content: [{ type: \"text\", text: `Dropped ${name} from the queue; it never started.` }],\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 (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 // 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 (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","/**\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 */\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\";\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 ExtensionAPI the nudge uses. */\nexport interface MuNudgeApi {\n on(\n event: \"tool_call\" | \"agent_before_settle\" | \"input\",\n handler: (event: unknown, ctx: unknown) => unknown,\n ): unknown;\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/**\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 ... --for`. `\"\"` stands for the default workstream\n * (resolved by mu 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 seg of command.split(/&&|\\|\\||;|\\n|\\|/)) {\n const words = seg.trim().split(/\\s+/);\n const at = words.findIndex((w) => w === \"mu\" || w.endsWith(\"/mu\"));\n if (at < 0) continue;\n const [noun, verb] = [words[at + 1], words[at + 2]];\n const isSendSpawn = noun === \"agent\" && (verb === \"send\" || verb === \"spawn\");\n const isClaimFor = noun === \"task\" && verb === \"claim\" && words.includes(\"--for\");\n if (!isSendSpawn && !isClaimFor) continue;\n let ws = \"\";\n for (let k = at + 3; k < words.length; k++) {\n const w = words[k] ?? \"\";\n if (w === \"-w\" || w === \"--workstream\") ws = unquote(words[k + 1] ?? \"\");\n else if (w.startsWith(\"--workstream=\")) ws = unquote(w.slice(\"--workstream=\".length));\n }\n if (ws === \"\" && isClaimFor) {\n const ref = words[at + 3] ?? \"\";\n if (ref.includes(\"/\")) ws = unquote(ref.split(\"/\")[0] ?? \"\");\n }\n if (ws !== \"scratch\") found.add(ws);\n }\n return found.size > 0 ? [...found] : undefined;\n}\n\nfunction unquote(s: string): string {\n return s.replace(/^['\"]|['\"]$/g, \"\");\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\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): 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) 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 await 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"],"mappings":"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","names":["existsSync","readFileSync","statSync","join","fileURLToPath","existsSync","join","join","existsSync","join","existsSync","readFileSync","statSync","fileURLToPath"]}
1
+ {"version":3,"sources":["../../extension/mu-pi.ts","../../src/ctl/protocol.ts","../../extension/delegate.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 { type DelegateCtx, type MuDelegateApi, registerDelegate } from \"./delegate.js\";\nimport { type MuNudgeApi, registerCloseNudge, registerNudge } 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 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 | \"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 /** 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 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): void {\n registerDelegate(pi);\n registerPrompts(pi);\n registerNudge(pi);\n registerCloseNudge(pi);\n serveCtl(pi);\n}\n\n/** Child side: serve `$MU_CTL_SOCK` for the mu that spawned this pi. */\nfunction serveCtl(pi: MuPiApi): void {\n const sock = process.env.MU_CTL_SOCK;\n if (!sock) return;\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 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 // 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, state: g.state };\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 default:\n return { ...fail(`${UNKNOWN_OP_PREFIX}${String(req.op)}`), ops: [...CTL_OPS] };\n }\n }\n\n const settledRun = () => ({\n lastText: g.lastText,\n ...(g.lastError !== undefined ? { lastError: g.lastError } : {}),\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 const waiter = () => done({ v: V, ok: true, ...status(), ...settledRun() });\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 process.stderr.write(\n `mu: control socket ${sockPath} is served by another pi; this pi will not take it\\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 process.stderr.write(`mu: control socket ${sockPath} was taken by another pi\\n`);\n return;\n } finally {\n rmSync(tmp, { force: true });\n }\n g.server = s;\n g.ino = inodeOf(sockPath);\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","/**\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\" | \"needs_input\";\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 /** 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 \"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 })\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 (ROADMAP § Pi extension, 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, statSync } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\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(event: \"session_shutdown\", handler: (event: unknown, ctx: DelegateCtx) => unknown): 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 for `n` running delegates; undefined clears the entry. */\n/** Footer text: delegates still spawning (the call returned no pane yet)\n * and delegates whose pane is up and working. */\nexport function delegateStatus(\n running: number,\n starting = 0,\n queued = 0,\n failed = 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 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 = { outcome?: string; lastText?: string; lastError?: string };\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 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/**\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 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};\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 const reserved = new Set<string>();\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),\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 /** 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 reserved.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).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 async function pickName(stem?: string): Promise<string> {\n const r = await mu([\"agent\", \"list\", \"-w\", W, \"--json\"]);\n const agents = json(r)?.agents;\n const taken = new Set(\n Array.isArray(agents)\n ? agents.map((a: unknown) => (a as { name?: unknown }).name).filter((n) => n)\n : [],\n );\n // A failed delegate whose pane is gone (closed from bash) leaves the footer.\n if (Array.isArray(agents)) {\n for (const f of [...failed]) if (!taken.has(f)) failed.delete(f);\n showStatus();\n }\n for (let n = 1; ; n++) {\n // A label names the delegate (delegate-review, then delegate-review-2);\n // without one it is numbered.\n const name = stem\n ? n === 1\n ? `delegate-${stem}`\n : `delegate-${stem}-${n}`\n : `delegate-${n}`;\n if (!taken.has(name) && !reserved.has(name)) {\n reserved.add(name); // sync after the await: parallel calls get distinct names\n return name;\n }\n }\n }\n\n async function spawn(\n params: Record<string, unknown>,\n cwd: string | undefined,\n signal?: AbortSignal,\n ): Promise<{ name: string; attach?: string; workspace?: string }> {\n const stem = labelStem(params.label);\n for (let attempt = 0; ; attempt++) {\n signal?.throwIfAborted();\n const name = await pickName(stem);\n const args = [\"agent\", \"spawn\", name, \"-w\", W, \"--json\"];\n if (params.workspace === true) args.push(\"--workspace\");\n else if (cwd) args.push(\"--cwd\", cwd);\n if (typeof params.cli === \"string\" && params.cli) args.push(\"--cli\", params.cli);\n const r = await mu(args);\n if (signal?.aborted && r.code === 0) {\n // The user cancelled while the pane came up: take it down again.\n reserved.delete(name);\n await mu([\"agent\", \"close\", name, \"-w\", W]);\n signal.throwIfAborted();\n }\n // Another mu took the name between list and spawn: pick again.\n if (r.code !== 0 && /already exists/.test(r.stderr) && attempt < 3) {\n reserved.delete(name);\n continue;\n }\n if (r.code !== 0) {\n reserved.delete(name);\n throw failure(\"mu agent spawn\", r);\n }\n const out = json(r) ?? {};\n if (out.ctl !== \"ok\") {\n reserved.delete(name);\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 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 ...(typeof attach === \"string\" ? { attach } : {}),\n ...(typeof wsPath === \"string\" ? { workspace: wsPath } : {}),\n };\n }\n }\n\n async function deliver(name: string, wait: MuResult, keep: boolean, extras: MessageExtras) {\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 await pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content: delegateMessage(name, agent, pane, { ...extras, ...(tail ? { tail } : {}) }),\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 },\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 ): 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, attach, workspace } = await spawn(params, cwd, signal);\n const entry: Inflight = { abort: new AbortController(), cancelling: false };\n inflight.set(name, entry);\n freeSlot(); // now counted in inflight\n showStatus();\n const started = Date.now();\n // Start the wait alongside the send: it takes its baseline run count\n // at startup and resolves on the first settle past it. A model turn\n // outlasts a mu process start by orders of magnitude.\n const waiting = mu(\n [\"agent\", \"wait\", name, \"-w\", W, \"--json\", \"--timeout\", String(timeoutS)],\n entry.abort.signal,\n );\n const sent = await mu([\"agent\", \"send\", name, brief ? `${brief}\\n\\n${task}` : task, \"-w\", W]);\n if (sent.code !== 0) {\n entry.abort.abort();\n forget(name);\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\n ? \"Pane closed.\"\n : `Pane kept; close it with: mu agent close ${name} -w ${W}`;\n throw new Error(`${failure(`mu agent send to ${W}/${name}`, sent).message}. ${pane}`);\n }\n const settle = async (r: MuResult) => {\n forget(name);\n try {\n await deliver(name, r, keep, {\n timeoutS,\n elapsedMs: Date.now() - started,\n ...(queuedAs ? { queuedAs } : {}),\n ...(attach ? { attach } : {}),\n ...(workspace ? { workspace } : {}),\n });\n } catch (e) {\n // A throw here would be an unhandled rejection and a lost answer.\n await Promise.resolve(\n pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n 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 display: true,\n details: { name, workstream: W, outcome: null, closed: false },\n },\n { deliverAs: \"followUp\", triggerTurn: true },\n ),\n ).catch(() => {});\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 freeSlot();\n if (queuedAs) 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; 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.`,\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). Name a configured key such as 'pi_fast' to run a cheaper model.\",\n },\n keep: {\n type: \"boolean\",\n description: \"Keep the pane after it finishes, to talk to it again\",\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 // 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);\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 });\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 queue.splice(qi, 1);\n showStatus();\n return {\n content: [{ type: \"text\", text: `Dropped ${name} from the queue; it never started.` }],\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 (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 // 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 (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","/**\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 * 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 */\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\";\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 ExtensionAPI the nudge uses. */\nexport interface MuNudgeApi {\n on(\n event: \"tool_call\" | \"agent_before_settle\" | \"input\",\n handler: (event: unknown, ctx: unknown) => unknown,\n ): unknown;\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/**\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 ... --for`. `\"\"` stands for the default workstream\n * (resolved by mu 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 seg of command.split(/&&|\\|\\||;|\\n|\\|/)) {\n const words = seg.trim().split(/\\s+/);\n const at = words.findIndex((w) => w === \"mu\" || w.endsWith(\"/mu\"));\n if (at < 0) continue;\n const [noun, verb] = [words[at + 1], words[at + 2]];\n const isSendSpawn = noun === \"agent\" && (verb === \"send\" || verb === \"spawn\");\n const isClaimFor = noun === \"task\" && verb === \"claim\" && words.includes(\"--for\");\n if (!isSendSpawn && !isClaimFor) continue;\n let ws = \"\";\n for (let k = at + 3; k < words.length; k++) {\n const w = words[k] ?? \"\";\n if (w === \"-w\" || w === \"--workstream\") ws = unquote(words[k + 1] ?? \"\");\n else if (w.startsWith(\"--workstream=\")) ws = unquote(w.slice(\"--workstream=\".length));\n }\n if (ws === \"\" && isClaimFor) {\n const ref = words[at + 3] ?? \"\";\n if (ref.includes(\"/\")) ws = unquote(ref.split(\"/\")[0] ?? \"\");\n }\n if (ws !== \"scratch\") found.add(ws);\n }\n return found.size > 0 ? [...found] : undefined;\n}\n\nfunction unquote(s: string): string {\n return s.replace(/^['\"]|['\"]$/g, \"\");\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\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): 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) 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 await 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): 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) => {\n if (fired) return;\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 await 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"],"mappings":"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","names":["existsSync","readFileSync","statSync","join","fileURLToPath","existsSync","join","join","existsSync","join","existsSync","readFileSync","statSync","fileURLToPath"]}
package/dist/index.d.ts CHANGED
@@ -3427,7 +3427,7 @@ interface TaskWaitOptions {
3427
3427
  /** Emit a yellow STUCK warning to stderr (once per task per wait call)
3428
3428
  * when an IN_PROGRESS task's owner has been in `needs_input` for at
3429
3429
  * least this many milliseconds since the agent row's last update.
3430
- * Default 300_000 (5 min). Pass 0 to disable.
3430
+ * Default `DEFAULT_STUCK_AFTER_MS` (2 min). Pass 0 to disable.
3431
3431
  *
3432
3432
  * Surfaced by agent_attention_required: a worker sitting in
3433
3433
  * needs_input leaves wait blocked indefinitely. The cause may be a