@struktoai/mirage-cli 0.0.7-alpha.2 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bin/mirage.ts","../../src/main.ts","../../src/config.ts","../../src/daemon.ts","../../src/execute.ts","../../src/job.ts","../../src/mcp.ts","../../src/provision.ts","../../src/session.ts","../../src/workspace.ts"],"sourcesContent":["#!/usr/bin/env node\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { DaemonConfigError } from '@struktoai/mirage-server'\nimport { buildProgram } from '../main.ts'\n\nconst ALIASES: Record<string, string> = {\n '--workspace_id': '--workspace',\n '--session_id': '--session',\n}\n\nfunction rewriteArgv(argv: string[]): string[] {\n return argv.map((arg) => {\n for (const [from, to] of Object.entries(ALIASES)) {\n if (arg === from) return to\n if (arg.startsWith(from + '=')) return to + arg.slice(from.length)\n }\n return arg\n })\n}\n\nbuildProgram()\n .parseAsync(rewriteArgv(process.argv))\n .catch((err: unknown) => {\n if (err instanceof DaemonConfigError) {\n console.error(err.message)\n process.exit(2)\n }\n console.error(err)\n process.exit(1)\n })\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { Command } from 'commander'\nimport { registerConfigCommands } from './config.ts'\nimport { registerDaemonCommands } from './daemon.ts'\nimport { registerExecuteCommand } from './execute.ts'\nimport { registerJobCommands } from './job.ts'\nimport { registerMcpCommand } from './mcp.ts'\nimport { registerProvisionCommand } from './provision.ts'\nimport { registerSessionCommands } from './session.ts'\nimport { registerWorkspaceCommands } from './workspace.ts'\n\nfunction resolveVersion(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 6; i++) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as {\n name?: string\n version?: string\n }\n if (pkg.name === '@struktoai/mirage-cli' && pkg.version) return pkg.version\n } catch {\n // package.json absent at this level: keep walking up to the package root\n }\n dir = dirname(dir)\n }\n return '0.0.0'\n}\n\nexport function buildProgram(): Command {\n const program = new Command()\n program\n .name('mirage')\n .description('Mirage daemon CLI: manage workspaces and execute commands.')\n .version(resolveVersion())\n registerWorkspaceCommands(program)\n registerSessionCommands(program)\n registerJobCommands(program)\n registerExecuteCommand(program)\n registerMcpCommand(program)\n registerProvisionCommand(program)\n registerDaemonCommands(program)\n registerConfigCommands(program)\n return program\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { compareCodePoints } from '@struktoai/mirage-core/utils/sort'\nimport { ALLOWED_KEYS, DaemonConfigError } from '@struktoai/mirage-server'\nimport type { Command } from 'commander'\nimport { emit, fail } from './output.ts'\nimport { getConfig, listConfig, resolvedConfig, setConfig, unsetConfig } from './settings.ts'\n\nfunction mask(key: string, value: string): string {\n if (key === 'auth_token' && value !== '') return '***'\n return value\n}\n\ninterface ResolvedEntry {\n value: string\n origin: string\n}\n\nfunction humanTable(table: Record<string, string>): string {\n return Object.entries(table)\n .map(([k, v]) => `${k} = ${v}`)\n .join('\\n')\n}\n\nfunction humanResolved(table: Record<string, ResolvedEntry>): string {\n return Object.entries(table)\n .map(([k, e]) => `${k} = ${e.value} (${e.origin})`)\n .join('\\n')\n}\n\nfunction listResolved(): void {\n let resolved: Record<string, [string, string]>\n try {\n resolved = resolvedConfig()\n } catch (e) {\n fail((e as Error).message, 2)\n return\n }\n const payload: Record<string, ResolvedEntry> = {}\n for (const [key, [value, origin]] of Object.entries(resolved)) {\n payload[key] = { value: mask(key, value), origin }\n }\n emit(payload, humanResolved)\n}\n\nfunction listFile(): void {\n let table: Record<string, string>\n try {\n table = listConfig()\n } catch (e) {\n if (!(e instanceof DaemonConfigError)) throw e\n fail(e.message, 2)\n return\n }\n const unknown = Object.keys(table)\n .filter((k) => !ALLOWED_KEYS.has(k))\n .sort(compareCodePoints)\n if (unknown.length > 0) {\n process.stderr.write(\n 'warning: unknown [daemon] keys (daemon will refuse to ' + `start): ${unknown.join(', ')}\\n`,\n )\n }\n emit(table, humanTable)\n}\n\nexport function registerConfigCommands(program: Command): void {\n const config = program\n .command('config')\n .description('Read and write daemon settings in config.toml.')\n\n config\n .command('list')\n .option('--resolved', 'show effective values and their origins')\n .description('Print the config.toml [daemon] table.')\n .action((opts: { resolved?: boolean }) => {\n if (opts.resolved === true) listResolved()\n else listFile()\n })\n\n config\n .command('get')\n .argument('<key>')\n .description('Print one [daemon] key.')\n .action((key: string) => {\n let value: string | undefined\n try {\n value = getConfig(key)\n } catch (e) {\n fail((e as Error).message, 2)\n return\n }\n if (value === undefined) {\n fail(`${key} is not set`, 1)\n return\n }\n emit({ [key]: value }, () => value)\n })\n\n config\n .command('set')\n .argument('<key>')\n .argument('<value>')\n .description('Write a [daemon] key (path settings apply on next daemon restart).')\n .action((key: string, value: string) => {\n try {\n setConfig(key, value)\n } catch (e) {\n fail((e as Error).message, 2)\n return\n }\n emit({ [key]: value, written: true }, () => `${key} = ${value}`)\n })\n\n config\n .command('unset')\n .argument('<key>')\n .description('Remove a [daemon] key.')\n .action((key: string) => {\n try {\n unsetConfig(key)\n } catch (e) {\n fail((e as Error).message, 2)\n return\n }\n emit({ [key]: null, unset: true }, () => `unset ${key}`)\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { pidFilePath } from '@struktoai/mirage-server'\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, fail, formatAge } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\ninterface DaemonStatus {\n running: boolean\n pid: number | null\n url: string\n uptimeS?: number\n workspaces?: number\n}\n\nfunction formatStatus(d: DaemonStatus): string {\n if (!d.running) return `Daemon not running. URL: ${d.url}`\n const parts: string[] = [`Running. PID ${d.pid !== null ? String(d.pid) : '?'}`]\n if (d.uptimeS !== undefined) {\n parts.push(`uptime ${formatAge(Date.now() / 1000 - d.uptimeS)}`)\n }\n if (d.workspaces !== undefined) {\n parts.push(`${String(d.workspaces)} workspace${d.workspaces === 1 ? '' : 's'}`)\n }\n return parts.join(', ') + `. URL: ${d.url}`\n}\n\nfunction formatStop(d: { via?: string; pid?: number }): string {\n const via = d.via ?? '?'\n return `Stopped (via ${via}${d.pid !== undefined ? `, PID ${String(d.pid)}` : ''}).`\n}\n\nfunction formatRestart(d: { spawnedFresh?: boolean }): string {\n if (d.spawnedFresh === true) return 'Restarted (eager spawn).'\n return 'Restarted; next CLI command will auto-spawn.'\n}\n\nfunction formatKill(d: { killed: boolean; pid?: number | null }): string {\n if (d.killed) return `Killed PID ${String(d.pid ?? '?')}.`\n if (d.pid === null || d.pid === undefined) return 'Daemon not running.'\n return `Already gone (PID ${String(d.pid)}).`\n}\n\nfunction readPid(): number | null {\n const p = pidFilePath()\n if (!existsSync(p)) return null\n const text = readFileSync(p, 'utf-8').trim()\n const pid = Number(text)\n return Number.isFinite(pid) && pid > 0 ? pid : null\n}\n\nfunction processAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException).code\n if (code === 'ESRCH') return false\n if (code === 'EPERM') return true\n return false\n }\n}\n\nfunction buildClient() {\n return makeClient(loadDaemonSettings())\n}\n\nasync function waitForUnreachable(timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs\n while (Date.now() < deadline) {\n const c = buildClient()\n if (!(await c.isReachable(300))) return true\n await new Promise((r) => setTimeout(r, 200))\n }\n return false\n}\n\nexport function registerDaemonCommands(program: Command): void {\n const d = program.command('daemon').description('Manage the daemon process lifecycle.')\n\n d.command('status')\n .description('Show daemon health, PID, uptime, workspace count.')\n .action(async () => {\n const pid = readPid()\n const c = buildClient()\n const url = c.settings.url\n try {\n const r = await c.request('GET', '/v1/health')\n if (r.status !== 200) {\n emit({ running: false, pid, url } as DaemonStatus, formatStatus)\n process.exit(1)\n }\n const body = (await r.json()) as Record<string, unknown>\n emit({ running: true, pid, url, ...body } as DaemonStatus, formatStatus)\n } catch {\n emit({ running: false, pid, url } as DaemonStatus, formatStatus)\n process.exit(1)\n }\n })\n\n d.command('stop')\n .description('Gracefully stop the daemon.')\n .option('--timeout <s>', 'Seconds to wait for graceful exit', '5')\n .action(async (opts: { timeout: string }) => {\n const timeoutMs = Number(opts.timeout) * 1000\n const c = buildClient()\n let r: Response\n try {\n r = await c.request('POST', '/v1/shutdown')\n } catch (err: unknown) {\n fail(`daemon not reachable: ${String(err)}`)\n }\n if (r.status >= 400) fail(`shutdown failed: ${await r.text()}`, 2)\n if (await waitForUnreachable(timeoutMs)) {\n emit({ stopped: true, via: 'graceful' }, formatStop)\n return\n }\n const pid = readPid()\n if (pid !== null && processAlive(pid)) {\n try {\n process.kill(pid, 'SIGTERM')\n emit({ stopped: true, via: 'sigterm', pid }, formatStop)\n return\n } catch {\n // fall through to fail\n }\n }\n fail(`daemon did not exit within ${opts.timeout}s and no live PID found`, 2)\n })\n\n d.command('restart')\n .description('Stop the daemon. Next CLI command auto-spawns a fresh one.')\n .option('--timeout <s>', 'Seconds to wait for graceful exit', '5')\n .option('--eager', 'Spawn a fresh daemon immediately')\n .action(async (opts: { timeout: string; eager?: boolean }) => {\n const timeoutMs = Number(opts.timeout) * 1000\n try {\n await buildClient().request('POST', '/v1/shutdown')\n } catch {\n // already unreachable; fall through to pid cleanup\n }\n if (!(await waitForUnreachable(timeoutMs))) {\n const pid = readPid()\n if (pid !== null && processAlive(pid)) {\n try {\n process.kill(pid, 'SIGTERM')\n } catch {\n // process may have exited between checks\n }\n }\n }\n if (opts.eager === true) {\n await buildClient().ensureRunning({ allowSpawn: true })\n emit({ restarted: true, spawnedFresh: true }, formatRestart)\n return\n }\n emit(\n {\n restarted: true,\n spawnedFresh: false,\n note: 'next workspace create will auto-spawn',\n },\n formatRestart,\n )\n })\n\n d.command('kill')\n .description('SIGKILL the daemon. Last resort -- skips graceful shutdown.')\n .action(() => {\n const pid = readPid()\n if (pid === null) {\n emit({ killed: false, reason: 'no daemon running', pid: null }, formatKill)\n return\n }\n if (!processAlive(pid)) {\n emit({ killed: false, reason: 'process already gone', pid }, formatKill)\n return\n }\n try {\n process.kill(pid, 'SIGKILL')\n } catch {\n emit({ killed: false, reason: 'process gone', pid }, formatKill)\n return\n }\n emit({ killed: true, pid }, formatKill)\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { readFileSync } from 'node:fs'\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, exitCodeFromResponse, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\nexport function registerExecuteCommand(program: Command): void {\n program\n .command('execute')\n .description('Execute a command.')\n .requiredOption('-w, --workspace <id>', 'Workspace id')\n .requiredOption('-c, --command <command>', 'Shell command to execute')\n .option('-s, --session <id>', 'Session id')\n .option('--cwd <path>', 'Working directory for this line (a workspace path)')\n .option('--runtime <name>', \"Workspace runtime entry to place this line's captured stages on\")\n .option('--bg', 'Background; return job_id immediately')\n .action(\n async (opts: {\n workspace: string\n command: string\n session?: string\n cwd?: string\n runtime?: string\n bg?: boolean\n }) => {\n const body: Record<string, unknown> = { command: opts.command, provision: false }\n if (opts.session !== undefined) body.sessionId = opts.session\n if (opts.cwd !== undefined) body.cwd = opts.cwd\n if (opts.runtime !== undefined) body.runtime = opts.runtime\n if (opts.bg !== true && !process.stdin.isTTY) {\n body.stdinBase64 = readFileSync(0).toString('base64')\n }\n const path =\n `/v1/workspaces/${opts.workspace}/execute` + (opts.bg === true ? '?background=true' : '')\n const c = makeClient(loadDaemonSettings())\n await c.ensureRunning({ allowSpawn: false })\n const response = await handleResponse(\n await c.request('POST', path, { body: JSON.stringify(body) }),\n )\n emit(response)\n process.exit(exitCodeFromResponse(response))\n },\n )\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, exitCodeFromResponse, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\nfunction buildClient() {\n return makeClient(loadDaemonSettings())\n}\n\nexport function registerJobCommands(program: Command): void {\n const job = program.command('job').description('Manage daemon jobs.')\n\n job\n .command('list')\n .option('-w, --workspace <id>')\n .action(async (opts: { workspace?: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const path =\n '/v1/jobs' + (opts.workspace !== undefined ? `?workspaceId=${opts.workspace}` : '')\n emit(await handleResponse(await c.request('GET', path)))\n })\n\n job\n .command('get')\n .argument('<id>')\n .action(async (id: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const response = await handleResponse(await c.request('GET', `/v1/jobs/${id}`))\n emit(response)\n process.exit(exitCodeFromResponse(response))\n })\n\n job\n .command('wait')\n .argument('<id>')\n .option('--timeout <s>')\n .action(async (id: string, opts: { timeout?: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const body: Record<string, unknown> = {}\n if (opts.timeout !== undefined) body.timeoutS = Number(opts.timeout)\n const response = await handleResponse(\n await c.request('POST', `/v1/jobs/${id}/wait`, { body: JSON.stringify(body) }),\n )\n emit(response)\n process.exit(exitCodeFromResponse(response))\n })\n\n job\n .command('cancel')\n .argument('<id>')\n .action(async (id: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(await handleResponse(await c.request('DELETE', `/v1/jobs/${id}`)))\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { serveMirageMcp } from '@struktoai/mirage-agents/mcp'\nimport type { Workspace } from '@struktoai/mirage-node'\nimport { buildWorkspaceFromConfig, resolveWorkspaceConfig } from '@struktoai/mirage-server'\nimport type { Command } from 'commander'\n\nexport interface McpConfigResolutionOptions {\n cwd?: string\n env?: Record<string, string | undefined>\n}\n\ninterface McpCommandOptions {\n staleWriteProtection: boolean\n}\n\nexport function resolveMcpConfig(\n config: string | undefined,\n options: McpConfigResolutionOptions = {},\n): string {\n return resolveWorkspaceConfig(config, {\n ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),\n ...(options.env !== undefined ? { env: options.env } : {}),\n envNames: ['MIRAGE_MCP_CONFIG', 'MIRAGE_CONFIG'],\n })\n}\n\nexport async function buildMcpWorkspace(configPath: string): Promise<Workspace> {\n return buildWorkspaceFromConfig(configPath)\n}\n\nasync function runMcpServer(config: string | undefined, options: McpCommandOptions): Promise<void> {\n const configPath = resolveMcpConfig(config)\n const workspace = await buildMcpWorkspace(configPath)\n try {\n await serveMirageMcp(workspace, {\n staleWriteProtection: options.staleWriteProtection,\n })\n } catch (error) {\n await workspace.close()\n throw error\n }\n}\n\nexport function registerMcpCommand(program: Command): void {\n program\n .command('mcp')\n .argument('[config]', 'Mirage workspace YAML config')\n .option('--no-stale-write-protection', 'allow edits after a file changed since it was read')\n .description('Serve a Mirage workspace as MCP tools over stdio.')\n .action(runMcpServer)\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\nexport function registerProvisionCommand(program: Command): void {\n program\n .command('provision')\n .description('Estimate cost / preview a command without running it.')\n .requiredOption('-w, --workspace <id>', 'Workspace id')\n .requiredOption('-c, --command <command>', 'Shell command to estimate')\n .option('-s, --session <id>', 'Session id')\n .action(async (opts: { workspace: string; command: string; session?: string }) => {\n const body: Record<string, unknown> = { command: opts.command, provision: true }\n if (opts.session !== undefined) body.sessionId = opts.session\n const c = makeClient(loadDaemonSettings())\n await c.ensureRunning({ allowSpawn: false })\n emit(\n await handleResponse(\n await c.request('POST', `/v1/workspaces/${opts.workspace}/execute`, {\n body: JSON.stringify(body),\n }),\n ),\n )\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\nfunction buildClient() {\n return makeClient(loadDaemonSettings())\n}\n\nconst MODES = new Set(['read', 'write', 'exec', 'r', 'rw', 'rwx'])\n\n/**\n * Parse `-m` values like `/data:read` into a modes mapping. Modes are\n * the words ('read', 'write', 'exec') or their cumulative filesystem\n * aliases ('r', 'rw', 'rwx'). A bare prefix (no mode suffix) keeps\n * the mount's own configured mode. The mode is taken from the last\n * `:` so mount prefixes that contain colons still parse.\n */\nexport function parseMountModes(mounts: string[]): Record<string, string> {\n const modes: Record<string, string> = {}\n for (const item of mounts) {\n const idx = item.lastIndexOf(':')\n const mode = idx >= 0 ? item.slice(idx + 1) : ''\n if (idx >= 0 && MODES.has(mode)) {\n modes[item.slice(0, idx)] = mode\n } else {\n modes[item] = 'exec'\n }\n }\n return modes\n}\n\nexport function registerSessionCommands(program: Command): void {\n const sess = program.command('session').description('Manage workspace sessions.')\n\n sess\n .command('create')\n .argument('<wsId>')\n .option('--id <sessionId>')\n .option(\n '-m, --mount <prefix>',\n \"narrow a mount's mode for this session: '/data:read' (alias '/data:r'), \" +\n \"'/scratch:rw', '/bin:rwx', or a bare '/data' to keep the mount's own \" +\n 'mode; repeatable. This narrows only: a mount you do not name keeps its ' +\n 'own mode, and keeping a session away from one is a hide in its profile',\n (value: string, prev: string[]) => prev.concat([value]),\n [] as string[],\n )\n .option(\n '-p, --profile <name>',\n \"the profile this session runs under, by name from the workspace's profiles; \" +\n 'omit it to take the workspace default',\n )\n .action(async (wsId: string, opts: { id?: string; mount?: string[]; profile?: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const body: Record<string, unknown> = {}\n if (opts.id !== undefined) body.sessionId = opts.id\n if (opts.mount !== undefined && opts.mount.length > 0) {\n body.mounts = parseMountModes(opts.mount)\n }\n if (opts.profile !== undefined) body.profile = opts.profile\n emit(\n await handleResponse(\n await c.request('POST', `/v1/workspaces/${wsId}/sessions`, {\n body: JSON.stringify(body),\n }),\n ),\n )\n })\n\n sess\n .command('list')\n .argument('<wsId>')\n .action(async (wsId: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(await handleResponse(await c.request('GET', `/v1/workspaces/${wsId}/sessions`)))\n })\n\n sess\n .command('delete')\n .argument('<wsId>')\n .argument('<sessionId>')\n .action(async (wsId: string, sessionId: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n await handleResponse(\n await c.request('DELETE', `/v1/workspaces/${wsId}/sessions/${sessionId}`),\n ),\n )\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport type { Command } from 'commander'\nimport {\n absolutizeScripts,\n checkWorkspaceConfigFile,\n interpolateEnv,\n} from '@struktoai/mirage-server'\nimport { parse as yamlParse } from 'yaml'\nimport { makeClient } from './client.ts'\nimport { emit, fail, formatAge, formatTable, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\nfunction buildClient() {\n return makeClient(loadDaemonSettings())\n}\n\nfunction envRecord(): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [k, v] of Object.entries(process.env)) {\n if (typeof v === 'string') out[k] = v\n }\n return out\n}\n\n// A config handed to `load` or `clone`: env-interpolated, and with its\n// relative script paths and code refs rebased onto the file's directory\n// exactly as `create` rebases them, so `resource: ./wiki.mjs:WikiResource`\n// in an override means \"next to this file\", never \"wherever the daemon\n// runs\". Not validated, because an override may name only a subset of\n// mounts. Mirrors `_resolve_config_arg` in the Python CLI.\nfunction loadConfigArgument(path: string): unknown {\n if (!existsSync(path)) fail(`config file not found: ${path}`, 2)\n const text = readFileSync(path, 'utf-8')\n let config: unknown\n try {\n config = interpolateEnv(yamlParse(text), envRecord())\n } catch (err: unknown) {\n fail(`invalid config YAML/JSON at ${path}: ${String(err)}`, 2)\n }\n if (typeof config === 'object' && config !== null && !Array.isArray(config)) {\n absolutizeScripts(config as Record<string, unknown>, dirname(resolve(path)))\n }\n return config\n}\n\ninterface WorkspaceBrief {\n id: string\n mode: string\n mountCount: number\n sessionCount: number\n createdAt: number\n}\n\ninterface MountSummary {\n prefix: string\n resource: string\n mode: string\n}\n\ninterface SessionSummary {\n sessionId: string\n cwd: string\n}\n\ninterface Internals {\n cacheBytes: number | null\n cacheEntries: number | null\n historyLength: number\n inFlightJobs: number\n}\n\ninterface WorkspaceDetail {\n id: string\n mode: string\n createdAt: number\n mounts?: MountSummary[]\n sessions?: SessionSummary[]\n internals?: Internals | null\n}\n\nfunction formatWorkspaceList(items: WorkspaceBrief[]): string {\n if (items.length === 0) return 'No active workspaces.'\n const rows = items.map((w) => [\n w.id,\n w.mode,\n String(w.mountCount),\n String(w.sessionCount),\n formatAge(w.createdAt),\n ])\n return formatTable(['ID', 'MODE', 'MOUNTS', 'SESSIONS', 'AGE'], rows)\n}\n\nfunction formatWorkspaceDetail(d: WorkspaceDetail): string {\n const lines: string[] = [\n `ID: ${d.id}`,\n `Mode: ${d.mode}`,\n `Created: ${formatAge(d.createdAt)} ago`,\n ]\n if (d.mounts !== undefined && d.mounts.length > 0) {\n const rows = d.mounts.map((m) => [m.prefix, m.resource, m.mode])\n lines.push('', 'Mounts:')\n for (const ln of formatTable(['PREFIX', 'RESOURCE', 'MODE'], rows).split('\\n')) {\n lines.push(' ' + ln)\n }\n }\n if (d.sessions !== undefined && d.sessions.length > 0) {\n const rows = d.sessions.map((s) => [s.sessionId, s.cwd])\n lines.push('', 'Sessions:')\n for (const ln of formatTable(['SESSION', 'CWD'], rows).split('\\n')) {\n lines.push(' ' + ln)\n }\n }\n if (d.internals != null) {\n lines.push('', 'Internals:')\n for (const k of ['cacheBytes', 'cacheEntries', 'historyLength', 'inFlightJobs'] as const) {\n const value = d.internals[k]\n lines.push(` ${k.padEnd(16)} ${value === null ? 'n/a (not tracked)' : String(value)}`)\n }\n }\n return lines.join('\\n')\n}\n\ninterface AskRecord {\n id: string\n sessionId: string\n agentId: string\n command: string\n argv: string[]\n cwd: string\n paths: string[]\n reason: string\n outcome: string | null\n scope: string\n note: string\n}\n\nfunction formatAsks(items: AskRecord[]): string {\n if (items.length === 0) return 'No asks.'\n return formatTable(\n ['ID', 'SESSION', 'COMMAND', 'STATUS', 'REASON'],\n items.map((a) => [\n a.id,\n a.sessionId,\n [a.command, ...a.argv].join(' '),\n a.outcome ?? 'pending',\n a.reason,\n ]),\n )\n}\n\ninterface VersionLogItem {\n id: string\n message: string\n}\n\ninterface DiffResult {\n added: string[]\n modified: string[]\n deleted: string[]\n}\n\nfunction formatVersionLog(items: VersionLogItem[]): string {\n if (items.length === 0) return 'No versions.'\n return formatTable(\n ['VERSION', 'MESSAGE'],\n items.map((v) => [v.id.slice(0, 12), v.message]),\n )\n}\n\nfunction formatDiff(changes: DiffResult): string {\n const lines: string[] = []\n for (const kind of ['added', 'modified', 'deleted'] as const) {\n for (const path of changes[kind]) lines.push(`${kind.padEnd(9)} ${path}`)\n }\n return lines.length > 0 ? lines.join('\\n') : 'No changes.'\n}\n\nexport function registerWorkspaceCommands(program: Command): void {\n const ws = program.command('workspace').description('Manage workspaces.')\n\n ws.command('create')\n .description('Create a workspace; daemon auto-spawns if not running.')\n .argument('<config>', 'YAML/JSON workspace config')\n .option('--id <id>', 'Explicit workspace id')\n .action(async (configPath: string, opts: { id?: string }) => {\n // Checked and env-interpolated here (the user's shell env is the\n // source of truth, and a missing var must fail before the round\n // trip), but sent in the file's own spelling: the daemon runs the\n // same check, and it speaks snake_case like the Python one.\n const cfg = checkWorkspaceConfigFile(configPath)\n const body: { config: unknown; id?: string } = { config: cfg }\n if (opts.id !== undefined) body.id = opts.id\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: true })\n const r = await c.request('POST', '/v1/workspaces', { body: JSON.stringify(body) })\n emit((await handleResponse(r)) as WorkspaceDetail, formatWorkspaceDetail)\n })\n\n ws.command('list')\n .description('List active workspaces.')\n .action(async () => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n (await handleResponse(await c.request('GET', '/v1/workspaces'))) as WorkspaceBrief[],\n formatWorkspaceList,\n )\n })\n\n ws.command('get')\n .description('Show full details for one workspace.')\n .argument('<id>')\n .option('--verbose', 'Include cache/dirty/history internals')\n .action(async (id: string, opts: { verbose?: boolean }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const path = `/v1/workspaces/${id}` + (opts.verbose === true ? '?verbose=true' : '')\n emit(\n (await handleResponse(await c.request('GET', path))) as WorkspaceDetail,\n formatWorkspaceDetail,\n )\n })\n\n ws.command('delete')\n .description('Stop and remove a workspace.')\n .argument('<id>')\n .action(async (id: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n (await handleResponse(await c.request('DELETE', `/v1/workspaces/${id}`))) as {\n id: string\n },\n (d) => `Deleted workspace ${d.id}.`,\n )\n })\n\n ws.command('clone')\n .description('Clone a workspace, optionally from one of its past versions.')\n .argument('<srcId>')\n .option('--id <id>', 'Explicit id for the clone')\n .option('--at <ref>', 'Clone from a past version (id or branch) not the live state')\n .action(async (srcId: string, opts: { id?: string; at?: string }) => {\n const body: Record<string, unknown> = { sourceId: srcId }\n if (opts.id !== undefined) body.id = opts.id\n if (opts.at !== undefined) body.at = opts.at\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('POST', '/v1/workspaces/clone', { body: JSON.stringify(body) })\n emit((await handleResponse(r)) as WorkspaceDetail, formatWorkspaceDetail)\n })\n\n ws.command('commit')\n .description(\"Commit the workspace's current state as a version.\")\n .argument('<id>')\n .option('-m, --message <msg>', 'Version message', '')\n .option('-b, --branch <branch>', 'Branch to commit on', 'main')\n .action(async (id: string, opts: { message: string; branch: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('POST', `/v1/workspaces/${id}/commit`, {\n body: JSON.stringify({ message: opts.message, branch: opts.branch }),\n })\n emit(\n (await handleResponse(r)) as { version: string; branch: string },\n (d) => `Committed ${d.version.slice(0, 12)} on ${d.branch}.`,\n )\n })\n\n ws.command('branch')\n .description(\"Create a branch at another branch's current version.\")\n .argument('<id>')\n .argument('<name>')\n .option('--from <branch>', 'Branch to fork from', 'main')\n .action(async (id: string, name: string, opts: { from: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('POST', `/v1/workspaces/${id}/branch`, {\n body: JSON.stringify({ name, fromBranch: opts.from }),\n })\n emit(\n (await handleResponse(r)) as { branch: string; version: string },\n (d) => `Created branch ${d.branch} at ${d.version.slice(0, 12)}.`,\n )\n })\n\n ws.command('log')\n .description(\"List a workspace's versions (newest first).\")\n .argument('<id>')\n .option('-b, --branch <branch>', 'Branch', 'main')\n .action(async (id: string, opts: { branch: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('GET', `/v1/workspaces/${id}/versions?branch=${opts.branch}`)\n emit((await handleResponse(r)) as VersionLogItem[], formatVersionLog)\n })\n\n ws.command('diff')\n .description('Show changed files (git-style): live vs HEAD, live vs <a>, or <a> vs <b>.')\n .argument('<id>')\n .argument('[a]', 'Base ref; omit to use live state')\n .argument('[b]', 'Compare ref; omit to use live state')\n .option('-b, --branch <branch>', 'Branch', 'main')\n .action(\n async (\n id: string,\n a: string | undefined,\n b: string | undefined,\n opts: { branch: string },\n ) => {\n const params = new URLSearchParams({ branch: opts.branch })\n if (a !== undefined) params.set('a', a)\n if (b !== undefined) params.set('b', b)\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('GET', `/v1/workspaces/${id}/diff?${params.toString()}`)\n emit((await handleResponse(r)) as DiffResult, formatDiff)\n },\n )\n\n ws.command('list-asks')\n .description('List pending asks (every decision with --all).')\n .argument('<id>')\n .option('--session <sessionId>', \"Only this session's asks\")\n .option('--all', 'Include settled decisions, not just pending asks')\n .action(async (id: string, opts: { session?: string; all?: boolean }) => {\n const params = new URLSearchParams()\n if (opts.session !== undefined) params.set('sessionId', opts.session)\n if (opts.all === true) params.set('all', 'true')\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const qs = params.toString()\n const r = await c.request('GET', `/v1/workspaces/${id}/asks${qs === '' ? '' : `?${qs}`}`)\n emit((await handleResponse(r)) as AskRecord[], formatAsks)\n })\n\n ws.command('allow')\n .description('Allow a pending ask; the retry of the asked line passes.')\n .argument('<id>')\n .argument('<askId>', 'Ask id, as quoted in the refusal')\n .option(\n '--scope <scope>',\n 'once answers the exact line; session answers every line the rule covers',\n 'once',\n )\n .option('--note <note>', 'What to record alongside the answer', '')\n .action(async (id: string, askId: string, opts: { scope: string; note: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('POST', `/v1/workspaces/${id}/asks/${askId}`, {\n body: JSON.stringify({ answer: 'allow', scope: opts.scope, note: opts.note }),\n })\n emit((await handleResponse(r)) as AskRecord, (d) => `Allowed ${d.id} (${d.scope}).`)\n })\n\n ws.command('deny')\n .description('Deny a pending ask; the retry is refused in the deny voice, once.')\n .argument('<id>')\n .argument('<askId>', 'Ask id, as quoted in the refusal')\n .option('--note <note>', 'What to record alongside the answer', '')\n .action(async (id: string, askId: string, opts: { note: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('POST', `/v1/workspaces/${id}/asks/${askId}`, {\n body: JSON.stringify({ answer: 'deny', note: opts.note }),\n })\n emit((await handleResponse(r)) as AskRecord, (d) => `Denied ${d.id}.`)\n })\n\n ws.command('checkout')\n .description('Restore a workspace in place to one of its versions.')\n .argument('<id>')\n .argument('<ref>', 'Version id or branch to restore')\n .action(async (id: string, ref: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('POST', `/v1/workspaces/${id}/checkout`, {\n body: JSON.stringify({ ref }),\n })\n emit((await handleResponse(r)) as WorkspaceDetail, formatWorkspaceDetail)\n })\n\n ws.command('snapshot')\n .description(\n 'Snapshot a workspace to a tar file. The path is resolved to an absolute path and the daemon writes the tar.',\n )\n .argument('<id>')\n .argument('<output>', 'Path to write the .tar to')\n .action(async (id: string, output: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('POST', `/v1/workspaces/${id}/snapshot`, {\n body: JSON.stringify({ path: resolve(output) }),\n })\n const d = (await handleResponse(r)) as { id: string; path: string; size: number }\n emit(d, (x) => `Snapshot ${x.id} -> ${x.path} (${x.size.toLocaleString()} bytes).`)\n })\n\n ws.command('load')\n .description('Load a workspace from a tar file.')\n .argument('<tar>', 'Path to a .tar produced by `mirage workspace snapshot`')\n .argument('[config]', 'Workspace YAML/JSON config')\n .option('--id <id>', 'Explicit workspace id')\n .action(async (tarPath: string, configPath: string | undefined, opts: { id?: string }) => {\n if (!existsSync(tarPath)) fail(`tar file not found: ${tarPath}`, 2)\n const body: { path: string; id?: string; override?: unknown } = { path: resolve(tarPath) }\n if (opts.id !== undefined) body.id = opts.id\n if (configPath !== undefined) body.override = loadConfigArgument(configPath)\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: true })\n const r = await c.request('POST', '/v1/workspaces/load', { body: JSON.stringify(body) })\n emit((await handleResponse(r)) as WorkspaceDetail, formatWorkspaceDetail)\n })\n}\n"],"mappings":"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","names":["DaemonConfigError","readFileSync","dirname","readFileSync","readFileSync","buildClient","buildClient","existsSync","readFileSync","buildClient","existsSync","readFileSync","dirname","readFileSync","DaemonConfigError"]}
1
+ {"version":3,"sources":["../../src/bin/mirage.ts","../../src/main.ts","../../src/config.ts","../../src/daemon.ts","../../src/vfs.ts","../../src/shell.ts","../../src/tools.ts","../../src/job.ts","../../src/login.ts","../../src/mcp.ts","../../src/rpc.ts","../../src/ssh.ts","../../src/session.ts","../../src/workspace.ts"],"sourcesContent":["#!/usr/bin/env node\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { DaemonConfigError } from '@struktoai/mirage-server/daemon_config'\nimport { DaemonUnreachable } from '../client.ts'\nimport { LoginError } from '../credentials.ts'\nimport { buildProgram } from '../main.ts'\n\nconst ALIASES: Record<string, string> = {\n '--workspace_id': '--workspace',\n '--session_id': '--session',\n '--background': '--bg',\n}\n\nfunction rewriteArgv(argv: string[]): string[] {\n return argv.map((arg) => {\n for (const [from, to] of Object.entries(ALIASES)) {\n if (arg === from) return to\n if (arg.startsWith(from + '=')) return to + arg.slice(from.length)\n }\n return arg\n })\n}\n\nbuildProgram()\n .parseAsync(rewriteArgv(process.argv))\n .catch((err: unknown) => {\n if (err instanceof DaemonConfigError) {\n console.error(err.message)\n process.exit(2)\n }\n if (err instanceof DaemonUnreachable || err instanceof LoginError) {\n console.error(err.message)\n process.exit(1)\n }\n console.error(err)\n process.exit(1)\n })\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { Command } from 'commander'\nimport { registerConfigCommands } from './config.ts'\nimport { registerDaemonCommands } from './daemon.ts'\nimport { registerShellCommand } from './shell.ts'\nimport { registerToolCommands } from './tools.ts'\nimport { registerVfsCommands } from './vfs.ts'\nimport { registerJobCommands } from './job.ts'\nimport { registerLoginCommands } from './login.ts'\nimport { registerMcpCommand } from './mcp.ts'\nimport { registerRpcCommand } from './rpc.ts'\nimport { registerCodexExecCommand, registerSshProxyCommand } from './ssh.ts'\nimport { registerSessionCommands } from './session.ts'\nimport { registerWorkspaceCommands } from './workspace.ts'\n\nfunction resolveVersion(): string {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 6; i++) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')) as {\n name?: string\n version?: string\n }\n if (pkg.name === '@struktoai/mirage-cli' && pkg.version) return pkg.version\n } catch {\n // package.json absent at this level: keep walking up to the package root\n }\n dir = dirname(dir)\n }\n return '0.0.0'\n}\n\nexport function buildProgram(): Command {\n const program = new Command()\n program\n .name('mirage')\n .description('Mirage daemon CLI: manage workspaces and run shell lines.')\n .version(resolveVersion())\n registerWorkspaceCommands(program)\n registerSessionCommands(program)\n registerJobCommands(program)\n registerShellCommand(program)\n registerVfsCommands(program)\n registerToolCommands(program)\n registerMcpCommand(program)\n registerRpcCommand(program)\n registerSshProxyCommand(program)\n registerCodexExecCommand(program)\n registerLoginCommands(program)\n registerDaemonCommands(program)\n registerConfigCommands(program)\n return program\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { compareCodePoints } from '@struktoai/mirage-core/utils/sort'\nimport { ALLOWED_KEYS, DaemonConfigError } from '@struktoai/mirage-server/daemon_config'\nimport type { Command } from 'commander'\nimport { emit, fail } from './output.ts'\nimport { getConfig, listConfig, resolvedConfig, setConfig, unsetConfig } from './settings.ts'\n\nfunction mask(key: string, value: string): string {\n if (key === 'auth_token' && value !== '') return '***'\n return value\n}\n\ninterface ResolvedEntry {\n value: string\n origin: string\n}\n\nfunction humanTable(table: Record<string, string>): string {\n return Object.entries(table)\n .map(([k, v]) => `${k} = ${v}`)\n .join('\\n')\n}\n\nfunction humanResolved(table: Record<string, ResolvedEntry>): string {\n return Object.entries(table)\n .map(([k, e]) => `${k} = ${e.value} (${e.origin})`)\n .join('\\n')\n}\n\nfunction listResolved(): void {\n let resolved: Record<string, [string, string]>\n try {\n resolved = resolvedConfig()\n } catch (e) {\n fail((e as Error).message, 2)\n return\n }\n const payload: Record<string, ResolvedEntry> = {}\n for (const [key, [value, origin]] of Object.entries(resolved)) {\n payload[key] = { value: mask(key, value), origin }\n }\n emit(payload, humanResolved)\n}\n\nfunction listFile(): void {\n let table: Record<string, string>\n try {\n table = listConfig()\n } catch (e) {\n if (!(e instanceof DaemonConfigError)) throw e\n fail(e.message, 2)\n return\n }\n const unknown = Object.keys(table)\n .filter((k) => !ALLOWED_KEYS.has(k))\n .sort(compareCodePoints)\n if (unknown.length > 0) {\n process.stderr.write(\n 'warning: unknown [daemon] keys (daemon will refuse to ' + `start): ${unknown.join(', ')}\\n`,\n )\n }\n emit(table, humanTable)\n}\n\nexport function registerConfigCommands(program: Command): void {\n const config = program\n .command('config')\n .description('Read and write daemon settings in config.toml.')\n\n config\n .command('list')\n .option('--resolved', 'show effective values and their origins')\n .description('Print the config.toml [daemon] table.')\n .action((opts: { resolved?: boolean }) => {\n if (opts.resolved === true) listResolved()\n else listFile()\n })\n\n config\n .command('get')\n .argument('<key>')\n .description('Print one [daemon] key.')\n .action((key: string) => {\n let value: string | undefined\n try {\n value = getConfig(key)\n } catch (e) {\n fail((e as Error).message, 2)\n return\n }\n if (value === undefined) {\n fail(`${key} is not set`, 1)\n return\n }\n emit({ [key]: value }, () => value)\n })\n\n config\n .command('set')\n .argument('<key>')\n .argument('<value>')\n .description('Write a [daemon] key (path settings apply on next daemon restart).')\n .action((key: string, value: string) => {\n try {\n setConfig(key, value)\n } catch (e) {\n fail((e as Error).message, 2)\n return\n }\n emit({ [key]: value, written: true }, () => `${key} = ${value}`)\n })\n\n config\n .command('unset')\n .argument('<key>')\n .description('Remove a [daemon] key.')\n .action((key: string) => {\n try {\n unsetConfig(key)\n } catch (e) {\n fail((e as Error).message, 2)\n return\n }\n emit({ [key]: null, unset: true }, () => `unset ${key}`)\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { pidFilePath } from '@struktoai/mirage-server/paths'\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, fail, formatAge } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\ninterface DaemonStatus {\n running: boolean\n pid: number | null\n url: string\n uptime_s?: number\n workspaces?: number\n}\n\nfunction formatStatus(d: DaemonStatus): string {\n if (!d.running) return `Daemon not running. URL: ${d.url}`\n const parts: string[] = [`Running. PID ${d.pid !== null ? String(d.pid) : '?'}`]\n if (d.uptime_s !== undefined) {\n parts.push(`uptime ${formatAge(Date.now() / 1000 - d.uptime_s)}`)\n }\n if (d.workspaces !== undefined) {\n parts.push(`${String(d.workspaces)} workspace${d.workspaces === 1 ? '' : 's'}`)\n }\n return parts.join(', ') + `. URL: ${d.url}`\n}\n\nfunction formatStop(d: { via?: string; pid?: number }): string {\n const via = d.via ?? '?'\n return `Stopped (via ${via}${d.pid !== undefined ? `, PID ${String(d.pid)}` : ''}).`\n}\n\nfunction formatRestart(d: { spawned_fresh?: boolean }): string {\n if (d.spawned_fresh === true) return 'Restarted (eager spawn).'\n return 'Restarted; next CLI command will auto-spawn.'\n}\n\nfunction formatKill(d: { killed: boolean; pid?: number | null }): string {\n if (d.killed) return `Killed PID ${String(d.pid ?? '?')}.`\n if (d.pid === null || d.pid === undefined) return 'Daemon not running.'\n return `Already gone (PID ${String(d.pid)}).`\n}\n\nfunction readPid(): number | null {\n const p = pidFilePath()\n if (!existsSync(p)) return null\n const text = readFileSync(p, 'utf-8').trim()\n const pid = Number(text)\n return Number.isFinite(pid) && pid > 0 ? pid : null\n}\n\nfunction processAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException).code\n if (code === 'ESRCH') return false\n if (code === 'EPERM') return true\n return false\n }\n}\n\nfunction buildClient() {\n return makeClient(loadDaemonSettings())\n}\n\nasync function waitForUnreachable(timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs\n while (Date.now() < deadline) {\n const c = buildClient()\n if (!(await c.isReachable(300))) return true\n await new Promise((r) => setTimeout(r, 200))\n }\n return false\n}\n\nexport function registerDaemonCommands(program: Command): void {\n const d = program.command('daemon').description('Manage the daemon process lifecycle.')\n\n d.command('status')\n .description('Show daemon health, PID, uptime, workspace count.')\n .action(async () => {\n const pid = readPid()\n const c = buildClient()\n const url = c.settings.url\n try {\n const r = await c.request('GET', '/v1/health')\n if (r.status !== 200) {\n emit({ running: false, pid, url } as DaemonStatus, formatStatus)\n process.exit(1)\n }\n const body = (await r.json()) as Record<string, unknown>\n emit({ running: true, pid, url, ...body } as DaemonStatus, formatStatus)\n } catch {\n emit({ running: false, pid, url } as DaemonStatus, formatStatus)\n process.exit(1)\n }\n })\n\n d.command('stop')\n .description('Gracefully stop the daemon.')\n .option('--timeout <s>', 'Seconds to wait for graceful exit', '5')\n .action(async (opts: { timeout: string }) => {\n const timeoutMs = Number(opts.timeout) * 1000\n const c = buildClient()\n let r: Response\n try {\n r = await c.request('POST', '/v1/shutdown')\n } catch (err: unknown) {\n fail(`daemon not reachable: ${String(err)}`)\n }\n if (r.status >= 400) fail(`shutdown failed: ${await r.text()}`, 2)\n if (await waitForUnreachable(timeoutMs)) {\n emit({ stopped: true, via: 'graceful' }, formatStop)\n return\n }\n const pid = readPid()\n if (pid !== null && processAlive(pid)) {\n try {\n process.kill(pid, 'SIGTERM')\n emit({ stopped: true, via: 'sigterm', pid }, formatStop)\n return\n } catch {\n // fall through to fail\n }\n }\n fail(`daemon did not exit within ${opts.timeout}s and no live PID found`, 2)\n })\n\n d.command('restart')\n .description('Stop the daemon. Next CLI command auto-spawns a fresh one.')\n .option('--timeout <s>', 'Seconds to wait for graceful exit', '5')\n .option('--eager', 'Spawn a fresh daemon immediately')\n .action(async (opts: { timeout: string; eager?: boolean }) => {\n const timeoutMs = Number(opts.timeout) * 1000\n try {\n await buildClient().request('POST', '/v1/shutdown')\n } catch {\n // already unreachable; fall through to pid cleanup\n }\n if (!(await waitForUnreachable(timeoutMs))) {\n const pid = readPid()\n if (pid !== null && processAlive(pid)) {\n try {\n process.kill(pid, 'SIGTERM')\n } catch {\n // process may have exited between checks\n }\n }\n }\n if (opts.eager === true) {\n await buildClient().ensureRunning({ allowSpawn: true })\n emit({ restarted: true, spawned_fresh: true }, formatRestart)\n return\n }\n emit(\n {\n restarted: true,\n spawned_fresh: false,\n note: 'next workspace create will auto-spawn',\n },\n formatRestart,\n )\n })\n\n d.command('kill')\n .description('SIGKILL the daemon. Last resort -- skips graceful shutdown.')\n .action(() => {\n const pid = readPid()\n if (pid === null) {\n emit({ killed: false, reason: 'no daemon running', pid: null }, formatKill)\n return\n }\n if (!processAlive(pid)) {\n emit({ killed: false, reason: 'process already gone', pid }, formatKill)\n return\n }\n try {\n process.kill(pid, 'SIGKILL')\n } catch {\n emit({ killed: false, reason: 'process gone', pid }, formatKill)\n return\n }\n emit({ killed: true, pid }, formatKill)\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { Buffer } from 'node:buffer'\nimport { buffer } from 'node:stream/consumers'\nimport type { Command } from 'commander'\nimport {\n BYTES,\n FLAG,\n INTEGER,\n OWNER,\n SIZE,\n VFS_CALLS,\n type VfsCall,\n} from '@struktoai/mirage-server/vfs_calls'\nimport { makeClient } from './client.ts'\nimport { emit, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\ninterface Target {\n workspace: string\n session?: string\n explain?: boolean\n}\n\ntype Answer = Record<string, unknown>\n\n/** Send one session call to the daemon. Mirrors Python's `post`. */\nexport async function post(\n target: Target,\n route: string,\n body: Record<string, unknown>,\n): Promise<Response> {\n const c = makeClient(loadDaemonSettings())\n await c.ensureRunning({ allowSpawn: false })\n const query = new URLSearchParams()\n if (target.session !== undefined) query.set('session_id', target.session)\n if (target.explain === true) query.set('explain', 'true')\n const suffix = query.size === 0 ? '' : `?${query.toString()}`\n const path = `/v1/workspaces/${encodeURIComponent(target.workspace)}/${route}${suffix}`\n return c.request('POST', path, { body: JSON.stringify(body) })\n}\n\n/**\n * A call's answer, or its failure in the call's own words: a refused or\n * failed call prints its errno and exits 1, with the policy's reason on a\n * line of its own. Mirrors Python's `answer`.\n */\nexport async function answer(r: Response): Promise<unknown> {\n if (r.status >= 400) {\n const text = await r.clone().text()\n let body: { detail?: string; errno?: string; refusal?: { reason: string } | null } = {}\n try {\n body = JSON.parse(text) as typeof body\n } catch {\n // not JSON: the generic handler reports the raw text\n }\n if (body.errno !== undefined) {\n process.stderr.write(`${String(body.detail)} (${body.errno})\\n`)\n if (body.refusal) process.stderr.write(`policy denied: ${body.refusal.reason}\\n`)\n process.exit(1)\n }\n }\n return handleResponse(r)\n}\n\nfunction explained(said: Answer): string {\n let verdict = String(said.outcome)\n if (said.reason !== '') verdict += `: ${String(said.reason)}`\n let line = `${String(said.call)} ${(said.paths as string[]).join(' ')} [${verdict}]`\n if (said.error !== '') line += ` ${String(said.error)}`\n return line\n}\n\nconst text =\n (key: string) =>\n (result: Answer): string =>\n Buffer.from(String(result[key]), 'base64').toString('utf-8')\n\nconst HUMAN: Readonly<Record<string, (result: Answer) => string>> = {\n read: text('data_base64'),\n getxattr: text('value_base64'),\n readdir: (result) => (result.entries as string[]).join('\\n'),\n list_files: (result) => (result.files as string[]).join('\\n'),\n listxattr: (result) => (result.names as string[]).join('\\n'),\n readlink: (result) => String(result.target),\n}\n\nconst flagName = (name: string): string => name.replace(/_base64$/, '')\n\nasync function value(call: VfsCall, name: string, given: unknown): Promise<unknown> {\n if (call.params[name] === BYTES) {\n const data = typeof given === 'string' ? Buffer.from(given) : await buffer(process.stdin)\n return data.toString('base64')\n }\n if (call.params[name] === OWNER && typeof given === 'string' && /^\\d+$/.test(given))\n return Number(given)\n return given\n}\n\nfunction camel(name: string): string {\n return name.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())\n}\n\n/**\n * The `mirage vfs <call>` command for one call: the call's required\n * arguments in order, then an option for each of the rest. Mirrors\n * Python's `command`.\n */\nfunction command(vfs: Command, call: VfsCall): void {\n const cmd = vfs.command(call.name.replace(/_/g, '-')).description(call.description)\n const positional = Object.keys(call.params).filter(\n (name) => call.required.includes(name) && call.params[name] !== BYTES,\n )\n for (const name of positional) cmd.argument(`<${name}>`)\n for (const name of Object.keys(call.params)) {\n if (positional.includes(name)) continue\n if (call.params[name] === BYTES) {\n const flag = flagName(name)\n cmd.option(`--${flag} <text>`, `The ${flag} as text; stdin when absent`)\n } else if (call.params[name] === FLAG) {\n cmd.option(`--${name}`)\n } else if (call.params[name] === INTEGER || call.params[name] === SIZE) {\n cmd.option(`--${name} <n>`, `The ${name}`, Number)\n } else {\n cmd.option(`--${name} <value>`)\n }\n }\n cmd\n .requiredOption('-w, --workspace <id>', 'Workspace id')\n .option('-s, --session <id>', 'Session id')\n .option('--explain', 'Say what the call would do; run nothing')\n .action(async (...given: unknown[]) => {\n const opts = given[positional.length] as Target & Record<string, unknown>\n const body: Record<string, unknown> = {}\n for (const [i, name] of positional.entries()) {\n body[name] = call.params[name] === INTEGER ? Number(given[i]) : given[i]\n }\n for (const name of Object.keys(call.params)) {\n if (positional.includes(name)) continue\n const raw = opts[camel(call.params[name] === BYTES ? flagName(name) : name)]\n if (call.params[name] === BYTES || raw !== undefined)\n body[name] = await value(call, name, raw)\n }\n const result = (await answer(await post(opts, `vfs/${call.name}`, body))) as Answer\n emit(result, opts.explain === true ? explained : HUMAN[call.name])\n })\n}\n\n/** `mirage vfs <call>` for each `session.vfs` call, and `mirage glob`. */\nexport function registerVfsCommands(program: Command): void {\n const vfs = program\n .command('vfs')\n .description(\"The session's VFS calls, one command per call, as POSIX names them.\")\n for (const call of VFS_CALLS) command(vfs, call)\n program\n .command('glob')\n .description('Every path a pattern matches, as the session sees them.')\n .argument('<pattern>', 'Pathname pattern such as /**/*.py')\n .requiredOption('-w, --workspace <id>', 'Workspace id')\n .option('-s, --session <id>', 'Session id')\n .action(async (pattern: string, opts: Target) => {\n const result = (await answer(await post(opts, 'glob', { pattern }))) as {\n paths: string[]\n }\n emit(result, (r) => r.paths.join('\\n'))\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, fail, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\nimport { answer, post } from './vfs.ts'\n\ninterface ExplainedNode {\n type: string\n text: string\n outcome?: string\n exit_code?: number\n reason?: string\n source?: string\n runtime?: string\n children: ExplainedNode[]\n}\n\nexport interface ExplanationRecord {\n line: string\n outcome: string\n reason: string\n exit_code: number\n node: ExplainedNode\n}\n\n/** An explained line as a tree, one node a row, each command with its verdict. */\nexport function formatExplanation(data: ExplanationRecord): string {\n let verdict = `${data.outcome}, exit ${String(data.exit_code)}`\n if (data.reason !== '') verdict += `: ${data.reason}`\n const out = [`${data.line} [${verdict}]`]\n for (const child of data.node.children) explainedLines(child, 1, out)\n return out.join('\\n')\n}\n\n/** Append one node of an explained line, and what it holds, as rows. */\nfunction explainedLines(node: ExplainedNode, depth: number, out: string[]): void {\n const pad = ' '.repeat(depth)\n if (node.outcome === undefined) {\n out.push(`${pad}${node.type}: ${node.text}`)\n } else {\n let line = `${pad}${node.text} [${node.outcome}`\n if (node.exit_code !== undefined && node.exit_code !== 0)\n line += `, exit ${String(node.exit_code)}`\n line += node.reason !== undefined && node.reason !== '' ? `: ${node.reason}]` : ']'\n if (node.source !== undefined && node.source !== '') line += ` ${node.source}`\n if (node.runtime !== undefined && node.runtime !== '') line += ` on ${node.runtime}`\n out.push(line)\n }\n for (const child of node.children) explainedLines(child, depth + 1, out)\n}\n\n/**\n * Run a shell line with raw stdout and stderr streamed as bytes. `--json`\n * collects the same streams into the final result. Piped stdin uploads\n * concurrently in either mode, and Ctrl-C cancels the request with exit130.\n * `--bg` returns the job id after stdin uploads; `--explain` runs nothing.\n */\nexport function registerShellCommand(program: Command): void {\n program\n .command('shell')\n .description('Run a shell line in a workspace.')\n .requiredOption('-w, --workspace <id>', 'Workspace id')\n .requiredOption('-c, --command <command>', 'Shell line to run')\n .option('-s, --session <id>', 'Session id')\n .option('--cwd <path>', 'Working directory for this line (a workspace path)')\n .option('--runtime <name>', \"Workspace runtime entry to place this line's captured stages on\")\n .option('--bg', 'Background; return job_id immediately')\n .option('--json', 'Collect output and print the final result as JSON')\n .option('--explain', 'Say what the line would do, as a tree; run nothing')\n .action(\n async (opts: {\n workspace: string\n command: string\n session?: string\n cwd?: string\n runtime?: string\n bg?: boolean\n explain?: boolean\n json?: boolean\n }) => {\n const body: Record<string, unknown> = { command: opts.command }\n if (opts.cwd !== undefined) body.cwd = opts.cwd\n if (opts.runtime !== undefined) body.runtime = opts.runtime\n if (opts.explain === true) {\n const said = await answer(await post(opts, 'shell', body))\n emit(said as ExplanationRecord, opts.json === true ? undefined : formatExplanation)\n return\n }\n const session =\n opts.session === undefined ? '' : `session_id=${encodeURIComponent(opts.session)}`\n const path = `/v1/workspaces/${encodeURIComponent(opts.workspace)}/shell`\n const c = makeClient(loadDaemonSettings())\n await c.ensureRunning({ allowSpawn: false })\n const foreground = session === '' ? path : `${path}?${session}`\n const background =\n session === '' ? `${path}?background=true` : `${path}?${session}&background=true`\n const piped = !process.stdin.isTTY\n if (opts.bg !== true) {\n const { streamShell } = await import('./stream.ts')\n try {\n process.exitCode = await streamShell(\n c,\n `${foreground}${session === '' ? '?' : '&'}stream=true`,\n body,\n piped,\n opts.json === true,\n )\n } catch (error) {\n fail(error instanceof Error ? error.message : String(error), 2)\n }\n return\n }\n const response = piped\n ? await c.requestUpload('POST', background, body, { name: 'stdin', data: process.stdin })\n : await c.request('POST', background, { body: JSON.stringify(body) })\n emit(await handleResponse(response))\n },\n )\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { buffer } from 'node:stream/consumers'\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\ninterface Target {\n workspace: string\n session?: string\n}\n\n/**\n * Run one tool through the daemon's route and print its answer: JSON, or\n * the tool's text on a terminal. Exits 1 when the tool failed.\n */\nasync function callTool(\n target: Target,\n name: string,\n args: Record<string, unknown>,\n): Promise<void> {\n const c = makeClient(loadDaemonSettings())\n await c.ensureRunning({ allowSpawn: false })\n const query =\n target.session === undefined ? '' : `?session_id=${encodeURIComponent(target.session)}`\n const path = `/v1/workspaces/${encodeURIComponent(target.workspace)}/tools/${name}${query}`\n const response = (await handleResponse(\n await c.request('POST', path, { body: JSON.stringify(args) }),\n )) as { text: string; is_error: boolean }\n emit(response, (r) => r.text)\n if (response.is_error) process.exitCode = 1\n}\n\nfunction toolCommand(program: Command, name: string, description: string): Command {\n return program\n .command(name)\n .description(description)\n .requiredOption('-w, --workspace <id>', 'Workspace id')\n .option('-s, --session <id>', 'Session id')\n}\n\n/** `mirage tools <tool>`: the session's agent tools, one verb each, run as MCP runs them. */\nexport function registerToolCommands(parent: Command): void {\n const program = parent\n .command('tools')\n .description(\"The session's agent tools, as MCP serves them.\")\n toolCommand(program, 'shell', 'Run a command line and read its output as the agent does.')\n .argument('<command>', 'The command line to run')\n .action(async (command: string, opts: Target) => {\n await callTool(opts, 'shell', { command })\n })\n toolCommand(program, 'read', 'Read a file with line numbers.')\n .argument('<path>', 'File to read')\n .option('--offset <n>', 'Line to start at (0-based)', Number)\n .option('--limit <n>', 'Most lines to return', Number)\n .action(async (path: string, opts: Target & { offset?: number; limit?: number }) => {\n const args: Record<string, unknown> = { path }\n if (opts.offset !== undefined) args.offset = opts.offset\n if (opts.limit !== undefined) args.limit = opts.limit\n await callTool(opts, 'read', args)\n })\n toolCommand(program, 'write', 'Write a file; an existing one must be read in full first.')\n .argument('<path>', 'File to write')\n .option('--content <text>', 'Text to write; stdin when absent')\n .action(async (path: string, opts: Target & { content?: string }) => {\n const content = opts.content ?? (await buffer(process.stdin)).toString('utf-8')\n await callTool(opts, 'write', { path, content })\n })\n toolCommand(program, 'edit', 'Replace a string in an existing file.')\n .argument('<path>', 'File to edit')\n .argument('<old>', 'The exact text to replace')\n .argument('<new>', 'The text to put in its place')\n .option('--replace-all', 'Replace every occurrence')\n .action(\n async (\n path: string,\n oldString: string,\n newString: string,\n opts: Target & { replaceAll?: boolean },\n ) => {\n await callTool(opts, 'edit', {\n path,\n old_string: oldString,\n new_string: newString,\n replace_all: opts.replaceAll === true,\n })\n },\n )\n toolCommand(program, 'ls', 'List a directory.')\n .argument('<path>', 'Directory to list')\n .action(async (path: string, opts: Target) => {\n await callTool(opts, 'ls', { path })\n })\n toolCommand(program, 'grep', 'Search files recursively, as grep -rn does.')\n .argument('<pattern>', 'Regular expression to search for')\n .argument('<path>', 'File or directory to search under')\n .option('-i, --ignore-case', 'Match case-insensitively')\n .option('-F, --fixed-strings', 'Read the pattern as a literal string')\n .option('--include <glob>', 'Search only files whose name matches the glob')\n .option('-C, --context <n>', 'Lines of context around each match', Number)\n .option('-l, --files-with-matches', 'Print only the names of matching files')\n .option('-c, --count', 'Print only a count of matching lines per file')\n .option('-m, --max-count <n>', 'Stop each file after this many matches', Number)\n .action(\n async (\n pattern: string,\n path: string,\n opts: Target & {\n ignoreCase?: boolean\n fixedStrings?: boolean\n include?: string\n context?: number\n filesWithMatches?: boolean\n count?: boolean\n maxCount?: number\n },\n ) => {\n const args: Record<string, unknown> = { pattern, path }\n if (opts.ignoreCase === true) args.ignore_case = true\n if (opts.fixedStrings === true) args.fixed_strings = true\n if (opts.include !== undefined) args.include = opts.include\n if (opts.context !== undefined) args.context = opts.context\n if (opts.filesWithMatches === true) args.files_with_matches = true\n if (opts.count === true) args.count = true\n if (opts.maxCount !== undefined) args.max_count = opts.maxCount\n await callTool(opts, 'grep', args)\n },\n )\n toolCommand(program, 'glob', 'Find files whose path matches a pattern.')\n .argument('<pattern>', 'Pathname pattern such as **/*.py')\n .argument('[path]', 'Directory a relative pattern is matched under', '/')\n .action(async (pattern: string, path: string, opts: Target) => {\n await callTool(opts, 'glob', { pattern, path })\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, exitCodeFromResponse, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\nfunction buildClient() {\n return makeClient(loadDaemonSettings())\n}\n\nexport function registerJobCommands(program: Command): void {\n const job = program.command('job').description('Manage daemon jobs.')\n\n job\n .command('list')\n .option('-w, --workspace <id>')\n .action(async (opts: { workspace?: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const path =\n '/v1/jobs' +\n (opts.workspace !== undefined ? `?workspace_id=${encodeURIComponent(opts.workspace)}` : '')\n emit(await handleResponse(await c.request('GET', path)))\n })\n\n job\n .command('get')\n .argument('<id>')\n .action(async (id: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const response = await handleResponse(\n await c.request('GET', `/v1/jobs/${encodeURIComponent(id)}`),\n )\n emit(response)\n process.exitCode = exitCodeFromResponse(response)\n })\n\n job\n .command('wait')\n .argument('<id>')\n .option('--timeout <s>')\n .action(async (id: string, opts: { timeout?: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const body: Record<string, unknown> = {}\n if (opts.timeout !== undefined) body.timeout_s = Number(opts.timeout)\n const response = await handleResponse(\n await c.request('POST', `/v1/jobs/${encodeURIComponent(id)}/wait`, {\n body: JSON.stringify(body),\n }),\n )\n emit(response)\n process.exitCode = exitCodeFromResponse(response)\n })\n\n job\n .command('cancel')\n .argument('<id>')\n .action(async (id: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(await handleResponse(await c.request('DELETE', `/v1/jobs/${encodeURIComponent(id)}`)))\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { spawn } from 'node:child_process'\nimport { createHash, randomBytes } from 'node:crypto'\nimport { createServer } from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport type { Command } from 'commander'\nimport { rstripSlash } from '@struktoai/mirage-core/utils/slash'\nimport {\n AUTHORIZATION_SERVER_PATH,\n PROTECTED_RESOURCE_PATH,\n} from '@struktoai/mirage-server/auth/config'\n\nimport {\n LoginError,\n endsAt,\n jsonBody,\n readLogin,\n removeLogin,\n renewBy,\n tokenClaims,\n writeLogin,\n type Login,\n} from './credentials.ts'\nimport { emit, fail } from './output.ts'\nimport { isLocalUrl, loadDaemonSettings } from './settings.ts'\n\nconst CALLBACK_PATH = '/callback'\nconst CALLBACK_TIMEOUT_SECONDS = 300\nconst SCOPE = 'profile email offline_access'\n\nfunction noLogin(url: string): string {\n return (\n `${url} publishes no login: a local daemon needs none, and a server ` +\n 'with a shared token takes `mirage login --token`'\n )\n}\n\n/** Where an issuer publishes its endpoints (RFC 8414). */\nexport function metadataUrl(issuer: string): string {\n const parts = new URL(issuer)\n return `${parts.protocol}//${parts.host}${AUTHORIZATION_SERVER_PATH}${rstripSlash(parts.pathname)}`\n}\n\nasync function getJson(url: string): Promise<Record<string, unknown>> {\n let reply: Response\n try {\n reply = await fetch(url, { signal: AbortSignal.timeout(30_000) })\n } catch (error) {\n throw new LoginError(`could not reach ${url}: ${String(error)}`)\n }\n if (reply.status !== 200) throw new LoginError(`${url} answered ${String(reply.status)}`)\n return jsonBody(reply)\n}\n\nfunction challenge(verifier: string): string {\n return createHash('sha256').update(verifier).digest('base64url')\n}\n\n/**\n * Open a URL in the browser: `$BROWSER` when set, else the system's\n * opener. The printed URL is the way in when none opens.\n */\nfunction openBrowser(url: string): void {\n const custom = process.env.BROWSER ?? ''\n const [command, args]: [string, string[]] =\n custom !== ''\n ? [custom, [url]]\n : process.platform === 'darwin'\n ? ['open', [url]]\n : process.platform === 'win32'\n ? ['rundll32', ['url.dll,FileProtocolHandler', url]]\n : ['xdg-open', [url]]\n const child = spawn(command, args, { stdio: 'ignore', detached: true })\n child.on('error', (error) => {\n console.error(`could not open the browser: ${error.message}`)\n })\n child.unref()\n}\n\ninterface Callback {\n redirect: string\n answer: Promise<Record<string, string>>\n close: () => void\n}\n\n/** A one-time listener on 127.0.0.1 that the browser comes back to. */\nasync function listen(state: string): Promise<Callback> {\n let settle: (query: Record<string, string>) => void = () => undefined\n const answer = new Promise<Record<string, string>>((resolve) => {\n settle = resolve\n })\n const server = createServer((req, res) => {\n const parts = new URL(req.url ?? '/', 'http://127.0.0.1')\n const query = Object.fromEntries(parts.searchParams)\n if (parts.pathname !== CALLBACK_PATH || query.state !== state) {\n res.writeHead(404).end()\n return\n }\n const text =\n query.code !== undefined\n ? 'Logged in to Mirage. You can close this tab.'\n : `Login failed: ${query.error ?? 'no code'}.`\n const escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' })\n res.end(`<!doctype html><p>${escaped}</p>`)\n settle(query)\n })\n await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve))\n const { port } = server.address() as AddressInfo\n return {\n redirect: `http://127.0.0.1:${String(port)}${CALLBACK_PATH}`,\n answer,\n close: () => {\n server.closeAllConnections()\n server.close()\n },\n }\n}\n\n/**\n * Log in through the server's issuer in the browser. The server names its\n * issuer and OAuth client; the browser signs in there (or is already\n * signed in) and comes back to a one-time listener on 127.0.0.1 with a\n * code, which is swapped for the tokens with PKCE, so no secret is kept\n * on this machine. Null when the server publishes no login.\n */\nexport async function browserLogin(url: string): Promise<Login | null> {\n let found: Response\n try {\n found = await fetch(url + PROTECTED_RESOURCE_PATH, { signal: AbortSignal.timeout(30_000) })\n } catch (error) {\n if (isLocalUrl(url)) return null\n throw new LoginError(`could not reach ${url}: ${String(error)}`)\n }\n if (found.status === 404) return null\n const resource = await jsonBody(found)\n const servers = resource.authorization_servers\n const clientId = resource.client_id\n if (!Array.isArray(servers) || servers.length === 0 || typeof clientId !== 'string') {\n throw new LoginError(`${url} published no issuer to log in through`)\n }\n const issuer = String(servers[0])\n const meta = await getJson(metadataUrl(issuer))\n if (meta.issuer !== issuer) {\n throw new LoginError(`${issuer} published another issuer's endpoints`)\n }\n const verifier = randomBytes(48).toString('base64url')\n const state = randomBytes(16).toString('base64url')\n const callback = await listen(state)\n let answer: Record<string, string>\n try {\n const authorize = new URL(String(meta.authorization_endpoint))\n const params = {\n response_type: 'code',\n client_id: clientId,\n redirect_uri: callback.redirect,\n scope: SCOPE,\n state,\n code_challenge: challenge(verifier),\n code_challenge_method: 'S256',\n }\n for (const [key, value] of Object.entries(params)) authorize.searchParams.set(key, value)\n process.stderr.write(\n `Log in to ${url} in your browser. If it does not open, go to:\\n\\n ${authorize.href}\\n\\n`,\n )\n openBrowser(authorize.href)\n let timer: NodeJS.Timeout | undefined\n const late = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n reject(new LoginError('the browser did not come back in time'))\n }, CALLBACK_TIMEOUT_SECONDS * 1000)\n })\n try {\n answer = await Promise.race([callback.answer, late])\n } finally {\n clearTimeout(timer)\n }\n } finally {\n callback.close()\n }\n const code = answer.code\n if (code === undefined) {\n throw new LoginError(`the issuer refused the login: ${answer.error ?? 'no code'}`)\n }\n const tokenEndpoint = String(meta.token_endpoint)\n const signedIn = Date.now() / 1000\n let reply: Response\n try {\n reply = await fetch(tokenEndpoint, {\n method: 'POST',\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: callback.redirect,\n client_id: clientId,\n code_verifier: verifier,\n }),\n signal: AbortSignal.timeout(30_000),\n })\n } catch (error) {\n throw new LoginError(`could not reach the issuer: ${String(error)}`)\n }\n const body = await jsonBody(reply)\n if (reply.status !== 200 || typeof body.access_token !== 'string') {\n const reason = typeof body.error === 'string' ? body.error : String(reply.status)\n throw new LoginError(`the issuer refused the code: ${reason}`)\n }\n const refresh = body.refresh_token\n return {\n url,\n access_token: body.access_token,\n logged_in_at: signedIn,\n refresh_token: typeof refresh === 'string' && refresh !== '' ? refresh : null,\n expires_at: endsAt(body, signedIn),\n client_id: clientId,\n token_endpoint: tokenEndpoint,\n }\n}\n\n/** Keep a pasted token, once the server takes it. */\nexport async function tokenLogin(url: string, token: string): Promise<Login> {\n let reply: Response\n try {\n reply = await fetch(`${url}/v1/workspaces`, {\n headers: { Authorization: `Bearer ${token}` },\n signal: AbortSignal.timeout(30_000),\n })\n } catch (error) {\n throw new LoginError(`could not reach ${url}: ${String(error)}`)\n }\n if (reply.status === 401) throw new LoginError(`${url} refused the token`)\n if (!reply.ok) throw new LoginError(`${url} answered ${String(reply.status)}`)\n const exp = tokenClaims(token).exp\n return {\n url,\n access_token: token,\n logged_in_at: Date.now() / 1000,\n refresh_token: null,\n expires_at: typeof exp === 'number' ? exp : null,\n client_id: null,\n token_endpoint: null,\n }\n}\n\nexport function registerLoginCommands(program: Command): void {\n program\n .command('login')\n .description('Log in to the server the CLI points at.')\n .option(\n '--token <token>',\n 'Keep this token instead of using the browser; - reads it from stdin',\n )\n .action(async (opts: { token?: string }) => {\n let token = opts.token\n if (token === '-') {\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer)\n token = Buffer.concat(chunks).toString('utf-8').trim()\n if (token === '') fail('no token on stdin')\n }\n const url = rstripSlash(loadDaemonSettings().url)\n const login =\n token !== undefined && token !== '' ? await tokenLogin(url, token) : await browserLogin(url)\n if (login === null) {\n process.stdout.write(noLogin(url) + '\\n')\n return\n }\n writeLogin(login)\n const account = tokenClaims(login.access_token).sub\n const who = typeof account === 'string' ? ` as ${account}.` : '.'\n process.stdout.write(`Logged in to ${url}${who}\\n`)\n })\n program\n .command('logout')\n .description('Forget the stored login.')\n .action(() => {\n const login = removeLogin()\n process.stdout.write(login !== null ? `Logged out of ${login.url}.\\n` : 'Not logged in.\\n')\n })\n program\n .command('whoami')\n .description('Print who the login is for, and when to log in again.')\n .action(() => {\n const url = rstripSlash(loadDaemonSettings().url)\n const login = readLogin()\n if (login?.url !== url) fail(`not logged in to ${url}`)\n const account = tokenClaims(login.access_token).sub\n emit(\n {\n account: typeof account === 'string' ? account : null,\n url,\n renew_by: new Date(renewBy(login) * 1000).toISOString().slice(0, 10),\n },\n (row) =>\n Object.entries(row)\n .map(([k, v]) => `${k}: ${String(v)}`)\n .join('\\n'),\n )\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { resolveWorkspaceConfig } from '@struktoai/mirage-server/workspace_config'\nimport type { Command } from 'commander'\nimport { makeClient, type DaemonClient } from './client.ts'\nimport { LoginError } from './credentials.ts'\nimport { fail, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\nexport const MCP_ENV_NAMES = ['MIRAGE_MCP_CONFIG', 'MIRAGE_CONFIG']\n\ninterface McpCommandOptions {\n workspace?: string\n session?: string\n allCalls?: boolean\n}\n\n/**\n * Whether a daemon workspace holds a session. A daemon refusal throws\n * rather than exiting, so a minted workspace is deleted before the exit.\n */\nasync function hasSession(\n client: DaemonClient,\n workspacePath: string,\n sessionId: string,\n): Promise<boolean> {\n const r = await client.request('GET', `${workspacePath}/sessions`)\n if (r.status >= 400) {\n const { detail } = (await r.json()) as { detail?: unknown }\n throw new Error(`daemon error ${String(r.status)}: ${String(detail)}`)\n }\n const rows: unknown = await r.json()\n return (\n Array.isArray(rows) &&\n rows.some((row) => (row as { session_id?: unknown }).session_id === sessionId)\n )\n}\n\n/**\n * Serve a workspace's MCP tools over stdio. The tools are the daemon's:\n * this relays stdio to the workspace's `/v1/workspaces/:id/mcp`\n * endpoint, starting the daemon when it is not running. A config with no\n * `workspace_id` makes a workspace that lives as long as this process, as\n * a stdio server's state does. A workspace with a name, the config's\n * `workspace_id` or `--workspace`, outlives it. The daemon answers a\n * config's name with the live workspace created from that same config,\n * and refuses it when the live one came from another. `--session` serves\n * the tools as that session, under its profile, as it does for\n * `mirage shell`. `--all-calls` also serves each VFS call as a\n * `vfs_<call>` tool, and `explain` on `shell` and on each of them.\n */\nasync function runMcp(config: string | undefined, options: McpCommandOptions): Promise<void> {\n if (options.workspace !== undefined && config !== undefined) {\n fail('pass a config or --workspace, not both', 2)\n }\n let path: string | undefined\n if (options.workspace === undefined) {\n try {\n path = resolveWorkspaceConfig(config, { envNames: MCP_ENV_NAMES })\n } catch (error) {\n fail(error instanceof Error ? error.message : String(error), 2)\n }\n }\n const { relayStdio } = await import('@struktoai/mirage-server/mcp')\n await relayWorkspace(\n path,\n options.workspace,\n options.session,\n 'mcp',\n relayStdio,\n options.allCalls === true,\n )\n}\n\n/**\n * Delete a relay's temporary workspace on the relay's own server. Sends the\n * token the relay last used, so it works after the login ended or changed\n * and without a refresh; only when the server refuses that token does it\n * ask the login for a fresh one and try once more. A delete that still\n * fails is reported on stderr.\n */\nasync function deleteWorkspace(client: DaemonClient, workspaceId: string): Promise<void> {\n const path = `/v1/workspaces/${encodeURIComponent(workspaceId)}`\n const { url, idleGraceSeconds } = client.settings\n const attempt = (bearer: string): Promise<Response> =>\n makeClient({ url, idleGraceSeconds, authToken: bearer }).request('DELETE', path)\n let done = await attempt(client.held)\n if (done.status === 401 && client.settings.login !== undefined) {\n let fresh: string\n try {\n fresh = await client.token()\n } catch (error) {\n if (!(error instanceof LoginError)) throw error\n process.stderr.write(`could not delete workspace ${workspaceId}: ${error.message}\\n`)\n return\n }\n done = await attempt(fresh)\n }\n if (!done.ok) {\n process.stderr.write(\n `could not delete workspace ${workspaceId}: daemon error ${String(done.status)}\\n`,\n )\n }\n}\n\n/**\n * Relay this process's stdio to one of a workspace's endpoints. The\n * workspace is created from `path`, or `workspace` names one the daemon\n * holds; a created workspace with no `workspace_id` in its config is\n * deleted when the relay ends (see `deleteWorkspace`). A named session\n * must exist. `allCalls` asks the MCP endpoint for the VFS calls too.\n */\nexport async function relayWorkspace(\n path: string | undefined,\n workspace: string | undefined,\n session: string | undefined,\n endpoint: 'mcp' | 'rpc',\n relay: (url: string, token: () => Promise<string>) => Promise<void>,\n allCalls = false,\n): Promise<void> {\n const client = makeClient(loadDaemonSettings())\n try {\n await client.ensureRunning({ allowSpawn: true })\n } catch (error) {\n fail(error instanceof Error ? error.message : String(error))\n }\n let workspaceId: string\n let minted = false\n if (path !== undefined) {\n const { checkWorkspaceConfigFile } = await import('@struktoai/mirage-node/config')\n const loaded = checkWorkspaceConfigFile(path)\n const body = JSON.stringify({ config: loaded })\n const created = await handleResponse(await client.request('POST', '/v1/workspaces', { body }))\n workspaceId = (created as { id: string }).id\n minted = typeof loaded.workspace_id !== 'string' || loaded.workspace_id === ''\n } else {\n workspaceId = workspace ?? ''\n await handleResponse(\n await client.request('GET', `/v1/workspaces/${encodeURIComponent(workspaceId)}`),\n )\n }\n const workspacePath = `/v1/workspaces/${encodeURIComponent(workspaceId)}`\n const query = new URLSearchParams()\n if (session !== undefined) query.set('session_id', session)\n if (allCalls) query.set('calls', 'all')\n const suffix = query.size === 0 ? '' : `?${query.toString()}`\n const url = `${client.settings.url}${workspacePath}/${endpoint}${suffix}`\n let refusal: string | undefined\n try {\n if (session !== undefined) {\n refusal = await hasSession(client, workspacePath, session).then(\n (found) => (found ? undefined : `session not found: ${session}`),\n (error: unknown) => (error instanceof Error ? error.message : String(error)),\n )\n }\n if (refusal === undefined) await relay(url, () => client.token())\n } finally {\n if (minted) await deleteWorkspace(client, workspaceId)\n }\n if (refusal !== undefined) fail(refusal, 2)\n}\n\nexport function registerMcpCommand(program: Command): void {\n program\n .command('mcp')\n .argument('[config]', 'Mirage workspace YAML config')\n .option('-w, --workspace <id>', 'Serve this daemon workspace instead of loading a config')\n .option('-s, --session <id>', \"Session the tools act as; the workspace's default when absent\")\n .option('--all-calls', 'Also serve each VFS call as a tool, and explain')\n .description(\"Serve a Mirage workspace's MCP tools over stdio.\")\n .action(runMcp)\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { resolveWorkspaceConfig } from '@struktoai/mirage-server/workspace_config'\nimport type { Command } from 'commander'\nimport { relayWorkspace } from './mcp.ts'\nimport { fail } from './output.ts'\n\nexport const RPC_ENV_NAMES = ['MIRAGE_RPC_CONFIG', 'MIRAGE_CONFIG']\n\n/**\n * Serve a workspace session's API over JSON-RPC on stdio: line-delimited\n * JSON-RPC 2.0 on stdin and stdout, relayed to the workspace's\n * `/v1/workspaces/:id/rpc` endpoint, as `mirage mcp` relays MCP, with the\n * same config, `--workspace` and `--session` rules.\n */\nexport function registerRpcCommand(program: Command): void {\n program\n .command('rpc')\n .argument('[config]', 'Mirage workspace YAML config')\n .option('-w, --workspace <id>', 'Serve this daemon workspace instead of loading a config')\n .option('-s, --session <id>', \"Session the methods act as; the workspace's default when absent\")\n .description(\"Serve a workspace session's API over JSON-RPC on stdio.\")\n .action(\n async (config: string | undefined, options: { workspace?: string; session?: string }) => {\n if (options.workspace !== undefined && config !== undefined) {\n fail('pass a config or --workspace, not both', 2)\n }\n let path: string | undefined\n if (options.workspace === undefined) {\n try {\n path = resolveWorkspaceConfig(config, { envNames: RPC_ENV_NAMES })\n } catch (error) {\n fail(error instanceof Error ? error.message : String(error), 2)\n }\n }\n const { relayStdio } = await import('@struktoai/mirage-server/rpc')\n await relayWorkspace(path, options.workspace, options.session, 'rpc', relayStdio)\n },\n )\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { fail } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\n/**\n * Carry SSH to a workspace over the server's HTTPS port, on stdio: for\n * `ssh -o ProxyCommand=\"mirage ssh-proxy %r\" <id>@mirage`. The login is this\n * CLI's token, so no SSH key and no SSH port are needed.\n */\nexport function registerSshProxyCommand(program: Command): void {\n program\n .command('ssh-proxy')\n .argument('<workspace>', 'The workspace to log in to')\n .description(\"Carry SSH to a workspace over the server's HTTPS port, on stdio.\")\n .action(async (workspace: string) => {\n const client = makeClient(loadDaemonSettings())\n try {\n await client.ensureRunning({ allowSpawn: true })\n } catch (error) {\n fail(error instanceof Error ? error.message : String(error))\n }\n const base = client.settings.url\n const token = await client.token()\n const url = `ws${base.slice('http'.length)}/v1/workspaces/${encodeURIComponent(workspace)}/ssh`\n const headers: Record<string, string> =\n token === '' ? {} : { Authorization: `Bearer ${token}` }\n const { TunnelRefused, relaySsh } = await import('@struktoai/mirage-server/ssh/relay')\n try {\n await relaySsh(url, headers)\n } catch (error) {\n if (error instanceof TunnelRefused) fail(`ssh-proxy: ${error.message}`)\n throw error\n }\n })\n}\n\n/**\n * Serve a workspace to `codex exec-server forward` on a local port: for\n * `codex exec-server forward --connect ws://HOST:PORT`. Each connection is\n * relayed to the server's codex-exec route with this CLI's token, which\n * forward cannot send itself. Keep it on loopback.\n */\nexport function registerCodexExecCommand(program: Command): void {\n program\n .command('codex-exec')\n .argument('<workspace>', 'The workspace to serve')\n .option('--listen <address>', 'HOST:PORT to accept codex exec-server forward on', '127.0.0.1:0')\n .description('Serve a workspace to `codex exec-server forward` on a local port.')\n .action(async (workspace: string, opts: { listen: string }) => {\n const at = opts.listen.lastIndexOf(':')\n const host = opts.listen.slice(0, at)\n const port = opts.listen.slice(at + 1)\n if (at <= 0 || !/^\\d+$/.test(port)) fail('codex-exec: --listen takes HOST:PORT')\n const client = makeClient(loadDaemonSettings())\n try {\n await client.ensureRunning({ allowSpawn: true })\n } catch (error) {\n fail(error instanceof Error ? error.message : String(error))\n }\n const base = client.settings.url\n const url = `ws${base.slice('http'.length)}/v1/workspaces/${encodeURIComponent(workspace)}/codex-exec`\n const { relayCodex } = await import('@struktoai/mirage-server/ssh/relay')\n await relayCodex(host.replace(/^\\[|\\]$/g, ''), Number(port), url, () => client.token())\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, fail, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\nfunction buildClient() {\n return makeClient(loadDaemonSettings())\n}\n\nconst MODES = new Set(['read', 'write', 'exec', 'r', 'rw', 'rwx'])\n\n/**\n * Parse `-m` values like `/data:read` into a modes mapping. Modes are\n * the words ('read', 'write', 'exec') or their cumulative filesystem\n * aliases ('r', 'rw', 'rwx'). A bare prefix (no mode suffix) keeps\n * the mount's own configured mode. The mode is taken from the last\n * `:` so mount prefixes that contain colons still parse.\n */\nexport function parseMountModes(mounts: string[]): Record<string, string> {\n const modes: Record<string, string> = {}\n for (const item of mounts) {\n const idx = item.lastIndexOf(':')\n const mode = idx >= 0 ? item.slice(idx + 1) : ''\n if (idx >= 0 && MODES.has(mode)) {\n modes[item.slice(0, idx)] = mode\n } else {\n modes[item] = 'exec'\n }\n }\n return modes\n}\n\nexport function registerSessionCommands(program: Command): void {\n const sess = program.command('session').description('Manage workspace sessions.')\n\n sess\n .command('create')\n .argument('<wsId>')\n .option('--id <sessionId>')\n .option(\n '-m, --mount <prefix>',\n \"narrow a mount's mode for this session: '/data:read' (alias '/data:r'), \" +\n \"'/scratch:rw', '/bin:rwx', or a bare '/data' to keep the mount's own \" +\n 'mode; repeatable. This narrows only: a mount you do not name keeps its ' +\n 'own mode, and keeping a session away from one is a hide in its profile',\n (value: string, prev: string[]) => prev.concat([value]),\n [] as string[],\n )\n .option(\n '-p, --profile <name>',\n \"the profile this session runs under, by name from the workspace's profiles; \" +\n 'omit it to take the workspace default',\n )\n .action(async (wsId: string, opts: { id?: string; mount?: string[]; profile?: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const body: Record<string, unknown> = {}\n if (opts.id !== undefined) body.session_id = opts.id\n if (opts.mount !== undefined && opts.mount.length > 0) {\n body.mounts = parseMountModes(opts.mount)\n }\n if (opts.profile !== undefined) body.profile = opts.profile\n emit(\n await handleResponse(\n await c.request('POST', `/v1/workspaces/${encodeURIComponent(wsId)}/sessions`, {\n body: JSON.stringify(body),\n }),\n ),\n )\n })\n\n sess\n .command('list')\n .argument('<wsId>')\n .action(async (wsId: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n await handleResponse(\n await c.request('GET', `/v1/workspaces/${encodeURIComponent(wsId)}/sessions`),\n ),\n )\n })\n\n sess\n .command('delete')\n .argument('<wsId>')\n .argument('<sessionId>')\n .action(async (wsId: string, sessionId: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n await handleResponse(\n await c.request(\n 'DELETE',\n `/v1/workspaces/${encodeURIComponent(wsId)}/sessions/${encodeURIComponent(sessionId)}`,\n ),\n ),\n )\n })\n\n sess\n .command('cancel')\n .description(\"Cancel the session's running and queued commands.\")\n .argument('<wsId>')\n .argument('<sessionId>')\n .action(async (wsId: string, sessionId: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n await handleResponse(\n await c.request(\n 'POST',\n `/v1/workspaces/${encodeURIComponent(wsId)}/sessions/${encodeURIComponent(sessionId)}/cancel`,\n ),\n ),\n )\n })\n\n sess\n .command('kill')\n .description(\"Kill the session's background jobs; the session stays open.\")\n .argument('<wsId>')\n .argument('<sessionId>')\n .action(async (wsId: string, sessionId: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n await handleResponse(\n await c.request(\n 'POST',\n `/v1/workspaces/${encodeURIComponent(wsId)}/sessions/${encodeURIComponent(sessionId)}/kill`,\n ),\n ),\n )\n })\n\n sess\n .command('update')\n .description(\"Replace the session's profile; its cwd, env and history stay.\")\n .argument('<wsId>')\n .argument('<sessionId>')\n .option('-p, --profile <name>', \"Replace the live session's profile.\")\n .option('--default-profile', 'Use the workspace default profile.')\n .action(\n async (\n wsId: string,\n sessionId: string,\n opts: { profile?: string; defaultProfile?: boolean },\n ) => {\n if ((opts.profile === undefined) === (opts.defaultProfile !== true))\n fail('choose --profile or --default-profile', 2)\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n await handleResponse(\n await c.request(\n 'PATCH',\n `/v1/workspaces/${encodeURIComponent(wsId)}/sessions/${encodeURIComponent(sessionId)}`,\n { body: JSON.stringify({ profile: opts.profile ?? null }) },\n ),\n ),\n )\n },\n )\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { createReadStream, existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport type { JsonValue } from '@struktoai/mirage-core/types'\nimport type { Command } from 'commander'\nimport { makeClient } from './client.ts'\nimport { emit, fail, formatAge, formatTable, handleResponse } from './output.ts'\nimport { loadDaemonSettings } from './settings.ts'\n\nfunction buildClient() {\n return makeClient(loadDaemonSettings())\n}\n\n// A config handed to `load` or `clone`: env-interpolated, and with its\n// relative script paths and code refs rebased onto the file's directory\n// exactly as `create` rebases them, so `vfs: ./wiki.mjs:WikiVFS`\n// in an override means \"next to this file\", never \"wherever the daemon\n// runs\". Not validated, because an override may name only a subset of\n// mounts. Mirrors `_resolve_config_arg` in the Python CLI, which is sync:\n// this half is async only because it defers `mirage-node/config` and\n// `yaml` so a `mirage` spawn that never loads a config pays neither. The\n// behaviour is the same; the divergence is the `await`, and it is the\n// reason `override` is a JsonValue rather than `unknown` -- dropping that\n// `await` would otherwise typecheck and put `{}` on the wire.\nasync function loadConfigArgument(path: string): Promise<JsonValue> {\n if (!existsSync(path)) fail(`config file not found: ${path}`, 2)\n const { absolutizeScripts, interpolateEnv, readProcessEnv } =\n await import('@struktoai/mirage-node/config')\n const { parse: yamlParse } = await import('yaml')\n const text = readFileSync(path, 'utf-8')\n let config: JsonValue\n try {\n // `yamlParse` is typed `any`; naming the shape here is what lets\n // `override` be a JsonValue, which is what makes a dropped `await`\n // on this function a type error rather than an empty body on the wire.\n config = interpolateEnv(yamlParse(text) as JsonValue, readProcessEnv())\n } catch (err: unknown) {\n fail(`invalid config YAML/JSON at ${path}: ${String(err)}`, 2)\n }\n if (typeof config === 'object' && config !== null && !Array.isArray(config)) {\n absolutizeScripts(config as Record<string, unknown>, dirname(resolve(path)))\n }\n return config\n}\n\ninterface WorkspaceBrief {\n id: string\n mode: string\n mount_count: number\n session_count: number\n created_at: number\n}\n\ninterface MountSummary {\n prefix: string\n vfs: string\n mode: string\n}\n\ninterface SessionSummary {\n session_id: string\n cwd: string\n}\n\ninterface Internals {\n cache_bytes: number | null\n cache_entries: number | null\n history_length: number\n in_flight_jobs: number\n}\n\ninterface WorkspaceDetail {\n id: string\n mode: string\n created_at: number\n mounts?: MountSummary[]\n sessions?: SessionSummary[]\n internals?: Internals | null\n}\n\nfunction formatWorkspaceList(items: WorkspaceBrief[]): string {\n if (items.length === 0) return 'No active workspaces.'\n const rows = items.map((w) => [\n w.id,\n w.mode,\n String(w.mount_count),\n String(w.session_count),\n formatAge(w.created_at),\n ])\n return formatTable(['ID', 'MODE', 'MOUNTS', 'SESSIONS', 'AGE'], rows)\n}\n\nfunction formatWorkspaceDetail(d: WorkspaceDetail): string {\n const lines: string[] = [\n `ID: ${d.id}`,\n `Mode: ${d.mode}`,\n `Created: ${formatAge(d.created_at)} ago`,\n ]\n if (d.mounts !== undefined && d.mounts.length > 0) {\n const rows = d.mounts.map((m) => [m.prefix, m.vfs, m.mode])\n lines.push('', 'Mounts:')\n for (const ln of formatTable(['PREFIX', 'VFS', 'MODE'], rows).split('\\n')) {\n lines.push(' ' + ln)\n }\n }\n if (d.sessions !== undefined && d.sessions.length > 0) {\n const rows = d.sessions.map((s) => [s.session_id, s.cwd])\n lines.push('', 'Sessions:')\n for (const ln of formatTable(['SESSION', 'CWD'], rows).split('\\n')) {\n lines.push(' ' + ln)\n }\n }\n if (d.internals != null) {\n lines.push('', 'Internals:')\n for (const k of ['cache_bytes', 'cache_entries', 'history_length', 'in_flight_jobs'] as const) {\n const value = d.internals[k]\n lines.push(` ${k.padEnd(16)} ${value === null ? 'n/a (not tracked)' : String(value)}`)\n }\n }\n return lines.join('\\n')\n}\n\ninterface AskRecord {\n id: string\n session_id: string\n command: string\n argv: string[]\n cwd: string\n paths: string[]\n reason: string\n outcome: string | null\n scope: string\n note: string\n}\n\nfunction formatAsks(items: AskRecord[]): string {\n if (items.length === 0) return 'No asks.'\n return formatTable(\n ['ID', 'SESSION', 'COMMAND', 'STATUS', 'REASON'],\n items.map((a) => [\n a.id,\n a.session_id,\n [a.command, ...a.argv].join(' '),\n a.outcome ?? 'pending',\n a.reason,\n ]),\n )\n}\n\nexport function registerWorkspaceCommands(program: Command): void {\n const ws = program.command('workspace').description('Manage workspaces.')\n for (const kind of ['vfs', 'skill']) {\n ws.command(`${kind}-md`)\n .argument('<wsId>')\n .description(`Generate ${kind} Markdown, or expose it inside the workspace with --path.`)\n .option('--path <path>', 'Expose a live file at this workspace path.')\n .option('--session <id>', 'Limit exposure or generation to this session.')\n .option('--profile <name>', 'Preview a profile without creating a file.')\n .action(async (wsId: string, opts: { path?: string; session?: string; profile?: string }) => {\n if (opts.profile !== undefined && (opts.path !== undefined || opts.session !== undefined))\n fail('--profile requires no --path or --session', 2)\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n let route = `/v1/workspaces/${encodeURIComponent(wsId)}`\n if (opts.session !== undefined) route += `/sessions/${encodeURIComponent(opts.session)}`\n route += `/${kind}-md`\n if (opts.profile !== undefined) route += `?profile=${encodeURIComponent(opts.profile)}`\n const response =\n opts.path === undefined\n ? await c.request('GET', route)\n : await c.request('PUT', route, { body: JSON.stringify({ path: opts.path }) })\n if (!response.ok) await handleResponse(response)\n if (opts.path === undefined) process.stdout.write(await response.text())\n })\n }\n\n ws.command('create')\n .description('Create a workspace; daemon auto-spawns if not running.')\n .argument('<config>', 'YAML/JSON workspace config')\n .option('--id <id>', 'Explicit workspace id')\n .action(async (configPath: string, opts: { id?: string }) => {\n // Checked and env-interpolated here (the user's shell env is the\n // source of truth, and a missing var must fail before the round\n // trip), but sent in the file's own spelling: the daemon runs the\n // same check, and it speaks snake_case like the Python one.\n const { checkWorkspaceConfigFile } = await import('@struktoai/mirage-node/config')\n let cfg: unknown\n try {\n cfg = checkWorkspaceConfigFile(configPath)\n } catch (err: unknown) {\n fail(err instanceof Error ? err.message : String(err), 2)\n }\n const body: { config: unknown; id?: string } = { config: cfg }\n if (opts.id !== undefined) body.id = opts.id\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: true })\n const r = await c.request('POST', '/v1/workspaces', { body: JSON.stringify(body) })\n emit((await handleResponse(r)) as WorkspaceDetail, formatWorkspaceDetail)\n })\n\n ws.command('list')\n .description('List active workspaces.')\n .action(async () => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n (await handleResponse(await c.request('GET', '/v1/workspaces'))) as WorkspaceBrief[],\n formatWorkspaceList,\n )\n })\n\n ws.command('get')\n .description('Show full details for one workspace.')\n .argument('<id>')\n .option('--verbose', 'Include cache/dirty/history internals')\n .action(async (id: string, opts: { verbose?: boolean }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const path =\n `/v1/workspaces/${encodeURIComponent(id)}` + (opts.verbose === true ? '?verbose=true' : '')\n emit(\n (await handleResponse(await c.request('GET', path))) as WorkspaceDetail,\n formatWorkspaceDetail,\n )\n })\n\n ws.command('delete')\n .description('Stop and remove a workspace.')\n .argument('<id>')\n .action(async (id: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n (await handleResponse(\n await c.request('DELETE', `/v1/workspaces/${encodeURIComponent(id)}`),\n )) as {\n id: string\n },\n (d) => `Deleted workspace ${d.id}.`,\n )\n })\n\n ws.command('close')\n .description('Stop a workspace and keep its state for the same id.')\n .argument('<id>')\n .action(async (id: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n (await handleResponse(\n await c.request('POST', `/v1/workspaces/${encodeURIComponent(id)}/close`),\n )) as {\n id: string\n },\n (d) => `Closed workspace ${d.id}.`,\n )\n })\n\n ws.command('cancel')\n .description('Cancel the running and queued commands of every session.')\n .argument('<id>')\n .action(async (id: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n await handleResponse(\n await c.request('POST', `/v1/workspaces/${encodeURIComponent(id)}/cancel`),\n ),\n )\n })\n\n ws.command('kill')\n .description('Kill the background jobs of every session.')\n .argument('<id>')\n .action(async (id: string) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n emit(\n await handleResponse(\n await c.request('POST', `/v1/workspaces/${encodeURIComponent(id)}/kill`),\n ),\n )\n })\n\n ws.command('clone')\n .description(\"Clone a workspace's live state.\")\n .argument('<srcId>')\n .option('--id <id>', 'Explicit id for the clone')\n .action(async (srcId: string, opts: { id?: string }) => {\n const body: Record<string, unknown> = {}\n if (opts.id !== undefined) body.id = opts.id\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request('POST', `/v1/workspaces/${encodeURIComponent(srcId)}/clone`, {\n body: JSON.stringify(body),\n })\n emit((await handleResponse(r)) as WorkspaceDetail, formatWorkspaceDetail)\n })\n\n ws.command('list-asks')\n .description('List pending asks (every decision with --all).')\n .argument('<id>')\n .option('--session <sessionId>', \"Only this session's asks\")\n .option('--all', 'Include settled decisions, not just pending asks')\n .action(async (id: string, opts: { session?: string; all?: boolean }) => {\n const params = new URLSearchParams()\n if (opts.session !== undefined) params.set('session_id', opts.session)\n if (opts.all === true) params.set('all', 'true')\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const qs = params.toString()\n const r = await c.request(\n 'GET',\n `/v1/workspaces/${encodeURIComponent(id)}/asks${qs === '' ? '' : `?${qs}`}`,\n )\n emit((await handleResponse(r)) as AskRecord[], formatAsks)\n })\n\n ws.command('allow')\n .description('Allow a pending ask; the retry of the asked line passes.')\n .argument('<id>')\n .argument('<askId>', 'Ask id, as quoted in the refusal')\n .option(\n '--scope <scope>',\n 'once answers the exact line; session answers every line the rule covers',\n 'once',\n )\n .option('--note <note>', 'What to record alongside the answer', '')\n .action(async (id: string, askId: string, opts: { scope: string; note: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request(\n 'POST',\n `/v1/workspaces/${encodeURIComponent(id)}/asks/${encodeURIComponent(askId)}`,\n {\n body: JSON.stringify({ answer: 'allow', scope: opts.scope, note: opts.note }),\n },\n )\n emit((await handleResponse(r)) as AskRecord, (d) => `Allowed ${d.id} (${d.scope}).`)\n })\n\n ws.command('deny')\n .description('Deny a pending ask; the retry is refused in the deny voice, once.')\n .argument('<id>')\n .argument('<askId>', 'Ask id, as quoted in the refusal')\n .option('--note <note>', 'What to record alongside the answer', '')\n .action(async (id: string, askId: string, opts: { note: string }) => {\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const r = await c.request(\n 'POST',\n `/v1/workspaces/${encodeURIComponent(id)}/asks/${encodeURIComponent(askId)}`,\n {\n body: JSON.stringify({ answer: 'deny', note: opts.note }),\n },\n )\n emit((await handleResponse(r)) as AskRecord, (d) => `Denied ${d.id}.`)\n })\n\n ws.command('snapshot')\n .description(\n \"Snapshot a workspace. The server sends the tar back and it is written to <output> here, whether the server runs on this machine or another; with --key it goes to the server's snapshot store.\",\n )\n .argument('<id>')\n .argument('[output]', 'File to write the .tar to, on this machine')\n .option('--key <key>', \"Put it in the server's snapshot store instead\")\n .action(async (id: string, output: string | undefined, opts: { key?: string }) => {\n if (output !== undefined && opts.key !== undefined) {\n fail('snapshot takes an output file or --key', 2)\n }\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: false })\n const path = `/v1/workspaces/${encodeURIComponent(id)}/snapshot`\n const human = (d: { id: string; size: number }, target: string): string =>\n `Snapshot ${d.id} -> ${target} (${d.size.toLocaleString()} bytes).`\n if (opts.key !== undefined) {\n const key = opts.key\n const r = await c.request('POST', path, {\n body: JSON.stringify({ key }),\n timeoutMs: null,\n })\n emit((await handleResponse(r)) as { id: string; key: string; size: number }, (d) =>\n human(d, key),\n )\n return\n }\n if (output === undefined) fail('snapshot takes an output file or --key', 2)\n const target = output\n const r = await c.request('GET', path, { timeoutMs: null })\n if (!r.ok) await handleResponse(r)\n const tar = new Uint8Array(await r.arrayBuffer())\n writeFileSync(target, tar)\n emit({ id, path: target, size: tar.byteLength }, (d) => human(d, target))\n })\n\n ws.command('load')\n .description(\n \"Load a workspace from a snapshot. <file> is read here and uploaded, whether the server runs on this machine or another; with --key the tar comes from the server's snapshot store.\",\n )\n .argument('[file]', 'The .tar to upload; omit with --key')\n .argument('[config]', 'Workspace YAML/JSON config')\n .option('--key <key>', \"Load from the server's snapshot store\")\n .option('--id <id>', 'Explicit workspace id')\n .action(\n async (\n first: string | undefined,\n second: string | undefined,\n opts: { key?: string; id?: string },\n ) => {\n const given = [first, second].filter((p): p is string => p !== undefined)\n if (opts.key !== undefined && given.length > 1)\n fail('load takes a FILE or --key, not both', 2)\n if (opts.key === undefined && given.length === 0) {\n fail('load takes a FILE (or --key) and an optional CONFIG', 2)\n }\n const tarPath = opts.key === undefined ? given.shift() : undefined\n const configPath = given[0]\n for (const p of [tarPath, configPath]) {\n if (p !== undefined && !existsSync(p)) fail(`file not found: ${p}`, 2)\n }\n const body: Record<string, JsonValue> = {}\n if (opts.id !== undefined) body.id = opts.id\n if (configPath !== undefined) body.override = await loadConfigArgument(configPath)\n const c = buildClient()\n await c.ensureRunning({ allowSpawn: true })\n const r =\n tarPath === undefined\n ? await c.request('POST', '/v1/workspaces/load', {\n body: JSON.stringify({ ...body, key: opts.key }),\n timeoutMs: null,\n })\n : await c.requestUpload('POST', '/v1/workspaces/load', body, {\n name: 'snapshot',\n data: createReadStream(tarPath),\n })\n emit((await handleResponse(r)) as WorkspaceDetail, formatWorkspaceDetail)\n },\n )\n}\n"],"mappings":"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","names":["DaemonConfigError","readFileSync","dirname","value","text","Buffer","text","Buffer","buffer","command","buffer","buildClient","command","answer","resolve","text","value","resolveWorkspaceConfig","resolveWorkspaceConfig","buildClient","value","existsSync","readFileSync","buildClient","existsSync","text","readFileSync","value","target","r","dirname","readFileSync","DaemonConfigError"]}