zooid 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bin.ts","../src/commands/dev.ts","../src/bootstrap/admin.ts","../src/bootstrap/configs.ts","../src/bootstrap/data-layout.ts","../src/bootstrap/derive.ts","../src/bootstrap/paths.ts","../src/bootstrap/tokens.ts","../src/daemon/start-daemon.ts","../../transport-http/src/server.ts","../src/prepull-images.ts","../src/services/tuwunel.ts","../src/web/resolve.ts","../src/web/fetch.ts","../src/web/pin.ts","../src/web/static.ts","../src/web/watch.ts","../src/observability/paths.ts","../src/observability/file-sink.ts","../src/observability/capture-agent.ts","../src/observability/capture-tuwunel.ts","../src/commands/dev-cascade.ts","../src/commands/init.ts","../src/commands/init/generators.ts","../src/commands/init/registry.ts","../src/commands/init/sniff.ts","../src/commands/init/prompts.ts","../src/commands/logs.ts","../src/commands/start.ts","../src/commands/status.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport { cac } from 'cac'\nimport { runDev } from './commands/dev.js'\nimport { runInit } from './commands/init.js'\nimport { resolveOptions } from './commands/init/prompts.js'\nimport { runLogs } from './commands/logs.js'\nimport { runStart } from './commands/start.js'\nimport { runStatus } from './commands/status.js'\n\nconst cli = cac('zooid')\n\ncli\n .command('start', 'Run the daemon (production entry-point)')\n .option('--data <dir>', 'Persistent data root dir', { default: './data' })\n .option('--runtime <local|docker|podman>', 'Agent runtime')\n .option('--image <ref>', 'Agent container image')\n .option('--print-token', 'Print a 32-byte hex token and exit')\n .action(async (flags) => {\n await runStart({\n dataDir: flags.data,\n runtime: flags.runtime,\n image: flags.image,\n printToken: flags.printToken,\n })\n })\n\ncli\n .command('dev', 'Tuwunel + daemon + UI for local development')\n .option('--data <dir>', 'Persistent data root dir', { default: './data' })\n .option('--engine <docker|podman>', 'Container engine', { default: 'docker' })\n .option('--ui-port <n>', 'UI HTTP port', { default: 5173 })\n .option('--admin-user <name>', 'Admin username', { default: 'admin' })\n .option('--admin-password <pw>', 'Admin password', { default: 'admin' })\n .option(\n '--watch-web [path]',\n 'Run vite build --watch on @zooid/zoon-web. Path defaults to sibling ../zoon/packages/web.',\n )\n .action(async (flags) => {\n await runDev({\n dataDir: flags.data,\n engine: flags.engine,\n uiPort: Number(flags.uiPort),\n adminUser: flags.adminUser,\n adminPassword: flags.adminPassword,\n watchWeb: flags.watchWeb as string | boolean | undefined,\n })\n })\n\ncli\n .command(\n 'logs [source]',\n 'Read captured logs. source=tuwunel|daemon|dev|agent-<name>[.acp], or \"prune\" to delete old days',\n )\n .option('--data <dir>', 'Persistent data root dir', { default: './data' })\n .option('--day <YYYY-MM-DD>', 'Day partition (defaults to today)')\n .option('--turn <id>', 'Filter ACP taps to a single turn id')\n .option('-f, --follow', 'Tail the file (not yet implemented)')\n .option('--keep <n>', 'For `logs prune`: days to retain', { default: 14 })\n .action(async (source, flags) => {\n if (source === 'prune') {\n await runLogs({\n dataDir: resolve(process.cwd(), flags.data),\n subcommand: 'prune',\n keep: Number(flags.keep),\n })\n return\n }\n await runLogs({\n dataDir: resolve(process.cwd(), flags.data),\n source,\n day: flags.day,\n turn: flags.turn,\n follow: Boolean(flags.follow),\n })\n })\n\ncli\n .command('status', 'Print Tuwunel + daemon health')\n .option('--data <dir>', 'Persistent data root dir', { default: './data' })\n .option('--port <n>', 'Tuwunel host port (defaults to zooid.yaml)')\n .action(async (flags) => {\n await runStatus({\n dataDir: flags.data,\n port: flags.port !== undefined ? Number(flags.port) : undefined,\n })\n })\n\ncli\n .command('init [dir]', 'Scaffold a new zooid workforce in the current (or named) directory')\n .option('--preset <name>', 'claude | codex | opencode')\n .option('--auth <mode>', 'subscription | api-key (claude/codex only)')\n .option('--model <id>', 'Model identifier')\n .option('--provider <id>', 'opencode provider: opencode-go | opencode | anthropic | openrouter | custom')\n .option('--api-key <value>', 'API key (api-key path; opencode always)')\n .option('--force', 'Allow scaffolding into a non-empty directory')\n .option('--overwrite', 'With --force, overwrite existing files')\n .option('--no-interactive', 'Disable prompts; require all flags up front')\n .action(async (dir: string | undefined, flags) => {\n const resolved = await resolveOptions({\n dir: dir ?? process.cwd(),\n preset: flags.preset,\n auth: flags.auth,\n model: flags.model,\n provider: flags.provider,\n apiKey: flags.apiKey,\n force: Boolean(flags.force),\n overwrite: Boolean(flags.overwrite),\n interactive: flags.interactive,\n })\n await runInit(resolved)\n })\n\ncli.help()\ncli.version('0.0.1')\ncli.parse()\n","import chalk from 'chalk'\nimport { Listr } from 'listr2'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { serve, type ServerType } from '@hono/node-server'\nimport {\n findConfigFile,\n findMatrixTransport,\n loadZooidConfig,\n} from '@zooid/core'\nimport { ensureAdminUser } from '../bootstrap/admin.js'\nimport { writeBootstrapConfigs } from '../bootstrap/configs.js'\nimport { resolveDataLayout } from '../bootstrap/data-layout.js'\nimport { deriveHomeserverShape } from '../bootstrap/derive.js'\nimport { resolvePaths } from '../bootstrap/paths.js'\nimport { ensureTokens, type Tokens } from '../bootstrap/tokens.js'\nimport { startDaemon, type DaemonHandle } from '../daemon/start-daemon.js'\nimport { TuwunelService } from '../services/tuwunel.js'\nimport { ensureWebRoot, webSourcePackage } from '../web/resolve.js'\nimport { readZoonWebPin } from '../web/pin.js'\nimport { webStatic } from '../web/static.js'\nimport { startWebWatch, type WebWatchHandle } from '../web/watch.js'\nimport {\n ensureDayFolder,\n pruneOldDays,\n resolveLogPaths,\n type LogPaths,\n} from '../observability/paths.js'\nimport {\n wireAgentCapture,\n type AgentCapture,\n} from '../observability/capture-agent.js'\nimport { captureChildToFile } from '../observability/capture-tuwunel.js'\nimport { buildShutdown } from './dev-cascade.js'\n\n// Walk up from this module until we find the @zooid/cli package.json. This\n// is robust to the source/bundle distinction: src/commands/dev.ts and\n// dist/bin.js end up at different depths, so a fixed `..` count breaks\n// after `tsup`. The package's \"name\" field disambiguates from any parent.\nconst CLI_ROOT = (() => {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 8; i++) {\n const pkgPath = resolve(dir, 'package.json')\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as { name?: string }\n if (pkg.name === 'zooid' || pkg.name === '@zooid/cli') return dir\n } catch {\n // ignore\n }\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n throw new Error('cli root not found (no @zooid/cli package.json above ' + import.meta.url + ')')\n})()\n\nexport interface DevFlags {\n cwd?: string\n dataDir: string\n hostPort?: number\n uiPort: number\n engine: 'docker' | 'podman'\n adminUser: string\n adminPassword: string\n installSignalHandlers?: boolean\n foreground?: boolean\n // Run `vite build --watch` against a @zooid/zoon-web package and serve its dist.\n // true = auto-detect (sibling ../zoon/packages/web or in-monorepo); string = explicit path.\n watchWeb?: string | boolean\n}\n\nexport interface DevHandle {\n stop: () => Promise<void>\n}\n\ninterface DevCtx {\n tokens?: Tokens\n svc?: TuwunelService\n daemon?: DaemonHandle\n uiServer?: ServerType\n webWatch?: WebWatchHandle\n logPaths?: LogPaths\n captures?: Record<string, AgentCapture>\n tuwunelCaptureDone?: Promise<void>\n}\n\nexport async function runDev(flags: DevFlags): Promise<DevHandle> {\n const cwd = flags.cwd ?? process.cwd()\n const found = findConfigFile(cwd)\n if (!found) throw new Error(`zooid.yaml not found in ${cwd}`)\n // Load .env files from the workforce dir before anything reads process.env.\n // Order matches the convention used by Vite/Next: .env.local overrides .env,\n // and real shell vars override both (loadEnvFile never overwrites existing\n // process.env entries). Spawned agents inherit these via runtime-local.\n loadEnvFiles(cwd)\n\n // Resolve data paths up front — they only depend on cwd/flags, not the\n // parsed config — so we can ensure tokens before any loadZooidConfig call.\n const dataRoot = resolve(cwd, flags.dataDir)\n const layout = resolveDataLayout(dataRoot)\n const paths = resolvePaths(layout.matrixDir)\n const logPaths = resolveLogPaths({ dataDir: layout.dataRoot })\n\n // Bootstrap AS tokens and export to env BEFORE parsing zooid.yaml. The\n // parser's MATRIX_AS_TOKEN / MATRIX_HS_TOKEN defaults (see [ZOD048]) and\n // any explicit `${MATRIX_AS_TOKEN}` interpolations both need the vars set.\n const tokens = ensureTokens(paths.envPath)\n process.env.MATRIX_AS_TOKEN = tokens.asToken\n process.env.MATRIX_HS_TOKEN = tokens.hsToken\n\n const rawYaml = readFileSync(found.path, 'utf8')\n const preview = loadZooidConfig(rawYaml, { configDir: dirname(found.path) })\n const matrix = findMatrixTransport(preview)\n if (!matrix) {\n throw new Error('zooid.yaml: zooid dev requires at least one matrix transport')\n }\n const agentUserIds = Object.values(preview.agents)\n .filter((a) => a.matrix?.transport === matrix.name)\n .map((a) => a.matrix!.user_id)\n const shape = deriveHomeserverShape(matrix.transport, agentUserIds)\n const port = flags.hostPort ?? shape.port\n const homeserver = `http://localhost:${port}`\n\n await ensureDayFolder(logPaths)\n await pruneOldDays({ dataDir: layout.dataRoot, retainDays: 14 })\n\n const ctx: DevCtx = { logPaths, tokens }\n\n const tasks = new Listr<DevCtx>(\n [\n {\n title: 'Write tuwunel.toml + appservice.yaml',\n task: () => {\n if (!ctx.tokens) throw new Error('tokens not ready')\n writeBootstrapConfigs({\n paths,\n serverName: shape.serverName,\n asToken: ctx.tokens.asToken,\n hsToken: ctx.tokens.hsToken,\n senderLocalpart: matrix.transport.sender_localpart,\n userNamespace: matrix.transport.user_namespace,\n })\n },\n },\n {\n title: `Start Tuwunel container (${flags.engine})`,\n task: () => {\n ctx.svc = new TuwunelService({\n name: 'zooid-tuwunel',\n hostPort: port,\n paths,\n engine: flags.engine,\n })\n const child = ctx.svc.start()\n ctx.tuwunelCaptureDone = captureChildToFile(child, logPaths.tuwunelLog)\n },\n },\n {\n title: 'Wait for Tuwunel /_matrix/client/versions',\n task: async () => {\n if (!ctx.svc) throw new Error('service not started')\n // 180s covers Docker Desktop's first-run bind-mount setup on macOS\n // (which can sit in `created` for 30–90s before transitioning to\n // `running`) plus Tuwunel's RocksDB init. Repeated runs against an\n // existing DB are far quicker.\n await ctx.svc.waitHealthy({ url: homeserver, timeoutMs: 180_000 })\n },\n },\n {\n title: `Register admin user @${flags.adminUser}:${shape.serverName}`,\n task: async (_, t) => {\n const r = await ensureAdminUser({\n homeserver,\n username: flags.adminUser,\n password: flags.adminPassword,\n })\n t.title = r.created\n ? `Registered admin: ${r.userId}`\n : `Admin already exists: ${r.userId}`\n },\n },\n {\n title: 'Start daemon',\n task: async (_ctx, t) => {\n const captures: Record<string, AgentCapture> = {}\n for (const name of Object.keys(preview.agents)) {\n captures[name] = wireAgentCapture({\n agent: name,\n paths: logPaths,\n verbosity: 'default',\n // Matrix cross-link is a follow-up — wire to transport-matrix's\n // most-recent (room_id, event_id) per session in a later cycle.\n matrixContext: () => null,\n })\n }\n ctx.captures = captures\n ctx.daemon = await startDaemon({\n configPath: found.path,\n cwd,\n installSignalHandlers: false,\n adminUserId: `@${flags.adminUser}:${shape.serverName}`,\n agentsDir: layout.agentsDir,\n // Local-only homeserver: make the workforce space publicly joinable\n // so a self-service-registered dev account lands in #<space> from\n // the web client without needing an invite.\n publicWorkforceSpace: true,\n onTap: (agentName, event) => captures[agentName]?.onTap(event),\n prepullLog: (line) => {\n t.output = line.replace(/^\\[zooid\\]\\s+/, '').trim()\n },\n })\n },\n },\n ...(flags.watchWeb\n ? [\n {\n title: 'Start @zooid/zoon-web watcher (vite build --watch)',\n task: async (): Promise<void> => {\n const pkgDir =\n typeof flags.watchWeb === 'string'\n ? resolve(flags.watchWeb)\n : webSourcePackage(CLI_ROOT)\n if (!pkgDir) {\n const defaultPath = dirname(dirname(dirname(CLI_ROOT))) + '/zoon/packages/web'\n throw new Error(\n `--watch-web: @zooid/zoon-web not found at ${defaultPath}.\\n` +\n `Pass an explicit path: --watch-web=/path/to/zoon/packages/web`,\n )\n }\n ctx.webWatch = await startWebWatch({ webPackageDir: pkgDir })\n },\n },\n ]\n : []),\n {\n title: `Serve @zooid/zoon-web on http://localhost:${flags.uiPort}`,\n task: async (_, t) => {\n const webRoot =\n ctx.webWatch?.distPath ??\n (await ensureWebRoot({\n cliRoot: CLI_ROOT,\n cacheDir: join(layout.dataRoot, 'web'),\n version: readZoonWebPin(CLI_ROOT),\n onProgress: (msg) => {\n t.output = msg\n },\n }))\n const app = webStatic({ webRoot, homeserverUrl: homeserver })\n ctx.uiServer = serve({ fetch: app.fetch, port: flags.uiPort })\n },\n },\n ],\n { concurrent: false, exitOnError: true },\n )\n\n await tasks.run()\n\n // Listr's interactive renderer is done — start streaming the watcher's\n // output to our terminal so vite rebuild logs are visible.\n ctx.webWatch?.attachStdio()\n\n const shutdown = buildShutdown({\n stopUi: async () => {\n const s = ctx.uiServer\n if (!s) return\n await new Promise<void>((r) => s.close(() => r()))\n },\n stopDaemon: async () => {\n await ctx.daemon?.stop()\n },\n stopTuwunel: async () => {\n await ctx.svc?.stop()\n },\n stopWebWatch: async () => {\n await ctx.webWatch?.stop()\n },\n stopCaptures: async () => {\n if (!ctx.captures) return\n await Promise.all(Object.values(ctx.captures).map((c) => c.close()))\n },\n finalizeTuwunelCapture: async () => {\n if (ctx.tuwunelCaptureDone) await ctx.tuwunelCaptureDone\n },\n })\n\n if (flags.installSignalHandlers !== false) {\n const handler = async (): Promise<void> => {\n process.stdout.write(chalk.dim('\\nStopping…\\n'))\n await shutdown()\n process.exit(0)\n }\n process.on('SIGINT', () => void handler())\n process.on('SIGTERM', () => void handler())\n }\n\n process.stdout.write(\n [\n '',\n chalk.bold('Tuwunel is up.') + ` ${homeserver}`,\n chalk.bold('UI: ') + ` http://localhost:${flags.uiPort}`,\n ` ${chalk.cyan('admin user:')} ${flags.adminUser} / ${flags.adminPassword}`,\n ` ${chalk.cyan('data dir:')} ${layout.dataRoot}`,\n ...(ctx.webWatch\n ? [` ${chalk.cyan('web watcher:')} live (vite build --watch on @zooid/zoon-web)`]\n : []),\n '',\n chalk.dim('Press Ctrl-C to stop.'),\n '',\n ].join('\\n'),\n )\n\n if (flags.foreground !== false) {\n await ctx.daemon!.whenStopped\n }\n\n return { stop: shutdown }\n}\n\nfunction loadEnvFiles(cwd: string): void {\n // .env.local takes precedence over .env, but neither overrides shell-exported\n // vars — process.loadEnvFile() refuses to overwrite already-set keys.\n for (const name of ['.env.local', '.env']) {\n const path = resolve(cwd, name)\n if (!existsSync(path)) continue\n try {\n process.loadEnvFile(path)\n } catch (err) {\n console.warn(`[zooid dev] failed to load ${name}: ${(err as Error).message}`)\n }\n }\n}\n","export interface EnsureAdminOpts {\n homeserver: string\n username: string\n password: string\n}\n\nexport interface EnsureAdminResult {\n created: boolean\n userId: string\n}\n\nexport async function ensureAdminUser(\n opts: EnsureAdminOpts,\n): Promise<EnsureAdminResult> {\n const r = await fetch(`${opts.homeserver}/_matrix/client/v3/register`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n auth: { type: 'm.login.dummy' },\n username: opts.username,\n password: opts.password,\n inhibit_login: true,\n }),\n })\n if (r.ok) {\n const j = (await r.json()) as { user_id: string }\n return { created: true, userId: j.user_id }\n }\n const j = (await r.json()) as { errcode?: string; error?: string }\n if (j.errcode === 'M_USER_IN_USE') {\n const host = new URL(opts.homeserver).hostname\n return { created: false, userId: `@${opts.username}:${host}` }\n }\n throw new Error(\n `register ${opts.username}: ${r.status} ${j.errcode ?? ''} ${j.error ?? ''}`.trim(),\n )\n}\n","import { mkdirSync, writeFileSync } from 'node:fs'\nimport { renderRegistration } from '@zooid/transport-matrix'\nimport type { Paths } from './paths.js'\n\nexport interface TuwunelTomlOpts {\n serverName: string\n}\n\n/**\n * Tuwunel binds 8448 inside the container; the host port is whatever\n * `docker run -p <host>:8448` maps it to. So `port` here is fixed.\n */\nconst TUWUNEL_INTERNAL_PORT = 8448\n\nexport function renderTuwunelToml(opts: TuwunelTomlOpts): string {\n return [\n '[global]',\n `server_name = \"${opts.serverName}\"`,\n 'database_path = \"/var/lib/tuwunel/db\"',\n 'media_path = \"/var/lib/tuwunel/media\"',\n 'appservice_dir = \"/var/lib/tuwunel/registrations\"',\n 'allow_registration = true',\n 'yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true',\n 'allow_local_presence = true',\n 'address = [\"0.0.0.0\"]',\n `port = [${TUWUNEL_INTERNAL_PORT}]`,\n '',\n ].join('\\n')\n}\n\nexport interface BootstrapConfigsOpts {\n paths: Paths\n serverName: string\n asToken: string\n hsToken: string\n senderLocalpart: string\n userNamespace: string\n}\n\nexport function writeBootstrapConfigs(opts: BootstrapConfigsOpts): void {\n const { paths, serverName, asToken, hsToken, senderLocalpart, userNamespace } = opts\n mkdirSync(paths.dbDir, { recursive: true })\n mkdirSync(paths.mediaDir, { recursive: true })\n mkdirSync(paths.registrationsDir, { recursive: true })\n\n writeFileSync(paths.tuwunelTomlPath, renderTuwunelToml({ serverName }))\n\n const yaml = renderRegistration({\n id: 'zooid',\n url: `http://host.docker.internal:9099`,\n homeserver: `http://localhost:${TUWUNEL_INTERNAL_PORT}`,\n asToken,\n hsToken,\n senderLocalpart,\n userNamespace,\n // BotPool.bootstrap creates `#alias:<server>` rooms when missing — the\n // AS needs an aliases namespace to legally claim them.\n aliasNamespace: `#.*:${serverName}`,\n // zooid dev shares @.*:<server_name> between bots and the predefined\n // admin human, so the AS cannot claim the namespace exclusively.\n exclusive: false,\n })\n writeFileSync(paths.appserviceYamlPath, yaml)\n}\n","import { join } from 'node:path'\n\nexport interface DataLayout {\n dataRoot: string\n matrixDir: string\n logsDir: string\n agentsDir: string\n agentDir: (agentId: string) => string\n}\n\nexport function resolveDataLayout(dataRoot: string): DataLayout {\n const agentsDir = join(dataRoot, 'agents')\n return {\n dataRoot,\n matrixDir: join(dataRoot, 'matrix'),\n logsDir: join(dataRoot, 'logs'),\n agentsDir,\n agentDir: (id) => join(agentsDir, id),\n }\n}\n","import type { MatrixTransportConfig } from '@zooid/core'\n\nexport interface HomeserverShape {\n host: string\n port: number\n serverName: string\n}\n\nconst NAMESPACE_RE = /^@\\.\\*:([A-Za-z0-9.-]+)$/\n\nexport function deriveHomeserverShape(\n matrix: MatrixTransportConfig,\n agentUserIds: readonly string[],\n): HomeserverShape {\n const url = new URL(matrix.homeserver)\n const host = url.hostname\n const port = url.port\n ? Number(url.port)\n : url.protocol === 'https:'\n ? 443\n : 80\n\n const m = NAMESPACE_RE.exec(matrix.user_namespace)\n if (!m) {\n throw new Error(\n `user_namespace ${matrix.user_namespace!}: expected the simple form '@.*:<server_name>'`,\n )\n }\n const serverName = m[1]!\n\n for (const userId of agentUserIds) {\n if (!userId.endsWith(`:${serverName}`)) {\n throw new Error(\n `server_name mismatch: agent ${userId} does not end with :${serverName}`,\n )\n }\n }\n\n return { host, port, serverName }\n}\n","import { join } from 'node:path'\n\nexport interface Paths {\n dataDir: string\n dbDir: string\n mediaDir: string\n configDir: string\n registrationsDir: string\n tuwunelTomlPath: string\n appserviceYamlPath: string\n envPath: string\n}\n\nexport function resolvePaths(dataDir: string): Paths {\n const configDir = join(dataDir, 'config')\n const registrationsDir = join(configDir, 'registrations')\n return {\n dataDir,\n dbDir: join(dataDir, 'db'),\n mediaDir: join(dataDir, 'media'),\n configDir,\n registrationsDir,\n tuwunelTomlPath: join(configDir, 'tuwunel.toml'),\n appserviceYamlPath: join(registrationsDir, 'zooid.yaml'),\n envPath: join(configDir, '.env'),\n }\n}\n","import { randomBytes } from 'node:crypto'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\n\nexport interface Tokens {\n asToken: string\n hsToken: string\n}\n\nconst AS_RE = /^MATRIX_AS_TOKEN=(.+)$/m\nconst HS_RE = /^MATRIX_HS_TOKEN=(.+)$/m\n\nfunction genToken(prefix: string): string {\n return `${prefix}-${randomBytes(24).toString('hex')}`\n}\n\nexport function readTokens(envPath: string): Tokens | null {\n if (!existsSync(envPath)) return null\n const text = readFileSync(envPath, 'utf8')\n const as = text.match(AS_RE)?.[1]\n const hs = text.match(HS_RE)?.[1]\n if (!as && !hs) return null\n if (!as || !hs) {\n throw new Error(\n `${envPath}: missing MATRIX_AS_TOKEN or MATRIX_HS_TOKEN. Delete the file to regenerate, or restore the missing value.`,\n )\n }\n return { asToken: as, hsToken: hs }\n}\n\nexport function ensureTokens(envPath: string): Tokens {\n const existing = readTokens(envPath)\n if (existing) return existing\n const tokens: Tokens = { asToken: genToken('as'), hsToken: genToken('hs') }\n mkdirSync(dirname(envPath), { recursive: true })\n const previous = existsSync(envPath) ? readFileSync(envPath, 'utf8') : ''\n const next =\n previous.trimEnd() +\n (previous ? '\\n' : '') +\n `MATRIX_AS_TOKEN=${tokens.asToken}\\nMATRIX_HS_TOKEN=${tokens.hsToken}\\n`\n writeFileSync(envPath, next, { mode: 0o600 })\n return tokens\n}\n","import { readFileSync } from 'node:fs'\nimport { mkdir, unlink } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { dirname, isAbsolute, join, resolve } from 'node:path'\nimport type { AddressInfo } from 'node:net'\nimport { serve, type ServerType } from '@hono/node-server'\nimport {\n ApprovalCorrelator,\n findConfigFile,\n findHttpTransport,\n findMatrixTransport,\n loadZooidConfig,\n mergeCliFlags,\n type CliFlags,\n type TapEvent,\n} from '@zooid/core'\nimport { createApp } from '@zooid/transport-http'\nimport {\n MatrixClient,\n MediaClient,\n createMatrixTransport,\n ensureDefaultChannel,\n ensureWorkforceSpace,\n startWorkforcePublisher,\n type AgentBinding,\n type PublisherHandle,\n} from '@zooid/transport-matrix'\nimport {\n SpawnRegistry,\n startDaemonSocketServer,\n type DaemonSocketHandle,\n} from '@zooid/context-mcp'\nimport { buildAcpRegistry } from '../build-registry.js'\nimport { prepullImages } from '../prepull-images.js'\n\nexport interface StartDaemonOpts {\n configPath?: string\n cwd?: string\n cliFlags?: CliFlags\n installSignalHandlers?: boolean\n /** Admin Matrix user ID. Forwarded to the matrix transport for room bootstrap. */\n adminUserId?: string\n /** Observability tap forwarded to each AcpClient. */\n onTap?: (agentName: string, event: TapEvent) => void\n /**\n * Per-agent state root (`<dataRoot>/agents/`). Threaded into\n * `buildAcpRegistry` so each AcpClient persists `sessionId`s across\n * daemon restarts.\n */\n agentsDir?: string\n /** Skip the startup image-prepull pass entirely. */\n noPrepull?: boolean\n /** Force a re-pull of every resolved image at startup (no inspect check). */\n refreshImages?: boolean\n /**\n * Create the workforce space publicly joinable instead of invite-only. Set\n * only by `zooid dev`: the local homeserver is never deployed, so a\n * self-service-registered account can join `#<space>` from the web client\n * without an invite. Production (`zooid start`) leaves this off.\n */\n publicWorkforceSpace?: boolean\n /**\n * Per-line progress hook for the image-prepull pass. Called once per\n * top-level summary plus once per image (start + completion). Used by\n * `zooid dev` to surface pull progress under the \"Start daemon\" listr\n * task instead of leaving the user staring at an unmoving spinner.\n */\n prepullLog?: (line: string) => void\n}\n\nexport interface DaemonHandle {\n port: number\n agentNames: string[]\n stop(): Promise<void>\n whenStopped: Promise<void>\n}\n\nfunction listenAsync(server: ServerType): Promise<number> {\n return new Promise((resolve) => {\n const check = () => {\n const addr = server.address() as AddressInfo | string | null\n if (addr && typeof addr === 'object') resolve(addr.port)\n else setImmediate(check)\n }\n check()\n })\n}\n\nfunction closeAsync(server: ServerType): Promise<void> {\n return new Promise((resolve) => {\n server.close(() => resolve())\n })\n}\n\nexport async function startDaemon(opts: StartDaemonOpts = {}): Promise<DaemonHandle> {\n const cwd = opts.cwd ?? process.cwd()\n const found = opts.configPath ? { path: opts.configPath } : findConfigFile(cwd)\n if (!found) throw new Error('zooid.yaml is required')\n const configDir = dirname(found.path)\n const base = loadZooidConfig(readFileSync(found.path, 'utf8'), { configDir })\n const config = mergeCliFlags(base, opts.cliFlags ?? {})\n\n const approvals = new ApprovalCorrelator()\n\n const daemonSockPath = opts.agentsDir\n ? join(opts.agentsDir, '..', 'run', 'context.sock')\n : join(tmpdir(), `zooid-context-${process.pid}.sock`)\n await mkdir(dirname(daemonSockPath), { recursive: true }).catch(() => {})\n const contextSpawnRegistry = new SpawnRegistry()\n let contextSocket: DaemonSocketHandle | null = null\n try {\n contextSocket = await startDaemonSocketServer({\n sockPath: daemonSockPath,\n registry: contextSpawnRegistry,\n })\n } catch (err) {\n console.warn('[context] daemon socket startup failed; zooid-context MCP disabled:', err)\n }\n\n const dataDir = opts.agentsDir ? dirname(opts.agentsDir) : undefined\n const registry = buildAcpRegistry(config, {\n approvals,\n onTap: opts.onTap,\n agentsDir: opts.agentsDir,\n contextSpawnRegistry: contextSocket ? contextSpawnRegistry : undefined,\n daemonSockPath: contextSocket ? daemonSockPath : undefined,\n configDir,\n dataDir,\n daemonHome: process.env.HOME,\n })\n const agentNames = Object.keys(config.agents)\n\n if (config.runtime !== 'local') {\n await prepullImages(registry, {\n engine: config.runtime === 'podman' ? 'podman' : 'docker',\n runtime: config.runtime,\n skip: opts.noPrepull ?? process.env.ZOOID_NO_PREPULL === '1',\n refresh: opts.refreshImages ?? process.env.ZOOID_REFRESH_IMAGES === '1',\n log: opts.prepullLog,\n })\n }\n\n console.log(\n `[context] socket=${daemonSockPath} ` +\n `status=${contextSocket ? 'listening' : 'disabled'} ` +\n `agents={${agentNames\n .map((n) => `${n}:${registry.hasContextSpawn(n) ? 'yes' : 'no'}`)\n .join(', ')}}`,\n )\n\n let server: ServerType | null = null\n let stopped = false\n let resolveStopped!: () => void\n const whenStopped = new Promise<void>((r) => {\n resolveStopped = r\n })\n\n const matrix = findMatrixTransport(config)\n let port: number\n\n if (matrix) {\n const client = new MatrixClient({\n homeserver: matrix.transport.homeserver,\n asToken: matrix.transport.as_token,\n })\n const mediaClient = new MediaClient({\n homeserver: matrix.transport.homeserver,\n asToken: matrix.transport.as_token,\n })\n const isContainerRuntime = config.runtime !== 'local'\n const bindings: AgentBinding[] = []\n for (const a of Object.values(config.agents)) {\n if (a.matrix?.transport !== matrix.name) continue\n const binding: AgentBinding = {\n name: a.name,\n userId: a.matrix.user_id,\n rooms: a.matrix.rooms,\n trigger: a.matrix.trigger,\n }\n if (a.matrix.display_name !== undefined) binding.displayName = a.matrix.display_name\n // Resolve workspace dirs for media attachment routing.\n const workspaceDir = isAbsolute(a.workdir) ? a.workdir : resolve(configDir, a.workdir)\n binding.workspaceDir = workspaceDir\n binding.agentWorkspacePath = isContainerRuntime ? '/workspace' : workspaceDir\n bindings.push(binding)\n }\n const transport = createMatrixTransport({\n agents: registry,\n approvals,\n client,\n bindings,\n hsToken: matrix.transport.hs_token,\n adminUserId: opts.adminUserId,\n media: mediaClient,\n })\n const requestedPort = matrix.transport.port ?? 9000\n // Bind 0.0.0.0 explicitly — @hono/node-server defaults to IPv6-only on\n // macOS, which Docker's NAT bridge can't reach when Tuwunel pushes AS\n // events back to host.docker.internal:<port>.\n server = serve({ fetch: transport.app.fetch, port: requestedPort, hostname: '0.0.0.0' })\n port = await listenAsync(server)\n\n // user_namespace is a regex like `@.*:localhost`; the part after the last\n // `:` is the homeserver's server_name. Fall back to the homeserver URL's\n // host if the namespace shape is unexpected.\n const serverName =\n matrix.transport.user_namespace.split(':').slice(1).join(':').replace(/\\\\?\\)?$/, '') ||\n new URL(matrix.transport.homeserver).hostname\n const asUserId = `@${matrix.transport.sender_localpart}:${serverName}`\n const spaceLocalpart = matrix.transport.space ?? 'dev'\n const adminUserIds = opts.adminUserId ? [opts.adminUserId] : []\n let spaceRoomId: string | undefined\n try {\n spaceRoomId = await ensureWorkforceSpace({\n client,\n asUserId,\n serverName,\n spaceLocalpart,\n preset: 'public_chat',\n admins: adminUserIds,\n joinRule: opts.publicWorkforceSpace ? 'public' : 'invite',\n })\n console.log(`[matrix] ensured workforce space #${spaceLocalpart}:${serverName} → ${spaceRoomId}`)\n } catch (err) {\n console.warn('[matrix] workforce space provisioning failed:', err)\n }\n\n // Bootstrap *after* the listener is up: registerBot/createRoom/joinRoom\n // each trigger Tuwunel to push events back to the AS, and Tuwunel only\n // retries those a few times before dropping. Listening first ensures\n // those pushes don't hit a connection-refused. Bootstrap also runs\n // *after* the space exists so BotPool can attach each agent room as\n // m.space.child while joining it.\n await transport.bootstrap({ spaceRoomId, asUserId, adminUserIds })\n\n if (spaceRoomId) {\n try {\n const generalRoomId = await ensureDefaultChannel({\n client,\n asUserId,\n serverName,\n spaceId: spaceRoomId,\n admins: adminUserIds,\n })\n console.log(`[matrix] ensured default channel #general:${serverName} → ${generalRoomId}`)\n } catch (err) {\n console.warn('[matrix] default channel provisioning failed:', err)\n }\n try {\n const publisher: PublisherHandle = await startWorkforcePublisher({\n client,\n spaceRoomId,\n asUserId,\n getAgents: () => bindings,\n })\n console.log(`[matrix] published eco.zoon.workforce (${bindings.length} agents)`)\n void publisher\n } catch (err) {\n console.warn('[matrix] workforce roster publication failed:', err)\n }\n }\n } else {\n const http = findHttpTransport(config)\n if (!http) throw new Error('no transport declared in zooid.yaml')\n const token = process.env.ZOOID_TOKEN\n if (!token) throw new Error('ZOOID_TOKEN is required for http transport')\n const app = createApp({ agents: registry, approvals, token })\n server = serve({ fetch: app.fetch, port: http.transport.port, hostname: '0.0.0.0' })\n port = await listenAsync(server)\n }\n\n const stop = async (): Promise<void> => {\n if (stopped) return whenStopped\n stopped = true\n try {\n if (server) await closeAsync(server)\n } catch {\n // swallow\n }\n try {\n await registry.stopAll()\n } catch (err) {\n console.error('stopAll:', err)\n }\n try {\n if (contextSocket) await contextSocket.close()\n await unlink(daemonSockPath).catch(() => {})\n } catch {\n // swallow\n }\n resolveStopped()\n }\n\n if (opts.installSignalHandlers !== false) {\n const handler = (sig: NodeJS.Signals): void => {\n console.log(`received ${sig}, stopping agents...`)\n void stop().then(() => process.exit(0))\n }\n process.on('SIGINT', () => handler('SIGINT'))\n process.on('SIGTERM', () => handler('SIGTERM'))\n }\n\n return { port, agentNames, stop, whenStopped }\n}\n","import { Hono, type Context } from 'hono'\nimport { streamSSE, type SSEStreamingApi } from 'hono/streaming'\nimport { timingSafeEqual, randomUUID } from 'node:crypto'\nimport type {\n AcpRegistry,\n ApprovalCorrelator,\n RegisteredApproval,\n} from '@zooid/core'\nimport type {\n AgentEvent,\n ApprovalDecision,\n} from '@zooid/acp-client'\n\nexport interface CreateAppOptions {\n /** Long-lived registry that fronts every ACP agent. */\n agents: AcpRegistry\n /**\n * Correlator that pairs ACP `requestPermission` calls with HTTP-side\n * decisions. The transport listens to its `'registered'` and `'timeout'`\n * events to drive the SSE wire and resolves it via the POST decision route.\n */\n approvals: ApprovalCorrelator\n /** Bearer token; constant-time compared against `Authorization`. */\n token: string\n /**\n * Keepalive interval for open SSE streams (proxies kill idle connections).\n * 0 disables. Default: 30_000ms.\n */\n keepaliveMs?: number\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/\n\ninterface PromptBody {\n prompt: string\n}\n\nfunction isAuthorized(token: string, header: string | undefined): boolean {\n if (!header || !header.startsWith('Bearer ')) return false\n const provided = header.slice('Bearer '.length)\n if (provided.length !== token.length) return false\n return timingSafeEqual(Buffer.from(provided), Buffer.from(token))\n}\n\nfunction parsePromptBody(raw: unknown): PromptBody | { error: string } {\n if (!raw || typeof raw !== 'object') return { error: 'body must be a JSON object' }\n const obj = raw as Record<string, unknown>\n if (typeof obj.prompt !== 'string' || obj.prompt.length === 0) {\n return { error: 'missing or empty prompt' }\n }\n return { prompt: obj.prompt }\n}\n\nasync function readJson(c: Context): Promise<unknown | { error: string }> {\n const raw = await c.req.text()\n try {\n return JSON.parse(raw)\n } catch {\n return { error: 'body must be valid JSON' }\n }\n}\n\ninterface DecisionBody {\n decision: 'allow' | 'cancel'\n option_id?: string\n}\n\nfunction parseDecisionBody(raw: unknown): DecisionBody | { error: string } {\n if (!raw || typeof raw !== 'object') return { error: 'body must be a JSON object' }\n const obj = raw as Record<string, unknown>\n if (obj.decision !== 'allow' && obj.decision !== 'cancel') {\n return { error: 'decision must be \"allow\" or \"cancel\"' }\n }\n if (obj.decision === 'allow' && typeof obj.option_id !== 'string') {\n return { error: 'option_id is required when decision is \"allow\"' }\n }\n return {\n decision: obj.decision,\n option_id: typeof obj.option_id === 'string' ? obj.option_id : undefined,\n }\n}\n\nfunction approvalRequestFrame(handle: RegisteredApproval): string {\n return JSON.stringify({\n type: 'approval.request',\n approval_id: handle.approvalId,\n session_id: handle.sessionId,\n tool_call_id: handle.toolCallId,\n options: handle.options,\n })\n}\n\nexport function createApp({\n agents,\n approvals,\n token,\n keepaliveMs = 30_000,\n}: CreateAppOptions) {\n const app = new Hono()\n\n // Per-session SSE handle. The registry's onEvent dispatcher and the\n // correlator's `'registered'` / `'timeout'` listeners look up the\n // currently-attached stream by session id.\n const streams = new Map<string, SSEStreamingApi>()\n\n agents.onEvent = (_name, event: AgentEvent) => {\n const stream = streams.get(event.sessionId)\n if (!stream) return\n void stream.writeSSE({ data: JSON.stringify(event) })\n }\n // Always wire the registry's approval handler to the correlator. The\n // per-agent `approval_timeout_ms` is read off the registry so YAML-driven\n // timeouts still apply.\n agents.onApprovalRequest = async (name, req) => {\n const handle = approvals.register(name, req.sessionId, req, {\n timeoutMs: agents.getApprovalTimeoutMs(name),\n })\n return handle.decisionPromise\n }\n\n approvals.on('registered', (handle: RegisteredApproval) => {\n const stream = streams.get(handle.sessionId)\n if (!stream) return\n void stream.writeSSE({ data: approvalRequestFrame(handle) })\n })\n\n approvals.on('timeout', ({ approvalId, sessionId }: { approvalId: string; sessionId: string }) => {\n const stream = streams.get(sessionId)\n if (!stream) return\n void stream.writeSSE({\n data: JSON.stringify({ type: 'approval.timeout', approval_id: approvalId, session_id: sessionId }),\n })\n })\n\n function checkAgent(c: Context, name: string): Response | null {\n if (!agents.hasAgent(name)) {\n return c.json({ error: 'unknown agent' }, 404)\n }\n return null\n }\n\n function attachKeepalive(sse: SSEStreamingApi): NodeJS.Timeout | null {\n if (!keepaliveMs || keepaliveMs <= 0) return null\n const timer = setInterval(() => {\n void sse.writeSSE({ data: '', event: 'keepalive' }).catch(() => {})\n }, keepaliveMs)\n timer.unref?.()\n return timer\n }\n\n /**\n * POST /agents/:name/sessions — start a new ACP session.\n *\n * { session.start, session_id }\n * { turn.start }\n * ... ACP AgentEvents\n * { approval.request, ... } / { approval.timeout, ... } as they arrive\n * { turn.end, stop_reason }\n */\n app.post('/agents/:name/sessions', async (c) => {\n if (!isAuthorized(token, c.req.header('authorization'))) {\n return c.json({ error: 'unauthorized' }, 401)\n }\n const name = c.req.param('name')\n const reject = checkAgent(c, name)\n if (reject) return reject\n\n const parsed = await readJson(c)\n if (parsed && typeof parsed === 'object' && 'error' in parsed) {\n return c.json({ error: (parsed as { error: string }).error }, 400)\n }\n const body = parsePromptBody(parsed)\n if ('error' in body) return c.json({ error: body.error }, 400)\n\n const threadId = randomUUID()\n return streamSSE(c, async (sse) => {\n let sessionId: string | null = null\n let keepalive: NodeJS.Timeout | null = null\n try {\n sessionId = await agents.ensureSession(name, threadId)\n streams.set(sessionId, sse)\n keepalive = attachKeepalive(sse)\n await sse.writeSSE({\n data: JSON.stringify({ type: 'session.start', session_id: sessionId }),\n })\n await sse.writeSSE({ data: JSON.stringify({ type: 'turn.start' }) })\n const result = await agents.prompt(name, {\n threadId,\n content: [{ type: 'text', text: body.prompt }],\n })\n await sse.writeSSE({\n data: JSON.stringify({ type: 'turn.end', stop_reason: result.stopReason }),\n })\n } catch (err) {\n await sse.writeSSE({\n data: JSON.stringify({\n type: 'turn.end',\n stop_reason: 'error',\n error: (err as Error).message,\n }),\n })\n } finally {\n if (keepalive) clearInterval(keepalive)\n if (sessionId) {\n // The turn is over; cancel any approvals that the shim left\n // dangling so future POSTs against them 404 fast.\n approvals.cancelSession(sessionId)\n if (streams.get(sessionId) === sse) {\n streams.delete(sessionId)\n }\n }\n }\n })\n })\n\n /**\n * GET /agents/:name/sessions/:id/events — reattach to an in-flight stream.\n *\n * When a turn is in flight: replays any pending approvals via\n * `approvals.listPending(sid)`, then forwards live events until the turn\n * ends. When no turn is in flight: 404.\n */\n app.get('/agents/:name/sessions/:id/events', async (c) => {\n if (!isAuthorized(token, c.req.header('authorization'))) {\n return c.json({ error: 'unauthorized' }, 401)\n }\n const name = c.req.param('name')\n const reject = checkAgent(c, name)\n if (reject) return reject\n const id = c.req.param('id')\n if (!UUID_RE.test(id)) {\n return c.json({ error: 'session id must be a UUID' }, 400)\n }\n if (!streams.has(id)) {\n return c.json({ error: 'no in-flight session' }, 404)\n }\n return streamSSE(c, async (sse) => {\n // Take ownership of dispatch for this session id.\n streams.set(id, sse)\n const keepalive = attachKeepalive(sse)\n // Replay any approvals that are still pending so the reconnecting\n // client can decide on them.\n for (const handle of approvals.listPending(id)) {\n await sse.writeSSE({ data: approvalRequestFrame(handle) })\n }\n try {\n while (streams.get(id) === sse) {\n await new Promise((r) => setTimeout(r, 250))\n }\n } finally {\n if (keepalive) clearInterval(keepalive)\n }\n })\n })\n\n /**\n * POST /agents/:name/sessions/:sid/approvals/:approval_id — resolve a\n * pending permission request.\n */\n app.post('/agents/:name/sessions/:sid/approvals/:approval_id', async (c) => {\n if (!isAuthorized(token, c.req.header('authorization'))) {\n return c.json({ error: 'unauthorized' }, 401)\n }\n const name = c.req.param('name')\n const reject = checkAgent(c, name)\n if (reject) return reject\n\n const sid = c.req.param('sid')\n const approvalId = c.req.param('approval_id')\n const parsed = await readJson(c)\n if (parsed && typeof parsed === 'object' && 'error' in parsed) {\n return c.json({ error: (parsed as { error: string }).error }, 400)\n }\n const body = parseDecisionBody(parsed)\n if ('error' in body) return c.json({ error: body.error }, 400)\n\n const decision: ApprovalDecision =\n body.decision === 'cancel'\n ? { decision: 'cancel' }\n : { decision: 'allow', optionId: body.option_id! }\n const ok = approvals.resolve(sid, approvalId, decision)\n if (!ok) return c.json({ error: 'unknown approval' }, 404)\n return c.json({ ok: true })\n })\n\n /**\n * POST /agents/:name/sessions/:sid/cancel — cancel every pending approval\n * for the session. Idempotent. Returns 204.\n */\n app.post('/agents/:name/sessions/:sid/cancel', async (c) => {\n if (!isAuthorized(token, c.req.header('authorization'))) {\n return c.json({ error: 'unauthorized' }, 401)\n }\n const name = c.req.param('name')\n const reject = checkAgent(c, name)\n if (reject) return reject\n const sid = c.req.param('sid')\n approvals.cancelSession(sid)\n return c.body(null, 204)\n })\n\n return app\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst pExecFile = promisify(execFile)\n\nexport interface PrepullExec {\n (cmd: string, args: string[]): Promise<{ code: number; stdout: string; stderr: string }>\n}\n\nexport interface PrepullOptions {\n engine: 'docker' | 'podman'\n runtime: 'local' | 'docker' | 'podman'\n /** Injectable for tests. Defaults to a child_process.execFile-backed exec. */\n exec?: PrepullExec\n /** When true, skip the inspect check and pull every image. */\n refresh?: boolean\n /** When true, the function returns immediately without touching the engine. */\n skip?: boolean\n log?: (line: string) => void\n}\n\nexport interface PrepullableRegistry {\n agentNames(): string[]\n resolveSpawnImage(name: string): string | undefined\n}\n\n/**\n * Walk the registry's unique resolved-image set, `<engine> image inspect`\n * each one, and `<engine> pull` the ones not cached locally. Parallel and\n * fail-fast: any pull exit ≠ 0 throws with the engine's stderr embedded.\n * No-op when `opts.skip` or `opts.runtime === 'local'`.\n */\nexport async function prepullImages(\n registry: PrepullableRegistry,\n opts: PrepullOptions,\n): Promise<void> {\n if (opts.skip || opts.runtime === 'local') return\n const exec = opts.exec ?? defaultExec\n const log = opts.log ?? ((l: string) => console.log(l))\n\n const images = new Set<string>()\n for (const name of registry.agentNames()) {\n const img = registry.resolveSpawnImage(name)\n if (img) images.add(img)\n }\n\n const toPull: string[] = []\n let cached = 0\n if (opts.refresh) {\n toPull.push(...images)\n } else {\n await Promise.all(\n [...images].map(async (img) => {\n const r = await exec(opts.engine, ['image', 'inspect', img])\n if (r.code === 0) cached++\n else toPull.push(img)\n }),\n )\n }\n\n log(\n `[zooid] image prepull: ${images.size} unique images (${cached} cached, ${toPull.length} to pull)`,\n )\n if (toPull.length === 0) return\n\n await Promise.all(\n toPull.map(async (img) => {\n log(`[zooid] ${img} pulling…`)\n const start = Date.now()\n const r = await exec(opts.engine, ['pull', img])\n const secs = ((Date.now() - start) / 1000).toFixed(1)\n if (r.code !== 0) {\n throw new Error(\n `image prepull failed for ${img}:\\n${r.stderr.trim() || '(no stderr)'}`,\n )\n }\n log(`[zooid] ${img} ✓ ${secs}s`)\n }),\n )\n}\n\nconst defaultExec: PrepullExec = async (cmd, args) => {\n try {\n const { stdout, stderr } = await pExecFile(cmd, args, {\n maxBuffer: 16 * 1024 * 1024,\n })\n return { code: 0, stdout, stderr }\n } catch (err) {\n const e = err as NodeJS.ErrnoException & {\n code?: number | string\n stdout?: string\n stderr?: string\n }\n return {\n code: typeof e.code === 'number' ? e.code : 1,\n stdout: e.stdout ?? '',\n stderr: e.stderr ?? String(e),\n }\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport type { Paths } from '../bootstrap/paths.js'\n\nconst execFileAsync = promisify(execFile)\n\nexport interface TuwunelOpts {\n name: string\n image?: string\n hostPort: number\n paths: Paths\n engine: 'docker' | 'podman'\n}\n\nconst DEFAULT_IMAGE = 'ghcr.io/matrix-construct/tuwunel:latest'\n\nexport function buildRunArgs(opts: TuwunelOpts): string[] {\n const image = opts.image ?? DEFAULT_IMAGE\n return [\n 'run',\n '--rm',\n '--name',\n opts.name,\n '-p',\n `${opts.hostPort}:8448`,\n '-v',\n `${opts.paths.dbDir}:/var/lib/tuwunel/db`,\n '-v',\n `${opts.paths.mediaDir}:/var/lib/tuwunel/media`,\n '-v',\n `${opts.paths.tuwunelTomlPath}:/etc/tuwunel/tuwunel.toml:ro`,\n '-v',\n `${opts.paths.registrationsDir}:/var/lib/tuwunel/registrations:ro`,\n '-e',\n 'TUWUNEL_CONFIG=/etc/tuwunel/tuwunel.toml',\n image,\n ]\n}\n\nexport class TuwunelService {\n private child: ChildProcess | null = null\n constructor(private readonly opts: TuwunelOpts) {}\n\n start(): ChildProcess {\n this.child = spawn(this.opts.engine, buildRunArgs(this.opts), {\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n return this.child\n }\n\n async stop(): Promise<void> {\n // Foregrounded container: kill the engine process; --rm cleans up after.\n if (this.child && this.child.exitCode === null) {\n this.child.kill('SIGTERM')\n await new Promise<void>((resolve) => {\n this.child!.on('exit', () => resolve())\n })\n }\n this.child = null\n // Defensive: the parent may have died while the container was running, in\n // which case --rm doesn't fire. `<engine> stop` is a no-op if it's already\n // gone (errors are swallowed).\n await execEngine(this.opts.engine, ['stop', this.opts.name]).catch(() => {})\n }\n\n async waitHealthy(opts: { url: string; timeoutMs: number }): Promise<void> {\n // Two-phase wait: first the container has to transition from `created` to\n // `running` (Docker Desktop on macOS can take 30–90s on first-run bind-mount\n // setup), then Tuwunel has to open its DB and start serving HTTP. Polling\n // only HTTP loses both signals: a long create looks identical to a long\n // boot, and a crashed container looks identical to a slow one.\n const deadline = Date.now() + opts.timeoutMs\n\n // Phase 1: wait for the container to be running. Surface the actual\n // docker error if it transitions to `exited` instead — that's the\n // case where today we just hang for 60s and say \"did not become healthy\"\n // with no clue what really broke.\n while (Date.now() < deadline) {\n const state = await this.inspectState().catch(() => null)\n if (state?.status === 'running') break\n if (state?.status === 'exited') {\n throw new Error(\n `Tuwunel container exited before serving HTTP ` +\n `(exit=${state.exitCode}${state.error ? `, error=${state.error}` : ''}). ` +\n `Check the engine logs (\\`${this.opts.engine} logs ${this.opts.name}\\`).`,\n )\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n\n // Phase 2: container is running (or we ran out of time). Poll the HTTP\n // endpoint until either it answers or the deadline passes.\n while (Date.now() < deadline) {\n try {\n const r = await fetch(`${opts.url}/_matrix/client/versions`)\n if (r.ok) return\n } catch {\n // not yet\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n\n // Last-ditch diagnostic before throwing the generic timeout — surface the\n // current container state so the user knows whether to blame slow start,\n // slow boot, or a misconfiguration.\n const finalState = await this.inspectState().catch(() => null)\n const detail = finalState\n ? ` (container status=${finalState.status}${\n finalState.exitCode !== undefined ? `, exit=${finalState.exitCode}` : ''\n })`\n : ''\n throw new Error(\n `Tuwunel did not become healthy at ${opts.url} in ${opts.timeoutMs}ms${detail}`,\n )\n }\n\n /**\n * Read the engine's view of the container. Returns null if the container\n * isn't known to the engine (e.g. before spawn completed or after `--rm`).\n */\n private async inspectState(): Promise<{\n status: string\n exitCode?: number\n error?: string\n } | null> {\n try {\n const { stdout } = await execFileAsync(this.opts.engine, [\n 'inspect',\n this.opts.name,\n '--format',\n '{{.State.Status}}|{{.State.ExitCode}}|{{.State.Error}}',\n ])\n const [status, exitCodeRaw, error] = stdout.trim().split('|')\n const exitCode = exitCodeRaw && exitCodeRaw !== '<no value>' ? Number(exitCodeRaw) : undefined\n return {\n status: status ?? 'unknown',\n ...(Number.isFinite(exitCode) ? { exitCode: exitCode as number } : {}),\n ...(error ? { error } : {}),\n }\n } catch {\n return null\n }\n }\n}\n\nfunction execEngine(engine: string, args: string[]): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(engine, args, { stdio: 'pipe' })\n let stderr = ''\n child.stderr.on('data', (b) => (stderr += String(b)))\n child.on('exit', (code) => {\n if (code === 0) resolve()\n else reject(new Error(`${engine} ${args.join(' ')} failed: ${stderr.trim()}`))\n })\n child.on('error', reject)\n })\n}\n","import { existsSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fetchWebBundle, type FetchWebBundleOptions } from './fetch.js'\n\nconst ENV_OVERRIDE = 'ZOOID_DEV_WEB_ROOT_OVERRIDE'\n\nexport interface EnsureWebRootOptions {\n cliRoot: string\n cacheDir: string\n version: string | undefined\n fetchBundle?: (opts: FetchWebBundleOptions) => Promise<string>\n onProgress?: (msg: string) => void\n}\n\nexport async function ensureWebRoot(opts: EnsureWebRootOptions): Promise<string> {\n const override = process.env[ENV_OVERRIDE]\n if (override && existsSync(join(override, 'index.html'))) return resolve(override)\n\n const fromSource = webSourcePackage(opts.cliRoot)\n if (fromSource && existsSync(join(fromSource, 'dist', 'index.html'))) {\n return join(fromSource, 'dist')\n }\n\n if (!opts.version) {\n throw new Error(\n `No @zooid/zoon-web version pin (zooid.zoonWebVersion) in the cli package.json ` +\n `and no monorepo sibling build found.\\n` +\n `Set ${ENV_OVERRIDE} to a built dist, or run from the monorepo.`,\n )\n }\n opts.onProgress?.(`Fetching @zooid/zoon-web ${opts.version}…`)\n const fetchBundleFn = opts.fetchBundle ?? fetchWebBundle\n return fetchBundleFn({ version: opts.version, cacheDir: opts.cacheDir })\n}\n\n// Returns the path to the in-tree @zooid/zoon-web package (zoon/packages/web) if the\n// CLI is running from the monorepo source. Returns null when running from an\n// installed package (no sibling zoon/ tree).\nexport function webSourcePackage(cliRoot: string): string | null {\n const workspaceRoot = dirname(dirname(dirname(cliRoot)))\n const candidate = join(workspaceRoot, 'zoon', 'packages', 'web')\n return existsSync(join(candidate, 'package.json')) ? candidate : null\n}\n","import { mkdirSync, renameSync, rmSync, existsSync, readdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { createHash, randomUUID } from 'node:crypto'\nimport * as tar from 'tar'\n\nconst PKG = '@zooid/zoon-web'\nconst DEFAULT_REGISTRY = 'https://registry.npmjs.org'\n\nexport interface FetchWebBundleOptions {\n version: string\n cacheDir: string\n registryUrl?: string\n fetch?: typeof globalThis.fetch\n}\n\n/**\n * Ensure <cacheDir>/<version> holds the extracted dist/ of @zooid/zoon-web.\n * Atomic: extracts into a temp dir and renames, so a crash never leaves a\n * half-populated version dir. A populated version dir (index.html present)\n * is the completion marker.\n */\nexport async function fetchWebBundle(opts: FetchWebBundleOptions): Promise<string> {\n const target = join(opts.cacheDir, opts.version)\n if (existsSync(join(target, 'index.html'))) return target\n if (existsSync(target)) rmSync(target, { recursive: true, force: true }) // crashed extract\n\n const f = opts.fetch ?? globalThis.fetch\n const registry = (opts.registryUrl ?? DEFAULT_REGISTRY).replace(/\\/$/, '')\n let tgz: Buffer\n try {\n const metaRes = await f(`${registry}/${PKG}`)\n if (!metaRes.ok) throw new Error(`registry metadata: HTTP ${metaRes.status}`)\n const meta = (await metaRes.json()) as {\n versions?: Record<string, { dist?: { tarball?: string; integrity?: string } }>\n }\n const dist = meta.versions?.[opts.version]?.dist\n if (!dist?.tarball || !dist.integrity) {\n throw new Error(`${PKG}@${opts.version} not found on the registry`)\n }\n const tgzRes = await f(dist.tarball)\n if (!tgzRes.ok) throw new Error(`tarball: HTTP ${tgzRes.status}`)\n tgz = Buffer.from(await tgzRes.arrayBuffer())\n const sha = 'sha512-' + createHash('sha512').update(tgz).digest('base64')\n if (sha !== dist.integrity) {\n throw new Error(`integrity mismatch for ${PKG}@${opts.version}: got ${sha}`)\n }\n } catch (err) {\n throw new Error(\n `Failed to fetch ${PKG}@${opts.version} from ${registry}.\\n` +\n ` Cache: ${opts.cacheDir}\\n` +\n ` Offline? Point ZOOID_DEV_WEB_ROOT_OVERRIDE at a built dist as a manual escape hatch.\\n` +\n ` Cause: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n\n const tmp = join(opts.cacheDir, `.tmp-${randomUUID().slice(0, 8)}`)\n mkdirSync(tmp, { recursive: true })\n const tgzPath = join(tmp, '.bundle.tgz')\n try {\n writeFileSync(tgzPath, tgz)\n // node-tar handles gunzip, pax headers, and long names itself, and its\n // defaults refuse absolute paths and `..` traversal.\n await tar.extract({\n file: tgzPath,\n cwd: tmp,\n strip: 2, // package/dist/<file> → <file>\n filter: (p) => p === 'package/dist' || p.startsWith('package/dist/'),\n })\n rmSync(tgzPath)\n if (!existsSync(join(tmp, 'index.html'))) {\n throw new Error(`${PKG}@${opts.version} tarball has no dist/index.html`)\n }\n renameSync(tmp, target)\n } catch (err) {\n rmSync(tmp, { recursive: true, force: true })\n throw err\n }\n\n for (const entry of readdirSync(opts.cacheDir)) {\n if (entry !== opts.version) {\n rmSync(join(opts.cacheDir, entry), { recursive: true, force: true })\n }\n }\n return target\n}\n","import { readFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport function readZoonWebPin(cliRoot: string): string | undefined {\n try {\n const pkg = JSON.parse(readFileSync(join(cliRoot, 'package.json'), 'utf8')) as {\n zooid?: { zoonWebVersion?: string }\n }\n return pkg.zooid?.zoonWebVersion\n } catch {\n return undefined\n }\n}\n","import { readFileSync, statSync } from 'node:fs'\nimport { extname, join, normalize } from 'node:path'\nimport { Hono } from 'hono'\n\nexport interface WebStaticOpts {\n webRoot: string\n homeserverUrl: string\n}\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n}\n\nfunction isAssetPath(p: string): boolean {\n return p.startsWith('/assets/') || /\\.[a-z0-9]+$/i.test(p)\n}\n\nexport function webStatic(opts: WebStaticOpts): Hono {\n const app = new Hono()\n\n app.get('/config.json', (c) => c.json({ homeserver_url: opts.homeserverUrl }))\n\n app.get('*', (c) => {\n const url = new URL(c.req.url)\n const requested = decodeURIComponent(url.pathname)\n const wantFile = requested === '/' ? '/index.html' : requested\n\n const safe = normalize(wantFile).replace(/^(\\.\\.[/\\\\])+/g, '')\n const filePath = join(opts.webRoot, safe)\n if (!filePath.startsWith(opts.webRoot)) return c.notFound()\n\n try {\n const stat = statSync(filePath)\n if (stat.isFile()) {\n const body = readFileSync(filePath)\n const ct = MIME[extname(filePath)] ?? 'application/octet-stream'\n return c.body(body as unknown as ArrayBuffer, 200, { 'content-type': ct })\n }\n } catch {\n // fall through to history fallback\n }\n\n if (isAssetPath(requested)) return c.notFound()\n const indexBytes = readFileSync(join(opts.webRoot, 'index.html'))\n return c.body(indexBytes as unknown as ArrayBuffer, 200, {\n 'content-type': MIME['.html']!,\n })\n })\n\n return app\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport { existsSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport interface WebWatchHandle {\n distPath: string\n // Pipe captured child output onwards. Call once Listr / interactive\n // renderers are done, otherwise vite output will get garbled.\n attachStdio: () => void\n stop: () => Promise<void>\n}\n\nexport interface WebWatchOpts {\n webPackageDir: string\n // Wait up to this many ms for vite's first build to finish before resolving.\n firstBuildTimeoutMs?: number\n}\n\n// Spawns `vite build --watch` in webPackageDir and resolves once the first\n// build has completed (detected via index.html mtime > spawn time).\nexport async function startWebWatch(opts: WebWatchOpts): Promise<WebWatchHandle> {\n const distPath = join(opts.webPackageDir, 'dist')\n const indexPath = join(distPath, 'index.html')\n const timeoutMs = opts.firstBuildTimeoutMs ?? 60_000\n const spawnTime = Date.now()\n\n const child: ChildProcess = spawn(\n 'pnpm',\n ['-C', opts.webPackageDir, 'exec', 'vite', 'build', '--watch'],\n { stdio: ['ignore', 'pipe', 'pipe'] },\n )\n\n let buffered = ''\n const onData = (chunk: Buffer): void => {\n buffered += chunk.toString('utf8')\n }\n child.stdout?.on('data', onData)\n child.stderr?.on('data', onData)\n\n let attached = false\n const attachStdio = (): void => {\n if (attached) return\n attached = true\n child.stdout?.off('data', onData)\n child.stderr?.off('data', onData)\n if (buffered) process.stdout.write(buffered)\n buffered = ''\n child.stdout?.pipe(process.stdout)\n child.stderr?.pipe(process.stderr)\n }\n\n let exited = false\n child.once('exit', () => {\n exited = true\n })\n\n while (Date.now() - spawnTime < timeoutMs) {\n if (exited) {\n attachStdio()\n throw new Error(`vite build --watch exited before first build (code ${child.exitCode})`)\n }\n if (existsSync(indexPath)) {\n const m = statSync(indexPath).mtimeMs\n // Slack for clock granularity on macOS HFS+/APFS.\n if (m >= spawnTime - 500) return makeHandle()\n }\n await new Promise((r) => setTimeout(r, 200))\n }\n // Timed out: clean up and surface what vite said.\n attachStdio()\n await stopChild(child)\n throw new Error(`vite build --watch did not produce ${indexPath} within ${timeoutMs}ms`)\n\n function makeHandle(): WebWatchHandle {\n return {\n distPath,\n attachStdio,\n stop: () => stopChild(child),\n }\n }\n}\n\nasync function stopChild(child: ChildProcess): Promise<void> {\n if (child.exitCode !== null) return\n child.kill('SIGTERM')\n await new Promise<void>((resolve) => {\n let done = false\n const finish = (): void => {\n if (done) return\n done = true\n resolve()\n }\n child.once('exit', finish)\n setTimeout(() => {\n try {\n child.kill('SIGKILL')\n } catch {\n // already gone\n }\n finish()\n }, 2000)\n })\n}\n","import { mkdir, readdir, rm, symlink, unlink } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface LogPaths {\n dataDir: string\n logsDir: string\n dayDir: string\n daySlug: string\n todayLink: string\n tuwunelLog: string\n daemonLog: string\n devLog: string\n agentLog: (agentName: string) => string\n agentTap: (agentName: string) => string\n}\n\nexport interface ResolveOpts {\n dataDir: string\n /** Defaults to `new Date()`. Tests pin this for determinism. */\n now?: Date\n}\n\n// Local-time slug — we want the wall-clock day a session started, not UTC.\nfunction localDateSlug(d: Date): string {\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, '0')\n const day = String(d.getDate()).padStart(2, '0')\n return `${y}-${m}-${day}`\n}\n\nconst DAY_RE = /^\\d{4}-\\d{2}-\\d{2}$/\n\nexport function resolveLogPaths({ dataDir, now }: ResolveOpts): LogPaths {\n const slug = localDateSlug(now ?? new Date())\n const logsDir = join(dataDir, 'logs')\n const dayDir = join(logsDir, slug)\n return {\n dataDir,\n logsDir,\n dayDir,\n daySlug: slug,\n todayLink: join(logsDir, 'today'),\n tuwunelLog: join(dayDir, 'tuwunel.log'),\n daemonLog: join(dayDir, 'daemon.log'),\n devLog: join(dayDir, 'dev.log'),\n agentLog: (n) => join(dayDir, `agent-${n}.log`),\n agentTap: (n) => join(dayDir, `agent-${n}.acp.jsonl`),\n }\n}\n\nexport async function ensureDayFolder(p: LogPaths): Promise<void> {\n await mkdir(p.dayDir, { recursive: true })\n // Symlink target is the relative slug so the link survives a moved data dir.\n try {\n await unlink(p.todayLink)\n } catch {\n // may not exist\n }\n await symlink(p.daySlug, p.todayLink)\n}\n\nexport interface PruneOpts {\n dataDir: string\n now?: Date\n retainDays: number\n}\n\nexport async function pruneOldDays(opts: PruneOpts): Promise<string[]> {\n if (opts.retainDays <= 0) return []\n const logsDir = join(opts.dataDir, 'logs')\n let entries: string[]\n try {\n entries = await readdir(logsDir)\n } catch {\n return []\n }\n const today = opts.now ?? new Date()\n const cutoff = new Date(\n today.getFullYear(),\n today.getMonth(),\n today.getDate() - opts.retainDays + 1,\n ).getTime()\n const removed: string[] = []\n for (const name of entries) {\n if (!DAY_RE.test(name)) continue\n const [y, m, d] = name.split('-').map(Number)\n const t = new Date(y, m - 1, d).getTime()\n if (t < cutoff) {\n await rm(join(logsDir, name), { recursive: true, force: true })\n removed.push(name)\n }\n }\n return removed\n}\n","import { createWriteStream, type WriteStream } from 'node:fs'\nimport { mkdir } from 'node:fs/promises'\nimport { dirname } from 'node:path'\n\nexport type Verbosity = 'default' | 'verbose-thoughts' | 'verbose'\n\nexport interface JsonlSinkOpts {\n /** Truncate any single string field longer than this. Default 4 KB. */\n maxStringLen?: number\n}\n\nconst TRUNC_MARKER = '…[truncated]'\n\nexport class JsonlSink {\n private stream: WriteStream | null = null\n private readonly maxStringLen: number\n private readonly readyPromise: Promise<void>\n\n constructor(\n private readonly path: string,\n opts: JsonlSinkOpts = {},\n ) {\n this.maxStringLen = opts.maxStringLen ?? 4096\n this.readyPromise = (async () => {\n await mkdir(dirname(this.path), { recursive: true })\n this.stream = createWriteStream(this.path, { flags: 'a' })\n })()\n }\n\n async write(obj: unknown): Promise<void> {\n await this.readyPromise\n const capped = capStrings(obj, this.maxStringLen)\n const line = JSON.stringify(capped) + '\\n'\n return new Promise((resolve, reject) => {\n this.stream!.write(line, (err) => (err ? reject(err) : resolve()))\n })\n }\n\n async close(): Promise<void> {\n await this.readyPromise\n return new Promise((resolve) => {\n this.stream!.end(() => resolve())\n })\n }\n}\n\nfunction capStrings(v: unknown, max: number): unknown {\n if (typeof v === 'string') {\n return v.length <= max ? v : v.slice(0, max) + TRUNC_MARKER\n }\n if (Array.isArray(v)) return v.map((x) => capStrings(x, max))\n if (v && typeof v === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, val] of Object.entries(v)) out[k] = capStrings(val, max)\n return out\n }\n return v\n}\n\nconst DEFAULT_VARIANTS = new Set([\n 'tool_call',\n 'tool_call_update',\n 'plan',\n 'available_commands_update',\n 'current_mode_update',\n 'user_message_chunk',\n])\n\nexport function shouldCaptureUpdate(\n verbosity: Verbosity,\n variant: string,\n): boolean {\n if (verbosity === 'verbose') return true\n if (verbosity === 'verbose-thoughts') {\n return DEFAULT_VARIANTS.has(variant) || variant === 'agent_thought_chunk'\n }\n return DEFAULT_VARIANTS.has(variant)\n}\n","import type { TapEvent } from '@zooid/core'\nimport type { LogPaths } from './paths.js'\nimport { JsonlSink, shouldCaptureUpdate, type Verbosity } from './file-sink.js'\n\nexport interface MatrixContext {\n room_id: string\n event_id: string\n}\n\nexport interface WireAgentCaptureOpts {\n agent: string\n paths: LogPaths\n verbosity: Verbosity\n /** Returns the most-recently-known matrix context for the agent, or null. */\n matrixContext: () => MatrixContext | null\n /** Override for tests. */\n now?: () => Date\n}\n\nexport interface AgentCapture {\n onTap: (event: TapEvent) => void\n close: () => Promise<void>\n}\n\nexport function wireAgentCapture(opts: WireAgentCaptureOpts): AgentCapture {\n const sink = new JsonlSink(opts.paths.agentTap(opts.agent))\n const now = opts.now ?? (() => new Date())\n const pending: Promise<unknown>[] = []\n\n const onTap = (event: TapEvent): void => {\n if (event.kind === 'session_update') {\n const variant =\n (event.update as { sessionUpdate?: string }).sessionUpdate ?? 'unknown'\n if (!shouldCaptureUpdate(opts.verbosity, variant)) return\n }\n const matrix = opts.matrixContext()\n const envelope: Record<string, unknown> = {\n ts: now().toISOString(),\n agent: opts.agent,\n session_id: event.sessionId,\n turn_id: event.turnId,\n kind: event.kind,\n }\n if (matrix) envelope.matrix = matrix\n if (event.kind === 'session_update') envelope.notification = event.update\n else if (event.kind === 'turn_started') envelope.prompt_text = event.promptText\n else if (event.kind === 'turn_completed') envelope.stop_reason = event.stopReason\n pending.push(sink.write(envelope))\n }\n\n return {\n onTap,\n close: async () => {\n await Promise.all(pending)\n await sink.close()\n },\n }\n}\n","import { createWriteStream } from 'node:fs'\nimport { mkdir } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport type { ChildProcess } from 'node:child_process'\n\n/**\n * Tee a child's stdout and stderr to one log file, in arrival order.\n * Returns a promise that resolves once the file has been flushed after\n * the child exits.\n */\nexport function captureChildToFile(\n child: ChildProcess,\n path: string,\n): Promise<void> {\n return (async () => {\n await mkdir(dirname(path), { recursive: true })\n const stream = createWriteStream(path, { flags: 'a' })\n if (child.stdout) child.stdout.on('data', (b: Buffer) => stream.write(b))\n if (child.stderr) child.stderr.on('data', (b: Buffer) => stream.write(b))\n await new Promise<void>((resolve) => {\n child.on('exit', () => stream.end(() => resolve()))\n })\n })()\n}\n","export interface ShutdownLayers {\n stopUi: () => Promise<void>\n stopDaemon: () => Promise<void>\n stopTuwunel: () => Promise<void>\n stopWebWatch?: () => Promise<void>\n /** Flush per-agent ACP taps before stopping the daemon. */\n stopCaptures?: () => Promise<void>\n /** Resolves once Tuwunel's captured stdio file is flushed. */\n finalizeTuwunelCapture?: () => Promise<void>\n}\n\nexport function buildShutdown(layers: ShutdownLayers): () => Promise<void> {\n let started: Promise<void> | null = null\n return () => {\n if (started) return started\n started = (async () => {\n const order = [\n 'stopUi',\n 'stopWebWatch',\n 'stopCaptures',\n 'stopDaemon',\n 'stopTuwunel',\n 'finalizeTuwunelCapture',\n ] as const\n for (const step of order) {\n try {\n await layers[step]?.()\n } catch (err) {\n console.error(`${step}:`, err)\n }\n }\n })()\n return started\n }\n}\n","import { existsSync, mkdirSync, readdirSync, writeFileSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport {\n generateAgentsMd,\n generateClaudeMd,\n generateClaudeSettings,\n generateEnv,\n generateGitignore,\n generateOpencodeJson,\n generateOpencodeReadme,\n generateZooidYaml,\n} from './init/generators.js'\nimport {\n findOpencodeProvider,\n findSimplePreset,\n} from './init/registry.js'\nimport { sniffCredentials } from './init/sniff.js'\n\nexport interface InitOptions {\n dir: string\n preset: 'claude' | 'codex' | 'opencode'\n /** Required for claude/codex; ignored for opencode. */\n auth?: 'subscription' | 'api-key'\n /** Required for claude/codex; required for opencode (paired with `provider`). */\n model?: string\n /** Required for opencode. */\n provider?: string\n /** Required on api-key path; required for opencode. */\n apiKey?: string\n /** Allow generating into a non-empty dir. */\n force?: boolean\n /** Required with `force` to overwrite existing files. */\n overwrite?: boolean\n}\n\ninterface WriteSpec {\n path: string\n content: string\n}\n\n// Pre-existing entries that don't count toward \"non-empty\". Lets operators\n// run `pnpm install` before `zooid init` without tripping the guard.\nconst IGNORED_PREEXISTING = new Set([\n '.',\n '..',\n '.git',\n '.DS_Store',\n 'node_modules',\n 'package.json',\n 'package-lock.json',\n 'pnpm-lock.yaml',\n 'yarn.lock',\n])\n\nexport async function runInit(opts: InitOptions): Promise<void> {\n const dir = resolve(opts.dir)\n mkdirSync(dir, { recursive: true })\n\n if (!opts.force) {\n const blocking = readdirSync(dir).filter((n) => !IGNORED_PREEXISTING.has(n))\n if (blocking.length > 0) {\n throw new Error(\n `${dir} is non-empty (use --force to allow scaffolding into it). Conflicting entries: ${blocking.join(', ')}`,\n )\n }\n }\n\n const writes: WriteSpec[] = []\n\n if (opts.preset === 'claude' || opts.preset === 'codex') {\n if (!opts.model) throw new Error(`--model is required for preset ${opts.preset}`)\n if (!opts.auth) throw new Error('--auth (subscription|api-key) is required for claude/codex')\n const meta = findSimplePreset(opts.preset)!\n\n writes.push({\n path: 'zooid.yaml',\n content: generateZooidYaml({ preset: opts.preset, model: opts.model }),\n })\n writes.push({ path: 'agents/zooid-assistant/AGENTS.md', content: generateAgentsMd() })\n\n if (opts.preset === 'claude') {\n writes.push({\n path: 'agents/zooid-assistant/CLAUDE.md',\n content: generateClaudeMd(),\n })\n writes.push({\n path: 'agents/zooid-assistant/.claude/settings.json',\n content: generateClaudeSettings(),\n })\n }\n\n if (opts.auth === 'api-key') {\n if (!opts.apiKey) throw new Error('--api-key is required when --auth=api-key')\n writes.push({\n path: '.env',\n content: generateEnv({ envVar: meta.apiKeyEnvVar, value: opts.apiKey }),\n })\n }\n } else if (opts.preset === 'opencode') {\n if (!opts.provider) throw new Error('--provider is required for opencode')\n const isCustom = opts.provider === 'custom'\n const providerMeta = isCustom ? undefined : findOpencodeProvider(opts.provider)\n if (!isCustom && !providerMeta) throw new Error(`unknown opencode provider: ${opts.provider}`)\n if (!isCustom && !opts.model) throw new Error('--model is required (paired with --provider)')\n if (!isCustom && !opts.apiKey) throw new Error('--api-key is required for opencode')\n\n writes.push({ path: 'zooid.yaml', content: generateZooidYaml({ preset: 'opencode' }) })\n writes.push({ path: 'agents/zooid-assistant/AGENTS.md', content: generateAgentsMd() })\n writes.push({\n path: 'agents/zooid-assistant/opencode.json',\n content: generateOpencodeJson({\n provider: opts.provider,\n model: opts.model,\n apiKeyEnvVar: providerMeta?.apiKeyEnvVar,\n }),\n })\n if (isCustom) {\n writes.push({\n path: 'agents/zooid-assistant/opencode.json.README',\n content: generateOpencodeReadme(),\n })\n } else {\n writes.push({\n path: '.env',\n content: generateEnv({ envVar: providerMeta!.apiKeyEnvVar, value: opts.apiKey! }),\n })\n }\n } else {\n throw new Error(`unknown preset: ${String(opts.preset)}`)\n }\n\n writes.push({ path: '.gitignore', content: generateGitignore() })\n\n for (const w of writes) {\n const full = join(dir, w.path)\n const exists = existsSync(full)\n if (exists && !opts.overwrite) {\n console.warn(`⚠ ${w.path} exists; left as-is (use --force --overwrite to replace)`)\n continue\n }\n mkdirSync(dirname(full), { recursive: true })\n writeFileSync(full, w.content)\n console.log(`✓ Created ${w.path}`)\n }\n\n if ((opts.preset === 'claude' || opts.preset === 'codex') && opts.auth === 'subscription') {\n const s = sniffCredentials(opts.preset)\n if (s.found) {\n console.log(`✓ Found ${opts.preset} config at ${s.path}`)\n } else {\n console.warn(\n `⚠ No ${opts.preset} config detected — run \\`${opts.preset}\\` to log in before \\`zooid dev\\``,\n )\n }\n }\n\n console.log('\\nNext: zooid dev')\n}\n","export interface ZooidYamlOpts {\n preset: 'claude' | 'codex' | 'opencode'\n /** Only set for claude / codex; opencode reads its own opencode.json. */\n model?: string\n}\n\nexport function generateZooidYaml(opts: ZooidYamlOpts): string {\n const acpBlock =\n opts.preset === 'opencode'\n ? ` acp: { preset: opencode }`\n : ` acp:\\n preset: ${opts.preset}\\n model: ${opts.model}`\n return `runtime: local\n\ntransports:\n matrix:\n homeserver: http://localhost:8448\n port: 9099\n\nagents:\n zooid-assistant:\n${acpBlock}\n matrix:\n display_name: 'Zooid Assistant'\n rooms: ['#zooid']\n`\n}\n\nexport function generateAgentsMd(): string {\n return `# zooid-assistant\n\nYou are the zooid setup assistant. Your job is to help the operator get a workforce running, add agents, and configure zooid for their use case.\n\n## Resources\n\n- Zooid documentation: https://zooid.dev/docs/\n- Use your web fetch tool to read documentation pages when answering questions.\n\n## Stack facts\n\n- **Tuwunel** is a lightweight Rust Matrix homeserver (Conduit fork) backed by RocksDB. Single binary, low resource floor — not \"heavy\" for typical workforces.\n- **Logs land on disk** in \\`./data/\\` inside this zooid home dir: tuwunel logs, the daemon, and each agent's ACP stream. Use \\`zooid logs <source>\\` to tail them (sources: \\`tuwunel\\`, \\`daemon\\`, \\`dev\\`, \\`agent-<name>\\`, \\`agent-<name>.acp\\`). Debugging is mostly \"read the log file\" — don't tell the operator it's opaque.\n\n## Behavior\n\n- Be terse. Give the answer; link to the doc page; stop.\n- When the operator asks how to do something, prefer to fetch the relevant docs section over guessing from training data.\n- When the operator asks you to *configure* something, propose a yaml edit and let them apply it. Don't write files directly unless they ask.\n`\n}\n\n/**\n * Claude Code auto-loads `CLAUDE.md`, not `AGENTS.md`. We keep `AGENTS.md`\n * as the canonical content (codex / opencode read it directly) and ship a\n * one-line `CLAUDE.md` that pulls it in via Claude Code's `@<path>` import.\n */\nexport function generateClaudeMd(): string {\n return `@AGENTS.md\\n`\n}\n\nexport function generateClaudeSettings(): string {\n return (\n JSON.stringify(\n {\n permissions: {\n allow: ['WebFetch(domain:zooid.dev)'],\n },\n },\n null,\n 2,\n ) + '\\n'\n )\n}\n\nexport interface OpencodeJsonOpts {\n provider: string\n model?: string\n apiKeyEnvVar?: string\n}\n\nexport function generateOpencodeJson(opts: OpencodeJsonOpts): string {\n if (opts.provider === 'custom') {\n return (\n JSON.stringify(\n {\n $schema: 'https://opencode.ai/config.json',\n model: 'TODO/your-model',\n provider: { TODO: { options: {} } },\n },\n null,\n 2,\n ) + '\\n'\n )\n }\n const cfg = {\n $schema: 'https://opencode.ai/config.json',\n model: `${opts.provider}/${opts.model}`,\n provider: {\n [opts.provider]: {\n options: { apiKey: `{env:${opts.apiKeyEnvVar}}` },\n },\n },\n permission: { webfetch: 'allow' as const },\n }\n return JSON.stringify(cfg, null, 2) + '\\n'\n}\n\nexport interface EnvOpts {\n envVar: string\n value: string\n}\n\nexport function generateEnv(opts: EnvOpts): string {\n return `${opts.envVar}=${opts.value}\\n`\n}\n\nexport function generateGitignore(): string {\n return ['.env', 'node_modules/', 'data/', ''].join('\\n')\n}\n\nexport function generateOpencodeReadme(): string {\n return `See https://opencode.ai/config for the full opencode.json schema, including\nprovider-specific options and per-tool permissions.\n`\n}\n","export interface SimplePresetMeta {\n preset: 'claude' | 'codex'\n models: string[]\n subscriptionLabel: string\n apiKeyEnvVar: string\n apiKeyPromptLabel: string\n /** Home-relative directory checked on the subscription sniff (existence only). */\n credentialDir: string\n}\n\nexport const SIMPLE_PRESETS: readonly SimplePresetMeta[] = [\n {\n preset: 'claude',\n models: ['claude-sonnet-4-6', 'claude-opus-4-7', 'claude-haiku-4-5'],\n subscriptionLabel: 'Claude subscription (Pro / Max / Team / Enterprise)',\n apiKeyEnvVar: 'ANTHROPIC_API_KEY',\n apiKeyPromptLabel: 'Anthropic',\n credentialDir: '.claude',\n },\n {\n preset: 'codex',\n models: ['gpt-5.5'],\n subscriptionLabel: 'ChatGPT subscription (Plus / Pro / Team)',\n apiKeyEnvVar: 'OPENAI_API_KEY',\n apiKeyPromptLabel: 'OpenAI',\n credentialDir: '.codex',\n },\n]\n\nexport interface OpencodeProviderMeta {\n id: string\n label: string\n description: string\n models: string[]\n apiKeyEnvVar: string\n}\n\nexport const OPENCODE_PROVIDERS: readonly OpencodeProviderMeta[] = [\n {\n id: 'opencode-go',\n label: 'opencode-go',\n description: '$10/mo subscription — Kimi, GLM, MiniMax',\n models: ['kimi-k2.6', 'kimi-k2.5', 'glm-5.1', 'glm-5', 'minimax-m2.7'],\n apiKeyEnvVar: 'OPENCODE_API_KEY',\n },\n {\n id: 'opencode',\n label: 'opencode (Zen)',\n description: 'free tier — curated models',\n models: ['kimi-k2.5-free', 'glm-4.7-free', 'minimax-m2.1-free'],\n apiKeyEnvVar: 'OPENCODE_API_KEY',\n },\n {\n id: 'anthropic',\n label: 'Anthropic',\n description: 'Claude via direct Anthropic API',\n models: ['claude-sonnet-4-6', 'claude-opus-4-7', 'claude-haiku-4-5'],\n apiKeyEnvVar: 'ANTHROPIC_API_KEY',\n },\n {\n id: 'openrouter',\n label: 'OpenRouter',\n description: 'many providers via OpenRouter',\n models: ['anthropic/claude-sonnet-4-6', 'zhipuai/glm-5', 'moonshot/kimi-k2.6'],\n apiKeyEnvVar: 'OPENROUTER_API_KEY',\n },\n]\n\nexport function findSimplePreset(name: string): SimplePresetMeta | undefined {\n return SIMPLE_PRESETS.find((p) => p.preset === name)\n}\n\nexport function findOpencodeProvider(id: string): OpencodeProviderMeta | undefined {\n return OPENCODE_PROVIDERS.find((p) => p.id === id)\n}\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { findSimplePreset } from './registry.js'\n\nexport interface SniffResult {\n found: boolean\n /** Absolute path that satisfied the sniff (the config directory). */\n path?: string\n}\n\n/**\n * Checks whether the operator's per-CLI config directory exists. NEVER reads\n * any file inside — only `existsSync` on the dir. One rule covers Linux,\n * macOS Keychain, and OS keyring without per-backend logic. The edge case\n * where the dir exists but the operator isn't actually logged in is accepted;\n * the spawned shim will surface a clearer error on first turn.\n *\n * `home` is overridable for tests.\n */\nexport function sniffCredentials(\n preset: 'claude' | 'codex',\n home: string = homedir(),\n): SniffResult {\n const meta = findSimplePreset(preset)\n if (!meta) return { found: false }\n const full = join(home, meta.credentialDir)\n if (existsSync(full)) return { found: true, path: full }\n return { found: false }\n}\n","import { select, password } from '@inquirer/prompts'\nimport {\n OPENCODE_PROVIDERS,\n findOpencodeProvider,\n findSimplePreset,\n} from './registry.js'\nimport type { InitOptions } from '../init.js'\n\nexport interface PromptInput {\n dir: string\n preset?: string\n auth?: string\n model?: string\n provider?: string\n apiKey?: string\n force?: boolean\n overwrite?: boolean\n interactive?: boolean\n}\n\nexport async function resolveOptions(flags: PromptInput): Promise<InitOptions> {\n const interactive = flags.interactive !== false && Boolean(process.stdin.isTTY)\n const ask = <T>(prompt: () => Promise<T>, fallback: () => string): Promise<T> => {\n if (!interactive) return Promise.reject(new Error(fallback()))\n return prompt()\n }\n\n const preset = (flags.preset as InitOptions['preset']) ?? (await ask(\n () => select({\n message: 'Which agent should zooid-assistant use?',\n choices: [\n { name: 'claude (Claude Code)', value: 'claude' as const },\n { name: 'codex (OpenAI Codex)', value: 'codex' as const },\n { name: 'opencode', value: 'opencode' as const },\n ],\n }),\n () => '--preset is required (claude | codex | opencode)',\n ))\n\n if (preset === 'opencode') {\n const provider = flags.provider ?? (await ask(\n () => select({\n message: 'Which provider?',\n choices: [\n ...OPENCODE_PROVIDERS.map((p) => ({\n name: `${p.label} (${p.description})`,\n value: p.id,\n })),\n { name: 'custom (write your own opencode.json block)', value: 'custom' },\n ],\n }),\n () => '--provider is required for opencode',\n ))\n if (provider === 'custom') {\n return {\n dir: flags.dir,\n preset,\n provider,\n force: flags.force,\n overwrite: flags.overwrite,\n }\n }\n const meta = findOpencodeProvider(provider)\n if (!meta) throw new Error(`unknown opencode provider: ${provider}`)\n const model = flags.model ?? (await ask(\n () => select({\n message: 'Which model?',\n choices: meta.models.map((m) => ({ name: m, value: m })),\n }),\n () => '--model is required',\n ))\n const apiKey = flags.apiKey ?? (await ask(\n () => password({ message: `${meta.label} API key:` }),\n () => '--api-key is required',\n ))\n return {\n dir: flags.dir,\n preset,\n provider,\n model,\n apiKey,\n force: flags.force,\n overwrite: flags.overwrite,\n }\n }\n\n const meta = findSimplePreset(preset)\n if (!meta) throw new Error(`unknown preset: ${preset}`)\n const auth = (flags.auth as 'subscription' | 'api-key') ?? (await ask(\n () => select({\n message: 'How do you authenticate?',\n choices: [\n { name: `My ${meta.subscriptionLabel}`, value: 'subscription' as const },\n { name: `I'll provide an API key`, value: 'api-key' as const },\n ],\n }),\n () => '--auth is required (subscription | api-key)',\n ))\n const model = flags.model ?? (await ask(\n () => select({\n message: 'Which model?',\n choices: meta.models.map((m) => ({ name: m, value: m })),\n }),\n () => '--model is required',\n ))\n const apiKey =\n auth === 'api-key'\n ? flags.apiKey ?? (await ask(\n () => password({ message: `${meta.apiKeyPromptLabel} API key:` }),\n () => '--api-key is required when --auth=api-key',\n ))\n : undefined\n\n return {\n dir: flags.dir,\n preset,\n auth,\n model,\n apiKey,\n force: flags.force,\n overwrite: flags.overwrite,\n }\n}\n","import { readFile, readdir, readlink } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { pruneOldDays } from '../observability/paths.js'\n\nexport interface LogsFlags {\n dataDir: string\n source?: string\n day?: string\n turn?: string\n follow?: boolean\n subcommand?: 'prune'\n keep?: number\n /** Tests inject an alternate writer. */\n writer?: (s: string) => void\n now?: Date\n}\n\nconst KNOWN_SOURCES = ['tuwunel', 'daemon', 'dev'] as const\n\nexport async function runLogs(flags: LogsFlags): Promise<void> {\n const writer = flags.writer ?? ((s: string) => process.stdout.write(s))\n\n if (flags.subcommand === 'prune') {\n const removed = await pruneOldDays({\n dataDir: flags.dataDir,\n retainDays: flags.keep ?? 14,\n now: flags.now,\n })\n writer(`pruned ${removed.length} day(s): ${removed.join(', ')}\\n`)\n return\n }\n\n const day = flags.day ?? (await resolveTodaySlug(flags.dataDir))\n if (!day) {\n writer('no logs yet\\n')\n return\n }\n const dayDir = join(flags.dataDir, 'logs', day)\n if (!existsSync(dayDir)) {\n writer(`no logs for ${day}\\n`)\n return\n }\n\n if (flags.turn) {\n await dumpByTurn(dayDir, flags.turn, writer)\n return\n }\n\n if (!flags.source) {\n const entries = await readdir(dayDir)\n const sources = new Set<string>()\n for (const e of entries) {\n if (e.endsWith('.log')) sources.add(e.replace(/\\.log$/, ''))\n if (e.endsWith('.acp.jsonl')) sources.add(e.replace(/\\.acp\\.jsonl$/, '.acp'))\n }\n writer([...sources].sort().join('\\n') + '\\n')\n return\n }\n\n const path = resolveSourcePath(dayDir, flags.source)\n if (!existsSync(path)) {\n writer(`no such source: ${flags.source}\\n`)\n return\n }\n writer(await readFile(path, 'utf8'))\n // -f is intentionally not implemented in this cycle; documented as a follow-up.\n}\n\nasync function resolveTodaySlug(dataDir: string): Promise<string | null> {\n const link = join(dataDir, 'logs', 'today')\n try {\n return await readlink(link)\n } catch {\n return null\n }\n}\n\nfunction resolveSourcePath(dayDir: string, source: string): string {\n if (source.startsWith('agent-')) {\n if (source.endsWith('.acp')) return join(dayDir, `${source.slice(0, -4)}.acp.jsonl`)\n return join(dayDir, `${source}.log`)\n }\n if ((KNOWN_SOURCES as readonly string[]).includes(source))\n return join(dayDir, `${source}.log`)\n return join(dayDir, source)\n}\n\nasync function dumpByTurn(\n dayDir: string,\n turnId: string,\n writer: (s: string) => void,\n): Promise<void> {\n const entries = await readdir(dayDir)\n const taps = entries.filter((e) => e.endsWith('.acp.jsonl')).sort()\n for (const f of taps) {\n const text = await readFile(join(dayDir, f), 'utf8')\n for (const line of text.split('\\n')) {\n if (!line) continue\n try {\n const obj = JSON.parse(line)\n if (obj.turn_id === turnId) writer(line + '\\n')\n } catch {\n // skip malformed line\n }\n }\n }\n}\n","import { randomBytes } from 'node:crypto'\nimport { resolve } from 'node:path'\nimport type { CliFlags } from '@zooid/core'\nimport { resolveDataLayout } from '../bootstrap/data-layout.js'\nimport { startDaemon } from '../daemon/start-daemon.js'\n\nexport interface StartFlags extends CliFlags {\n printToken?: boolean\n /** Data root dir; defaults to `./data` relative to cwd. */\n dataDir?: string\n}\n\nexport async function runStart(flags: StartFlags): Promise<void> {\n if (flags.printToken) {\n process.stdout.write(`${randomBytes(32).toString('hex')}\\n`)\n return\n }\n const dataRoot = resolve(process.cwd(), flags.dataDir ?? './data')\n const layout = resolveDataLayout(dataRoot)\n const handle = await startDaemon({\n cliFlags: flags,\n installSignalHandlers: true,\n agentsDir: layout.agentsDir,\n })\n console.log(`zooid listening on http://localhost:${handle.port}`)\n for (const name of handle.agentNames) console.log(` agent: ${name}`)\n await handle.whenStopped\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport chalk from 'chalk'\nimport { findConfigFile, findMatrixTransport, loadZooidConfig } from '@zooid/core'\nimport { deriveHomeserverShape } from '../bootstrap/derive.js'\n\nexport interface StatusFlags {\n cwd?: string\n dataDir: string\n /** Tuwunel host port. If omitted, derived from zooid.yaml's matrix transport. */\n port?: number\n}\n\nexport interface StatusReport {\n tuwunel: { status: 'up' | 'down'; url: string }\n daemon: { status: 'up' | 'down'; url: string } | { status: 'unknown'; reason: string }\n agents: { name: string; userId: string; trigger: string }[]\n}\n\nasync function probe(url: string, timeoutMs = 2_000): Promise<boolean> {\n try {\n const r = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) })\n return r.status > 0\n } catch {\n return false\n }\n}\n\nexport async function collectStatus(opts: {\n cwd: string\n tuwunelUrl: string\n}): Promise<StatusReport> {\n const tuwunelUp = await probe(`${opts.tuwunelUrl}/_matrix/client/versions`)\n const tuwunel: StatusReport['tuwunel'] = {\n status: tuwunelUp ? 'up' : 'down',\n url: opts.tuwunelUrl,\n }\n\n const found = findConfigFile(opts.cwd)\n if (!found) {\n return {\n tuwunel,\n daemon: { status: 'unknown', reason: 'no zooid.yaml' },\n agents: [],\n }\n }\n const cfg = loadZooidConfig(readFileSync(found.path, 'utf8'), {\n configDir: dirname(found.path),\n })\n const matrixEntry = Object.entries(cfg.transports).find(\n ([, t]) => t.type === 'matrix',\n ) as [string, { port?: number }] | undefined\n const daemonPort = matrixEntry?.[1]?.port ?? 8080\n const daemonUrl = `http://localhost:${daemonPort}`\n const daemonUp = await probe(daemonUrl)\n const agents: StatusReport['agents'] = []\n for (const a of Object.values(cfg.agents)) {\n if (a.matrix) {\n agents.push({\n name: a.name,\n userId: a.matrix.user_id,\n trigger: a.matrix.trigger,\n })\n }\n }\n return {\n tuwunel,\n daemon: { status: daemonUp ? 'up' : 'down', url: daemonUrl },\n agents,\n }\n}\n\nexport async function runStatus(flags: StatusFlags): Promise<void> {\n const cwd = flags.cwd ?? process.cwd()\n let port = flags.port\n if (port === undefined) {\n const found = findConfigFile(cwd)\n if (found) {\n const cfg = loadZooidConfig(readFileSync(found.path, 'utf8'), {\n configDir: dirname(found.path),\n })\n const matrix = findMatrixTransport(cfg)\n if (matrix) {\n const userIds = Object.values(cfg.agents)\n .filter((a) => a.matrix?.transport === matrix.name)\n .map((a) => a.matrix!.user_id)\n port = deriveHomeserverShape(matrix.transport, userIds).port\n }\n }\n }\n const tuwunelUrl = `http://localhost:${port ?? 8448}`\n const s = await collectStatus({ cwd, tuwunelUrl })\n const fmt = (st: 'up' | 'down' | 'unknown'): string =>\n st === 'up' ? chalk.green('up') : st === 'down' ? chalk.red('down') : chalk.yellow('unknown')\n process.stdout.write(\n [\n `tuwunel ${fmt(s.tuwunel.status)} ${s.tuwunel.url}`,\n `daemon ${fmt(s.daemon.status)} ${'url' in s.daemon ? s.daemon.url : s.daemon.reason}`,\n ...s.agents.map(\n (a) => ` agent: ${a.name} (${a.userId}, trigger: ${a.trigger})`,\n ),\n '',\n ].join('\\n'),\n )\n}\n"],"mappings":"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","names":["resolve","existsSync","readFileSync","dirname","join","resolve","serve","j","join","mkdirSync","writeFileSync","readFileSync","dirname","join","resolve","dirname","readFileSync","join","execFile","promisify","resolve","existsSync","dirname","join","resolve","mkdirSync","existsSync","writeFileSync","join","randomUUID","existsSync","join","resolve","dirname","readFileSync","join","readFileSync","join","Hono","spawn","existsSync","statSync","join","resolve","mkdir","unlink","join","mkdir","dirname","resolve","createWriteStream","mkdir","dirname","resolve","dirname","resolve","existsSync","readFileSync","join","serve","existsSync","mkdirSync","readdirSync","writeFileSync","dirname","join","resolve","existsSync","join","join","existsSync","resolve","mkdirSync","readdirSync","join","existsSync","dirname","writeFileSync","meta","model","apiKey","readdir","existsSync","join","join","existsSync","readdir","randomBytes","resolve","randomBytes","resolve","readFileSync","dirname","chalk","readFileSync","dirname","chalk","resolve"]}
1
+ {"version":3,"sources":["../src/bin.ts","../src/commands/dev.ts","../src/bootstrap/admin.ts","../src/bootstrap/configs.ts","../src/bootstrap/data-layout.ts","../src/bootstrap/derive.ts","../src/bootstrap/paths.ts","../src/bootstrap/tokens.ts","../src/daemon/start-daemon.ts","../../transport-http/src/server.ts","../src/prepull-images.ts","../src/services/tuwunel.ts","../src/web/resolve.ts","../src/web/fetch.ts","../src/web/pin.ts","../src/web/static.ts","../src/web/watch.ts","../src/observability/paths.ts","../src/observability/file-sink.ts","../src/observability/capture-agent.ts","../src/observability/capture-tuwunel.ts","../src/commands/dev-cascade.ts","../src/commands/init.ts","../src/commands/init/generators.ts","../src/commands/init/registry.ts","../src/commands/init/sniff.ts","../src/commands/init/prompts.ts","../src/commands/logs.ts","../src/commands/start.ts","../src/commands/status.ts"],"sourcesContent":["import { resolve } from 'node:path'\nimport { cac } from 'cac'\nimport { runDev } from './commands/dev.js'\nimport { runInit } from './commands/init.js'\nimport { resolveOptions } from './commands/init/prompts.js'\nimport { runLogs } from './commands/logs.js'\nimport { runStart } from './commands/start.js'\nimport { runStatus } from './commands/status.js'\n\nconst cli = cac('zooid')\n\ncli\n .command('start', 'Run the daemon (production entry-point)')\n .option('--data <dir>', 'Persistent data root dir', { default: './data' })\n .option('--runtime <local|docker|podman>', 'Agent runtime')\n .option('--image <ref>', 'Agent container image')\n .option('--print-token', 'Print a 32-byte hex token and exit')\n .action(async (flags) => {\n await runStart({\n dataDir: flags.data,\n runtime: flags.runtime,\n image: flags.image,\n printToken: flags.printToken,\n })\n })\n\ncli\n .command('dev', 'Tuwunel + daemon + UI for local development')\n .option('--data <dir>', 'Persistent data root dir', { default: './data' })\n .option('--engine <docker|podman>', 'Container engine', { default: 'docker' })\n .option('--ui-port <n>', 'UI HTTP port', { default: 5173 })\n .option('--admin-user <name>', 'Admin username', { default: 'admin' })\n .option('--admin-password <pw>', 'Admin password', { default: 'admin' })\n .option(\n '--watch-web [path]',\n 'Run vite build --watch on @zooid/web. Path defaults to sibling ../zooid-clients/packages/web.',\n )\n .action(async (flags) => {\n await runDev({\n dataDir: flags.data,\n engine: flags.engine,\n uiPort: Number(flags.uiPort),\n adminUser: flags.adminUser,\n adminPassword: flags.adminPassword,\n watchWeb: flags.watchWeb as string | boolean | undefined,\n })\n })\n\ncli\n .command(\n 'logs [source]',\n 'Read captured logs. source=tuwunel|daemon|dev|agent-<name>[.acp], or \"prune\" to delete old days',\n )\n .option('--data <dir>', 'Persistent data root dir', { default: './data' })\n .option('--day <YYYY-MM-DD>', 'Day partition (defaults to today)')\n .option('--turn <id>', 'Filter ACP taps to a single turn id')\n .option('-f, --follow', 'Tail the file (not yet implemented)')\n .option('--keep <n>', 'For `logs prune`: days to retain', { default: 14 })\n .action(async (source, flags) => {\n if (source === 'prune') {\n await runLogs({\n dataDir: resolve(process.cwd(), flags.data),\n subcommand: 'prune',\n keep: Number(flags.keep),\n })\n return\n }\n await runLogs({\n dataDir: resolve(process.cwd(), flags.data),\n source,\n day: flags.day,\n turn: flags.turn,\n follow: Boolean(flags.follow),\n })\n })\n\ncli\n .command('status', 'Print Tuwunel + daemon health')\n .option('--data <dir>', 'Persistent data root dir', { default: './data' })\n .option('--port <n>', 'Tuwunel host port (defaults to zooid.yaml)')\n .action(async (flags) => {\n await runStatus({\n dataDir: flags.data,\n port: flags.port !== undefined ? Number(flags.port) : undefined,\n })\n })\n\ncli\n .command('init [dir]', 'Scaffold a new zooid workforce in the current (or named) directory')\n .option('--preset <name>', 'claude | codex | opencode')\n .option('--auth <mode>', 'subscription | api-key (claude/codex only)')\n .option('--model <id>', 'Model identifier')\n .option('--provider <id>', 'opencode provider: opencode-go | opencode | anthropic | openrouter | custom')\n .option('--api-key <value>', 'API key (api-key path; opencode always)')\n .option('--force', 'Allow scaffolding into a non-empty directory')\n .option('--overwrite', 'With --force, overwrite existing files')\n .option('--no-interactive', 'Disable prompts; require all flags up front')\n .action(async (dir: string | undefined, flags) => {\n const resolved = await resolveOptions({\n dir: dir ?? process.cwd(),\n preset: flags.preset,\n auth: flags.auth,\n model: flags.model,\n provider: flags.provider,\n apiKey: flags.apiKey,\n force: Boolean(flags.force),\n overwrite: Boolean(flags.overwrite),\n interactive: flags.interactive,\n })\n await runInit(resolved)\n })\n\ncli.help()\ncli.version('0.0.1')\ncli.parse()\n","import chalk from 'chalk'\nimport { Listr } from 'listr2'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { serve, type ServerType } from '@hono/node-server'\nimport {\n findConfigFile,\n findMatrixTransport,\n loadZooidConfig,\n} from '@zooid/core'\nimport { ensureAdminUser } from '../bootstrap/admin.js'\nimport { writeBootstrapConfigs } from '../bootstrap/configs.js'\nimport { resolveDataLayout } from '../bootstrap/data-layout.js'\nimport { deriveHomeserverShape } from '../bootstrap/derive.js'\nimport { resolvePaths } from '../bootstrap/paths.js'\nimport { ensureTokens, type Tokens } from '../bootstrap/tokens.js'\nimport { startDaemon, type DaemonHandle } from '../daemon/start-daemon.js'\nimport { TuwunelService } from '../services/tuwunel.js'\nimport { ensureWebRoot, webSourcePackage } from '../web/resolve.js'\nimport { readZoonWebPin } from '../web/pin.js'\nimport { webStatic } from '../web/static.js'\nimport { startWebWatch, type WebWatchHandle } from '../web/watch.js'\nimport {\n ensureDayFolder,\n pruneOldDays,\n resolveLogPaths,\n type LogPaths,\n} from '../observability/paths.js'\nimport {\n wireAgentCapture,\n type AgentCapture,\n} from '../observability/capture-agent.js'\nimport { captureChildToFile } from '../observability/capture-tuwunel.js'\nimport { buildShutdown } from './dev-cascade.js'\n\n// Walk up from this module until we find the @zooid/cli package.json. This\n// is robust to the source/bundle distinction: src/commands/dev.ts and\n// dist/bin.js end up at different depths, so a fixed `..` count breaks\n// after `tsup`. The package's \"name\" field disambiguates from any parent.\nconst CLI_ROOT = (() => {\n let dir = dirname(fileURLToPath(import.meta.url))\n for (let i = 0; i < 8; i++) {\n const pkgPath = resolve(dir, 'package.json')\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as { name?: string }\n if (pkg.name === 'zooid' || pkg.name === '@zooid/cli') return dir\n } catch {\n // ignore\n }\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n throw new Error('cli root not found (no @zooid/cli package.json above ' + import.meta.url + ')')\n})()\n\nexport interface DevFlags {\n cwd?: string\n dataDir: string\n hostPort?: number\n uiPort: number\n engine: 'docker' | 'podman'\n adminUser: string\n adminPassword: string\n installSignalHandlers?: boolean\n foreground?: boolean\n // Run `vite build --watch` against a @zooid/web package and serve its dist.\n // true = auto-detect (sibling ../zooid-clients/packages/web or in-monorepo); string = explicit path.\n watchWeb?: string | boolean\n}\n\nexport interface DevHandle {\n stop: () => Promise<void>\n}\n\ninterface DevCtx {\n tokens?: Tokens\n svc?: TuwunelService\n daemon?: DaemonHandle\n uiServer?: ServerType\n webWatch?: WebWatchHandle\n logPaths?: LogPaths\n captures?: Record<string, AgentCapture>\n tuwunelCaptureDone?: Promise<void>\n}\n\nexport async function runDev(flags: DevFlags): Promise<DevHandle> {\n const cwd = flags.cwd ?? process.cwd()\n const found = findConfigFile(cwd)\n if (!found) throw new Error(`zooid.yaml not found in ${cwd}`)\n // Load .env files from the workforce dir before anything reads process.env.\n // Order matches the convention used by Vite/Next: .env.local overrides .env,\n // and real shell vars override both (loadEnvFile never overwrites existing\n // process.env entries). Spawned agents inherit these via runtime-local.\n loadEnvFiles(cwd)\n\n // Resolve data paths up front — they only depend on cwd/flags, not the\n // parsed config — so we can ensure tokens before any loadZooidConfig call.\n const dataRoot = resolve(cwd, flags.dataDir)\n const layout = resolveDataLayout(dataRoot)\n const paths = resolvePaths(layout.matrixDir)\n const logPaths = resolveLogPaths({ dataDir: layout.dataRoot })\n\n // Bootstrap AS tokens and export to env BEFORE parsing zooid.yaml. The\n // parser's MATRIX_AS_TOKEN / MATRIX_HS_TOKEN defaults (see [ZOD048]) and\n // any explicit `${MATRIX_AS_TOKEN}` interpolations both need the vars set.\n const tokens = ensureTokens(paths.envPath)\n process.env.MATRIX_AS_TOKEN = tokens.asToken\n process.env.MATRIX_HS_TOKEN = tokens.hsToken\n\n const rawYaml = readFileSync(found.path, 'utf8')\n const preview = loadZooidConfig(rawYaml, { configDir: dirname(found.path) })\n const matrix = findMatrixTransport(preview)\n if (!matrix) {\n throw new Error('zooid.yaml: zooid dev requires at least one matrix transport')\n }\n const agentUserIds = Object.values(preview.agents)\n .filter((a) => a.matrix?.transport === matrix.name)\n .map((a) => a.matrix!.user_id)\n const shape = deriveHomeserverShape(matrix.transport, agentUserIds)\n const port = flags.hostPort ?? shape.port\n const homeserver = `http://localhost:${port}`\n\n await ensureDayFolder(logPaths)\n await pruneOldDays({ dataDir: layout.dataRoot, retainDays: 14 })\n\n const ctx: DevCtx = { logPaths, tokens }\n\n const tasks = new Listr<DevCtx>(\n [\n {\n title: 'Write tuwunel.toml + appservice.yaml',\n task: () => {\n if (!ctx.tokens) throw new Error('tokens not ready')\n writeBootstrapConfigs({\n paths,\n serverName: shape.serverName,\n asToken: ctx.tokens.asToken,\n hsToken: ctx.tokens.hsToken,\n senderLocalpart: matrix.transport.sender_localpart,\n userNamespace: matrix.transport.user_namespace,\n })\n },\n },\n {\n title: `Start Tuwunel container (${flags.engine})`,\n task: () => {\n ctx.svc = new TuwunelService({\n name: 'zooid-tuwunel',\n hostPort: port,\n paths,\n engine: flags.engine,\n })\n const child = ctx.svc.start()\n ctx.tuwunelCaptureDone = captureChildToFile(child, logPaths.tuwunelLog)\n },\n },\n {\n title: 'Wait for Tuwunel /_matrix/client/versions',\n task: async () => {\n if (!ctx.svc) throw new Error('service not started')\n // 180s covers Docker Desktop's first-run bind-mount setup on macOS\n // (which can sit in `created` for 30–90s before transitioning to\n // `running`) plus Tuwunel's RocksDB init. Repeated runs against an\n // existing DB are far quicker.\n await ctx.svc.waitHealthy({ url: homeserver, timeoutMs: 180_000 })\n },\n },\n {\n title: `Register admin user @${flags.adminUser}:${shape.serverName}`,\n task: async (_, t) => {\n const r = await ensureAdminUser({\n homeserver,\n username: flags.adminUser,\n password: flags.adminPassword,\n })\n t.title = r.created\n ? `Registered admin: ${r.userId}`\n : `Admin already exists: ${r.userId}`\n },\n },\n {\n title: 'Start daemon',\n task: async (_ctx, t) => {\n const captures: Record<string, AgentCapture> = {}\n for (const name of Object.keys(preview.agents)) {\n captures[name] = wireAgentCapture({\n agent: name,\n paths: logPaths,\n verbosity: 'default',\n // Matrix cross-link is a follow-up — wire to transport-matrix's\n // most-recent (room_id, event_id) per session in a later cycle.\n matrixContext: () => null,\n })\n }\n ctx.captures = captures\n ctx.daemon = await startDaemon({\n configPath: found.path,\n cwd,\n installSignalHandlers: false,\n adminUserId: `@${flags.adminUser}:${shape.serverName}`,\n agentsDir: layout.agentsDir,\n // Local-only homeserver: make the workforce space publicly joinable\n // so a self-service-registered dev account lands in #<space> from\n // the web client without needing an invite.\n publicWorkforceSpace: true,\n onTap: (agentName, event) => captures[agentName]?.onTap(event),\n prepullLog: (line) => {\n t.output = line.replace(/^\\[zooid\\]\\s+/, '').trim()\n },\n })\n },\n },\n ...(flags.watchWeb\n ? [\n {\n title: 'Start @zooid/web watcher (vite build --watch)',\n task: async (): Promise<void> => {\n const pkgDir =\n typeof flags.watchWeb === 'string'\n ? resolve(flags.watchWeb)\n : webSourcePackage(CLI_ROOT)\n if (!pkgDir) {\n const defaultPath = dirname(dirname(dirname(CLI_ROOT))) + '/zooid-clients/packages/web'\n throw new Error(\n `--watch-web: @zooid/web not found at ${defaultPath}.\\n` +\n `Pass an explicit path: --watch-web=/path/to/zooid-clients/packages/web`,\n )\n }\n ctx.webWatch = await startWebWatch({ webPackageDir: pkgDir })\n },\n },\n ]\n : []),\n {\n title: `Serve @zooid/web on http://localhost:${flags.uiPort}`,\n task: async (_, t) => {\n const webRoot =\n ctx.webWatch?.distPath ??\n (await ensureWebRoot({\n cliRoot: CLI_ROOT,\n cacheDir: join(layout.dataRoot, 'web'),\n version: readZoonWebPin(CLI_ROOT),\n onProgress: (msg) => {\n t.output = msg\n },\n }))\n const app = webStatic({ webRoot, homeserverUrl: homeserver })\n ctx.uiServer = serve({ fetch: app.fetch, port: flags.uiPort })\n },\n },\n ],\n { concurrent: false, exitOnError: true },\n )\n\n await tasks.run()\n\n // Listr's interactive renderer is done — start streaming the watcher's\n // output to our terminal so vite rebuild logs are visible.\n ctx.webWatch?.attachStdio()\n\n const shutdown = buildShutdown({\n stopUi: async () => {\n const s = ctx.uiServer\n if (!s) return\n await new Promise<void>((r) => s.close(() => r()))\n },\n stopDaemon: async () => {\n await ctx.daemon?.stop()\n },\n stopTuwunel: async () => {\n await ctx.svc?.stop()\n },\n stopWebWatch: async () => {\n await ctx.webWatch?.stop()\n },\n stopCaptures: async () => {\n if (!ctx.captures) return\n await Promise.all(Object.values(ctx.captures).map((c) => c.close()))\n },\n finalizeTuwunelCapture: async () => {\n if (ctx.tuwunelCaptureDone) await ctx.tuwunelCaptureDone\n },\n })\n\n if (flags.installSignalHandlers !== false) {\n const handler = async (): Promise<void> => {\n process.stdout.write(chalk.dim('\\nStopping…\\n'))\n await shutdown()\n process.exit(0)\n }\n process.on('SIGINT', () => void handler())\n process.on('SIGTERM', () => void handler())\n }\n\n process.stdout.write(\n [\n '',\n chalk.bold('Tuwunel is up.') + ` ${homeserver}`,\n chalk.bold('UI: ') + ` http://localhost:${flags.uiPort}`,\n ` ${chalk.cyan('admin user:')} ${flags.adminUser} / ${flags.adminPassword}`,\n ` ${chalk.cyan('data dir:')} ${layout.dataRoot}`,\n ...(ctx.webWatch\n ? [` ${chalk.cyan('web watcher:')} live (vite build --watch on @zooid/web)`]\n : []),\n '',\n chalk.dim('Press Ctrl-C to stop.'),\n '',\n ].join('\\n'),\n )\n\n if (flags.foreground !== false) {\n await ctx.daemon!.whenStopped\n }\n\n return { stop: shutdown }\n}\n\nfunction loadEnvFiles(cwd: string): void {\n // .env.local takes precedence over .env, but neither overrides shell-exported\n // vars — process.loadEnvFile() refuses to overwrite already-set keys.\n for (const name of ['.env.local', '.env']) {\n const path = resolve(cwd, name)\n if (!existsSync(path)) continue\n try {\n process.loadEnvFile(path)\n } catch (err) {\n console.warn(`[zooid dev] failed to load ${name}: ${(err as Error).message}`)\n }\n }\n}\n","export interface EnsureAdminOpts {\n homeserver: string\n username: string\n password: string\n}\n\nexport interface EnsureAdminResult {\n created: boolean\n userId: string\n}\n\nexport async function ensureAdminUser(\n opts: EnsureAdminOpts,\n): Promise<EnsureAdminResult> {\n const r = await fetch(`${opts.homeserver}/_matrix/client/v3/register`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n auth: { type: 'm.login.dummy' },\n username: opts.username,\n password: opts.password,\n inhibit_login: true,\n }),\n })\n if (r.ok) {\n const j = (await r.json()) as { user_id: string }\n return { created: true, userId: j.user_id }\n }\n const j = (await r.json()) as { errcode?: string; error?: string }\n if (j.errcode === 'M_USER_IN_USE') {\n const host = new URL(opts.homeserver).hostname\n return { created: false, userId: `@${opts.username}:${host}` }\n }\n throw new Error(\n `register ${opts.username}: ${r.status} ${j.errcode ?? ''} ${j.error ?? ''}`.trim(),\n )\n}\n","import { mkdirSync, writeFileSync } from 'node:fs'\nimport { renderRegistration } from '@zooid/transport-matrix'\nimport type { Paths } from './paths.js'\n\nexport interface TuwunelTomlOpts {\n serverName: string\n}\n\n/**\n * Tuwunel binds 8448 inside the container; the host port is whatever\n * `docker run -p <host>:8448` maps it to. So `port` here is fixed.\n */\nconst TUWUNEL_INTERNAL_PORT = 8448\n\nexport function renderTuwunelToml(opts: TuwunelTomlOpts): string {\n return [\n '[global]',\n `server_name = \"${opts.serverName}\"`,\n 'database_path = \"/var/lib/tuwunel/db\"',\n 'media_path = \"/var/lib/tuwunel/media\"',\n 'appservice_dir = \"/var/lib/tuwunel/registrations\"',\n 'allow_registration = true',\n 'yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true',\n 'allow_local_presence = true',\n 'address = [\"0.0.0.0\"]',\n `port = [${TUWUNEL_INTERNAL_PORT}]`,\n '',\n ].join('\\n')\n}\n\nexport interface BootstrapConfigsOpts {\n paths: Paths\n serverName: string\n asToken: string\n hsToken: string\n senderLocalpart: string\n userNamespace: string\n}\n\nexport function writeBootstrapConfigs(opts: BootstrapConfigsOpts): void {\n const { paths, serverName, asToken, hsToken, senderLocalpart, userNamespace } = opts\n mkdirSync(paths.dbDir, { recursive: true })\n mkdirSync(paths.mediaDir, { recursive: true })\n mkdirSync(paths.registrationsDir, { recursive: true })\n\n writeFileSync(paths.tuwunelTomlPath, renderTuwunelToml({ serverName }))\n\n const yaml = renderRegistration({\n id: 'zooid',\n url: `http://host.docker.internal:9099`,\n homeserver: `http://localhost:${TUWUNEL_INTERNAL_PORT}`,\n asToken,\n hsToken,\n senderLocalpart,\n userNamespace,\n // BotPool.bootstrap creates `#alias:<server>` rooms when missing — the\n // AS needs an aliases namespace to legally claim them.\n aliasNamespace: `#.*:${serverName}`,\n // zooid dev shares @.*:<server_name> between bots and the predefined\n // admin human, so the AS cannot claim the namespace exclusively.\n exclusive: false,\n })\n writeFileSync(paths.appserviceYamlPath, yaml)\n}\n","import { join } from 'node:path'\n\nexport interface DataLayout {\n dataRoot: string\n matrixDir: string\n logsDir: string\n agentsDir: string\n agentDir: (agentId: string) => string\n}\n\nexport function resolveDataLayout(dataRoot: string): DataLayout {\n const agentsDir = join(dataRoot, 'agents')\n return {\n dataRoot,\n matrixDir: join(dataRoot, 'matrix'),\n logsDir: join(dataRoot, 'logs'),\n agentsDir,\n agentDir: (id) => join(agentsDir, id),\n }\n}\n","import type { MatrixTransportConfig } from '@zooid/core'\n\nexport interface HomeserverShape {\n host: string\n port: number\n serverName: string\n}\n\nconst NAMESPACE_RE = /^@\\.\\*:([A-Za-z0-9.-]+)$/\n\nexport function deriveHomeserverShape(\n matrix: MatrixTransportConfig,\n agentUserIds: readonly string[],\n): HomeserverShape {\n const url = new URL(matrix.homeserver)\n const host = url.hostname\n const port = url.port\n ? Number(url.port)\n : url.protocol === 'https:'\n ? 443\n : 80\n\n const m = NAMESPACE_RE.exec(matrix.user_namespace)\n if (!m) {\n throw new Error(\n `user_namespace ${matrix.user_namespace!}: expected the simple form '@.*:<server_name>'`,\n )\n }\n const serverName = m[1]!\n\n for (const userId of agentUserIds) {\n if (!userId.endsWith(`:${serverName}`)) {\n throw new Error(\n `server_name mismatch: agent ${userId} does not end with :${serverName}`,\n )\n }\n }\n\n return { host, port, serverName }\n}\n","import { join } from 'node:path'\n\nexport interface Paths {\n dataDir: string\n dbDir: string\n mediaDir: string\n configDir: string\n registrationsDir: string\n tuwunelTomlPath: string\n appserviceYamlPath: string\n envPath: string\n}\n\nexport function resolvePaths(dataDir: string): Paths {\n const configDir = join(dataDir, 'config')\n const registrationsDir = join(configDir, 'registrations')\n return {\n dataDir,\n dbDir: join(dataDir, 'db'),\n mediaDir: join(dataDir, 'media'),\n configDir,\n registrationsDir,\n tuwunelTomlPath: join(configDir, 'tuwunel.toml'),\n appserviceYamlPath: join(registrationsDir, 'zooid.yaml'),\n envPath: join(configDir, '.env'),\n }\n}\n","import { randomBytes } from 'node:crypto'\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\n\nexport interface Tokens {\n asToken: string\n hsToken: string\n}\n\nconst AS_RE = /^MATRIX_AS_TOKEN=(.+)$/m\nconst HS_RE = /^MATRIX_HS_TOKEN=(.+)$/m\n\nfunction genToken(prefix: string): string {\n return `${prefix}-${randomBytes(24).toString('hex')}`\n}\n\nexport function readTokens(envPath: string): Tokens | null {\n if (!existsSync(envPath)) return null\n const text = readFileSync(envPath, 'utf8')\n const as = text.match(AS_RE)?.[1]\n const hs = text.match(HS_RE)?.[1]\n if (!as && !hs) return null\n if (!as || !hs) {\n throw new Error(\n `${envPath}: missing MATRIX_AS_TOKEN or MATRIX_HS_TOKEN. Delete the file to regenerate, or restore the missing value.`,\n )\n }\n return { asToken: as, hsToken: hs }\n}\n\nexport function ensureTokens(envPath: string): Tokens {\n const existing = readTokens(envPath)\n if (existing) return existing\n const tokens: Tokens = { asToken: genToken('as'), hsToken: genToken('hs') }\n mkdirSync(dirname(envPath), { recursive: true })\n const previous = existsSync(envPath) ? readFileSync(envPath, 'utf8') : ''\n const next =\n previous.trimEnd() +\n (previous ? '\\n' : '') +\n `MATRIX_AS_TOKEN=${tokens.asToken}\\nMATRIX_HS_TOKEN=${tokens.hsToken}\\n`\n writeFileSync(envPath, next, { mode: 0o600 })\n return tokens\n}\n","import { readFileSync } from 'node:fs'\nimport { mkdir, unlink } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { dirname, isAbsolute, join, resolve } from 'node:path'\nimport type { AddressInfo } from 'node:net'\nimport { serve, type ServerType } from '@hono/node-server'\nimport {\n ApprovalCorrelator,\n findConfigFile,\n findHttpTransport,\n findMatrixTransport,\n loadZooidConfig,\n mergeCliFlags,\n type CliFlags,\n type TapEvent,\n} from '@zooid/core'\nimport { createApp } from '@zooid/transport-http'\nimport {\n MatrixClient,\n MediaClient,\n createMatrixTransport,\n ensureDefaultChannel,\n ensureWorkforceSpace,\n startWorkforcePublisher,\n type AgentBinding,\n type PublisherHandle,\n} from '@zooid/transport-matrix'\nimport {\n SpawnRegistry,\n startDaemonSocketServer,\n type DaemonSocketHandle,\n} from '@zooid/context-mcp'\nimport { buildAcpRegistry } from '../build-registry.js'\nimport { prepullImages } from '../prepull-images.js'\n\nexport interface StartDaemonOpts {\n configPath?: string\n cwd?: string\n cliFlags?: CliFlags\n installSignalHandlers?: boolean\n /** Admin Matrix user ID. Forwarded to the matrix transport for room bootstrap. */\n adminUserId?: string\n /** Observability tap forwarded to each AcpClient. */\n onTap?: (agentName: string, event: TapEvent) => void\n /**\n * Per-agent state root (`<dataRoot>/agents/`). Threaded into\n * `buildAcpRegistry` so each AcpClient persists `sessionId`s across\n * daemon restarts.\n */\n agentsDir?: string\n /** Skip the startup image-prepull pass entirely. */\n noPrepull?: boolean\n /** Force a re-pull of every resolved image at startup (no inspect check). */\n refreshImages?: boolean\n /**\n * Create the workforce space publicly joinable instead of invite-only. Set\n * only by `zooid dev`: the local homeserver is never deployed, so a\n * self-service-registered account can join `#<space>` from the web client\n * without an invite. Production (`zooid start`) leaves this off.\n */\n publicWorkforceSpace?: boolean\n /**\n * Per-line progress hook for the image-prepull pass. Called once per\n * top-level summary plus once per image (start + completion). Used by\n * `zooid dev` to surface pull progress under the \"Start daemon\" listr\n * task instead of leaving the user staring at an unmoving spinner.\n */\n prepullLog?: (line: string) => void\n}\n\nexport interface DaemonHandle {\n port: number\n agentNames: string[]\n stop(): Promise<void>\n whenStopped: Promise<void>\n}\n\nfunction listenAsync(server: ServerType): Promise<number> {\n return new Promise((resolve) => {\n const check = () => {\n const addr = server.address() as AddressInfo | string | null\n if (addr && typeof addr === 'object') resolve(addr.port)\n else setImmediate(check)\n }\n check()\n })\n}\n\nfunction closeAsync(server: ServerType): Promise<void> {\n return new Promise((resolve) => {\n server.close(() => resolve())\n })\n}\n\nexport async function startDaemon(opts: StartDaemonOpts = {}): Promise<DaemonHandle> {\n const cwd = opts.cwd ?? process.cwd()\n const found = opts.configPath ? { path: opts.configPath } : findConfigFile(cwd)\n if (!found) throw new Error('zooid.yaml is required')\n const configDir = dirname(found.path)\n const base = loadZooidConfig(readFileSync(found.path, 'utf8'), { configDir })\n const config = mergeCliFlags(base, opts.cliFlags ?? {})\n\n const approvals = new ApprovalCorrelator()\n\n const daemonSockPath = opts.agentsDir\n ? join(opts.agentsDir, '..', 'run', 'context.sock')\n : join(tmpdir(), `zooid-context-${process.pid}.sock`)\n await mkdir(dirname(daemonSockPath), { recursive: true }).catch(() => {})\n const contextSpawnRegistry = new SpawnRegistry()\n let contextSocket: DaemonSocketHandle | null = null\n try {\n contextSocket = await startDaemonSocketServer({\n sockPath: daemonSockPath,\n registry: contextSpawnRegistry,\n })\n } catch (err) {\n console.warn('[context] daemon socket startup failed; zooid-context MCP disabled:', err)\n }\n\n const dataDir = opts.agentsDir ? dirname(opts.agentsDir) : undefined\n const registry = buildAcpRegistry(config, {\n approvals,\n onTap: opts.onTap,\n agentsDir: opts.agentsDir,\n contextSpawnRegistry: contextSocket ? contextSpawnRegistry : undefined,\n daemonSockPath: contextSocket ? daemonSockPath : undefined,\n configDir,\n dataDir,\n daemonHome: process.env.HOME,\n })\n const agentNames = Object.keys(config.agents)\n\n if (config.runtime !== 'local') {\n await prepullImages(registry, {\n engine: config.runtime === 'podman' ? 'podman' : 'docker',\n runtime: config.runtime,\n skip: opts.noPrepull ?? process.env.ZOOID_NO_PREPULL === '1',\n refresh: opts.refreshImages ?? process.env.ZOOID_REFRESH_IMAGES === '1',\n log: opts.prepullLog,\n })\n }\n\n console.log(\n `[context] socket=${daemonSockPath} ` +\n `status=${contextSocket ? 'listening' : 'disabled'} ` +\n `agents={${agentNames\n .map((n) => `${n}:${registry.hasContextSpawn(n) ? 'yes' : 'no'}`)\n .join(', ')}}`,\n )\n\n let server: ServerType | null = null\n let stopped = false\n let resolveStopped!: () => void\n const whenStopped = new Promise<void>((r) => {\n resolveStopped = r\n })\n\n const matrix = findMatrixTransport(config)\n let port: number\n\n if (matrix) {\n const client = new MatrixClient({\n homeserver: matrix.transport.homeserver,\n asToken: matrix.transport.as_token,\n })\n const mediaClient = new MediaClient({\n homeserver: matrix.transport.homeserver,\n asToken: matrix.transport.as_token,\n })\n const isContainerRuntime = config.runtime !== 'local'\n const bindings: AgentBinding[] = []\n for (const a of Object.values(config.agents)) {\n if (a.matrix?.transport !== matrix.name) continue\n const binding: AgentBinding = {\n name: a.name,\n userId: a.matrix.user_id,\n rooms: a.matrix.rooms,\n trigger: a.matrix.trigger,\n }\n if (a.matrix.display_name !== undefined) binding.displayName = a.matrix.display_name\n // Resolve workspace dirs for media attachment routing.\n const workspaceDir = isAbsolute(a.workdir) ? a.workdir : resolve(configDir, a.workdir)\n binding.workspaceDir = workspaceDir\n binding.agentWorkspacePath = isContainerRuntime ? '/workspace' : workspaceDir\n bindings.push(binding)\n }\n // user_namespace is a regex like `@.*:localhost`; the part after the last\n // `:` is the homeserver's server_name. Fall back to the homeserver URL's\n // host if the namespace shape is unexpected.\n const serverName =\n matrix.transport.user_namespace.split(':').slice(1).join(':').replace(/\\\\?\\)?$/, '') ||\n new URL(matrix.transport.homeserver).hostname\n const asUserId = `@${matrix.transport.sender_localpart}:${serverName}`\n const transport = createMatrixTransport({\n agents: registry,\n approvals,\n client,\n bindings,\n hsToken: matrix.transport.hs_token,\n adminUserId: opts.adminUserId,\n botUserId: asUserId,\n media: mediaClient,\n })\n const requestedPort = matrix.transport.port ?? 9000\n // Bind 0.0.0.0 explicitly — @hono/node-server defaults to IPv6-only on\n // macOS, which Docker's NAT bridge can't reach when Tuwunel pushes AS\n // events back to host.docker.internal:<port>.\n server = serve({ fetch: transport.app.fetch, port: requestedPort, hostname: '0.0.0.0' })\n port = await listenAsync(server)\n const spaceLocalpart = matrix.transport.space ?? 'dev'\n const adminUserIds = opts.adminUserId ? [opts.adminUserId] : []\n let spaceRoomId: string | undefined\n try {\n spaceRoomId = await ensureWorkforceSpace({\n client,\n asUserId,\n serverName,\n spaceLocalpart,\n preset: 'public_chat',\n admins: adminUserIds,\n joinRule: opts.publicWorkforceSpace ? 'public' : 'invite',\n })\n console.log(`[matrix] ensured workforce space #${spaceLocalpart}:${serverName} → ${spaceRoomId}`)\n } catch (err) {\n console.warn('[matrix] workforce space provisioning failed:', err)\n }\n\n // Bootstrap *after* the listener is up: registerBot/createRoom/joinRoom\n // each trigger Tuwunel to push events back to the AS, and Tuwunel only\n // retries those a few times before dropping. Listening first ensures\n // those pushes don't hit a connection-refused. Bootstrap also runs\n // *after* the space exists so BotPool can attach each agent room as\n // m.space.child while joining it.\n await transport.bootstrap({ spaceRoomId, asUserId, adminUserIds })\n\n if (spaceRoomId) {\n try {\n const generalRoomId = await ensureDefaultChannel({\n client,\n asUserId,\n serverName,\n spaceId: spaceRoomId,\n admins: adminUserIds,\n })\n console.log(`[matrix] ensured default channel #general:${serverName} → ${generalRoomId}`)\n } catch (err) {\n console.warn('[matrix] default channel provisioning failed:', err)\n }\n try {\n const publisher: PublisherHandle = await startWorkforcePublisher({\n client,\n spaceRoomId,\n asUserId,\n getAgents: () => bindings,\n })\n console.log(`[matrix] published dev.zooid.workforce (${bindings.length} agents)`)\n void publisher\n } catch (err) {\n console.warn('[matrix] workforce roster publication failed:', err)\n }\n }\n } else {\n const http = findHttpTransport(config)\n if (!http) throw new Error('no transport declared in zooid.yaml')\n const token = process.env.ZOOID_TOKEN\n if (!token) throw new Error('ZOOID_TOKEN is required for http transport')\n const app = createApp({ agents: registry, approvals, token })\n server = serve({ fetch: app.fetch, port: http.transport.port, hostname: '0.0.0.0' })\n port = await listenAsync(server)\n }\n\n const stop = async (): Promise<void> => {\n if (stopped) return whenStopped\n stopped = true\n try {\n if (server) await closeAsync(server)\n } catch {\n // swallow\n }\n try {\n await registry.stopAll()\n } catch (err) {\n console.error('stopAll:', err)\n }\n try {\n if (contextSocket) await contextSocket.close()\n await unlink(daemonSockPath).catch(() => {})\n } catch {\n // swallow\n }\n resolveStopped()\n }\n\n if (opts.installSignalHandlers !== false) {\n const handler = (sig: NodeJS.Signals): void => {\n console.log(`received ${sig}, stopping agents...`)\n void stop().then(() => process.exit(0))\n }\n process.on('SIGINT', () => handler('SIGINT'))\n process.on('SIGTERM', () => handler('SIGTERM'))\n }\n\n return { port, agentNames, stop, whenStopped }\n}\n","import { Hono, type Context } from 'hono'\nimport { streamSSE, type SSEStreamingApi } from 'hono/streaming'\nimport { timingSafeEqual, randomUUID } from 'node:crypto'\nimport type {\n AcpRegistry,\n ApprovalCorrelator,\n RegisteredApproval,\n} from '@zooid/core'\nimport type {\n AgentEvent,\n ApprovalDecision,\n} from '@zooid/acp-client'\n\nexport interface CreateAppOptions {\n /** Long-lived registry that fronts every ACP agent. */\n agents: AcpRegistry\n /**\n * Correlator that pairs ACP `requestPermission` calls with HTTP-side\n * decisions. The transport listens to its `'registered'` and `'timeout'`\n * events to drive the SSE wire and resolves it via the POST decision route.\n */\n approvals: ApprovalCorrelator\n /** Bearer token; constant-time compared against `Authorization`. */\n token: string\n /**\n * Keepalive interval for open SSE streams (proxies kill idle connections).\n * 0 disables. Default: 30_000ms.\n */\n keepaliveMs?: number\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/\n\ninterface PromptBody {\n prompt: string\n}\n\nfunction isAuthorized(token: string, header: string | undefined): boolean {\n if (!header || !header.startsWith('Bearer ')) return false\n const provided = header.slice('Bearer '.length)\n if (provided.length !== token.length) return false\n return timingSafeEqual(Buffer.from(provided), Buffer.from(token))\n}\n\nfunction parsePromptBody(raw: unknown): PromptBody | { error: string } {\n if (!raw || typeof raw !== 'object') return { error: 'body must be a JSON object' }\n const obj = raw as Record<string, unknown>\n if (typeof obj.prompt !== 'string' || obj.prompt.length === 0) {\n return { error: 'missing or empty prompt' }\n }\n return { prompt: obj.prompt }\n}\n\nasync function readJson(c: Context): Promise<unknown | { error: string }> {\n const raw = await c.req.text()\n try {\n return JSON.parse(raw)\n } catch {\n return { error: 'body must be valid JSON' }\n }\n}\n\ninterface DecisionBody {\n decision: 'allow' | 'cancel'\n option_id?: string\n}\n\nfunction parseDecisionBody(raw: unknown): DecisionBody | { error: string } {\n if (!raw || typeof raw !== 'object') return { error: 'body must be a JSON object' }\n const obj = raw as Record<string, unknown>\n if (obj.decision !== 'allow' && obj.decision !== 'cancel') {\n return { error: 'decision must be \"allow\" or \"cancel\"' }\n }\n if (obj.decision === 'allow' && typeof obj.option_id !== 'string') {\n return { error: 'option_id is required when decision is \"allow\"' }\n }\n return {\n decision: obj.decision,\n option_id: typeof obj.option_id === 'string' ? obj.option_id : undefined,\n }\n}\n\nfunction approvalRequestFrame(handle: RegisteredApproval): string {\n return JSON.stringify({\n type: 'approval.request',\n approval_id: handle.approvalId,\n session_id: handle.sessionId,\n tool_call_id: handle.toolCallId,\n options: handle.options,\n })\n}\n\nexport function createApp({\n agents,\n approvals,\n token,\n keepaliveMs = 30_000,\n}: CreateAppOptions) {\n const app = new Hono()\n\n // Per-session SSE handle. The registry's onEvent dispatcher and the\n // correlator's `'registered'` / `'timeout'` listeners look up the\n // currently-attached stream by session id.\n const streams = new Map<string, SSEStreamingApi>()\n\n agents.onEvent = (_name, event: AgentEvent) => {\n const stream = streams.get(event.sessionId)\n if (!stream) return\n void stream.writeSSE({ data: JSON.stringify(event) })\n }\n // Always wire the registry's approval handler to the correlator. The\n // per-agent `approval_timeout_ms` is read off the registry so YAML-driven\n // timeouts still apply.\n agents.onApprovalRequest = async (name, req) => {\n const handle = approvals.register(name, req.sessionId, req, {\n timeoutMs: agents.getApprovalTimeoutMs(name),\n })\n return handle.decisionPromise\n }\n\n approvals.on('registered', (handle: RegisteredApproval) => {\n const stream = streams.get(handle.sessionId)\n if (!stream) return\n void stream.writeSSE({ data: approvalRequestFrame(handle) })\n })\n\n approvals.on('timeout', ({ approvalId, sessionId }: { approvalId: string; sessionId: string }) => {\n const stream = streams.get(sessionId)\n if (!stream) return\n void stream.writeSSE({\n data: JSON.stringify({ type: 'approval.timeout', approval_id: approvalId, session_id: sessionId }),\n })\n })\n\n function checkAgent(c: Context, name: string): Response | null {\n if (!agents.hasAgent(name)) {\n return c.json({ error: 'unknown agent' }, 404)\n }\n return null\n }\n\n function attachKeepalive(sse: SSEStreamingApi): NodeJS.Timeout | null {\n if (!keepaliveMs || keepaliveMs <= 0) return null\n const timer = setInterval(() => {\n void sse.writeSSE({ data: '', event: 'keepalive' }).catch(() => {})\n }, keepaliveMs)\n timer.unref?.()\n return timer\n }\n\n /**\n * POST /agents/:name/sessions — start a new ACP session.\n *\n * { session.start, session_id }\n * { turn.start }\n * ... ACP AgentEvents\n * { approval.request, ... } / { approval.timeout, ... } as they arrive\n * { turn.end, stop_reason }\n */\n app.post('/agents/:name/sessions', async (c) => {\n if (!isAuthorized(token, c.req.header('authorization'))) {\n return c.json({ error: 'unauthorized' }, 401)\n }\n const name = c.req.param('name')\n const reject = checkAgent(c, name)\n if (reject) return reject\n\n const parsed = await readJson(c)\n if (parsed && typeof parsed === 'object' && 'error' in parsed) {\n return c.json({ error: (parsed as { error: string }).error }, 400)\n }\n const body = parsePromptBody(parsed)\n if ('error' in body) return c.json({ error: body.error }, 400)\n\n const threadId = randomUUID()\n return streamSSE(c, async (sse) => {\n let sessionId: string | null = null\n let keepalive: NodeJS.Timeout | null = null\n try {\n sessionId = await agents.ensureSession(name, threadId)\n streams.set(sessionId, sse)\n keepalive = attachKeepalive(sse)\n await sse.writeSSE({\n data: JSON.stringify({ type: 'session.start', session_id: sessionId }),\n })\n await sse.writeSSE({ data: JSON.stringify({ type: 'turn.start' }) })\n const result = await agents.prompt(name, {\n threadId,\n content: [{ type: 'text', text: body.prompt }],\n })\n await sse.writeSSE({\n data: JSON.stringify({ type: 'turn.end', stop_reason: result.stopReason }),\n })\n } catch (err) {\n await sse.writeSSE({\n data: JSON.stringify({\n type: 'turn.end',\n stop_reason: 'error',\n error: (err as Error).message,\n }),\n })\n } finally {\n if (keepalive) clearInterval(keepalive)\n if (sessionId) {\n // The turn is over; cancel any approvals that the shim left\n // dangling so future POSTs against them 404 fast.\n approvals.cancelSession(sessionId)\n if (streams.get(sessionId) === sse) {\n streams.delete(sessionId)\n }\n }\n }\n })\n })\n\n /**\n * GET /agents/:name/sessions/:id/events — reattach to an in-flight stream.\n *\n * When a turn is in flight: replays any pending approvals via\n * `approvals.listPending(sid)`, then forwards live events until the turn\n * ends. When no turn is in flight: 404.\n */\n app.get('/agents/:name/sessions/:id/events', async (c) => {\n if (!isAuthorized(token, c.req.header('authorization'))) {\n return c.json({ error: 'unauthorized' }, 401)\n }\n const name = c.req.param('name')\n const reject = checkAgent(c, name)\n if (reject) return reject\n const id = c.req.param('id')\n if (!UUID_RE.test(id)) {\n return c.json({ error: 'session id must be a UUID' }, 400)\n }\n if (!streams.has(id)) {\n return c.json({ error: 'no in-flight session' }, 404)\n }\n return streamSSE(c, async (sse) => {\n // Take ownership of dispatch for this session id.\n streams.set(id, sse)\n const keepalive = attachKeepalive(sse)\n // Replay any approvals that are still pending so the reconnecting\n // client can decide on them.\n for (const handle of approvals.listPending(id)) {\n await sse.writeSSE({ data: approvalRequestFrame(handle) })\n }\n try {\n while (streams.get(id) === sse) {\n await new Promise((r) => setTimeout(r, 250))\n }\n } finally {\n if (keepalive) clearInterval(keepalive)\n }\n })\n })\n\n /**\n * POST /agents/:name/sessions/:sid/approvals/:approval_id — resolve a\n * pending permission request.\n */\n app.post('/agents/:name/sessions/:sid/approvals/:approval_id', async (c) => {\n if (!isAuthorized(token, c.req.header('authorization'))) {\n return c.json({ error: 'unauthorized' }, 401)\n }\n const name = c.req.param('name')\n const reject = checkAgent(c, name)\n if (reject) return reject\n\n const sid = c.req.param('sid')\n const approvalId = c.req.param('approval_id')\n const parsed = await readJson(c)\n if (parsed && typeof parsed === 'object' && 'error' in parsed) {\n return c.json({ error: (parsed as { error: string }).error }, 400)\n }\n const body = parseDecisionBody(parsed)\n if ('error' in body) return c.json({ error: body.error }, 400)\n\n const decision: ApprovalDecision =\n body.decision === 'cancel'\n ? { decision: 'cancel' }\n : { decision: 'allow', optionId: body.option_id! }\n const ok = approvals.resolve(sid, approvalId, decision)\n if (!ok) return c.json({ error: 'unknown approval' }, 404)\n return c.json({ ok: true })\n })\n\n /**\n * POST /agents/:name/sessions/:sid/cancel — cancel every pending approval\n * for the session. Idempotent. Returns 204.\n */\n app.post('/agents/:name/sessions/:sid/cancel', async (c) => {\n if (!isAuthorized(token, c.req.header('authorization'))) {\n return c.json({ error: 'unauthorized' }, 401)\n }\n const name = c.req.param('name')\n const reject = checkAgent(c, name)\n if (reject) return reject\n const sid = c.req.param('sid')\n approvals.cancelSession(sid)\n return c.body(null, 204)\n })\n\n return app\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst pExecFile = promisify(execFile)\n\nexport interface PrepullExec {\n (cmd: string, args: string[]): Promise<{ code: number; stdout: string; stderr: string }>\n}\n\nexport interface PrepullOptions {\n engine: 'docker' | 'podman'\n runtime: 'local' | 'docker' | 'podman'\n /** Injectable for tests. Defaults to a child_process.execFile-backed exec. */\n exec?: PrepullExec\n /** When true, skip the inspect check and pull every image. */\n refresh?: boolean\n /** When true, the function returns immediately without touching the engine. */\n skip?: boolean\n log?: (line: string) => void\n}\n\nexport interface PrepullableRegistry {\n agentNames(): string[]\n resolveSpawnImage(name: string): string | undefined\n}\n\n/**\n * Walk the registry's unique resolved-image set, `<engine> image inspect`\n * each one, and `<engine> pull` the ones not cached locally. Parallel and\n * fail-fast: any pull exit ≠ 0 throws with the engine's stderr embedded.\n * No-op when `opts.skip` or `opts.runtime === 'local'`.\n */\nexport async function prepullImages(\n registry: PrepullableRegistry,\n opts: PrepullOptions,\n): Promise<void> {\n if (opts.skip || opts.runtime === 'local') return\n const exec = opts.exec ?? defaultExec\n const log = opts.log ?? ((l: string) => console.log(l))\n\n const images = new Set<string>()\n for (const name of registry.agentNames()) {\n const img = registry.resolveSpawnImage(name)\n if (img) images.add(img)\n }\n\n const toPull: string[] = []\n let cached = 0\n if (opts.refresh) {\n toPull.push(...images)\n } else {\n await Promise.all(\n [...images].map(async (img) => {\n const r = await exec(opts.engine, ['image', 'inspect', img])\n if (r.code === 0) cached++\n else toPull.push(img)\n }),\n )\n }\n\n log(\n `[zooid] image prepull: ${images.size} unique images (${cached} cached, ${toPull.length} to pull)`,\n )\n if (toPull.length === 0) return\n\n await Promise.all(\n toPull.map(async (img) => {\n log(`[zooid] ${img} pulling…`)\n const start = Date.now()\n const r = await exec(opts.engine, ['pull', img])\n const secs = ((Date.now() - start) / 1000).toFixed(1)\n if (r.code !== 0) {\n throw new Error(\n `image prepull failed for ${img}:\\n${r.stderr.trim() || '(no stderr)'}`,\n )\n }\n log(`[zooid] ${img} ✓ ${secs}s`)\n }),\n )\n}\n\nconst defaultExec: PrepullExec = async (cmd, args) => {\n try {\n const { stdout, stderr } = await pExecFile(cmd, args, {\n maxBuffer: 16 * 1024 * 1024,\n })\n return { code: 0, stdout, stderr }\n } catch (err) {\n const e = err as NodeJS.ErrnoException & {\n code?: number | string\n stdout?: string\n stderr?: string\n }\n return {\n code: typeof e.code === 'number' ? e.code : 1,\n stdout: e.stdout ?? '',\n stderr: e.stderr ?? String(e),\n }\n }\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport type { Paths } from '../bootstrap/paths.js'\n\nconst execFileAsync = promisify(execFile)\n\nexport interface TuwunelOpts {\n name: string\n image?: string\n hostPort: number\n paths: Paths\n engine: 'docker' | 'podman'\n}\n\nconst DEFAULT_IMAGE = 'ghcr.io/matrix-construct/tuwunel:latest'\n\nexport function buildRunArgs(opts: TuwunelOpts): string[] {\n const image = opts.image ?? DEFAULT_IMAGE\n return [\n 'run',\n '--rm',\n '--name',\n opts.name,\n '-p',\n `${opts.hostPort}:8448`,\n '-v',\n `${opts.paths.dbDir}:/var/lib/tuwunel/db`,\n '-v',\n `${opts.paths.mediaDir}:/var/lib/tuwunel/media`,\n '-v',\n `${opts.paths.tuwunelTomlPath}:/etc/tuwunel/tuwunel.toml:ro`,\n '-v',\n `${opts.paths.registrationsDir}:/var/lib/tuwunel/registrations:ro`,\n '-e',\n 'TUWUNEL_CONFIG=/etc/tuwunel/tuwunel.toml',\n image,\n ]\n}\n\nexport class TuwunelService {\n private child: ChildProcess | null = null\n constructor(private readonly opts: TuwunelOpts) {}\n\n start(): ChildProcess {\n this.child = spawn(this.opts.engine, buildRunArgs(this.opts), {\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n return this.child\n }\n\n async stop(): Promise<void> {\n // Foregrounded container: kill the engine process; --rm cleans up after.\n if (this.child && this.child.exitCode === null) {\n this.child.kill('SIGTERM')\n await new Promise<void>((resolve) => {\n this.child!.on('exit', () => resolve())\n })\n }\n this.child = null\n // Defensive: the parent may have died while the container was running, in\n // which case --rm doesn't fire. `<engine> stop` is a no-op if it's already\n // gone (errors are swallowed).\n await execEngine(this.opts.engine, ['stop', this.opts.name]).catch(() => {})\n }\n\n async waitHealthy(opts: { url: string; timeoutMs: number }): Promise<void> {\n // Two-phase wait: first the container has to transition from `created` to\n // `running` (Docker Desktop on macOS can take 30–90s on first-run bind-mount\n // setup), then Tuwunel has to open its DB and start serving HTTP. Polling\n // only HTTP loses both signals: a long create looks identical to a long\n // boot, and a crashed container looks identical to a slow one.\n const deadline = Date.now() + opts.timeoutMs\n\n // Phase 1: wait for the container to be running. Surface the actual\n // docker error if it transitions to `exited` instead — that's the\n // case where today we just hang for 60s and say \"did not become healthy\"\n // with no clue what really broke.\n while (Date.now() < deadline) {\n const state = await this.inspectState().catch(() => null)\n if (state?.status === 'running') break\n if (state?.status === 'exited') {\n throw new Error(\n `Tuwunel container exited before serving HTTP ` +\n `(exit=${state.exitCode}${state.error ? `, error=${state.error}` : ''}). ` +\n `Check the engine logs (\\`${this.opts.engine} logs ${this.opts.name}\\`).`,\n )\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n\n // Phase 2: container is running (or we ran out of time). Poll the HTTP\n // endpoint until either it answers or the deadline passes.\n while (Date.now() < deadline) {\n try {\n const r = await fetch(`${opts.url}/_matrix/client/versions`)\n if (r.ok) return\n } catch {\n // not yet\n }\n await new Promise((resolve) => setTimeout(resolve, 500))\n }\n\n // Last-ditch diagnostic before throwing the generic timeout — surface the\n // current container state so the user knows whether to blame slow start,\n // slow boot, or a misconfiguration.\n const finalState = await this.inspectState().catch(() => null)\n const detail = finalState\n ? ` (container status=${finalState.status}${\n finalState.exitCode !== undefined ? `, exit=${finalState.exitCode}` : ''\n })`\n : ''\n throw new Error(\n `Tuwunel did not become healthy at ${opts.url} in ${opts.timeoutMs}ms${detail}`,\n )\n }\n\n /**\n * Read the engine's view of the container. Returns null if the container\n * isn't known to the engine (e.g. before spawn completed or after `--rm`).\n */\n private async inspectState(): Promise<{\n status: string\n exitCode?: number\n error?: string\n } | null> {\n try {\n const { stdout } = await execFileAsync(this.opts.engine, [\n 'inspect',\n this.opts.name,\n '--format',\n '{{.State.Status}}|{{.State.ExitCode}}|{{.State.Error}}',\n ])\n const [status, exitCodeRaw, error] = stdout.trim().split('|')\n const exitCode = exitCodeRaw && exitCodeRaw !== '<no value>' ? Number(exitCodeRaw) : undefined\n return {\n status: status ?? 'unknown',\n ...(Number.isFinite(exitCode) ? { exitCode: exitCode as number } : {}),\n ...(error ? { error } : {}),\n }\n } catch {\n return null\n }\n }\n}\n\nfunction execEngine(engine: string, args: string[]): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(engine, args, { stdio: 'pipe' })\n let stderr = ''\n child.stderr.on('data', (b) => (stderr += String(b)))\n child.on('exit', (code) => {\n if (code === 0) resolve()\n else reject(new Error(`${engine} ${args.join(' ')} failed: ${stderr.trim()}`))\n })\n child.on('error', reject)\n })\n}\n","import { existsSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fetchWebBundle, type FetchWebBundleOptions } from './fetch.js'\n\nconst ENV_OVERRIDE = 'ZOOID_DEV_WEB_ROOT_OVERRIDE'\n\nexport interface EnsureWebRootOptions {\n cliRoot: string\n cacheDir: string\n version: string | undefined\n fetchBundle?: (opts: FetchWebBundleOptions) => Promise<string>\n onProgress?: (msg: string) => void\n}\n\nexport async function ensureWebRoot(opts: EnsureWebRootOptions): Promise<string> {\n const override = process.env[ENV_OVERRIDE]\n if (override && existsSync(join(override, 'index.html'))) return resolve(override)\n\n const fromSource = webSourcePackage(opts.cliRoot)\n if (fromSource && existsSync(join(fromSource, 'dist', 'index.html'))) {\n return join(fromSource, 'dist')\n }\n\n if (!opts.version) {\n throw new Error(\n `No @zooid/web version pin (zooid.webVersion) in the cli package.json ` +\n `and no monorepo sibling build found.\\n` +\n `Set ${ENV_OVERRIDE} to a built dist, or run from the monorepo.`,\n )\n }\n opts.onProgress?.(`Fetching @zooid/web ${opts.version}…`)\n const fetchBundleFn = opts.fetchBundle ?? fetchWebBundle\n return fetchBundleFn({ version: opts.version, cacheDir: opts.cacheDir })\n}\n\n// Returns the path to the in-tree @zooid/web package (zooid-clients/packages/web) if the\n// CLI is running from the monorepo source. Returns null when running from an\n// installed package (no sibling zoon/ tree).\nexport function webSourcePackage(cliRoot: string): string | null {\n const workspaceRoot = dirname(dirname(dirname(cliRoot)))\n const candidate = join(workspaceRoot, 'zoon', 'packages', 'web')\n return existsSync(join(candidate, 'package.json')) ? candidate : null\n}\n","import { mkdirSync, renameSync, rmSync, existsSync, readdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { createHash, randomUUID } from 'node:crypto'\nimport * as tar from 'tar'\n\nconst PKG = '@zooid/web'\nconst DEFAULT_REGISTRY = 'https://registry.npmjs.org'\n\nexport interface FetchWebBundleOptions {\n version: string\n cacheDir: string\n registryUrl?: string\n fetch?: typeof globalThis.fetch\n}\n\n/**\n * Ensure <cacheDir>/<version> holds the extracted dist/ of @zooid/web.\n * Atomic: extracts into a temp dir and renames, so a crash never leaves a\n * half-populated version dir. A populated version dir (index.html present)\n * is the completion marker.\n */\nexport async function fetchWebBundle(opts: FetchWebBundleOptions): Promise<string> {\n const target = join(opts.cacheDir, opts.version)\n if (existsSync(join(target, 'index.html'))) return target\n if (existsSync(target)) rmSync(target, { recursive: true, force: true }) // crashed extract\n\n const f = opts.fetch ?? globalThis.fetch\n const registry = (opts.registryUrl ?? DEFAULT_REGISTRY).replace(/\\/$/, '')\n let tgz: Buffer\n try {\n const metaRes = await f(`${registry}/${PKG}`)\n if (!metaRes.ok) throw new Error(`registry metadata: HTTP ${metaRes.status}`)\n const meta = (await metaRes.json()) as {\n versions?: Record<string, { dist?: { tarball?: string; integrity?: string } }>\n }\n const dist = meta.versions?.[opts.version]?.dist\n if (!dist?.tarball || !dist.integrity) {\n throw new Error(`${PKG}@${opts.version} not found on the registry`)\n }\n const tgzRes = await f(dist.tarball)\n if (!tgzRes.ok) throw new Error(`tarball: HTTP ${tgzRes.status}`)\n tgz = Buffer.from(await tgzRes.arrayBuffer())\n const sha = 'sha512-' + createHash('sha512').update(tgz).digest('base64')\n if (sha !== dist.integrity) {\n throw new Error(`integrity mismatch for ${PKG}@${opts.version}: got ${sha}`)\n }\n } catch (err) {\n throw new Error(\n `Failed to fetch ${PKG}@${opts.version} from ${registry}.\\n` +\n ` Cache: ${opts.cacheDir}\\n` +\n ` Offline? Point ZOOID_DEV_WEB_ROOT_OVERRIDE at a built dist as a manual escape hatch.\\n` +\n ` Cause: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n\n const tmp = join(opts.cacheDir, `.tmp-${randomUUID().slice(0, 8)}`)\n mkdirSync(tmp, { recursive: true })\n const tgzPath = join(tmp, '.bundle.tgz')\n try {\n writeFileSync(tgzPath, tgz)\n // node-tar handles gunzip, pax headers, and long names itself, and its\n // defaults refuse absolute paths and `..` traversal.\n await tar.extract({\n file: tgzPath,\n cwd: tmp,\n strip: 2, // package/dist/<file> → <file>\n filter: (p) => p === 'package/dist' || p.startsWith('package/dist/'),\n })\n rmSync(tgzPath)\n if (!existsSync(join(tmp, 'index.html'))) {\n throw new Error(`${PKG}@${opts.version} tarball has no dist/index.html`)\n }\n renameSync(tmp, target)\n } catch (err) {\n rmSync(tmp, { recursive: true, force: true })\n throw err\n }\n\n for (const entry of readdirSync(opts.cacheDir)) {\n if (entry !== opts.version) {\n rmSync(join(opts.cacheDir, entry), { recursive: true, force: true })\n }\n }\n return target\n}\n","import { readFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport function readZoonWebPin(cliRoot: string): string | undefined {\n try {\n const pkg = JSON.parse(readFileSync(join(cliRoot, 'package.json'), 'utf8')) as {\n zooid?: { webVersion?: string }\n }\n return pkg.zooid?.webVersion\n } catch {\n return undefined\n }\n}\n","import { readFileSync, statSync } from 'node:fs'\nimport { extname, join, normalize } from 'node:path'\nimport { Hono } from 'hono'\n\nexport interface WebStaticOpts {\n webRoot: string\n homeserverUrl: string\n}\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n}\n\nfunction isAssetPath(p: string): boolean {\n return p.startsWith('/assets/') || /\\.[a-z0-9]+$/i.test(p)\n}\n\nexport function webStatic(opts: WebStaticOpts): Hono {\n const app = new Hono()\n\n app.get('/config.json', (c) => c.json({ homeserver_url: opts.homeserverUrl }))\n\n app.get('*', (c) => {\n const url = new URL(c.req.url)\n const requested = decodeURIComponent(url.pathname)\n const wantFile = requested === '/' ? '/index.html' : requested\n\n const safe = normalize(wantFile).replace(/^(\\.\\.[/\\\\])+/g, '')\n const filePath = join(opts.webRoot, safe)\n if (!filePath.startsWith(opts.webRoot)) return c.notFound()\n\n try {\n const stat = statSync(filePath)\n if (stat.isFile()) {\n const body = readFileSync(filePath)\n const ct = MIME[extname(filePath)] ?? 'application/octet-stream'\n return c.body(body as unknown as ArrayBuffer, 200, { 'content-type': ct })\n }\n } catch {\n // fall through to history fallback\n }\n\n if (isAssetPath(requested)) return c.notFound()\n const indexBytes = readFileSync(join(opts.webRoot, 'index.html'))\n return c.body(indexBytes as unknown as ArrayBuffer, 200, {\n 'content-type': MIME['.html']!,\n })\n })\n\n return app\n}\n","import { spawn, type ChildProcess } from 'node:child_process'\nimport { existsSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport interface WebWatchHandle {\n distPath: string\n // Pipe captured child output onwards. Call once Listr / interactive\n // renderers are done, otherwise vite output will get garbled.\n attachStdio: () => void\n stop: () => Promise<void>\n}\n\nexport interface WebWatchOpts {\n webPackageDir: string\n // Wait up to this many ms for vite's first build to finish before resolving.\n firstBuildTimeoutMs?: number\n}\n\n// Spawns `vite build --watch` in webPackageDir and resolves once the first\n// build has completed (detected via index.html mtime > spawn time).\nexport async function startWebWatch(opts: WebWatchOpts): Promise<WebWatchHandle> {\n const distPath = join(opts.webPackageDir, 'dist')\n const indexPath = join(distPath, 'index.html')\n const timeoutMs = opts.firstBuildTimeoutMs ?? 60_000\n const spawnTime = Date.now()\n\n const child: ChildProcess = spawn(\n 'pnpm',\n ['-C', opts.webPackageDir, 'exec', 'vite', 'build', '--watch'],\n { stdio: ['ignore', 'pipe', 'pipe'] },\n )\n\n let buffered = ''\n const onData = (chunk: Buffer): void => {\n buffered += chunk.toString('utf8')\n }\n child.stdout?.on('data', onData)\n child.stderr?.on('data', onData)\n\n let attached = false\n const attachStdio = (): void => {\n if (attached) return\n attached = true\n child.stdout?.off('data', onData)\n child.stderr?.off('data', onData)\n if (buffered) process.stdout.write(buffered)\n buffered = ''\n child.stdout?.pipe(process.stdout)\n child.stderr?.pipe(process.stderr)\n }\n\n let exited = false\n child.once('exit', () => {\n exited = true\n })\n\n while (Date.now() - spawnTime < timeoutMs) {\n if (exited) {\n attachStdio()\n throw new Error(`vite build --watch exited before first build (code ${child.exitCode})`)\n }\n if (existsSync(indexPath)) {\n const m = statSync(indexPath).mtimeMs\n // Slack for clock granularity on macOS HFS+/APFS.\n if (m >= spawnTime - 500) return makeHandle()\n }\n await new Promise((r) => setTimeout(r, 200))\n }\n // Timed out: clean up and surface what vite said.\n attachStdio()\n await stopChild(child)\n throw new Error(`vite build --watch did not produce ${indexPath} within ${timeoutMs}ms`)\n\n function makeHandle(): WebWatchHandle {\n return {\n distPath,\n attachStdio,\n stop: () => stopChild(child),\n }\n }\n}\n\nasync function stopChild(child: ChildProcess): Promise<void> {\n if (child.exitCode !== null) return\n child.kill('SIGTERM')\n await new Promise<void>((resolve) => {\n let done = false\n const finish = (): void => {\n if (done) return\n done = true\n resolve()\n }\n child.once('exit', finish)\n setTimeout(() => {\n try {\n child.kill('SIGKILL')\n } catch {\n // already gone\n }\n finish()\n }, 2000)\n })\n}\n","import { mkdir, readdir, rm, symlink, unlink } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface LogPaths {\n dataDir: string\n logsDir: string\n dayDir: string\n daySlug: string\n todayLink: string\n tuwunelLog: string\n daemonLog: string\n devLog: string\n agentLog: (agentName: string) => string\n agentTap: (agentName: string) => string\n}\n\nexport interface ResolveOpts {\n dataDir: string\n /** Defaults to `new Date()`. Tests pin this for determinism. */\n now?: Date\n}\n\n// Local-time slug — we want the wall-clock day a session started, not UTC.\nfunction localDateSlug(d: Date): string {\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, '0')\n const day = String(d.getDate()).padStart(2, '0')\n return `${y}-${m}-${day}`\n}\n\nconst DAY_RE = /^\\d{4}-\\d{2}-\\d{2}$/\n\nexport function resolveLogPaths({ dataDir, now }: ResolveOpts): LogPaths {\n const slug = localDateSlug(now ?? new Date())\n const logsDir = join(dataDir, 'logs')\n const dayDir = join(logsDir, slug)\n return {\n dataDir,\n logsDir,\n dayDir,\n daySlug: slug,\n todayLink: join(logsDir, 'today'),\n tuwunelLog: join(dayDir, 'tuwunel.log'),\n daemonLog: join(dayDir, 'daemon.log'),\n devLog: join(dayDir, 'dev.log'),\n agentLog: (n) => join(dayDir, `agent-${n}.log`),\n agentTap: (n) => join(dayDir, `agent-${n}.acp.jsonl`),\n }\n}\n\nexport async function ensureDayFolder(p: LogPaths): Promise<void> {\n await mkdir(p.dayDir, { recursive: true })\n // Symlink target is the relative slug so the link survives a moved data dir.\n try {\n await unlink(p.todayLink)\n } catch {\n // may not exist\n }\n await symlink(p.daySlug, p.todayLink)\n}\n\nexport interface PruneOpts {\n dataDir: string\n now?: Date\n retainDays: number\n}\n\nexport async function pruneOldDays(opts: PruneOpts): Promise<string[]> {\n if (opts.retainDays <= 0) return []\n const logsDir = join(opts.dataDir, 'logs')\n let entries: string[]\n try {\n entries = await readdir(logsDir)\n } catch {\n return []\n }\n const today = opts.now ?? new Date()\n const cutoff = new Date(\n today.getFullYear(),\n today.getMonth(),\n today.getDate() - opts.retainDays + 1,\n ).getTime()\n const removed: string[] = []\n for (const name of entries) {\n if (!DAY_RE.test(name)) continue\n const [y, m, d] = name.split('-').map(Number)\n const t = new Date(y, m - 1, d).getTime()\n if (t < cutoff) {\n await rm(join(logsDir, name), { recursive: true, force: true })\n removed.push(name)\n }\n }\n return removed\n}\n","import { createWriteStream, type WriteStream } from 'node:fs'\nimport { mkdir } from 'node:fs/promises'\nimport { dirname } from 'node:path'\n\nexport type Verbosity = 'default' | 'verbose-thoughts' | 'verbose'\n\nexport interface JsonlSinkOpts {\n /** Truncate any single string field longer than this. Default 4 KB. */\n maxStringLen?: number\n}\n\nconst TRUNC_MARKER = '…[truncated]'\n\nexport class JsonlSink {\n private stream: WriteStream | null = null\n private readonly maxStringLen: number\n private readonly readyPromise: Promise<void>\n\n constructor(\n private readonly path: string,\n opts: JsonlSinkOpts = {},\n ) {\n this.maxStringLen = opts.maxStringLen ?? 4096\n this.readyPromise = (async () => {\n await mkdir(dirname(this.path), { recursive: true })\n this.stream = createWriteStream(this.path, { flags: 'a' })\n })()\n }\n\n async write(obj: unknown): Promise<void> {\n await this.readyPromise\n const capped = capStrings(obj, this.maxStringLen)\n const line = JSON.stringify(capped) + '\\n'\n return new Promise((resolve, reject) => {\n this.stream!.write(line, (err) => (err ? reject(err) : resolve()))\n })\n }\n\n async close(): Promise<void> {\n await this.readyPromise\n return new Promise((resolve) => {\n this.stream!.end(() => resolve())\n })\n }\n}\n\nfunction capStrings(v: unknown, max: number): unknown {\n if (typeof v === 'string') {\n return v.length <= max ? v : v.slice(0, max) + TRUNC_MARKER\n }\n if (Array.isArray(v)) return v.map((x) => capStrings(x, max))\n if (v && typeof v === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, val] of Object.entries(v)) out[k] = capStrings(val, max)\n return out\n }\n return v\n}\n\nconst DEFAULT_VARIANTS = new Set([\n 'tool_call',\n 'tool_call_update',\n 'plan',\n 'available_commands_update',\n 'current_mode_update',\n 'user_message_chunk',\n])\n\nexport function shouldCaptureUpdate(\n verbosity: Verbosity,\n variant: string,\n): boolean {\n if (verbosity === 'verbose') return true\n if (verbosity === 'verbose-thoughts') {\n return DEFAULT_VARIANTS.has(variant) || variant === 'agent_thought_chunk'\n }\n return DEFAULT_VARIANTS.has(variant)\n}\n","import type { TapEvent } from '@zooid/core'\nimport type { LogPaths } from './paths.js'\nimport { JsonlSink, shouldCaptureUpdate, type Verbosity } from './file-sink.js'\n\nexport interface MatrixContext {\n room_id: string\n event_id: string\n}\n\nexport interface WireAgentCaptureOpts {\n agent: string\n paths: LogPaths\n verbosity: Verbosity\n /** Returns the most-recently-known matrix context for the agent, or null. */\n matrixContext: () => MatrixContext | null\n /** Override for tests. */\n now?: () => Date\n}\n\nexport interface AgentCapture {\n onTap: (event: TapEvent) => void\n close: () => Promise<void>\n}\n\nexport function wireAgentCapture(opts: WireAgentCaptureOpts): AgentCapture {\n const sink = new JsonlSink(opts.paths.agentTap(opts.agent))\n const now = opts.now ?? (() => new Date())\n const pending: Promise<unknown>[] = []\n\n const onTap = (event: TapEvent): void => {\n if (event.kind === 'session_update') {\n const variant =\n (event.update as { sessionUpdate?: string }).sessionUpdate ?? 'unknown'\n if (!shouldCaptureUpdate(opts.verbosity, variant)) return\n }\n const matrix = opts.matrixContext()\n const envelope: Record<string, unknown> = {\n ts: now().toISOString(),\n agent: opts.agent,\n session_id: event.sessionId,\n turn_id: event.turnId,\n kind: event.kind,\n }\n if (matrix) envelope.matrix = matrix\n if (event.kind === 'session_update') envelope.notification = event.update\n else if (event.kind === 'turn_started') envelope.prompt_text = event.promptText\n else if (event.kind === 'turn_completed') envelope.stop_reason = event.stopReason\n pending.push(sink.write(envelope))\n }\n\n return {\n onTap,\n close: async () => {\n await Promise.all(pending)\n await sink.close()\n },\n }\n}\n","import { createWriteStream } from 'node:fs'\nimport { mkdir } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport type { ChildProcess } from 'node:child_process'\n\n/**\n * Tee a child's stdout and stderr to one log file, in arrival order.\n * Returns a promise that resolves once the file has been flushed after\n * the child exits.\n */\nexport function captureChildToFile(\n child: ChildProcess,\n path: string,\n): Promise<void> {\n return (async () => {\n await mkdir(dirname(path), { recursive: true })\n const stream = createWriteStream(path, { flags: 'a' })\n if (child.stdout) child.stdout.on('data', (b: Buffer) => stream.write(b))\n if (child.stderr) child.stderr.on('data', (b: Buffer) => stream.write(b))\n await new Promise<void>((resolve) => {\n child.on('exit', () => stream.end(() => resolve()))\n })\n })()\n}\n","export interface ShutdownLayers {\n stopUi: () => Promise<void>\n stopDaemon: () => Promise<void>\n stopTuwunel: () => Promise<void>\n stopWebWatch?: () => Promise<void>\n /** Flush per-agent ACP taps before stopping the daemon. */\n stopCaptures?: () => Promise<void>\n /** Resolves once Tuwunel's captured stdio file is flushed. */\n finalizeTuwunelCapture?: () => Promise<void>\n}\n\nexport function buildShutdown(layers: ShutdownLayers): () => Promise<void> {\n let started: Promise<void> | null = null\n return () => {\n if (started) return started\n started = (async () => {\n const order = [\n 'stopUi',\n 'stopWebWatch',\n 'stopCaptures',\n 'stopDaemon',\n 'stopTuwunel',\n 'finalizeTuwunelCapture',\n ] as const\n for (const step of order) {\n try {\n await layers[step]?.()\n } catch (err) {\n console.error(`${step}:`, err)\n }\n }\n })()\n return started\n }\n}\n","import { existsSync, mkdirSync, readdirSync, writeFileSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport {\n generateAgentsMd,\n generateClaudeMd,\n generateClaudeSettings,\n generateEnv,\n generateGitignore,\n generateOpencodeJson,\n generateOpencodeReadme,\n generateZooidYaml,\n} from './init/generators.js'\nimport {\n findOpencodeProvider,\n findSimplePreset,\n} from './init/registry.js'\nimport { sniffCredentials } from './init/sniff.js'\n\nexport interface InitOptions {\n dir: string\n preset: 'claude' | 'codex' | 'opencode'\n /** Required for claude/codex; ignored for opencode. */\n auth?: 'subscription' | 'api-key'\n /** Required for claude/codex; required for opencode (paired with `provider`). */\n model?: string\n /** Required for opencode. */\n provider?: string\n /** Required on api-key path; required for opencode. */\n apiKey?: string\n /** Allow generating into a non-empty dir. */\n force?: boolean\n /** Required with `force` to overwrite existing files. */\n overwrite?: boolean\n}\n\ninterface WriteSpec {\n path: string\n content: string\n}\n\n// Pre-existing entries that don't count toward \"non-empty\". Lets operators\n// run `pnpm install` before `zooid init` without tripping the guard.\nconst IGNORED_PREEXISTING = new Set([\n '.',\n '..',\n '.git',\n '.DS_Store',\n 'node_modules',\n 'package.json',\n 'package-lock.json',\n 'pnpm-lock.yaml',\n 'yarn.lock',\n])\n\nexport async function runInit(opts: InitOptions): Promise<void> {\n const dir = resolve(opts.dir)\n mkdirSync(dir, { recursive: true })\n\n if (!opts.force) {\n const blocking = readdirSync(dir).filter((n) => !IGNORED_PREEXISTING.has(n))\n if (blocking.length > 0) {\n throw new Error(\n `${dir} is non-empty (use --force to allow scaffolding into it). Conflicting entries: ${blocking.join(', ')}`,\n )\n }\n }\n\n const writes: WriteSpec[] = []\n\n if (opts.preset === 'claude' || opts.preset === 'codex') {\n if (!opts.model) throw new Error(`--model is required for preset ${opts.preset}`)\n if (!opts.auth) throw new Error('--auth (subscription|api-key) is required for claude/codex')\n const meta = findSimplePreset(opts.preset)!\n\n writes.push({\n path: 'zooid.yaml',\n content: generateZooidYaml({ preset: opts.preset, model: opts.model }),\n })\n writes.push({ path: 'agents/zooid-assistant/AGENTS.md', content: generateAgentsMd() })\n\n if (opts.preset === 'claude') {\n writes.push({\n path: 'agents/zooid-assistant/CLAUDE.md',\n content: generateClaudeMd(),\n })\n writes.push({\n path: 'agents/zooid-assistant/.claude/settings.json',\n content: generateClaudeSettings(),\n })\n }\n\n if (opts.auth === 'api-key') {\n if (!opts.apiKey) throw new Error('--api-key is required when --auth=api-key')\n writes.push({\n path: '.env',\n content: generateEnv({ envVar: meta.apiKeyEnvVar, value: opts.apiKey }),\n })\n }\n } else if (opts.preset === 'opencode') {\n if (!opts.provider) throw new Error('--provider is required for opencode')\n const isCustom = opts.provider === 'custom'\n const providerMeta = isCustom ? undefined : findOpencodeProvider(opts.provider)\n if (!isCustom && !providerMeta) throw new Error(`unknown opencode provider: ${opts.provider}`)\n if (!isCustom && !opts.model) throw new Error('--model is required (paired with --provider)')\n if (!isCustom && !opts.apiKey) throw new Error('--api-key is required for opencode')\n\n writes.push({ path: 'zooid.yaml', content: generateZooidYaml({ preset: 'opencode' }) })\n writes.push({ path: 'agents/zooid-assistant/AGENTS.md', content: generateAgentsMd() })\n writes.push({\n path: 'agents/zooid-assistant/opencode.json',\n content: generateOpencodeJson({\n provider: opts.provider,\n model: opts.model,\n apiKeyEnvVar: providerMeta?.apiKeyEnvVar,\n }),\n })\n if (isCustom) {\n writes.push({\n path: 'agents/zooid-assistant/opencode.json.README',\n content: generateOpencodeReadme(),\n })\n } else {\n writes.push({\n path: '.env',\n content: generateEnv({ envVar: providerMeta!.apiKeyEnvVar, value: opts.apiKey! }),\n })\n }\n } else {\n throw new Error(`unknown preset: ${String(opts.preset)}`)\n }\n\n writes.push({ path: '.gitignore', content: generateGitignore() })\n\n for (const w of writes) {\n const full = join(dir, w.path)\n const exists = existsSync(full)\n if (exists && !opts.overwrite) {\n console.warn(`⚠ ${w.path} exists; left as-is (use --force --overwrite to replace)`)\n continue\n }\n mkdirSync(dirname(full), { recursive: true })\n writeFileSync(full, w.content)\n console.log(`✓ Created ${w.path}`)\n }\n\n if ((opts.preset === 'claude' || opts.preset === 'codex') && opts.auth === 'subscription') {\n const s = sniffCredentials(opts.preset)\n if (s.found) {\n console.log(`✓ Found ${opts.preset} config at ${s.path}`)\n } else {\n console.warn(\n `⚠ No ${opts.preset} config detected — run \\`${opts.preset}\\` to log in before \\`zooid dev\\``,\n )\n }\n }\n\n console.log('\\nNext: zooid dev')\n}\n","export interface ZooidYamlOpts {\n preset: 'claude' | 'codex' | 'opencode'\n /** Only set for claude / codex; opencode reads its own opencode.json. */\n model?: string\n}\n\nexport function generateZooidYaml(opts: ZooidYamlOpts): string {\n const acpBlock =\n opts.preset === 'opencode'\n ? ` acp: { preset: opencode }`\n : ` acp:\\n preset: ${opts.preset}\\n model: ${opts.model}`\n return `runtime: local\n\ntransports:\n matrix:\n homeserver: http://localhost:8448\n port: 9099\n\nagents:\n zooid-assistant:\n${acpBlock}\n matrix:\n display_name: 'Zooid Assistant'\n rooms: ['#zooid']\n`\n}\n\nexport function generateAgentsMd(): string {\n return `# zooid-assistant\n\nYou are the zooid setup assistant. Your job is to help the operator get a workforce running, add agents, and configure zooid for their use case.\n\n## Resources\n\n- Zooid documentation: https://zooid.dev/docs/\n- Use your web fetch tool to read documentation pages when answering questions.\n\n## Stack facts\n\n- **Tuwunel** is a lightweight Rust Matrix homeserver (Conduit fork) backed by RocksDB. Single binary, low resource floor — not \"heavy\" for typical workforces.\n- **Logs land on disk** in \\`./data/\\` inside this zooid home dir: tuwunel logs, the daemon, and each agent's ACP stream. Use \\`zooid logs <source>\\` to tail them (sources: \\`tuwunel\\`, \\`daemon\\`, \\`dev\\`, \\`agent-<name>\\`, \\`agent-<name>.acp\\`). Debugging is mostly \"read the log file\" — don't tell the operator it's opaque.\n\n## Behavior\n\n- Be terse. Give the answer; link to the doc page; stop.\n- When the operator asks how to do something, prefer to fetch the relevant docs section over guessing from training data.\n- When the operator asks you to *configure* something, propose a yaml edit and let them apply it. Don't write files directly unless they ask.\n`\n}\n\n/**\n * Claude Code auto-loads `CLAUDE.md`, not `AGENTS.md`. We keep `AGENTS.md`\n * as the canonical content (codex / opencode read it directly) and ship a\n * one-line `CLAUDE.md` that pulls it in via Claude Code's `@<path>` import.\n */\nexport function generateClaudeMd(): string {\n return `@AGENTS.md\\n`\n}\n\nexport function generateClaudeSettings(): string {\n return (\n JSON.stringify(\n {\n permissions: {\n allow: ['WebFetch(domain:zooid.dev)'],\n },\n },\n null,\n 2,\n ) + '\\n'\n )\n}\n\nexport interface OpencodeJsonOpts {\n provider: string\n model?: string\n apiKeyEnvVar?: string\n}\n\nexport function generateOpencodeJson(opts: OpencodeJsonOpts): string {\n if (opts.provider === 'custom') {\n return (\n JSON.stringify(\n {\n $schema: 'https://opencode.ai/config.json',\n model: 'TODO/your-model',\n provider: { TODO: { options: {} } },\n },\n null,\n 2,\n ) + '\\n'\n )\n }\n const cfg = {\n $schema: 'https://opencode.ai/config.json',\n model: `${opts.provider}/${opts.model}`,\n provider: {\n [opts.provider]: {\n options: { apiKey: `{env:${opts.apiKeyEnvVar}}` },\n },\n },\n permission: { webfetch: 'allow' as const },\n }\n return JSON.stringify(cfg, null, 2) + '\\n'\n}\n\nexport interface EnvOpts {\n envVar: string\n value: string\n}\n\nexport function generateEnv(opts: EnvOpts): string {\n return `${opts.envVar}=${opts.value}\\n`\n}\n\nexport function generateGitignore(): string {\n return ['.env', 'node_modules/', 'data/', ''].join('\\n')\n}\n\nexport function generateOpencodeReadme(): string {\n return `See https://opencode.ai/config for the full opencode.json schema, including\nprovider-specific options and per-tool permissions.\n`\n}\n","export interface SimplePresetMeta {\n preset: 'claude' | 'codex'\n models: string[]\n subscriptionLabel: string\n apiKeyEnvVar: string\n apiKeyPromptLabel: string\n /** Home-relative directory checked on the subscription sniff (existence only). */\n credentialDir: string\n}\n\nexport const SIMPLE_PRESETS: readonly SimplePresetMeta[] = [\n {\n preset: 'claude',\n models: ['claude-sonnet-4-6', 'claude-opus-4-7', 'claude-haiku-4-5'],\n subscriptionLabel: 'Claude subscription (Pro / Max / Team / Enterprise)',\n apiKeyEnvVar: 'ANTHROPIC_API_KEY',\n apiKeyPromptLabel: 'Anthropic',\n credentialDir: '.claude',\n },\n {\n preset: 'codex',\n models: ['gpt-5.5'],\n subscriptionLabel: 'ChatGPT subscription (Plus / Pro / Team)',\n apiKeyEnvVar: 'OPENAI_API_KEY',\n apiKeyPromptLabel: 'OpenAI',\n credentialDir: '.codex',\n },\n]\n\nexport interface OpencodeProviderMeta {\n id: string\n label: string\n description: string\n models: string[]\n apiKeyEnvVar: string\n}\n\nexport const OPENCODE_PROVIDERS: readonly OpencodeProviderMeta[] = [\n {\n id: 'opencode-go',\n label: 'opencode-go',\n description: '$10/mo subscription — Kimi, GLM, MiniMax',\n models: ['kimi-k2.6', 'kimi-k2.5', 'glm-5.1', 'glm-5', 'minimax-m2.7'],\n apiKeyEnvVar: 'OPENCODE_API_KEY',\n },\n {\n id: 'opencode',\n label: 'opencode (Zen)',\n description: 'free tier — curated models',\n models: ['kimi-k2.5-free', 'glm-4.7-free', 'minimax-m2.1-free'],\n apiKeyEnvVar: 'OPENCODE_API_KEY',\n },\n {\n id: 'anthropic',\n label: 'Anthropic',\n description: 'Claude via direct Anthropic API',\n models: ['claude-sonnet-4-6', 'claude-opus-4-7', 'claude-haiku-4-5'],\n apiKeyEnvVar: 'ANTHROPIC_API_KEY',\n },\n {\n id: 'openrouter',\n label: 'OpenRouter',\n description: 'many providers via OpenRouter',\n models: ['anthropic/claude-sonnet-4-6', 'zhipuai/glm-5', 'moonshot/kimi-k2.6'],\n apiKeyEnvVar: 'OPENROUTER_API_KEY',\n },\n]\n\nexport function findSimplePreset(name: string): SimplePresetMeta | undefined {\n return SIMPLE_PRESETS.find((p) => p.preset === name)\n}\n\nexport function findOpencodeProvider(id: string): OpencodeProviderMeta | undefined {\n return OPENCODE_PROVIDERS.find((p) => p.id === id)\n}\n","import { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { findSimplePreset } from './registry.js'\n\nexport interface SniffResult {\n found: boolean\n /** Absolute path that satisfied the sniff (the config directory). */\n path?: string\n}\n\n/**\n * Checks whether the operator's per-CLI config directory exists. NEVER reads\n * any file inside — only `existsSync` on the dir. One rule covers Linux,\n * macOS Keychain, and OS keyring without per-backend logic. The edge case\n * where the dir exists but the operator isn't actually logged in is accepted;\n * the spawned shim will surface a clearer error on first turn.\n *\n * `home` is overridable for tests.\n */\nexport function sniffCredentials(\n preset: 'claude' | 'codex',\n home: string = homedir(),\n): SniffResult {\n const meta = findSimplePreset(preset)\n if (!meta) return { found: false }\n const full = join(home, meta.credentialDir)\n if (existsSync(full)) return { found: true, path: full }\n return { found: false }\n}\n","import { select, password } from '@inquirer/prompts'\nimport {\n OPENCODE_PROVIDERS,\n findOpencodeProvider,\n findSimplePreset,\n} from './registry.js'\nimport type { InitOptions } from '../init.js'\n\nexport interface PromptInput {\n dir: string\n preset?: string\n auth?: string\n model?: string\n provider?: string\n apiKey?: string\n force?: boolean\n overwrite?: boolean\n interactive?: boolean\n}\n\nexport async function resolveOptions(flags: PromptInput): Promise<InitOptions> {\n const interactive = flags.interactive !== false && Boolean(process.stdin.isTTY)\n const ask = <T>(prompt: () => Promise<T>, fallback: () => string): Promise<T> => {\n if (!interactive) return Promise.reject(new Error(fallback()))\n return prompt()\n }\n\n const preset = (flags.preset as InitOptions['preset']) ?? (await ask(\n () => select({\n message: 'Which agent should zooid-assistant use?',\n choices: [\n { name: 'claude (Claude Code)', value: 'claude' as const },\n { name: 'codex (OpenAI Codex)', value: 'codex' as const },\n { name: 'opencode', value: 'opencode' as const },\n ],\n }),\n () => '--preset is required (claude | codex | opencode)',\n ))\n\n if (preset === 'opencode') {\n const provider = flags.provider ?? (await ask(\n () => select({\n message: 'Which provider?',\n choices: [\n ...OPENCODE_PROVIDERS.map((p) => ({\n name: `${p.label} (${p.description})`,\n value: p.id,\n })),\n { name: 'custom (write your own opencode.json block)', value: 'custom' },\n ],\n }),\n () => '--provider is required for opencode',\n ))\n if (provider === 'custom') {\n return {\n dir: flags.dir,\n preset,\n provider,\n force: flags.force,\n overwrite: flags.overwrite,\n }\n }\n const meta = findOpencodeProvider(provider)\n if (!meta) throw new Error(`unknown opencode provider: ${provider}`)\n const model = flags.model ?? (await ask(\n () => select({\n message: 'Which model?',\n choices: meta.models.map((m) => ({ name: m, value: m })),\n }),\n () => '--model is required',\n ))\n const apiKey = flags.apiKey ?? (await ask(\n () => password({ message: `${meta.label} API key:` }),\n () => '--api-key is required',\n ))\n return {\n dir: flags.dir,\n preset,\n provider,\n model,\n apiKey,\n force: flags.force,\n overwrite: flags.overwrite,\n }\n }\n\n const meta = findSimplePreset(preset)\n if (!meta) throw new Error(`unknown preset: ${preset}`)\n const auth = (flags.auth as 'subscription' | 'api-key') ?? (await ask(\n () => select({\n message: 'How do you authenticate?',\n choices: [\n { name: `My ${meta.subscriptionLabel}`, value: 'subscription' as const },\n { name: `I'll provide an API key`, value: 'api-key' as const },\n ],\n }),\n () => '--auth is required (subscription | api-key)',\n ))\n const model = flags.model ?? (await ask(\n () => select({\n message: 'Which model?',\n choices: meta.models.map((m) => ({ name: m, value: m })),\n }),\n () => '--model is required',\n ))\n const apiKey =\n auth === 'api-key'\n ? flags.apiKey ?? (await ask(\n () => password({ message: `${meta.apiKeyPromptLabel} API key:` }),\n () => '--api-key is required when --auth=api-key',\n ))\n : undefined\n\n return {\n dir: flags.dir,\n preset,\n auth,\n model,\n apiKey,\n force: flags.force,\n overwrite: flags.overwrite,\n }\n}\n","import { readFile, readdir, readlink } from 'node:fs/promises'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { pruneOldDays } from '../observability/paths.js'\n\nexport interface LogsFlags {\n dataDir: string\n source?: string\n day?: string\n turn?: string\n follow?: boolean\n subcommand?: 'prune'\n keep?: number\n /** Tests inject an alternate writer. */\n writer?: (s: string) => void\n now?: Date\n}\n\nconst KNOWN_SOURCES = ['tuwunel', 'daemon', 'dev'] as const\n\nexport async function runLogs(flags: LogsFlags): Promise<void> {\n const writer = flags.writer ?? ((s: string) => process.stdout.write(s))\n\n if (flags.subcommand === 'prune') {\n const removed = await pruneOldDays({\n dataDir: flags.dataDir,\n retainDays: flags.keep ?? 14,\n now: flags.now,\n })\n writer(`pruned ${removed.length} day(s): ${removed.join(', ')}\\n`)\n return\n }\n\n const day = flags.day ?? (await resolveTodaySlug(flags.dataDir))\n if (!day) {\n writer('no logs yet\\n')\n return\n }\n const dayDir = join(flags.dataDir, 'logs', day)\n if (!existsSync(dayDir)) {\n writer(`no logs for ${day}\\n`)\n return\n }\n\n if (flags.turn) {\n await dumpByTurn(dayDir, flags.turn, writer)\n return\n }\n\n if (!flags.source) {\n const entries = await readdir(dayDir)\n const sources = new Set<string>()\n for (const e of entries) {\n if (e.endsWith('.log')) sources.add(e.replace(/\\.log$/, ''))\n if (e.endsWith('.acp.jsonl')) sources.add(e.replace(/\\.acp\\.jsonl$/, '.acp'))\n }\n writer([...sources].sort().join('\\n') + '\\n')\n return\n }\n\n const path = resolveSourcePath(dayDir, flags.source)\n if (!existsSync(path)) {\n writer(`no such source: ${flags.source}\\n`)\n return\n }\n writer(await readFile(path, 'utf8'))\n // -f is intentionally not implemented in this cycle; documented as a follow-up.\n}\n\nasync function resolveTodaySlug(dataDir: string): Promise<string | null> {\n const link = join(dataDir, 'logs', 'today')\n try {\n return await readlink(link)\n } catch {\n return null\n }\n}\n\nfunction resolveSourcePath(dayDir: string, source: string): string {\n if (source.startsWith('agent-')) {\n if (source.endsWith('.acp')) return join(dayDir, `${source.slice(0, -4)}.acp.jsonl`)\n return join(dayDir, `${source}.log`)\n }\n if ((KNOWN_SOURCES as readonly string[]).includes(source))\n return join(dayDir, `${source}.log`)\n return join(dayDir, source)\n}\n\nasync function dumpByTurn(\n dayDir: string,\n turnId: string,\n writer: (s: string) => void,\n): Promise<void> {\n const entries = await readdir(dayDir)\n const taps = entries.filter((e) => e.endsWith('.acp.jsonl')).sort()\n for (const f of taps) {\n const text = await readFile(join(dayDir, f), 'utf8')\n for (const line of text.split('\\n')) {\n if (!line) continue\n try {\n const obj = JSON.parse(line)\n if (obj.turn_id === turnId) writer(line + '\\n')\n } catch {\n // skip malformed line\n }\n }\n }\n}\n","import { randomBytes } from 'node:crypto'\nimport { resolve } from 'node:path'\nimport type { CliFlags } from '@zooid/core'\nimport { resolveDataLayout } from '../bootstrap/data-layout.js'\nimport { startDaemon } from '../daemon/start-daemon.js'\n\nexport interface StartFlags extends CliFlags {\n printToken?: boolean\n /** Data root dir; defaults to `./data` relative to cwd. */\n dataDir?: string\n}\n\nexport async function runStart(flags: StartFlags): Promise<void> {\n if (flags.printToken) {\n process.stdout.write(`${randomBytes(32).toString('hex')}\\n`)\n return\n }\n const dataRoot = resolve(process.cwd(), flags.dataDir ?? './data')\n const layout = resolveDataLayout(dataRoot)\n const handle = await startDaemon({\n cliFlags: flags,\n installSignalHandlers: true,\n agentsDir: layout.agentsDir,\n })\n console.log(`zooid listening on http://localhost:${handle.port}`)\n for (const name of handle.agentNames) console.log(` agent: ${name}`)\n await handle.whenStopped\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport chalk from 'chalk'\nimport { findConfigFile, findMatrixTransport, loadZooidConfig } from '@zooid/core'\nimport { deriveHomeserverShape } from '../bootstrap/derive.js'\n\nexport interface StatusFlags {\n cwd?: string\n dataDir: string\n /** Tuwunel host port. If omitted, derived from zooid.yaml's matrix transport. */\n port?: number\n}\n\nexport interface StatusReport {\n tuwunel: { status: 'up' | 'down'; url: string }\n daemon: { status: 'up' | 'down'; url: string } | { status: 'unknown'; reason: string }\n agents: { name: string; userId: string; trigger: string }[]\n}\n\nasync function probe(url: string, timeoutMs = 2_000): Promise<boolean> {\n try {\n const r = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) })\n return r.status > 0\n } catch {\n return false\n }\n}\n\nexport async function collectStatus(opts: {\n cwd: string\n tuwunelUrl: string\n}): Promise<StatusReport> {\n const tuwunelUp = await probe(`${opts.tuwunelUrl}/_matrix/client/versions`)\n const tuwunel: StatusReport['tuwunel'] = {\n status: tuwunelUp ? 'up' : 'down',\n url: opts.tuwunelUrl,\n }\n\n const found = findConfigFile(opts.cwd)\n if (!found) {\n return {\n tuwunel,\n daemon: { status: 'unknown', reason: 'no zooid.yaml' },\n agents: [],\n }\n }\n const cfg = loadZooidConfig(readFileSync(found.path, 'utf8'), {\n configDir: dirname(found.path),\n })\n const matrixEntry = Object.entries(cfg.transports).find(\n ([, t]) => t.type === 'matrix',\n ) as [string, { port?: number }] | undefined\n const daemonPort = matrixEntry?.[1]?.port ?? 8080\n const daemonUrl = `http://localhost:${daemonPort}`\n const daemonUp = await probe(daemonUrl)\n const agents: StatusReport['agents'] = []\n for (const a of Object.values(cfg.agents)) {\n if (a.matrix) {\n agents.push({\n name: a.name,\n userId: a.matrix.user_id,\n trigger: a.matrix.trigger,\n })\n }\n }\n return {\n tuwunel,\n daemon: { status: daemonUp ? 'up' : 'down', url: daemonUrl },\n agents,\n }\n}\n\nexport async function runStatus(flags: StatusFlags): Promise<void> {\n const cwd = flags.cwd ?? process.cwd()\n let port = flags.port\n if (port === undefined) {\n const found = findConfigFile(cwd)\n if (found) {\n const cfg = loadZooidConfig(readFileSync(found.path, 'utf8'), {\n configDir: dirname(found.path),\n })\n const matrix = findMatrixTransport(cfg)\n if (matrix) {\n const userIds = Object.values(cfg.agents)\n .filter((a) => a.matrix?.transport === matrix.name)\n .map((a) => a.matrix!.user_id)\n port = deriveHomeserverShape(matrix.transport, userIds).port\n }\n }\n }\n const tuwunelUrl = `http://localhost:${port ?? 8448}`\n const s = await collectStatus({ cwd, tuwunelUrl })\n const fmt = (st: 'up' | 'down' | 'unknown'): string =>\n st === 'up' ? chalk.green('up') : st === 'down' ? chalk.red('down') : chalk.yellow('unknown')\n process.stdout.write(\n [\n `tuwunel ${fmt(s.tuwunel.status)} ${s.tuwunel.url}`,\n `daemon ${fmt(s.daemon.status)} ${'url' in s.daemon ? s.daemon.url : s.daemon.reason}`,\n ...s.agents.map(\n (a) => ` agent: ${a.name} (${a.userId}, trigger: ${a.trigger})`,\n ),\n '',\n ].join('\\n'),\n )\n}\n"],"mappings":"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","names":["resolve","existsSync","readFileSync","dirname","join","resolve","serve","j","join","mkdirSync","writeFileSync","readFileSync","dirname","join","resolve","dirname","readFileSync","join","execFile","promisify","resolve","existsSync","dirname","join","resolve","mkdirSync","existsSync","writeFileSync","join","randomUUID","existsSync","join","resolve","dirname","readFileSync","join","readFileSync","join","Hono","spawn","existsSync","statSync","join","resolve","mkdir","unlink","join","mkdir","dirname","resolve","createWriteStream","mkdir","dirname","resolve","dirname","resolve","existsSync","readFileSync","join","serve","existsSync","mkdirSync","readdirSync","writeFileSync","dirname","join","resolve","existsSync","join","join","existsSync","resolve","mkdirSync","readdirSync","join","existsSync","dirname","writeFileSync","meta","model","apiKey","readdir","existsSync","join","join","existsSync","readdir","randomBytes","resolve","randomBytes","resolve","readFileSync","dirname","chalk","readFileSync","dirname","chalk","resolve"]}