zidane 9.1.11 → 9.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acp-CxFKfjZ7.js → acp-Cz5mFUjB.js} +3 -3
- package/dist/{acp-CxFKfjZ7.js.map → acp-Cz5mFUjB.js.map} +1 -1
- package/dist/acp-cli.js +4 -4
- package/dist/acp.js +1 -1
- package/dist/{auth-store-port-8BMUBfqw.js → auth-store-port-CDJa8Q8U.js} +2 -2
- package/dist/{auth-store-port-8BMUBfqw.js.map → auth-store-port-CDJa8Q8U.js.map} +1 -1
- package/dist/{auto-update-restart-_S0w600V.js → auto-update-restart-B4pU7Qgf.js} +10 -10
- package/dist/{auto-update-restart-_S0w600V.js.map → auto-update-restart-B4pU7Qgf.js.map} +1 -1
- package/dist/chat.js +9 -9
- package/dist/{cli-shared-C6qeun-_.js → cli-shared-BVtiiICW.js} +3 -3
- package/dist/{cli-shared-C6qeun-_.js.map → cli-shared-BVtiiICW.js.map} +1 -1
- package/dist/{credentials-BPG17Xuo.js → credentials-axv5VvMR.js} +2 -2
- package/dist/{credentials-BPG17Xuo.js.map → credentials-axv5VvMR.js.map} +1 -1
- package/dist/daemon-cli.js +2 -2
- package/dist/{discovery-DWH6e_zd.js → discovery-D7qVZWzq.js} +4 -4
- package/dist/{discovery-DWH6e_zd.js.map → discovery-D7qVZWzq.js.map} +1 -1
- package/dist/{engine-C_Ndjp0u.js → engine-DjM5NPIf.js} +3 -3
- package/dist/{engine-C_Ndjp0u.js.map → engine-DjM5NPIf.js.map} +1 -1
- package/dist/{executor-BUWZhsfn.js → executor-DlW7qAeN.js} +2 -2
- package/dist/{executor-BUWZhsfn.js.map → executor-DlW7qAeN.js.map} +1 -1
- package/dist/extensions/testing.js +2 -2
- package/dist/{extensions-D4psC965.js → extensions-D7DeZNpn.js} +6 -6
- package/dist/{extensions-D4psC965.js.map → extensions-D7DeZNpn.js.map} +1 -1
- package/dist/extensions.js +5 -5
- package/dist/{google-CTQu7Zz-.js → google-D1zjAViO.js} +2 -2
- package/dist/{google-CTQu7Zz-.js.map → google-D1zjAViO.js.map} +1 -1
- package/dist/{host-D-sOuh0K.js → host-Ds3RDlG5.js} +9 -9
- package/dist/{host-D-sOuh0K.js.map → host-Ds3RDlG5.js.map} +1 -1
- package/dist/{host-signals-Dlxd0YYP.js → host-signals-C8x5Yso0.js} +5 -5
- package/dist/{host-signals-Dlxd0YYP.js.map → host-signals-C8x5Yso0.js.map} +1 -1
- package/dist/{host-version-smAFds1j.js → host-version-BGZumnpZ.js} +2 -2
- package/dist/{host-version-smAFds1j.js.map → host-version-BGZumnpZ.js.map} +1 -1
- package/dist/index.js +5 -5
- package/dist/ipc/remote.js +3 -3
- package/dist/{ipc-DnSKoy00.js → ipc-DGfuNEfR.js} +4 -4
- package/dist/{ipc-DnSKoy00.js.map → ipc-DGfuNEfR.js.map} +1 -1
- package/dist/ipc.js +4 -4
- package/dist/{links-BcfGBoRt.js → links-D_1RhPh5.js} +8 -8
- package/dist/{links-BcfGBoRt.js.map → links-D_1RhPh5.js.map} +1 -1
- package/dist/{loaded-entry-C0h8OMwN.js → loaded-entry-CLva6GQT.js} +2 -2
- package/dist/{loaded-entry-C0h8OMwN.js.map → loaded-entry-CLva6GQT.js.map} +1 -1
- package/dist/{memory-CZNbjYxJ.js → memory-CaFXUvQs.js} +15 -15
- package/dist/{memory-CZNbjYxJ.js.map → memory-CaFXUvQs.js.map} +1 -1
- package/dist/{path-display-DfFjoqUy.js → path-display-ZIWdFaTI.js} +3 -3
- package/dist/{path-display-DfFjoqUy.js.map → path-display-ZIWdFaTI.js.map} +1 -1
- package/dist/providers/google.js +1 -1
- package/dist/{providers-CCPHw25p.js → providers-CsYrxuX1.js} +2 -2
- package/dist/{providers-CCPHw25p.js.map → providers-CsYrxuX1.js.map} +1 -1
- package/dist/providers.js +1 -1
- package/dist/{registry-C-U_tMPi.js → registry-BY45AOA-.js} +2 -2
- package/dist/{registry-C-U_tMPi.js.map → registry-BY45AOA-.js.map} +1 -1
- package/dist/{registry-d-R3YZs1.js → registry-DTotchq6.js} +2 -2
- package/dist/{registry-d-R3YZs1.js.map → registry-DTotchq6.js.map} +1 -1
- package/dist/{registry-DHSQ4fdV.js → registry-Dl6261Xh.js} +2 -2
- package/dist/{registry-DHSQ4fdV.js.map → registry-Dl6261Xh.js.map} +1 -1
- package/dist/{remote-hosts-D77F5uTa.js → remote-hosts-usqMiMbs.js} +4 -4
- package/dist/{remote-hosts-D77F5uTa.js.map → remote-hosts-usqMiMbs.js.map} +1 -1
- package/dist/{setting-Cog4WQc1.js → setting-DzTMJIV3.js} +2 -2
- package/dist/{setting-Cog4WQc1.js.map → setting-DzTMJIV3.js.map} +1 -1
- package/dist/{settings-keys-B1q2NwvM.js → settings-keys-DDrfnBHi.js} +2 -2
- package/dist/{settings-keys-B1q2NwvM.js.map → settings-keys-DDrfnBHi.js.map} +1 -1
- package/dist/{system-freeze-CMY7QnoD.js → system-freeze-CY4Hc9WX.js} +2 -2
- package/dist/{system-freeze-CMY7QnoD.js.map → system-freeze-CY4Hc9WX.js.map} +1 -1
- package/dist/tui.js +15 -15
- package/dist/{version-DiGN0H-_.js → version-Bu3Nc8-U.js} +2 -2
- package/dist/{version-DiGN0H-_.js.map → version-Bu3Nc8-U.js.map} +1 -1
- package/dist/{wire-D4NlIUMg.js → wire-BKcREhuL.js} +2 -2
- package/dist/{wire-D4NlIUMg.js.map → wire-BKcREhuL.js.map} +1 -1
- package/dist/{ws-6EUa8pzM.js → ws-DriNRyP-.js} +4 -4
- package/dist/{ws-6EUa8pzM.js.map → ws-DriNRyP-.js.map} +1 -1
- package/dist/{ws-client-5i2lbQnC.js → ws-client-PZdbO0fj.js} +2 -2
- package/dist/{ws-client-5i2lbQnC.js.map → ws-client-PZdbO0fj.js.map} +1 -1
- package/docs/RELEASE.md +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor-BUWZhsfn.js","names":[],"sources":["../src/ipc/machine/params.ts","../src/ipc/machine/streams.ts","../src/ipc/machine/task-logs.ts","../src/ipc/machine/terminals.ts","../src/ipc/machine/executor.ts"],"sourcesContent":["/**\n * Shape checks for what a host sends a machine. The host is not trusted: a\n * malformed request is refused before anything runs.\n */\nimport type { MachineHandleRef } from '../../chat/machine-protocol'\n\nexport type Params = Record<string, unknown>\n\nexport function paramsOf(value: unknown): Params {\n if (!value || typeof value !== 'object' || Array.isArray(value))\n throw new Error('Invalid params: expected an object.')\n return value as Params\n}\n\nexport function str(params: Params, key: string): string {\n const value = params[key]\n if (typeof value !== 'string')\n throw new Error(`Invalid params: \"${key}\" must be a string.`)\n return value\n}\n\nexport function optStr(params: Params, key: string): string | undefined {\n const value = params[key]\n if (value === undefined)\n return undefined\n if (typeof value !== 'string')\n throw new Error(`Invalid params: \"${key}\" must be a string.`)\n return value\n}\n\nexport function optNum(params: Params, key: string): number | undefined {\n const value = params[key]\n if (value === undefined)\n return undefined\n if (typeof value !== 'number' || !Number.isFinite(value))\n throw new Error(`Invalid params: \"${key}\" must be a number.`)\n return value\n}\n\nexport function num(params: Params, key: string): number {\n const value = optNum(params, key)\n if (value === undefined)\n throw new Error(`Invalid params: \"${key}\" must be a number.`)\n return value\n}\n\nexport function optEnv(params: Params, key: string): Record<string, string> | undefined {\n const value = params[key]\n if (value === undefined)\n return undefined\n if (!value || typeof value !== 'object' || Array.isArray(value) || Object.values(value).some(v => typeof v !== 'string'))\n throw new Error(`Invalid params: \"${key}\" must map names to strings.`)\n return value as Record<string, string>\n}\n\nexport function handleRef(params: Params): MachineHandleRef {\n const handle = params.handle as Partial<MachineHandleRef> | undefined\n if (!handle || typeof handle.id !== 'string' || typeof handle.cwd !== 'string' || handle.id.length > 200)\n throw new Error('Invalid params: \"handle\" must be { id, cwd }.')\n return { id: handle.id, cwd: handle.cwd }\n}\n","/**\n * Live processes a machine runs for its host (`exec.stream`, `docs/MACHINES.md`):\n * `execStream` of its process context, its stdout / stderr sent as\n * `exec.stream.data` notifications (chunks of at most\n * `MACHINE_STREAM_CHUNK_BYTES`), then one `exec.stream.exit` once both are\n * drained. Bounded (`MACHINE_MAX_STREAMS`); a lost host link kills them all:\n * a stream carries a live protocol (a stdio MCP server), output it can't\n * deliver would desynchronize it.\n */\nimport type { ExecutionContext, ExecutionHandle, StreamHandle } from '../../contexts/types'\nimport { Buffer } from 'node:buffer'\nimport { MACHINE_MAX_STREAMS, MACHINE_STREAM_CHUNK_BYTES } from '../../chat/machine-protocol'\n\nexport interface MachineStreams {\n start: (context: ExecutionContext, handle: ExecutionHandle, input: { callId: string, command: string, cwd?: string, env?: Record<string, string> }) => Promise<{ pid: number }>\n write: (callId: string, data: string) => Promise<void>\n /** `exec.cancel` of a stream: `false` when no stream has this id. */\n kill: (callId: string) => boolean\n /** The host link dropped. */\n linkLost: () => void\n closeAll: () => Promise<void>\n /** Live streams. */\n count: () => number\n}\n\nexport function createMachineStreams(options: {\n send: (method: 'exec.stream.data' | 'exec.stream.exit', params: Record<string, unknown>) => boolean\n}): MachineStreams {\n const streams = new Map<string, StreamHandle>()\n\n async function pump(callId: string, name: 'stdout' | 'stderr', source: AsyncIterable<Uint8Array> | undefined): Promise<void> {\n if (!source)\n return\n for await (const chunk of source) {\n for (let at = 0; at < chunk.byteLength; at += MACHINE_STREAM_CHUNK_BYTES) {\n const data = Buffer.from(chunk.subarray(at, at + MACHINE_STREAM_CHUNK_BYTES)).toString('base64')\n if (!options.send('exec.stream.data', { callId, stream: name, data }))\n void streams.get(callId)?.kill()\n }\n }\n }\n\n const kill = (callId: string): boolean => {\n const stream = streams.get(callId)\n if (!stream)\n return false\n void stream.kill().catch(() => undefined)\n return true\n }\n\n return {\n async start(context, handle, { callId, command, cwd, env }) {\n if (!context.execStream)\n throw new Error('This machine cannot stream processes.')\n if (streams.has(callId))\n throw new Error(`A stream \"${callId}\" already runs.`)\n if (streams.size >= MACHINE_MAX_STREAMS)\n throw new Error(`This machine already runs ${MACHINE_MAX_STREAMS} live processes.`)\n const stream = await context.execStream(handle, command, { ...(cwd ? { cwd } : {}), ...(env ? { env } : {}) })\n streams.set(callId, stream)\n void Promise.all([pump(callId, 'stdout', stream.stdout), pump(callId, 'stderr', stream.stderr), stream.exited])\n .catch(() => undefined)\n .then(async () => {\n const code = await stream.exited\n streams.delete(callId)\n options.send('exec.stream.exit', { callId, code })\n })\n return { pid: stream.pid }\n },\n async write(callId, data) {\n const stream = streams.get(callId)\n if (!stream)\n throw new Error(`No live process \"${callId}\" on this machine.`)\n const bytes = Buffer.from(data, 'base64')\n if (bytes.byteLength > MACHINE_STREAM_CHUNK_BYTES)\n throw new Error(`exec.stream.write: at most ${MACHINE_STREAM_CHUNK_BYTES} bytes per call.`)\n await stream.write(bytes)\n },\n kill,\n linkLost() {\n for (const callId of streams.keys())\n kill(callId)\n },\n async closeAll() {\n const all = [...streams.values()]\n streams.clear()\n await Promise.all(all.map(stream => stream.kill().catch(() => undefined)))\n },\n count: () => streams.size,\n }\n}\n","/**\n * The machine's background-task logs (`<data dir>/tasks/`): the one place in\n * its data dir the host may read, and only the logs of tasks this machine\n * started. A command run for the host can reach that folder (no sandbox, or\n * a sandbox that allows the data dir's parent), so a log path is never\n * trusted as a path: it is opened without following a symlink, must be a\n * regular file, and its real path must be the same file inside the tasks\n * dir. Otherwise `ln -sf ~/.zidane/credentials.json <log>` would make the\n * (unsandboxed) machine process read anything for the host.\n */\nimport { Buffer } from 'node:buffer'\nimport { chmodSync, closeSync, constants, fstatSync, lstatSync, mkdirSync, openSync, readFileSync, realpathSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { isInside } from '../../chat/workspace-confinement'\n\nconst NO_FOLLOW = constants.O_NOFOLLOW ?? 0\n\nexport interface TaskLogs {\n /** The folder a handle's task logs go in: made owner-only, refused when it is not a real folder in the tasks dir. */\n outputDir: (handleId: string) => string\n add: (path: string) => void\n /** The task that writes `path` ended: {@link TaskLogs.prune} may forget its log. */\n finish: (path: string) => void\n /** Forget logs of ended tasks, oldest first, until at most `max` are known. Logs of running tasks stay. Returns how many are known. */\n prune: (max: number) => number\n has: (path: string) => boolean\n count: () => number\n read: (path: string, binary: boolean) => string\n size: (path: string) => number\n}\n\n/** `path` made (or kept) an owner-only real folder; a symlink there is refused, never followed. */\nfunction ownerOnlyDir(path: string): void {\n mkdirSync(path, { recursive: true, mode: 0o700 })\n const stat = lstatSync(path)\n if (!stat.isDirectory() || stat.isSymbolicLink())\n throw new Error(`${path} is not a folder of this machine's task logs.`)\n chmodSync(path, 0o700)\n}\n\nexport function createTaskLogs(dataDir: string): TaskLogs {\n const dir = join(dataDir, 'tasks')\n ownerOnlyDir(dir)\n const realDir = realpathSync.native(dir)\n /** Path → its task ended. Insertion order is start order. */\n const known = new Map<string, boolean>()\n /** Tasks that ended before `add` saw their log. */\n const endedEarly = new Set<string>()\n const refused = (path: string): Error => new Error(`${path} is not a task log of this machine.`)\n\n /** An fd on the log at `path`, checked as the module header says; the caller closes it. */\n const open = (path: string): number => {\n let fd: number\n try {\n fd = openSync(path, constants.O_RDONLY | NO_FOLLOW)\n }\n catch {\n throw refused(path)\n }\n try {\n const opened = fstatSync(fd)\n const real = realpathSync.native(path)\n const named = statSync(real)\n if (!opened.isFile() || !isInside(realDir, real) || named.ino !== opened.ino || named.dev !== opened.dev)\n throw refused(path)\n return fd\n }\n catch {\n closeSync(fd)\n throw refused(path)\n }\n }\n\n const withLog = <T>(path: string, fn: (fd: number) => T): T => {\n const fd = open(path)\n try {\n return fn(fd)\n }\n finally {\n closeSync(fd)\n }\n }\n\n return {\n outputDir(handleId) {\n const path = join(dir, Buffer.from(handleId).toString('hex').slice(0, 64))\n ownerOnlyDir(path)\n if (!isInside(realDir, realpathSync.native(path)))\n throw new Error(`${path} is not a folder of this machine's task logs.`)\n return path\n },\n add: path => void known.set(path, endedEarly.delete(path)),\n finish(path) {\n if (known.has(path))\n known.set(path, true)\n else\n endedEarly.add(path)\n },\n prune(max) {\n for (const [path, ended] of known) {\n if (known.size <= max)\n break\n if (ended)\n known.delete(path)\n }\n return known.size\n },\n has: path => known.has(path),\n count: () => known.size,\n read: (path, binary) => withLog(path, fd => (binary ? readFileSync(fd).toString('base64') : readFileSync(fd, 'utf8'))),\n size: path => withLog(path, fd => fstatSync(fd).size),\n }\n}\n","/**\n * PTYs a machine runs for its host. They outlive the host link for a grace\n * period, buffering their output (bounded), so a host that reconnects\n * reattaches with the backlog; past the grace they are killed.\n */\nimport type { ExecutionContext, ExecutionHandle, TerminalProcess } from '../../contexts/types'\nimport { Buffer } from 'node:buffer'\n\nexport const MACHINE_MAX_TERMINALS = 16\nexport const MACHINE_TERMINAL_BACKLOG_BYTES = 256 * 1024\nexport const MACHINE_TERMINAL_GRACE_MS = 5 * 60 * 1000\n\ninterface Entry {\n process: TerminalProcess\n backlog: Buffer[]\n backlogBytes: number\n /** Bytes produced since it opened. */\n total: number\n graceTimer?: ReturnType<typeof setTimeout>\n}\n\nexport interface MachineTerminals {\n open: (context: ExecutionContext, handle: ExecutionHandle, options: { cols: number, rows: number, cwd?: string }) => Promise<string>\n attach: (terminalId: string) => { attached: boolean, backlog: string, total: number }\n write: (terminalId: string, data: string) => void\n resize: (terminalId: string, cols: number, rows: number) => void\n kill: (terminalId: string) => Promise<void>\n /** The host link dropped: start every terminal's grace period. */\n linkLost: () => void\n closeAll: () => Promise<void>\n /** Live terminals. */\n count: () => number\n}\n\nexport function createMachineTerminals(options: {\n /** Live output to the host; `false` when the link is down. */\n send: (method: 'terminal.data' | 'terminal.exit', params: Record<string, unknown>) => boolean\n graceMs?: number\n}): MachineTerminals {\n const terminals = new Map<string, Entry>()\n const graceMs = options.graceMs ?? MACHINE_TERMINAL_GRACE_MS\n\n const entry = (terminalId: string): Entry => {\n const found = terminals.get(terminalId)\n if (!found)\n throw new Error(`No terminal \"${terminalId}\" on this machine.`)\n return found\n }\n\n const remember = (e: Entry, data: Uint8Array): void => {\n e.backlog.push(Buffer.from(data))\n e.backlogBytes += data.byteLength\n e.total += data.byteLength\n while (e.backlogBytes > MACHINE_TERMINAL_BACKLOG_BYTES && e.backlog.length > 1)\n e.backlogBytes -= e.backlog.shift()!.byteLength\n }\n\n const kill = async (terminalId: string): Promise<void> => {\n const e = terminals.get(terminalId)\n if (!e)\n return\n terminals.delete(terminalId)\n clearTimeout(e.graceTimer)\n await e.process.kill().catch(() => undefined)\n }\n\n return {\n async open(context, handle, { cols, rows, cwd }) {\n if (!context.openTerminal)\n throw new Error('This machine has no terminal support (it needs Bun).')\n if (terminals.size >= MACHINE_MAX_TERMINALS)\n throw new Error(`This machine already runs ${MACHINE_MAX_TERMINALS} terminals.`)\n const holder: { id?: string } = {}\n const pending: Uint8Array[] = []\n const process = await context.openTerminal(handle, {\n cols,\n rows,\n ...(cwd ? { cwd } : {}),\n onData: (data) => {\n const e = holder.id ? terminals.get(holder.id) : undefined\n if (!e) {\n pending.push(data)\n return\n }\n remember(e, data)\n options.send('terminal.data', { terminalId: holder.id, data: Buffer.from(data).toString('base64') })\n },\n })\n holder.id = process.id\n const e: Entry = { process, backlog: [], backlogBytes: 0, total: 0 }\n terminals.set(process.id, e)\n for (const data of pending)\n remember(e, data)\n void process.exited.then((code) => {\n if (terminals.get(process.id) !== e)\n return\n terminals.delete(process.id)\n clearTimeout(e.graceTimer)\n options.send('terminal.exit', { terminalId: process.id, code })\n })\n return process.id\n },\n attach(terminalId) {\n const e = terminals.get(terminalId)\n if (!e)\n return { attached: false, backlog: '', total: 0 }\n clearTimeout(e.graceTimer)\n e.graceTimer = undefined\n return { attached: true, backlog: Buffer.concat(e.backlog).toString('base64'), total: e.total }\n },\n write: (terminalId, data) => entry(terminalId).process.write(Buffer.from(data, 'base64')),\n resize: (terminalId, cols, rows) => entry(terminalId).process.resize(cols, rows),\n kill,\n linkLost() {\n for (const [id, e] of terminals) {\n clearTimeout(e.graceTimer)\n e.graceTimer = setTimeout(() => void kill(id), graceMs)\n e.graceTimer.unref?.()\n }\n },\n async closeAll() {\n await Promise.all([...terminals.keys()].map(kill))\n },\n count: () => terminals.size,\n }\n}\n","/**\n * What a machine runs for its host (`docs/MACHINES.md` § Machine side): the\n * machine protocol's host→machine methods, served from one `process`\n * execution context, behind a guard that never trusts the host. Every handle\n * cwd, command cwd and file path resolves against the handle's cwd and must\n * real-path into a declared root (symlinks followed), never into the\n * machine's data dir. The exceptions: its `worktrees/` (worktrees made there\n * are workspace content, `machineConfinement`), and reading a log file of a\n * background task this machine started (`./task-logs.ts`: opened without\n * following symlinks, checked to be that file).\n *\n * Transport-free: the agent (`./agent.ts`) feeds it requests and gives it a\n * `notify` toward the host, which is `false` while the link is down (task\n * exits are then queued until {@link MachineExecutor.linkUp}).\n */\nimport type { MachineRoot } from '../../chat/machine-protocol'\nimport type { LooseSandboxSettings } from '../../chat/sandbox-settings'\nimport type { WorkspaceConfinement } from '../../chat/workspace-confinement'\nimport type { ExecutionContext, ExecutionHandle, TaskExitInfo } from '../../contexts/types'\nimport type { Params } from './params'\nimport { Buffer } from 'node:buffer'\nimport { mkdirSync, realpathSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { isAbsolute, join, resolve } from 'node:path'\nimport { normalizeEnvironmentCheckout, workspacePath } from '../../chat/environment'\nimport { prepareWorktree, teardownWorktree } from '../../chat/environments'\nimport { resolveSandboxForRoots, sandboxUnreadableDirs } from '../../chat/sandbox-settings'\nimport { createWorkspaceConfinement, isInside } from '../../chat/workspace-confinement'\nimport { resolveStorageDirs } from '../../chat/xdg'\nimport { entryPortOf } from '../../contexts/entries'\nimport { createProcessContext } from '../../contexts/process'\nimport { handleRef, num, optEnv, optNum, optStr, paramsOf, str } from './params'\nimport { createMachineStreams } from './streams'\nimport { createTaskLogs } from './task-logs'\nimport { createMachineTerminals } from './terminals'\n\nexport const MACHINE_MAX_TASKS = 64\nexport const MACHINE_TASK_OUTPUT_BYTES = 8 * 1024 * 1024\nconst MAX_PENDING_EXITS = 256\nconst GLOB_CHARS = /[*?[\\]{}]/\n\nexport interface MachineExecutorOptions {\n roots: readonly MachineRoot[]\n /** The machine's own data dir: only its `worktrees/` and task logs are reachable by file ops. */\n dataDir: string\n /** A notification to the host; `false` when the link is down. */\n notify: (method: string, params: Record<string, unknown>) => boolean\n /** Terminals' grace after the link drops. */\n terminalGraceMs?: number\n /**\n * The machine user's own `sandbox*` settings (`docs/MACHINES.md` §\n * Sandbox): applied to every command this machine runs, whatever the host.\n */\n sandbox?: LooseSandboxSettings\n /**\n * The machine user's zidane data dir: private to file operations (with the\n * rest of {@link machinePrivateDirs}) and its credential files hidden from\n * sandboxed commands.\n */\n credentialsDataDir?: string\n /** Task logs kept before ended ones are forgotten (default 4 × {@link MACHINE_MAX_TASKS}). A test seam. */\n maxTaskLogs?: number\n}\n\n/**\n * What file operations never reach, whatever the roots (`docs/MACHINES.md` §\n * Security model): zidane's own folders as this process resolves them (data,\n * config, state, cache: credentials, tokens, extensions, plugins, skills,\n * mcps.json, SYSTEM.md, the machine's data, sync files), the default\n * `~/.zidane`, the given data dir (a server's `--data-dir`), and the\n * credential folders the sandbox hides (`~/.ssh`, `~/.aws`, …).\n */\nexport function machinePrivateDirs(zidaneDataDir?: string): string[] {\n const storage = resolveStorageDirs()\n return [...new Set([\n ...(zidaneDataDir ? [zidaneDataDir] : []),\n storage.dataDir,\n storage.configDir,\n storage.stateDir,\n storage.cacheDir,\n join(homedir(), '.zidane'),\n ...sandboxUnreadableDirs(zidaneDataDir),\n ])]\n}\n\nexport interface MachineExecutor {\n /** Serve one host request; throws (the agent turns it into a JSON-RPC error). */\n handle: (method: string, params: unknown) => Promise<unknown>\n /** The host link is (back) up: re-send what was queued. */\n linkUp: () => void\n /** The host link dropped: terminals start their grace. */\n linkLost: () => void\n close: () => Promise<void>\n /** What runs now: commands, background tasks, streams and terminals (a version update waits until all are 0). */\n activity: () => Promise<{ calls: number, tasks: number, streams: number, terminals: number }>\n /** The OS sandbox the machine applies, and why it can't when it is on but unavailable. */\n sandbox: { on: boolean, warning?: string }\n}\n\n/** The static directory of a glob (`/a/b/**\\/*.ts` → `/a/b`). */\nfunction globBase(path: string): string {\n const segments = path.split('/')\n const index = segments.findIndex(s => GLOB_CHARS.test(s))\n return index < 0 ? path : segments.slice(0, index).join('/') || '/'\n}\n\n/**\n * A folder a user offers to share (`zidane machine share --root`, a share\n * link): its real path must exist and not be, or be inside, a private\n * folder (a root there would lend what {@link machinePrivateDirs} keeps out).\n * Returns the real path.\n */\nexport function shareableRoot(root: string, zidaneDataDir?: string): string {\n let real: string\n try {\n real = realpathSync.native(root)\n }\n catch {\n throw new Error(`${root} does not exist.`)\n }\n const hidden = machinePrivateDirs(zidaneDataDir).map(realPathOr).find(dir => isInside(dir, real))\n if (hidden)\n throw new Error(`${root} is inside ${hidden} (zidane's own data or credentials): share a folder outside it.`)\n return real\n}\n\nfunction realPathOr(path: string): string {\n try {\n return realpathSync.native(path)\n }\n catch {\n return path\n }\n}\n\nexport function machineConfinement(roots: readonly MachineRoot[], dataDir: string, privateDirs: readonly string[] = []): WorkspaceConfinement {\n // Worktrees made in the data dir's `worktrees/` are workspace content; nothing else there is.\n const worktrees = join(dataDir, 'worktrees')\n mkdirSync(worktrees, { recursive: true })\n return createWorkspaceConfinement([...roots.map(root => root.path), worktrees], {\n dataDir,\n privateDirs,\n names: { roots: 'the machine\\'s roots', dataDir: 'the machine\\'s data dir, which the host can\\'t reach' },\n })\n}\n\n/**\n * A listing's entries whose real path is reachable: a traversal can follow a\n * symlinked folder out of the roots, or walk into a private one, from a base\n * that passed the check.\n */\nfunction reachableEntries<T>(confinement: WorkspaceConfinement, base: string, entries: readonly T[]): T[] {\n return entries.filter((entry) => {\n const path = typeof entry === 'string' ? entry : (entry as { path?: unknown }).path\n if (typeof path !== 'string')\n return false\n try {\n confinement.checkPath(isAbsolute(path) ? path : resolve(base, path))\n return true\n }\n catch {\n return false\n }\n })\n}\n\n/** `fs.list`: a path or glob under the handle's cwd, no `..` in a pattern, only reachable entries back. */\nasync function listReachable(context: ExecutionContext, confinement: WorkspaceConfinement, handle: ExecutionHandle, params: Params): Promise<unknown[]> {\n const pattern = str(params, 'path')\n if (GLOB_CHARS.test(pattern) && pattern.split(/[/\\\\]/).includes('..'))\n throw new Error(`\"${pattern}\": a pattern can't climb with \"..\".`)\n const path = workspacePath(handle.cwd, pattern)\n confinement.checkPath(globBase(path))\n const raw = params.options && typeof params.options === 'object' ? params.options as Record<string, unknown> : {}\n const listOptions = {\n ...(typeof raw.glob === 'boolean' ? { glob: raw.glob } : {}),\n ...(typeof raw.limit === 'number' ? { limit: raw.limit } : {}),\n ...(typeof raw.metadata === 'boolean' ? { metadata: raw.metadata } : {}),\n ...(typeof raw.gitignore === 'boolean' ? { gitignore: raw.gitignore } : {}),\n }\n return reachableEntries(confinement, globBase(path), await context.listFiles(handle, path, listOptions))\n}\n\n/** One process context for every handle, under the machine user's own sandbox when it is on. */\nfunction sandboxedContext(options: MachineExecutorOptions, confinement: WorkspaceConfinement): { sandbox: ReturnType<typeof resolveSandboxForRoots>, context: ExecutionContext } {\n const sandbox = resolveSandboxForRoots(options.sandbox ?? { sandbox: false }, confinement.roots, {\n ...(options.credentialsDataDir ? { dataDir: options.credentialsDataDir } : {}),\n // Not the task logs: the machine process writes them, and a command able to write there could swap one for a symlink.\n })\n return { sandbox, context: createProcessContext({ cwd: confinement.roots[0]!, ...(sandbox.isolation ? { isolation: sandbox.isolation } : {}) }) }\n}\n\n/**\n * The entry calls (`fs.stat`, `fs.readdir`, `fs.mkdir`, `fs.move`, `fs.copy`,\n * `fs.remove`, `fs.emptyDirs`): every path confined like `fs.write`'s, then\n * the process context's own entry port (it never overwrites).\n */\nfunction entryMethods(\n context: ExecutionContext,\n confinement: WorkspaceConfinement,\n handleFor: (params: Params) => Promise<ExecutionHandle>,\n checked: (handle: ExecutionHandle, path: string) => string,\n): Record<string, (params: Params) => Promise<unknown>> {\n const on = async (params: Params) => {\n const handle = await handleFor(params)\n return {\n handle,\n port: entryPortOf(context, handle),\n path: (key: string) => checked(handle, str(params, key)),\n // The entry itself, never followed: a link pointing out can still be renamed or removed.\n entry: (key: string) => {\n const absolute = workspacePath(handle.cwd, str(params, key))\n confinement.checkEntry(absolute)\n return absolute\n },\n }\n }\n return {\n 'fs.stat': async (params) => {\n const { port, entry } = await on(params)\n return { kind: await port.stat(entry('path')) }\n },\n 'fs.readdir': async (params) => {\n const { port, path } = await on(params)\n return { names: await port.list(path('path')) }\n },\n 'fs.mkdir': async (params) => {\n const { port, path } = await on(params)\n await port.mkdir(path('path'))\n return { ok: true }\n },\n 'fs.move': async (params) => {\n const { port, entry } = await on(params)\n await port.move(entry('from'), entry('to'))\n return { ok: true }\n },\n 'fs.copy': async (params) => {\n const { port, path } = await on(params)\n await port.copy(path('from'), path('to'))\n return { ok: true }\n },\n 'fs.remove': async (params) => {\n const { port, entry } = await on(params)\n await port.remove(entry('path'))\n return { ok: true }\n },\n 'fs.emptyDirs': async (params) => {\n const { port, path } = await on(params)\n const base = path('path')\n const found = await port.emptyDirs(base, Math.min(num(params, 'limit'), 10_000))\n // A symlinked folder can lead out of the roots: only what is reachable comes back.\n return { paths: reachableEntries(confinement, base, found) }\n },\n }\n}\n\n/** Background tasks still running on these handles. */\nasync function runningTasks(context: ExecutionContext, handles: Iterable<ExecutionHandle>): Promise<number> {\n let running = 0\n for (const handle of handles)\n running += (await context.listBackground?.(handle).catch(() => []) ?? []).filter(t => t.status === 'running').length\n return running\n}\n\nexport function createMachineExecutor(options: MachineExecutorOptions): MachineExecutor {\n const confinement = machineConfinement(options.roots, options.dataDir, machinePrivateDirs(options.credentialsDataDir))\n const { sandbox, context } = sandboxedContext(options, confinement)\n const handles = new Map<string, ExecutionHandle>()\n const calls = new Map<string, AbortController>()\n const taskLogs = createTaskLogs(options.dataDir)\n const pendingExits: Array<Record<string, unknown>> = []\n const terminals = createMachineTerminals({ send: options.notify, ...(options.terminalGraceMs !== undefined ? { graceMs: options.terminalGraceMs } : {}) })\n const streams = createMachineStreams({ send: options.notify })\n\n /** A handle's cwd, checked on every call (not only at spawn): the host names it each time. */\n async function handleFor(params: Params): Promise<ExecutionHandle> {\n const ref = handleRef(params)\n const cwd = confinement.resolveFolder(ref.cwd)\n const existing = handles.get(ref.id)\n if (existing && existing.cwd === cwd)\n return existing\n const handle = await context.spawn({ cwd })\n handles.set(ref.id, handle)\n // The id now names another folder: the old handle (and its tasks) would otherwise live on unreachable.\n if (existing)\n await context.destroy(existing).catch(() => undefined)\n return handle\n }\n\n /** `path` resolved like the context resolves it, then confined. */\n function checked(handle: ExecutionHandle, path: string): string {\n const absolute = workspacePath(handle.cwd, path)\n confinement.checkPath(absolute)\n return absolute\n }\n\n /** A log of a task this machine started, by its path (never through the context: see `./task-logs.ts`). */\n const taskLog = (handle: ExecutionHandle, path: string): string | undefined => {\n const absolute = workspacePath(handle.cwd, path)\n return taskLogs.has(absolute) ? absolute : undefined\n }\n\n const cwdOption = (handle: ExecutionHandle, params: Params): { cwd?: string } => {\n const cwd = optStr(params, 'cwd')\n return cwd === undefined ? {} : { cwd: confinement.resolveFolder(workspacePath(handle.cwd, cwd)) }\n }\n\n const taskExited = (info: TaskExitInfo): void => {\n taskLogs.finish(info.outputPath)\n const exit = { taskId: info.taskId, exit: { ...info } }\n if (options.notify('task.exit', exit))\n return\n pendingExits.push(exit)\n if (pendingExits.length > MAX_PENDING_EXITS)\n pendingExits.shift()\n }\n\n const methods: Record<string, (params: Params) => Promise<unknown>> = {\n 'machine.ping': async () => ({ ok: true }),\n 'exec.spawn': async (params) => {\n const handle = await handleFor(params)\n return { id: handleRef(params).id, cwd: handle.cwd }\n },\n 'exec.run': async (params) => {\n const handle = await handleFor(params)\n const callId = str(params, 'callId')\n // A second call under one id would take over its cancel: the first could no longer be stopped.\n if (calls.has(callId))\n throw new Error(`A call \"${callId}\" is already running.`)\n const controller = new AbortController()\n calls.set(callId, controller)\n try {\n const env = optEnv(params, 'env')\n const timeout = optNum(params, 'timeout')\n return await context.exec(handle, str(params, 'command'), { ...cwdOption(handle, params), ...(env ? { env } : {}), ...(timeout !== undefined ? { timeout } : {}), signal: controller.signal })\n }\n finally {\n calls.delete(callId)\n }\n },\n 'exec.cancel': async (params) => {\n const callId = str(params, 'callId')\n const controller = calls.get(callId)\n controller?.abort()\n return { cancelled: controller !== undefined || streams.kill(callId) }\n },\n 'exec.stream': async (params) => {\n const handle = await handleFor(params)\n const env = optEnv(params, 'env')\n return streams.start(context, handle, { callId: str(params, 'callId'), command: str(params, 'command'), ...cwdOption(handle, params), ...(env ? { env } : {}) })\n },\n 'exec.stream.write': async (params) => {\n await streams.write(str(params, 'callId'), str(params, 'data'))\n return { ok: true }\n },\n 'exec.destroy': async (params) => {\n const ref = handleRef(params)\n const handle = handles.get(ref.id)\n handles.delete(ref.id)\n if (handle)\n await context.destroy(handle)\n return { ok: true }\n },\n 'fs.read': async (params) => {\n const handle = await handleFor(params)\n const log = taskLog(handle, str(params, 'path'))\n if (log)\n return { content: taskLogs.read(log, params.binary === true) }\n const path = checked(handle, str(params, 'path'))\n if (params.binary === true)\n return { content: Buffer.from(await context.readFileBinary!(handle, path)).toString('base64') }\n return { content: await context.readFile(handle, path) }\n },\n 'fs.write': async (params) => {\n const handle = await handleFor(params)\n const path = checked(handle, str(params, 'path'))\n // An entry create: the entry port's write never replaces a file that appeared since the check.\n const write = params.exclusive === true ? entryPortOf(context, handle).write : (p: string, b: Buffer) => context.writeFile(handle, p, b)\n await write(path, Buffer.from(str(params, 'content'), 'base64'))\n return { ok: true }\n },\n 'fs.list': async params => ({ entries: await listReachable(context, confinement, await handleFor(params), params) }),\n 'fs.size': async (params) => {\n const handle = await handleFor(params)\n const log = taskLog(handle, str(params, 'path'))\n return { size: log ? taskLogs.size(log) : await context.fileSize!(handle, checked(handle, str(params, 'path'))) }\n },\n ...entryMethods(context, confinement, handleFor, checked),\n 'bg.start': async (params) => {\n const handle = await handleFor(params)\n const running = (await context.listBackground!(handle)).filter(t => t.status === 'running').length\n if (taskLogs.prune((options.maxTaskLogs ?? MACHINE_MAX_TASKS * 4) - 1) >= (options.maxTaskLogs ?? MACHINE_MAX_TASKS * 4) || running >= MACHINE_MAX_TASKS)\n throw new Error(`This machine already runs ${MACHINE_MAX_TASKS} background tasks.`)\n const env = optEnv(params, 'env')\n const cap = optNum(params, 'maxOutputBytes')\n const task = await context.execBackground!(handle, str(params, 'command'), {\n ...cwdOption(handle, params),\n ...(env ? { env } : {}),\n outputDir: taskLogs.outputDir(handleRef(params).id),\n maxOutputBytes: Math.min(cap && cap > 0 ? cap : MACHINE_TASK_OUTPUT_BYTES, MACHINE_TASK_OUTPUT_BYTES),\n onExit: taskExited,\n })\n taskLogs.add(task.outputPath)\n return { taskId: task.taskId, pid: task.pid, outputPath: task.outputPath }\n },\n 'bg.list': async params => ({ tasks: await context.listBackground!(await handleFor(params)) }),\n 'bg.kill': async params => ({ exit: await context.killBackground!(await handleFor(params), str(params, 'taskId')) }),\n 'bg.wait': async (params) => {\n const timeoutMs = optNum(params, 'timeoutMs')\n return { exit: await context.waitBackground!(await handleFor(params), str(params, 'taskId'), timeoutMs !== undefined ? { timeoutMs } : {}) }\n },\n 'terminal.open': async (params) => {\n const handle = await handleFor(params)\n const terminalId = await terminals.open(context, handle, { cols: num(params, 'cols'), rows: num(params, 'rows'), ...cwdOption(handle, params) })\n return { terminalId }\n },\n 'terminal.attach': async params => terminals.attach(str(params, 'terminalId')),\n 'terminal.write': async (params) => {\n terminals.write(str(params, 'terminalId'), str(params, 'data'))\n return { ok: true }\n },\n 'terminal.resize': async (params) => {\n terminals.resize(str(params, 'terminalId'), num(params, 'cols'), num(params, 'rows'))\n return { ok: true }\n },\n 'terminal.kill': async (params) => {\n await terminals.kill(str(params, 'terminalId'))\n return { ok: true }\n },\n // The host stops viewing; the PTY keeps running (as after a lost link, without the grace).\n 'terminal.detach': async () => ({ ok: true }),\n 'env.checkFolder': async params => ({ cwd: confinement.resolveFolder(str(params, 'cwd')) }),\n 'env.prepareWorktree': async (params) => {\n const cwd = confinement.resolveFolder(str(params, 'cwd'))\n const config = (params.config && typeof params.config === 'object' ? params.config : {}) as Record<string, string | number | boolean>\n const base = optStr(params, 'base')\n const prepared = await prepareWorktree({ cwd, environment: { kind: 'worktree', state: 'provisioning', branch: str(params, 'branch'), ...(base ? { base } : {}), ...(params.checkout ? { checkout: normalizeEnvironmentCheckout(params.checkout) ?? {} } : {}) }, config }, options.dataDir)\n const ref = prepared.environment?.ref as { path: string, repoRoot: string }\n confinement.resolveFolder(ref.path)\n return { cwd: prepared.cwd ?? ref.path, branch: prepared.environment?.branch, base: prepared.environment?.base, ref }\n },\n 'env.teardownWorktree': async (params) => {\n const ref = (params.ref ?? {}) as { path?: unknown, repoRoot?: unknown }\n if (typeof ref.path !== 'string' || typeof ref.repoRoot !== 'string')\n throw new Error('Invalid params: \"ref\" must be { path, repoRoot }.')\n confinement.checkPath(ref.path)\n confinement.resolveFolder(ref.repoRoot)\n const config = (params.config && typeof params.config === 'object' ? params.config : {}) as Record<string, string | number | boolean>\n return teardownWorktree({ path: ref.path, repoRoot: ref.repoRoot }, optStr(params, 'branch'), config)\n },\n }\n\n return {\n async handle(method, raw) {\n if (!Object.hasOwn(methods, method))\n throw new Error(`Unknown machine method \"${method}\".`)\n return methods[method]!(paramsOf(raw))\n },\n linkUp() {\n while (pendingExits.length > 0) {\n if (!options.notify('task.exit', pendingExits[0]!))\n return\n pendingExits.shift()\n }\n },\n activity: async () => ({ calls: calls.size, tasks: await runningTasks(context, handles.values()), streams: streams.count(), terminals: terminals.count() }),\n sandbox: { on: sandbox.isolation !== undefined, ...(sandbox.warning ? { warning: sandbox.warning } : {}) },\n linkLost: () => { terminals.linkLost(); streams.linkLost() },\n async close() {\n for (const controller of calls.values())\n controller.abort()\n await streams.closeAll()\n await terminals.closeAll()\n await Promise.all([...handles.values()].map(handle => context.destroy(handle).catch(() => undefined)))\n handles.clear()\n },\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"executor-DlW7qAeN.js","names":[],"sources":["../src/ipc/machine/params.ts","../src/ipc/machine/streams.ts","../src/ipc/machine/task-logs.ts","../src/ipc/machine/terminals.ts","../src/ipc/machine/executor.ts"],"sourcesContent":["/**\n * Shape checks for what a host sends a machine. The host is not trusted: a\n * malformed request is refused before anything runs.\n */\nimport type { MachineHandleRef } from '../../chat/machine-protocol'\n\nexport type Params = Record<string, unknown>\n\nexport function paramsOf(value: unknown): Params {\n if (!value || typeof value !== 'object' || Array.isArray(value))\n throw new Error('Invalid params: expected an object.')\n return value as Params\n}\n\nexport function str(params: Params, key: string): string {\n const value = params[key]\n if (typeof value !== 'string')\n throw new Error(`Invalid params: \"${key}\" must be a string.`)\n return value\n}\n\nexport function optStr(params: Params, key: string): string | undefined {\n const value = params[key]\n if (value === undefined)\n return undefined\n if (typeof value !== 'string')\n throw new Error(`Invalid params: \"${key}\" must be a string.`)\n return value\n}\n\nexport function optNum(params: Params, key: string): number | undefined {\n const value = params[key]\n if (value === undefined)\n return undefined\n if (typeof value !== 'number' || !Number.isFinite(value))\n throw new Error(`Invalid params: \"${key}\" must be a number.`)\n return value\n}\n\nexport function num(params: Params, key: string): number {\n const value = optNum(params, key)\n if (value === undefined)\n throw new Error(`Invalid params: \"${key}\" must be a number.`)\n return value\n}\n\nexport function optEnv(params: Params, key: string): Record<string, string> | undefined {\n const value = params[key]\n if (value === undefined)\n return undefined\n if (!value || typeof value !== 'object' || Array.isArray(value) || Object.values(value).some(v => typeof v !== 'string'))\n throw new Error(`Invalid params: \"${key}\" must map names to strings.`)\n return value as Record<string, string>\n}\n\nexport function handleRef(params: Params): MachineHandleRef {\n const handle = params.handle as Partial<MachineHandleRef> | undefined\n if (!handle || typeof handle.id !== 'string' || typeof handle.cwd !== 'string' || handle.id.length > 200)\n throw new Error('Invalid params: \"handle\" must be { id, cwd }.')\n return { id: handle.id, cwd: handle.cwd }\n}\n","/**\n * Live processes a machine runs for its host (`exec.stream`, `docs/MACHINES.md`):\n * `execStream` of its process context, its stdout / stderr sent as\n * `exec.stream.data` notifications (chunks of at most\n * `MACHINE_STREAM_CHUNK_BYTES`), then one `exec.stream.exit` once both are\n * drained. Bounded (`MACHINE_MAX_STREAMS`); a lost host link kills them all:\n * a stream carries a live protocol (a stdio MCP server), output it can't\n * deliver would desynchronize it.\n */\nimport type { ExecutionContext, ExecutionHandle, StreamHandle } from '../../contexts/types'\nimport { Buffer } from 'node:buffer'\nimport { MACHINE_MAX_STREAMS, MACHINE_STREAM_CHUNK_BYTES } from '../../chat/machine-protocol'\n\nexport interface MachineStreams {\n start: (context: ExecutionContext, handle: ExecutionHandle, input: { callId: string, command: string, cwd?: string, env?: Record<string, string> }) => Promise<{ pid: number }>\n write: (callId: string, data: string) => Promise<void>\n /** `exec.cancel` of a stream: `false` when no stream has this id. */\n kill: (callId: string) => boolean\n /** The host link dropped. */\n linkLost: () => void\n closeAll: () => Promise<void>\n /** Live streams. */\n count: () => number\n}\n\nexport function createMachineStreams(options: {\n send: (method: 'exec.stream.data' | 'exec.stream.exit', params: Record<string, unknown>) => boolean\n}): MachineStreams {\n const streams = new Map<string, StreamHandle>()\n\n async function pump(callId: string, name: 'stdout' | 'stderr', source: AsyncIterable<Uint8Array> | undefined): Promise<void> {\n if (!source)\n return\n for await (const chunk of source) {\n for (let at = 0; at < chunk.byteLength; at += MACHINE_STREAM_CHUNK_BYTES) {\n const data = Buffer.from(chunk.subarray(at, at + MACHINE_STREAM_CHUNK_BYTES)).toString('base64')\n if (!options.send('exec.stream.data', { callId, stream: name, data }))\n void streams.get(callId)?.kill()\n }\n }\n }\n\n const kill = (callId: string): boolean => {\n const stream = streams.get(callId)\n if (!stream)\n return false\n void stream.kill().catch(() => undefined)\n return true\n }\n\n return {\n async start(context, handle, { callId, command, cwd, env }) {\n if (!context.execStream)\n throw new Error('This machine cannot stream processes.')\n if (streams.has(callId))\n throw new Error(`A stream \"${callId}\" already runs.`)\n if (streams.size >= MACHINE_MAX_STREAMS)\n throw new Error(`This machine already runs ${MACHINE_MAX_STREAMS} live processes.`)\n const stream = await context.execStream(handle, command, { ...(cwd ? { cwd } : {}), ...(env ? { env } : {}) })\n streams.set(callId, stream)\n void Promise.all([pump(callId, 'stdout', stream.stdout), pump(callId, 'stderr', stream.stderr), stream.exited])\n .catch(() => undefined)\n .then(async () => {\n const code = await stream.exited\n streams.delete(callId)\n options.send('exec.stream.exit', { callId, code })\n })\n return { pid: stream.pid }\n },\n async write(callId, data) {\n const stream = streams.get(callId)\n if (!stream)\n throw new Error(`No live process \"${callId}\" on this machine.`)\n const bytes = Buffer.from(data, 'base64')\n if (bytes.byteLength > MACHINE_STREAM_CHUNK_BYTES)\n throw new Error(`exec.stream.write: at most ${MACHINE_STREAM_CHUNK_BYTES} bytes per call.`)\n await stream.write(bytes)\n },\n kill,\n linkLost() {\n for (const callId of streams.keys())\n kill(callId)\n },\n async closeAll() {\n const all = [...streams.values()]\n streams.clear()\n await Promise.all(all.map(stream => stream.kill().catch(() => undefined)))\n },\n count: () => streams.size,\n }\n}\n","/**\n * The machine's background-task logs (`<data dir>/tasks/`): the one place in\n * its data dir the host may read, and only the logs of tasks this machine\n * started. A command run for the host can reach that folder (no sandbox, or\n * a sandbox that allows the data dir's parent), so a log path is never\n * trusted as a path: it is opened without following a symlink, must be a\n * regular file, and its real path must be the same file inside the tasks\n * dir. Otherwise `ln -sf ~/.zidane/credentials.json <log>` would make the\n * (unsandboxed) machine process read anything for the host.\n */\nimport { Buffer } from 'node:buffer'\nimport { chmodSync, closeSync, constants, fstatSync, lstatSync, mkdirSync, openSync, readFileSync, realpathSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { isInside } from '../../chat/workspace-confinement'\n\nconst NO_FOLLOW = constants.O_NOFOLLOW ?? 0\n\nexport interface TaskLogs {\n /** The folder a handle's task logs go in: made owner-only, refused when it is not a real folder in the tasks dir. */\n outputDir: (handleId: string) => string\n add: (path: string) => void\n /** The task that writes `path` ended: {@link TaskLogs.prune} may forget its log. */\n finish: (path: string) => void\n /** Forget logs of ended tasks, oldest first, until at most `max` are known. Logs of running tasks stay. Returns how many are known. */\n prune: (max: number) => number\n has: (path: string) => boolean\n count: () => number\n read: (path: string, binary: boolean) => string\n size: (path: string) => number\n}\n\n/** `path` made (or kept) an owner-only real folder; a symlink there is refused, never followed. */\nfunction ownerOnlyDir(path: string): void {\n mkdirSync(path, { recursive: true, mode: 0o700 })\n const stat = lstatSync(path)\n if (!stat.isDirectory() || stat.isSymbolicLink())\n throw new Error(`${path} is not a folder of this machine's task logs.`)\n chmodSync(path, 0o700)\n}\n\nexport function createTaskLogs(dataDir: string): TaskLogs {\n const dir = join(dataDir, 'tasks')\n ownerOnlyDir(dir)\n const realDir = realpathSync.native(dir)\n /** Path → its task ended. Insertion order is start order. */\n const known = new Map<string, boolean>()\n /** Tasks that ended before `add` saw their log. */\n const endedEarly = new Set<string>()\n const refused = (path: string): Error => new Error(`${path} is not a task log of this machine.`)\n\n /** An fd on the log at `path`, checked as the module header says; the caller closes it. */\n const open = (path: string): number => {\n let fd: number\n try {\n fd = openSync(path, constants.O_RDONLY | NO_FOLLOW)\n }\n catch {\n throw refused(path)\n }\n try {\n const opened = fstatSync(fd)\n const real = realpathSync.native(path)\n const named = statSync(real)\n if (!opened.isFile() || !isInside(realDir, real) || named.ino !== opened.ino || named.dev !== opened.dev)\n throw refused(path)\n return fd\n }\n catch {\n closeSync(fd)\n throw refused(path)\n }\n }\n\n const withLog = <T>(path: string, fn: (fd: number) => T): T => {\n const fd = open(path)\n try {\n return fn(fd)\n }\n finally {\n closeSync(fd)\n }\n }\n\n return {\n outputDir(handleId) {\n const path = join(dir, Buffer.from(handleId).toString('hex').slice(0, 64))\n ownerOnlyDir(path)\n if (!isInside(realDir, realpathSync.native(path)))\n throw new Error(`${path} is not a folder of this machine's task logs.`)\n return path\n },\n add: path => void known.set(path, endedEarly.delete(path)),\n finish(path) {\n if (known.has(path))\n known.set(path, true)\n else\n endedEarly.add(path)\n },\n prune(max) {\n for (const [path, ended] of known) {\n if (known.size <= max)\n break\n if (ended)\n known.delete(path)\n }\n return known.size\n },\n has: path => known.has(path),\n count: () => known.size,\n read: (path, binary) => withLog(path, fd => (binary ? readFileSync(fd).toString('base64') : readFileSync(fd, 'utf8'))),\n size: path => withLog(path, fd => fstatSync(fd).size),\n }\n}\n","/**\n * PTYs a machine runs for its host. They outlive the host link for a grace\n * period, buffering their output (bounded), so a host that reconnects\n * reattaches with the backlog; past the grace they are killed.\n */\nimport type { ExecutionContext, ExecutionHandle, TerminalProcess } from '../../contexts/types'\nimport { Buffer } from 'node:buffer'\n\nexport const MACHINE_MAX_TERMINALS = 16\nexport const MACHINE_TERMINAL_BACKLOG_BYTES = 256 * 1024\nexport const MACHINE_TERMINAL_GRACE_MS = 5 * 60 * 1000\n\ninterface Entry {\n process: TerminalProcess\n backlog: Buffer[]\n backlogBytes: number\n /** Bytes produced since it opened. */\n total: number\n graceTimer?: ReturnType<typeof setTimeout>\n}\n\nexport interface MachineTerminals {\n open: (context: ExecutionContext, handle: ExecutionHandle, options: { cols: number, rows: number, cwd?: string }) => Promise<string>\n attach: (terminalId: string) => { attached: boolean, backlog: string, total: number }\n write: (terminalId: string, data: string) => void\n resize: (terminalId: string, cols: number, rows: number) => void\n kill: (terminalId: string) => Promise<void>\n /** The host link dropped: start every terminal's grace period. */\n linkLost: () => void\n closeAll: () => Promise<void>\n /** Live terminals. */\n count: () => number\n}\n\nexport function createMachineTerminals(options: {\n /** Live output to the host; `false` when the link is down. */\n send: (method: 'terminal.data' | 'terminal.exit', params: Record<string, unknown>) => boolean\n graceMs?: number\n}): MachineTerminals {\n const terminals = new Map<string, Entry>()\n const graceMs = options.graceMs ?? MACHINE_TERMINAL_GRACE_MS\n\n const entry = (terminalId: string): Entry => {\n const found = terminals.get(terminalId)\n if (!found)\n throw new Error(`No terminal \"${terminalId}\" on this machine.`)\n return found\n }\n\n const remember = (e: Entry, data: Uint8Array): void => {\n e.backlog.push(Buffer.from(data))\n e.backlogBytes += data.byteLength\n e.total += data.byteLength\n while (e.backlogBytes > MACHINE_TERMINAL_BACKLOG_BYTES && e.backlog.length > 1)\n e.backlogBytes -= e.backlog.shift()!.byteLength\n }\n\n const kill = async (terminalId: string): Promise<void> => {\n const e = terminals.get(terminalId)\n if (!e)\n return\n terminals.delete(terminalId)\n clearTimeout(e.graceTimer)\n await e.process.kill().catch(() => undefined)\n }\n\n return {\n async open(context, handle, { cols, rows, cwd }) {\n if (!context.openTerminal)\n throw new Error('This machine has no terminal support (it needs Bun).')\n if (terminals.size >= MACHINE_MAX_TERMINALS)\n throw new Error(`This machine already runs ${MACHINE_MAX_TERMINALS} terminals.`)\n const holder: { id?: string } = {}\n const pending: Uint8Array[] = []\n const process = await context.openTerminal(handle, {\n cols,\n rows,\n ...(cwd ? { cwd } : {}),\n onData: (data) => {\n const e = holder.id ? terminals.get(holder.id) : undefined\n if (!e) {\n pending.push(data)\n return\n }\n remember(e, data)\n options.send('terminal.data', { terminalId: holder.id, data: Buffer.from(data).toString('base64') })\n },\n })\n holder.id = process.id\n const e: Entry = { process, backlog: [], backlogBytes: 0, total: 0 }\n terminals.set(process.id, e)\n for (const data of pending)\n remember(e, data)\n void process.exited.then((code) => {\n if (terminals.get(process.id) !== e)\n return\n terminals.delete(process.id)\n clearTimeout(e.graceTimer)\n options.send('terminal.exit', { terminalId: process.id, code })\n })\n return process.id\n },\n attach(terminalId) {\n const e = terminals.get(terminalId)\n if (!e)\n return { attached: false, backlog: '', total: 0 }\n clearTimeout(e.graceTimer)\n e.graceTimer = undefined\n return { attached: true, backlog: Buffer.concat(e.backlog).toString('base64'), total: e.total }\n },\n write: (terminalId, data) => entry(terminalId).process.write(Buffer.from(data, 'base64')),\n resize: (terminalId, cols, rows) => entry(terminalId).process.resize(cols, rows),\n kill,\n linkLost() {\n for (const [id, e] of terminals) {\n clearTimeout(e.graceTimer)\n e.graceTimer = setTimeout(() => void kill(id), graceMs)\n e.graceTimer.unref?.()\n }\n },\n async closeAll() {\n await Promise.all([...terminals.keys()].map(kill))\n },\n count: () => terminals.size,\n }\n}\n","/**\n * What a machine runs for its host (`docs/MACHINES.md` § Machine side): the\n * machine protocol's host→machine methods, served from one `process`\n * execution context, behind a guard that never trusts the host. Every handle\n * cwd, command cwd and file path resolves against the handle's cwd and must\n * real-path into a declared root (symlinks followed), never into the\n * machine's data dir. The exceptions: its `worktrees/` (worktrees made there\n * are workspace content, `machineConfinement`), and reading a log file of a\n * background task this machine started (`./task-logs.ts`: opened without\n * following symlinks, checked to be that file).\n *\n * Transport-free: the agent (`./agent.ts`) feeds it requests and gives it a\n * `notify` toward the host, which is `false` while the link is down (task\n * exits are then queued until {@link MachineExecutor.linkUp}).\n */\nimport type { MachineRoot } from '../../chat/machine-protocol'\nimport type { LooseSandboxSettings } from '../../chat/sandbox-settings'\nimport type { WorkspaceConfinement } from '../../chat/workspace-confinement'\nimport type { ExecutionContext, ExecutionHandle, TaskExitInfo } from '../../contexts/types'\nimport type { Params } from './params'\nimport { Buffer } from 'node:buffer'\nimport { mkdirSync, realpathSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { isAbsolute, join, resolve } from 'node:path'\nimport { normalizeEnvironmentCheckout, workspacePath } from '../../chat/environment'\nimport { prepareWorktree, teardownWorktree } from '../../chat/environments'\nimport { resolveSandboxForRoots, sandboxUnreadableDirs } from '../../chat/sandbox-settings'\nimport { createWorkspaceConfinement, isInside } from '../../chat/workspace-confinement'\nimport { resolveStorageDirs } from '../../chat/xdg'\nimport { entryPortOf } from '../../contexts/entries'\nimport { createProcessContext } from '../../contexts/process'\nimport { handleRef, num, optEnv, optNum, optStr, paramsOf, str } from './params'\nimport { createMachineStreams } from './streams'\nimport { createTaskLogs } from './task-logs'\nimport { createMachineTerminals } from './terminals'\n\nexport const MACHINE_MAX_TASKS = 64\nexport const MACHINE_TASK_OUTPUT_BYTES = 8 * 1024 * 1024\nconst MAX_PENDING_EXITS = 256\nconst GLOB_CHARS = /[*?[\\]{}]/\n\nexport interface MachineExecutorOptions {\n roots: readonly MachineRoot[]\n /** The machine's own data dir: only its `worktrees/` and task logs are reachable by file ops. */\n dataDir: string\n /** A notification to the host; `false` when the link is down. */\n notify: (method: string, params: Record<string, unknown>) => boolean\n /** Terminals' grace after the link drops. */\n terminalGraceMs?: number\n /**\n * The machine user's own `sandbox*` settings (`docs/MACHINES.md` §\n * Sandbox): applied to every command this machine runs, whatever the host.\n */\n sandbox?: LooseSandboxSettings\n /**\n * The machine user's zidane data dir: private to file operations (with the\n * rest of {@link machinePrivateDirs}) and its credential files hidden from\n * sandboxed commands.\n */\n credentialsDataDir?: string\n /** Task logs kept before ended ones are forgotten (default 4 × {@link MACHINE_MAX_TASKS}). A test seam. */\n maxTaskLogs?: number\n}\n\n/**\n * What file operations never reach, whatever the roots (`docs/MACHINES.md` §\n * Security model): zidane's own folders as this process resolves them (data,\n * config, state, cache: credentials, tokens, extensions, plugins, skills,\n * mcps.json, SYSTEM.md, the machine's data, sync files), the default\n * `~/.zidane`, the given data dir (a server's `--data-dir`), and the\n * credential folders the sandbox hides (`~/.ssh`, `~/.aws`, …).\n */\nexport function machinePrivateDirs(zidaneDataDir?: string): string[] {\n const storage = resolveStorageDirs()\n return [...new Set([\n ...(zidaneDataDir ? [zidaneDataDir] : []),\n storage.dataDir,\n storage.configDir,\n storage.stateDir,\n storage.cacheDir,\n join(homedir(), '.zidane'),\n ...sandboxUnreadableDirs(zidaneDataDir),\n ])]\n}\n\nexport interface MachineExecutor {\n /** Serve one host request; throws (the agent turns it into a JSON-RPC error). */\n handle: (method: string, params: unknown) => Promise<unknown>\n /** The host link is (back) up: re-send what was queued. */\n linkUp: () => void\n /** The host link dropped: terminals start their grace. */\n linkLost: () => void\n close: () => Promise<void>\n /** What runs now: commands, background tasks, streams and terminals (a version update waits until all are 0). */\n activity: () => Promise<{ calls: number, tasks: number, streams: number, terminals: number }>\n /** The OS sandbox the machine applies, and why it can't when it is on but unavailable. */\n sandbox: { on: boolean, warning?: string }\n}\n\n/** The static directory of a glob (`/a/b/**\\/*.ts` → `/a/b`). */\nfunction globBase(path: string): string {\n const segments = path.split('/')\n const index = segments.findIndex(s => GLOB_CHARS.test(s))\n return index < 0 ? path : segments.slice(0, index).join('/') || '/'\n}\n\n/**\n * A folder a user offers to share (`zidane machine share --root`, a share\n * link): its real path must exist and not be, or be inside, a private\n * folder (a root there would lend what {@link machinePrivateDirs} keeps out).\n * Returns the real path.\n */\nexport function shareableRoot(root: string, zidaneDataDir?: string): string {\n let real: string\n try {\n real = realpathSync.native(root)\n }\n catch {\n throw new Error(`${root} does not exist.`)\n }\n const hidden = machinePrivateDirs(zidaneDataDir).map(realPathOr).find(dir => isInside(dir, real))\n if (hidden)\n throw new Error(`${root} is inside ${hidden} (zidane's own data or credentials): share a folder outside it.`)\n return real\n}\n\nfunction realPathOr(path: string): string {\n try {\n return realpathSync.native(path)\n }\n catch {\n return path\n }\n}\n\nexport function machineConfinement(roots: readonly MachineRoot[], dataDir: string, privateDirs: readonly string[] = []): WorkspaceConfinement {\n // Worktrees made in the data dir's `worktrees/` are workspace content; nothing else there is.\n const worktrees = join(dataDir, 'worktrees')\n mkdirSync(worktrees, { recursive: true })\n return createWorkspaceConfinement([...roots.map(root => root.path), worktrees], {\n dataDir,\n privateDirs,\n names: { roots: 'the machine\\'s roots', dataDir: 'the machine\\'s data dir, which the host can\\'t reach' },\n })\n}\n\n/**\n * A listing's entries whose real path is reachable: a traversal can follow a\n * symlinked folder out of the roots, or walk into a private one, from a base\n * that passed the check.\n */\nfunction reachableEntries<T>(confinement: WorkspaceConfinement, base: string, entries: readonly T[]): T[] {\n return entries.filter((entry) => {\n const path = typeof entry === 'string' ? entry : (entry as { path?: unknown }).path\n if (typeof path !== 'string')\n return false\n try {\n confinement.checkPath(isAbsolute(path) ? path : resolve(base, path))\n return true\n }\n catch {\n return false\n }\n })\n}\n\n/** `fs.list`: a path or glob under the handle's cwd, no `..` in a pattern, only reachable entries back. */\nasync function listReachable(context: ExecutionContext, confinement: WorkspaceConfinement, handle: ExecutionHandle, params: Params): Promise<unknown[]> {\n const pattern = str(params, 'path')\n if (GLOB_CHARS.test(pattern) && pattern.split(/[/\\\\]/).includes('..'))\n throw new Error(`\"${pattern}\": a pattern can't climb with \"..\".`)\n const path = workspacePath(handle.cwd, pattern)\n confinement.checkPath(globBase(path))\n const raw = params.options && typeof params.options === 'object' ? params.options as Record<string, unknown> : {}\n const listOptions = {\n ...(typeof raw.glob === 'boolean' ? { glob: raw.glob } : {}),\n ...(typeof raw.limit === 'number' ? { limit: raw.limit } : {}),\n ...(typeof raw.metadata === 'boolean' ? { metadata: raw.metadata } : {}),\n ...(typeof raw.gitignore === 'boolean' ? { gitignore: raw.gitignore } : {}),\n }\n return reachableEntries(confinement, globBase(path), await context.listFiles(handle, path, listOptions))\n}\n\n/** One process context for every handle, under the machine user's own sandbox when it is on. */\nfunction sandboxedContext(options: MachineExecutorOptions, confinement: WorkspaceConfinement): { sandbox: ReturnType<typeof resolveSandboxForRoots>, context: ExecutionContext } {\n const sandbox = resolveSandboxForRoots(options.sandbox ?? { sandbox: false }, confinement.roots, {\n ...(options.credentialsDataDir ? { dataDir: options.credentialsDataDir } : {}),\n // Not the task logs: the machine process writes them, and a command able to write there could swap one for a symlink.\n })\n return { sandbox, context: createProcessContext({ cwd: confinement.roots[0]!, ...(sandbox.isolation ? { isolation: sandbox.isolation } : {}) }) }\n}\n\n/**\n * The entry calls (`fs.stat`, `fs.readdir`, `fs.mkdir`, `fs.move`, `fs.copy`,\n * `fs.remove`, `fs.emptyDirs`): every path confined like `fs.write`'s, then\n * the process context's own entry port (it never overwrites).\n */\nfunction entryMethods(\n context: ExecutionContext,\n confinement: WorkspaceConfinement,\n handleFor: (params: Params) => Promise<ExecutionHandle>,\n checked: (handle: ExecutionHandle, path: string) => string,\n): Record<string, (params: Params) => Promise<unknown>> {\n const on = async (params: Params) => {\n const handle = await handleFor(params)\n return {\n handle,\n port: entryPortOf(context, handle),\n path: (key: string) => checked(handle, str(params, key)),\n // The entry itself, never followed: a link pointing out can still be renamed or removed.\n entry: (key: string) => {\n const absolute = workspacePath(handle.cwd, str(params, key))\n confinement.checkEntry(absolute)\n return absolute\n },\n }\n }\n return {\n 'fs.stat': async (params) => {\n const { port, entry } = await on(params)\n return { kind: await port.stat(entry('path')) }\n },\n 'fs.readdir': async (params) => {\n const { port, path } = await on(params)\n return { names: await port.list(path('path')) }\n },\n 'fs.mkdir': async (params) => {\n const { port, path } = await on(params)\n await port.mkdir(path('path'))\n return { ok: true }\n },\n 'fs.move': async (params) => {\n const { port, entry } = await on(params)\n await port.move(entry('from'), entry('to'))\n return { ok: true }\n },\n 'fs.copy': async (params) => {\n const { port, path } = await on(params)\n await port.copy(path('from'), path('to'))\n return { ok: true }\n },\n 'fs.remove': async (params) => {\n const { port, entry } = await on(params)\n await port.remove(entry('path'))\n return { ok: true }\n },\n 'fs.emptyDirs': async (params) => {\n const { port, path } = await on(params)\n const base = path('path')\n const found = await port.emptyDirs(base, Math.min(num(params, 'limit'), 10_000))\n // A symlinked folder can lead out of the roots: only what is reachable comes back.\n return { paths: reachableEntries(confinement, base, found) }\n },\n }\n}\n\n/** Background tasks still running on these handles. */\nasync function runningTasks(context: ExecutionContext, handles: Iterable<ExecutionHandle>): Promise<number> {\n let running = 0\n for (const handle of handles)\n running += (await context.listBackground?.(handle).catch(() => []) ?? []).filter(t => t.status === 'running').length\n return running\n}\n\nexport function createMachineExecutor(options: MachineExecutorOptions): MachineExecutor {\n const confinement = machineConfinement(options.roots, options.dataDir, machinePrivateDirs(options.credentialsDataDir))\n const { sandbox, context } = sandboxedContext(options, confinement)\n const handles = new Map<string, ExecutionHandle>()\n const calls = new Map<string, AbortController>()\n const taskLogs = createTaskLogs(options.dataDir)\n const pendingExits: Array<Record<string, unknown>> = []\n const terminals = createMachineTerminals({ send: options.notify, ...(options.terminalGraceMs !== undefined ? { graceMs: options.terminalGraceMs } : {}) })\n const streams = createMachineStreams({ send: options.notify })\n\n /** A handle's cwd, checked on every call (not only at spawn): the host names it each time. */\n async function handleFor(params: Params): Promise<ExecutionHandle> {\n const ref = handleRef(params)\n const cwd = confinement.resolveFolder(ref.cwd)\n const existing = handles.get(ref.id)\n if (existing && existing.cwd === cwd)\n return existing\n const handle = await context.spawn({ cwd })\n handles.set(ref.id, handle)\n // The id now names another folder: the old handle (and its tasks) would otherwise live on unreachable.\n if (existing)\n await context.destroy(existing).catch(() => undefined)\n return handle\n }\n\n /** `path` resolved like the context resolves it, then confined. */\n function checked(handle: ExecutionHandle, path: string): string {\n const absolute = workspacePath(handle.cwd, path)\n confinement.checkPath(absolute)\n return absolute\n }\n\n /** A log of a task this machine started, by its path (never through the context: see `./task-logs.ts`). */\n const taskLog = (handle: ExecutionHandle, path: string): string | undefined => {\n const absolute = workspacePath(handle.cwd, path)\n return taskLogs.has(absolute) ? absolute : undefined\n }\n\n const cwdOption = (handle: ExecutionHandle, params: Params): { cwd?: string } => {\n const cwd = optStr(params, 'cwd')\n return cwd === undefined ? {} : { cwd: confinement.resolveFolder(workspacePath(handle.cwd, cwd)) }\n }\n\n const taskExited = (info: TaskExitInfo): void => {\n taskLogs.finish(info.outputPath)\n const exit = { taskId: info.taskId, exit: { ...info } }\n if (options.notify('task.exit', exit))\n return\n pendingExits.push(exit)\n if (pendingExits.length > MAX_PENDING_EXITS)\n pendingExits.shift()\n }\n\n const methods: Record<string, (params: Params) => Promise<unknown>> = {\n 'machine.ping': async () => ({ ok: true }),\n 'exec.spawn': async (params) => {\n const handle = await handleFor(params)\n return { id: handleRef(params).id, cwd: handle.cwd }\n },\n 'exec.run': async (params) => {\n const handle = await handleFor(params)\n const callId = str(params, 'callId')\n // A second call under one id would take over its cancel: the first could no longer be stopped.\n if (calls.has(callId))\n throw new Error(`A call \"${callId}\" is already running.`)\n const controller = new AbortController()\n calls.set(callId, controller)\n try {\n const env = optEnv(params, 'env')\n const timeout = optNum(params, 'timeout')\n return await context.exec(handle, str(params, 'command'), { ...cwdOption(handle, params), ...(env ? { env } : {}), ...(timeout !== undefined ? { timeout } : {}), signal: controller.signal })\n }\n finally {\n calls.delete(callId)\n }\n },\n 'exec.cancel': async (params) => {\n const callId = str(params, 'callId')\n const controller = calls.get(callId)\n controller?.abort()\n return { cancelled: controller !== undefined || streams.kill(callId) }\n },\n 'exec.stream': async (params) => {\n const handle = await handleFor(params)\n const env = optEnv(params, 'env')\n return streams.start(context, handle, { callId: str(params, 'callId'), command: str(params, 'command'), ...cwdOption(handle, params), ...(env ? { env } : {}) })\n },\n 'exec.stream.write': async (params) => {\n await streams.write(str(params, 'callId'), str(params, 'data'))\n return { ok: true }\n },\n 'exec.destroy': async (params) => {\n const ref = handleRef(params)\n const handle = handles.get(ref.id)\n handles.delete(ref.id)\n if (handle)\n await context.destroy(handle)\n return { ok: true }\n },\n 'fs.read': async (params) => {\n const handle = await handleFor(params)\n const log = taskLog(handle, str(params, 'path'))\n if (log)\n return { content: taskLogs.read(log, params.binary === true) }\n const path = checked(handle, str(params, 'path'))\n if (params.binary === true)\n return { content: Buffer.from(await context.readFileBinary!(handle, path)).toString('base64') }\n return { content: await context.readFile(handle, path) }\n },\n 'fs.write': async (params) => {\n const handle = await handleFor(params)\n const path = checked(handle, str(params, 'path'))\n // An entry create: the entry port's write never replaces a file that appeared since the check.\n const write = params.exclusive === true ? entryPortOf(context, handle).write : (p: string, b: Buffer) => context.writeFile(handle, p, b)\n await write(path, Buffer.from(str(params, 'content'), 'base64'))\n return { ok: true }\n },\n 'fs.list': async params => ({ entries: await listReachable(context, confinement, await handleFor(params), params) }),\n 'fs.size': async (params) => {\n const handle = await handleFor(params)\n const log = taskLog(handle, str(params, 'path'))\n return { size: log ? taskLogs.size(log) : await context.fileSize!(handle, checked(handle, str(params, 'path'))) }\n },\n ...entryMethods(context, confinement, handleFor, checked),\n 'bg.start': async (params) => {\n const handle = await handleFor(params)\n const running = (await context.listBackground!(handle)).filter(t => t.status === 'running').length\n if (taskLogs.prune((options.maxTaskLogs ?? MACHINE_MAX_TASKS * 4) - 1) >= (options.maxTaskLogs ?? MACHINE_MAX_TASKS * 4) || running >= MACHINE_MAX_TASKS)\n throw new Error(`This machine already runs ${MACHINE_MAX_TASKS} background tasks.`)\n const env = optEnv(params, 'env')\n const cap = optNum(params, 'maxOutputBytes')\n const task = await context.execBackground!(handle, str(params, 'command'), {\n ...cwdOption(handle, params),\n ...(env ? { env } : {}),\n outputDir: taskLogs.outputDir(handleRef(params).id),\n maxOutputBytes: Math.min(cap && cap > 0 ? cap : MACHINE_TASK_OUTPUT_BYTES, MACHINE_TASK_OUTPUT_BYTES),\n onExit: taskExited,\n })\n taskLogs.add(task.outputPath)\n return { taskId: task.taskId, pid: task.pid, outputPath: task.outputPath }\n },\n 'bg.list': async params => ({ tasks: await context.listBackground!(await handleFor(params)) }),\n 'bg.kill': async params => ({ exit: await context.killBackground!(await handleFor(params), str(params, 'taskId')) }),\n 'bg.wait': async (params) => {\n const timeoutMs = optNum(params, 'timeoutMs')\n return { exit: await context.waitBackground!(await handleFor(params), str(params, 'taskId'), timeoutMs !== undefined ? { timeoutMs } : {}) }\n },\n 'terminal.open': async (params) => {\n const handle = await handleFor(params)\n const terminalId = await terminals.open(context, handle, { cols: num(params, 'cols'), rows: num(params, 'rows'), ...cwdOption(handle, params) })\n return { terminalId }\n },\n 'terminal.attach': async params => terminals.attach(str(params, 'terminalId')),\n 'terminal.write': async (params) => {\n terminals.write(str(params, 'terminalId'), str(params, 'data'))\n return { ok: true }\n },\n 'terminal.resize': async (params) => {\n terminals.resize(str(params, 'terminalId'), num(params, 'cols'), num(params, 'rows'))\n return { ok: true }\n },\n 'terminal.kill': async (params) => {\n await terminals.kill(str(params, 'terminalId'))\n return { ok: true }\n },\n // The host stops viewing; the PTY keeps running (as after a lost link, without the grace).\n 'terminal.detach': async () => ({ ok: true }),\n 'env.checkFolder': async params => ({ cwd: confinement.resolveFolder(str(params, 'cwd')) }),\n 'env.prepareWorktree': async (params) => {\n const cwd = confinement.resolveFolder(str(params, 'cwd'))\n const config = (params.config && typeof params.config === 'object' ? params.config : {}) as Record<string, string | number | boolean>\n const base = optStr(params, 'base')\n const prepared = await prepareWorktree({ cwd, environment: { kind: 'worktree', state: 'provisioning', branch: str(params, 'branch'), ...(base ? { base } : {}), ...(params.checkout ? { checkout: normalizeEnvironmentCheckout(params.checkout) ?? {} } : {}) }, config }, options.dataDir)\n const ref = prepared.environment?.ref as { path: string, repoRoot: string }\n confinement.resolveFolder(ref.path)\n return { cwd: prepared.cwd ?? ref.path, branch: prepared.environment?.branch, base: prepared.environment?.base, ref }\n },\n 'env.teardownWorktree': async (params) => {\n const ref = (params.ref ?? {}) as { path?: unknown, repoRoot?: unknown }\n if (typeof ref.path !== 'string' || typeof ref.repoRoot !== 'string')\n throw new Error('Invalid params: \"ref\" must be { path, repoRoot }.')\n confinement.checkPath(ref.path)\n confinement.resolveFolder(ref.repoRoot)\n const config = (params.config && typeof params.config === 'object' ? params.config : {}) as Record<string, string | number | boolean>\n return teardownWorktree({ path: ref.path, repoRoot: ref.repoRoot }, optStr(params, 'branch'), config)\n },\n }\n\n return {\n async handle(method, raw) {\n if (!Object.hasOwn(methods, method))\n throw new Error(`Unknown machine method \"${method}\".`)\n return methods[method]!(paramsOf(raw))\n },\n linkUp() {\n while (pendingExits.length > 0) {\n if (!options.notify('task.exit', pendingExits[0]!))\n return\n pendingExits.shift()\n }\n },\n activity: async () => ({ calls: calls.size, tasks: await runningTasks(context, handles.values()), streams: streams.count(), terminals: terminals.count() }),\n sandbox: { on: sandbox.isolation !== undefined, ...(sandbox.warning ? { warning: sandbox.warning } : {}) },\n linkLost: () => { terminals.linkLost(); streams.linkLost() },\n async close() {\n for (const controller of calls.values())\n controller.abort()\n await streams.closeAll()\n await terminals.closeAll()\n await Promise.all([...handles.values()].map(handle => context.destroy(handle).catch(() => undefined)))\n handles.clear()\n },\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { g as projectNameOf } from "../validate-Cv5unNYq.js";
|
|
2
2
|
import { t as createMemoryStore } from "../memory-DoS93vcA.js";
|
|
3
|
-
import { a as HOST_EVENT_NAMES, i as createRpcDomain, o as isSyncInterceptor, r as createGuard, t as createExtensionRuntime } from "../host-
|
|
4
|
-
import { _ as createMemorySettingsPort, b as createScriptedDialogPort, ht as createScheduleHandlers, ut as createOwner, v as createMemoryStoragePort, y as createRecordingUiClientPort } from "../registry-
|
|
3
|
+
import { a as HOST_EVENT_NAMES, i as createRpcDomain, o as isSyncInterceptor, r as createGuard, t as createExtensionRuntime } from "../host-Ds3RDlG5.js";
|
|
4
|
+
import { _ as createMemorySettingsPort, b as createScriptedDialogPort, ht as createScheduleHandlers, ut as createOwner, v as createMemoryStoragePort, y as createRecordingUiClientPort } from "../registry-DTotchq6.js";
|
|
5
5
|
import { d as querySessions } from "../references-BEKthBnn.js";
|
|
6
6
|
import { r as createLogger } from "../logger-BQj8QCJp.js";
|
|
7
7
|
import { t as createSchedules } from "../scheduler-D5T4GvNo.js";
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { g as errorMessage } from "./errors-BuX_vK2H.js";
|
|
2
2
|
import { a as withProvenance } from "./json-BjClr43H.js";
|
|
3
|
-
import { Kt as isSettingKey, Qt as settingsForDefinition, Ut as validateDefinition, yt as toWireSettings } from "./registry-
|
|
3
|
+
import { Kt as isSettingKey, Qt as settingsForDefinition, Ut as validateDefinition, yt as toWireSettings } from "./registry-DTotchq6.js";
|
|
4
4
|
import { i as writeJsonFileAtomic } from "./atomic-write-BewQOXlD.js";
|
|
5
5
|
import { n as findGitRoot } from "./project-root-BZcgGJMi.js";
|
|
6
6
|
import { s as resolveCompletionSubmit } from "./completion-core-C2TNQjPQ.js";
|
|
7
7
|
import { t as projectUserPaths } from "./project-user-paths-Chsi83mp.js";
|
|
8
|
-
import { t as checkZidaneVersion } from "./host-version-
|
|
8
|
+
import { t as checkZidaneVersion } from "./host-version-BGZumnpZ.js";
|
|
9
9
|
import { a as fetchInstallSource, c as resolveNpmVersion, i as defaultWhich, l as resolveSubdirRoot, n as abortableInstallIo, o as lastLine, r as defaultExec, s as parseInstallSource, t as InstallSourceError } from "./source-3ZnEPOSa.js";
|
|
10
10
|
import { P as resolvePanelLoadContext, T as normalizePanelContent, j as panelSurfaces } from "./references-BEKthBnn.js";
|
|
11
11
|
import { r as createLogger, t as consoleSink } from "./logger-BQj8QCJp.js";
|
|
12
|
-
import { f as readExtensionManifest, h as withTimeout, i as discoverExtensions, l as loadExtensionFolder, o as findEntryFile, p as releaseExtensionModules, r as definitionExport, s as importExtensionEntry } from "./discovery-
|
|
12
|
+
import { f as readExtensionManifest, h as withTimeout, i as discoverExtensions, l as loadExtensionFolder, o as findEntryFile, p as releaseExtensionModules, r as definitionExport, s as importExtensionEntry } from "./discovery-D7qVZWzq.js";
|
|
13
13
|
import { a as registerExtensionApiHostModules } from "./host-modules-C2GGiSjg.js";
|
|
14
|
-
import { i as runtimeEntryOf, n as isRuntimeLoadedExtension, t as NO_DEFINITION_ERROR } from "./loaded-entry-
|
|
14
|
+
import { i as runtimeEntryOf, n as isRuntimeLoadedExtension, t as NO_DEFINITION_ERROR } from "./loaded-entry-CLva6GQT.js";
|
|
15
15
|
import { t as resolveStorageDirs } from "./xdg-DFSAQQG8.js";
|
|
16
16
|
import { b as unregisterOAuthProvider, g as getOAuthProvider, p as BUILTIN_OAUTH_PROVIDER_IDS, y as registerOAuthProvider } from "./oauth-HKL8zPcd.js";
|
|
17
17
|
import { l as normalizePaletteItems, u as normalizePaletteRunResult } from "./palette-DhfYhvnx.js";
|
|
@@ -1372,7 +1372,7 @@ async function buildExtensionRegistry(loaded, options = {}) {
|
|
|
1372
1372
|
refused,
|
|
1373
1373
|
dispose: async () => {}
|
|
1374
1374
|
}));
|
|
1375
|
-
const [{ createExtensionRuntime }, { createFileStoragePort, projectStorageFolder }] = await Promise.all([import("./host-
|
|
1375
|
+
const [{ createExtensionRuntime }, { createFileStoragePort, projectStorageFolder }] = await Promise.all([import("./host-Ds3RDlG5.js").then((n) => n.n), import("./registry-DTotchq6.js").then((n) => n.x)]);
|
|
1376
1376
|
const ports = options.runtime?.ports ?? {};
|
|
1377
1377
|
const bridge = options.hostRuntime;
|
|
1378
1378
|
const host = ports.host ?? (bridge ? {
|
|
@@ -4048,4 +4048,4 @@ function createSharedWatches() {
|
|
|
4048
4048
|
//#endregion
|
|
4049
4049
|
export { toWireConfigSchema as $, removeInstalledExtension as A, createRegistryViewSource as B, extensionSourceLabel as C, parseExtensionInstallSource as D, listExtensionCandidates as E, extensionRuntimeOf as F, runExtensionAction as G, registryViewState as H, filterExtensionRegistry as I, isValidExtensionConfigItem as J, clampExtensionConfigNumber as K, filterRegistryPlugins as L, reloadChangedExtensions as M, buildExtensionRegistry as N, readExtensionInstallOrigin as O, disposeExtensionRegistry as P, sanitizeExtensionConfigActionPatch as Q, partitionExtensionCatalog as R, changeExtensionOrigin as S, installExtensionFromSpec as T, listActionSummaries as U, extensionConfigSettingsPort as V, probeActionStatuses as W, resolveExtensionConfig as X, isValidExtensionConfigValue as Y, resolveExtensionConfigValue as Z, configSyncFailures as _, listExtensionPaletteItems as a, suggestCompletionItems as at, loadExtensionsConfig as b, panelSummaries as c, UI_HOST_MODULES as ct, subscribeExtensionPalette as d, COMPLETION_TIMEOUT_MS as et, subscribeExtensionPanel as f, applyExtensionsConfigReport as g, createConfigSettingsLayer as h, createExtensionPromptBridge as i, resolveExtensionCompletionSubmit as it, updateInstalledExtension as j, readExtensionInstallProvenance as k, runExtensionPaletteItem as l, classifyUiImport as lt, discoverAndBuildExtensionRegistry as m, Contract as n, completionProviderSummaries as nt, loadExtensionPanel as o, usableCompletionProviders as ot, integrationMethodFromOAuthProvider as p, coerceExtensionConfigInput as q, Registry as r, createCompletionRunner as rt, panelHostRuntime as s, resolveUiEntries as st, createSharedWatches as t, MAX_COMPLETION_ITEMS as tt, runExtensionPanelAction as u, isUiHostModule as ut, configuredExtensions as v, fetchExtensionSource as w, ExtensionInstallError as x, createExtensionsConfigSync as y, createRegistryView as z };
|
|
4050
4050
|
|
|
4051
|
-
//# sourceMappingURL=extensions-
|
|
4051
|
+
//# sourceMappingURL=extensions-D7DeZNpn.js.map
|