@mu-crew/mu 3.1.0 → 3.2.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../extension/mu-pi.ts","../../src/ctl/protocol.ts","../../extension/delegate.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 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 {\n CTL_OPS,\n CTL_PROTOCOL_VERSION,\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\";\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}\n\n/** The slice of pi's ExtensionAPI this extension uses. */\nexport interface MuPiApi extends MuDelegateApi {\n on(\n event: \"session_start\" | \"session_shutdown\" | \"agent_start\" | \"agent_end\" | \"agent_settled\",\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/** 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/**\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 ctx?: MuPiContext;\n pi: MuPiApi;\n handle: (req: Record<string, unknown>, conn: Socket) => Promise<Reply>;\n fresh?: PendingFresh;\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\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\nexport default function muPi(pi: MuPiApi): void {\n registerDelegate(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 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 });\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 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 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) return fail(\"a fresh send 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 \"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 /** 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(), lastText: g.lastText });\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(), lastText: g.lastText });\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 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 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/**\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] 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 })\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 } 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}\n\n/** The slice of pi's ExtensionContext the delegate side uses. */\nexport interface DelegateCtx {\n hasUI?: boolean;\n ui?: { notify(message: string, type?: \"info\" | \"warning\" | \"error\"): void };\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(id: string, params: Record<string, unknown>, signal?: AbortSignal): 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/** `mu agent wait --timeout` for a delegate, in seconds. */\nexport const DELEGATE_TIMEOUT_S = 3600;\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 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. */\nfunction 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 };\n\n/** What happened to the pane after delivery, for the message. */\nexport type PaneFate = { closed: true } | { closed: false; why: string };\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. `tail` is `mu agent read -n 50` for the outcomes without text.\n */\nexport function delegateMessage(\n name: string,\n agent: WaitAgent | undefined,\n pane: PaneFate,\n tail?: string,\n attach?: string,\n): string {\n const who = `Delegate ${W}/${name}`;\n const fate = pane.closed ? \"Pane closed.\" : `Pane kept (${pane.why}).`;\n const look = [\n attach ? `Attach: ${attach}` : undefined,\n `Read: mu agent read ${name} -n 50 -w ${W}`,\n ].filter((x) => x !== undefined);\n const tailBlock = tail?.trim() ? `\\n\\nPane tail:\\n${tail.trimEnd()}` : \"\";\n switch (agent?.outcome) {\n case \"done\":\n return `${who} finished. ${fate}\\n\\n${agent.lastText ?? \"\"}`;\n case \"empty\":\n return `${who} finished without a text answer. ${fate}${tailBlock}`;\n case \"died\":\n return `${who} died before answering. ${fate}${tailBlock}`;\n case \"timeout\":\n case \"pending\":\n return [\n `${who} is still running after ${DELEGATE_TIMEOUT_S}s; stopped waiting. ${fate}`,\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}${tailBlock}`;\n }\n}\n\ntype Inflight = { abort: AbortController; cancelled: boolean };\n\nexport function registerDelegate(pi: MuDelegateApi, run: MuRunner = defaultRunner()): void {\n if (!delegateEnabled()) return;\n const inflight = new Map<string, Inflight>();\n const reserved = new Set<string>();\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(): 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 for (let n = 1; ; n++) {\n const name = `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 ): Promise<{ name: string; attach?: string }> {\n for (let attempt = 0; ; attempt++) {\n const name = await pickName();\n const args = [\"agent\", \"spawn\", name, \"-w\", W, \"--json\"];\n if (params.workspace === true) args.push(\"--workspace\");\n if (typeof params.cli === \"string\" && params.cli) args.push(\"--cli\", params.cli);\n const r = await mu(args);\n // Another mu took the name between list and spawn: pick again.\n if (r.code !== 0 && /already exists/.test(r.stderr) && attempt < 3) continue;\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 return { name, ...(typeof attach === \"string\" ? { attach } : {}) };\n }\n }\n\n async function deliver(name: string, wait: MuResult, keep: boolean, attach?: string) {\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\"\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 await pi.sendMessage(\n {\n customType: DELEGATE_MESSAGE_TYPE,\n content: delegateMessage(name, agent, pane, tail, attach),\n display: true,\n details: { name, workstream: W, outcome: outcome ?? null, closed: pane.closed },\n },\n { deliverAs: \"followUp\", triggerTurn: true },\n );\n }\n\n pi.registerTool({\n name: DELEGATE_TOOL,\n label: \"mu delegate\",\n description: `Hand one self-contained task to a fresh pi agent in its own mux pane (mu's ${W} workstream) and keep working. Returns at once; the delegate's final answer arrives later as a follow-up message, so do not wait or poll for it. Use it for independent side work (research, a review, a draft, an investigation) you would otherwise do serially. The delegate starts with no context: put everything it needs in task. Several calls run in parallel. The pane is closed after a clean finish unless keep is true; the user can attach to it meanwhile.`,\n promptSnippet:\n \"Delegate a self-contained task to a background pi agent; its answer arrives later\",\n parameters: {\n type: \"object\",\n properties: {\n task: { type: \"string\", description: \"The complete task, with all context it needs\" },\n brief: {\n type: \"string\",\n description: \"Optional persona or ground rules, sent before the task\",\n },\n workspace: {\n type: \"boolean\",\n description: \"Give it its own VCS workspace (for tasks that edit files)\",\n },\n cli: {\n type: \"string\",\n description: \"Agent CLI key; resolves $MU_<CLI>_COMMAND (default pi)\",\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) {\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 brief = typeof params.brief === \"string\" ? params.brief.trim() : \"\";\n const keep = params.keep === true;\n const { name, attach } = await spawn(params);\n const entry: Inflight = { abort: new AbortController(), cancelled: false };\n inflight.set(name, entry);\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(DELEGATE_TIMEOUT_S)],\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 inflight.delete(name);\n throw failure(`mu agent send to ${W}/${name}`, sent);\n }\n void waiting.then(async (r) => {\n if (inflight.get(name) !== entry || entry.cancelled) return;\n inflight.delete(name);\n reserved.delete(name);\n await deliver(name, r, keep, attach);\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 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: { name, workstream: W, attach: attach ?? null, keep },\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) {\n const name = typeof params.name === \"string\" ? params.name : \"\";\n if (!name) throw new Error(\"mu_delegate_cancel needs a name\");\n const entry = inflight.get(name);\n if (entry) entry.cancelled = true;\n const ab = await mu([\"agent\", \"abort\", name, \"-w\", W]);\n if (ab.code !== 0) {\n if (entry) entry.cancelled = false;\n throw failure(`mu agent abort ${W}/${name}`, ab);\n }\n entry?.abort.abort();\n inflight.delete(name);\n reserved.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) return;\n const names = [...inflight.keys()];\n for (const e of inflight.values()) e.abort.abort();\n inflight.clear();\n const msg = `${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 if (ctx?.hasUI && ctx.ui) ctx.ui.notify(msg, \"warning\");\n else process.stderr.write(`mu: ${msg}\\n`);\n });\n}\n"],"mappings":"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","names":["existsSync","join","join","existsSync"]}