agentix-cli 0.29.0 → 0.30.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/{agent-LS4CZPJ6.js → agent-SPE7Q7MD.js} +2 -2
- package/dist/{board-dashboard-6QQCKFB3.js → board-dashboard-K4DM32SO.js} +2 -2
- package/dist/{chunk-LNWX4MPX.js → chunk-42DCRKUD.js} +130 -129
- package/dist/chunk-42DCRKUD.js.map +1 -0
- package/dist/chunk-45BLFNDG.js +170 -0
- package/dist/chunk-45BLFNDG.js.map +1 -0
- package/dist/{chunk-SBCZLZG3.js → chunk-AUNDQPDR.js} +2 -2
- package/dist/chunk-DWADWDMU.js +96 -0
- package/dist/chunk-DWADWDMU.js.map +1 -0
- package/dist/{chunk-3QVOWDHZ.js → chunk-EL3J74N2.js} +2 -2
- package/dist/{chunk-AE2LDMZU.js → chunk-GK7XAM3D.js} +2 -2
- package/dist/chunk-GK7XAM3D.js.map +1 -0
- package/dist/{chunk-OTXDKKEU.js → chunk-GUBMLV34.js} +134 -122
- package/dist/chunk-GUBMLV34.js.map +1 -0
- package/dist/{chunk-Z2Y24ETP.js → chunk-IVQO43U2.js} +2 -2
- package/dist/{chunk-F5AEXRPR.js → chunk-MGNJWBVP.js} +2 -2
- package/dist/{chunk-6F2IKJ2F.js → chunk-Q7CZIRBB.js} +2 -2
- package/dist/{chunk-UYSNGBDT.js → chunk-UU4WOZNR.js} +2 -2
- package/dist/{chunk-JIOLJIBM.js → chunk-V4HURNMX.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +161 -155
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/program-DWZAI4GY.js +2 -0
- package/dist/query-3HXGBKGM.js +2 -0
- package/dist/registry-EJRWAJYG.js +2 -0
- package/dist/{request-planner-BKT6RZKX.js → request-planner-BCOXUAPA.js} +2 -2
- package/dist/{review-candidates-F3OFYTCZ.js → review-candidates-O2PS7L3B.js} +2 -2
- package/dist/routing-5K7PGHPL.js +2 -0
- package/dist/{seat-ZVHXNAEN.js → seat-FZRNRAHQ.js} +2 -2
- package/dist/{select-L7C52URW.js → select-SOJYFAMI.js} +2 -2
- package/dist/wiki-34XVI32N.js +2 -0
- package/dist/workspace-setup-G6KGWPHY.js +2 -0
- package/package.json +1 -1
- package/dist/chunk-67Q4DCPS.js +0 -54
- package/dist/chunk-67Q4DCPS.js.map +0 -1
- package/dist/chunk-AE2LDMZU.js.map +0 -1
- package/dist/chunk-I3SIXTJO.js +0 -44
- package/dist/chunk-I3SIXTJO.js.map +0 -1
- package/dist/chunk-LNWX4MPX.js.map +0 -1
- package/dist/chunk-OTXDKKEU.js.map +0 -1
- package/dist/chunk-XPXO5K4L.js +0 -164
- package/dist/chunk-XPXO5K4L.js.map +0 -1
- package/dist/program-I4J63BQ7.js +0 -2
- package/dist/query-R7EI3VGX.js +0 -2
- package/dist/registry-UJIJBLUR.js +0 -2
- package/dist/routing-S5WSFIAD.js +0 -2
- package/dist/wiki-5YQI4YKM.js +0 -2
- package/dist/workspace-setup-B3F3TUDE.js +0 -2
- /package/dist/{agent-LS4CZPJ6.js.map → agent-SPE7Q7MD.js.map} +0 -0
- /package/dist/{board-dashboard-6QQCKFB3.js.map → board-dashboard-K4DM32SO.js.map} +0 -0
- /package/dist/{chunk-SBCZLZG3.js.map → chunk-AUNDQPDR.js.map} +0 -0
- /package/dist/{chunk-3QVOWDHZ.js.map → chunk-EL3J74N2.js.map} +0 -0
- /package/dist/{chunk-Z2Y24ETP.js.map → chunk-IVQO43U2.js.map} +0 -0
- /package/dist/{chunk-F5AEXRPR.js.map → chunk-MGNJWBVP.js.map} +0 -0
- /package/dist/{chunk-6F2IKJ2F.js.map → chunk-Q7CZIRBB.js.map} +0 -0
- /package/dist/{chunk-UYSNGBDT.js.map → chunk-UU4WOZNR.js.map} +0 -0
- /package/dist/{chunk-JIOLJIBM.js.map → chunk-V4HURNMX.js.map} +0 -0
- /package/dist/{program-I4J63BQ7.js.map → program-DWZAI4GY.js.map} +0 -0
- /package/dist/{query-R7EI3VGX.js.map → query-3HXGBKGM.js.map} +0 -0
- /package/dist/{registry-UJIJBLUR.js.map → registry-EJRWAJYG.js.map} +0 -0
- /package/dist/{request-planner-BKT6RZKX.js.map → request-planner-BCOXUAPA.js.map} +0 -0
- /package/dist/{review-candidates-F3OFYTCZ.js.map → review-candidates-O2PS7L3B.js.map} +0 -0
- /package/dist/{routing-S5WSFIAD.js.map → routing-5K7PGHPL.js.map} +0 -0
- /package/dist/{seat-ZVHXNAEN.js.map → seat-FZRNRAHQ.js.map} +0 -0
- /package/dist/{select-L7C52URW.js.map → select-SOJYFAMI.js.map} +0 -0
- /package/dist/{wiki-5YQI4YKM.js.map → wiki-34XVI32N.js.map} +0 -0
- /package/dist/{workspace-setup-B3F3TUDE.js.map → workspace-setup-G6KGWPHY.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/a2a.ts","../src/commands/desktop.ts","../src/desktop/install.ts","../src/commands/monitor.ts","../src/attach/install.ts","../src/program.ts","../src/commands/daemon.ts","../src/commands/init.ts","../src/commands/setup.ts","../src/commands/token.ts","../src/commands/manage.ts","../src/commands/db.ts","../src/commands/ledger.ts","../src/intent/replay.ts","../src/commands/decisions.ts","../src/commands/trace.ts","../src/commands/guard.ts","../src/guard/seeds.ts","../src/commands/point.ts","../src/decisions/seats/ui-element.ts","../src/computer-use/screen.ts","../src/computer-use/candidates.ts","../src/commands/look.ts","../src/computer-use/look.ts","../src/computer-use/probes.ts","../src/computer-use/verify.ts","../src/decisions/seats/screen-state.ts","../src/commands/paste.ts","../src/decisions/seats/paste-transform.ts","../src/clipboard/transforms.ts","../src/commands/notify.ts","../src/commands/decide.ts","../src/commands/teach.ts","../src/teach/lessons.ts","../src/commands/attach.ts","../src/commands/process.ts","../src/commands/rag.ts","../src/commands/backlog.ts","../src/commands/schedule.ts","../src/utils/nl-cron.ts","../src/commands/connect.ts","../src/connect/telegram.ts","../src/utils/dotenv-mutator.ts","../src/connect/whatsapp.ts","../src/connect/mesh.ts","../src/commands/usage.ts","../src/commands/board.ts","../src/commands/wiki.ts","../src/commands/graph.ts","../src/commands/procedure.ts","../src/commands/procedure-extract.ts","../src/commands/workflow.ts","../src/workflows/templates/index.ts","../src/commands/webhook.ts","../src/commands/business.ts","../src/commands/plan.ts","../src/commands/notifications.ts","../src/commands/retention.ts","../src/commands/actions.ts","../src/commands/watch.ts","../src/commands/tui.ts","../src/tui/opencode-cli.ts","../src/commands/chat.ts","../src/commands/deprecation.ts","../src/commands/memory.ts","../src/commands/serve.ts","../src/commands/demo.ts","../src/commands/demo-workflow.ts","../src/commands/whatsapp.ts","../src/commands/plugin.ts","../src/commands/completion.ts"],"sourcesContent":["import { Command } from \"commander\"\nimport { A2AServer } from \"@/a2a\"\nimport type { ProviderName } from \"@/agent/providers\"\n\nexport const a2a = new Command()\n .name(\"a2a\")\n .description(\"start an A2A (Agent-to-Agent) protocol server for external agent integration\")\n .option(\"--port <port>\", \"server port\", \"3171\")\n .option(\"--host <host>\", \"server host\", \"0.0.0.0\")\n .option(\"-p, --provider <provider>\", \"AI provider\", \"claude-code\")\n .option(\"-m, --model <model>\", \"model to use\")\n .option(\"--api-key <key>\", \"API key for the provider\")\n .option(\"-c, --cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--no-cors\", \"disable CORS headers\")\n .action(async (opts) => {\n const server = new A2AServer({\n port: parseInt(opts.port, 10),\n host: opts.host,\n provider: opts.provider as ProviderName,\n model: opts.model,\n apiKey: opts.apiKey,\n cwd: opts.cwd,\n cors: opts.cors !== false,\n })\n\n await server.start()\n })\n","import { Command } from 'commander'\nimport { execFileSync } from 'node:child_process'\nimport { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { homedir, release, tmpdir } from 'node:os'\nimport { fileURLToPath } from 'node:url'\nimport { setTimeout as sleep } from 'node:timers/promises'\nimport { loadDaemonConfig } from '@/daemon/config'\nimport { DESKTOP_APP, DESKTOP_LABEL, HELPER_APP, desktopPlatformError, desktopPlist, installedHelper, selectDesktopAgent } from '@/desktop/install'\n\nfunction checkPlatform() {\n const error = desktopPlatformError(process.platform, process.arch, release())\n if (error) throw new Error(error)\n}\nfunction launchTarget() { return `gui/${process.getuid!()}/${DESKTOP_LABEL}` }\nfunction plistPath() { return join(homedir(), 'Library/LaunchAgents', `${DESKTOP_LABEL}.plist`) }\nasync function stop() {\n try { execFileSync('launchctl', ['bootout', launchTarget()], { stdio: 'pipe' }) } catch { /* may already be stopped */ }\n for (let i = 0; i < 30; i++) {\n try { execFileSync('launchctl', ['print', launchTarget()], { stdio: 'pipe' }) }\n catch { return }\n await sleep(200)\n }\n throw new Error('The desktop login service did not stop. Retry agentx desktop stop before installing.')\n}\nfunction start() {\n if (!existsSync(plistPath())) throw new Error('Run agentx desktop install first.')\n let loaded = true\n try { execFileSync('launchctl', ['print', launchTarget()], { stdio: 'pipe' }) } catch { loaded = false }\n if (!loaded) execFileSync('launchctl', ['bootstrap', `gui/${process.getuid!()}`, plistPath()], { stdio: 'pipe' })\n execFileSync('launchctl', ['kickstart', launchTarget()], { stdio: 'pipe' })\n}\nfunction packageRoot() {\n const here = dirname(fileURLToPath(import.meta.url))\n for (const dir of [resolve(here, '..'), resolve(here, '../..'), process.cwd()]) {\n try {\n if (JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')).name === 'agentix-cli' && existsSync(join(dir, 'apps/mac-voice/build.sh'))) return dir\n } catch { /* next candidate */ }\n }\n throw new Error('Desktop sources are missing from this installation. Update AgentX to a release containing apps/mac-voice and apps/mac-helper.')\n}\nexport const desktop = new Command('desktop').description('install and control the macOS desktop assistant')\ndesktop.command('install').description('build, install, and start voice and computer-use helpers at login')\n .option('--agent <id>', 'agent to use (defaults to the first configured agent)')\n .option('--dry-run', 'show the installation plan without building or changing login items')\n .action(async opts => {\n checkPlatform()\n const config = loadDaemonConfig()\n const agent = selectDesktopAgent(config.agents, opts.agent)\n const url = config.dashboard?.daemonUrl || `http://${config.node.bind.replace(/^0\\.0\\.0\\.0:/, '127.0.0.1:')}`\n const root = packageRoot()\n const apps = join(homedir(), 'Applications')\n console.log(`Desktop assistant → ${join(apps, DESKTOP_APP)}\\nComputer-use helper → ${join(apps, HELPER_APP)}\\nAgent → ${agent}\\nDaemon → ${url}\\nStarts at login → ${plistPath()}`)\n if (opts.dryRun) return\n try { execFileSync('xcrun', ['--find', 'swiftc'], { stdio: 'pipe' }) }\n catch { throw new Error('Apple command-line tools are required. Run xcode-select --install, finish installation, then retry.') }\n // Compile in a temporary directory: npm installations may be read-only.\n const stage = mkdtempSync(join(tmpdir(), 'agentx-desktop-'))\n try {\n for (const name of ['mac-helper', 'mac-voice']) {\n cpSync(join(root, 'apps', name), join(stage, name), { recursive: true, filter: source => !source.split('/').includes('build') })\n execFileSync('/bin/bash', [join(stage, name, 'build.sh')], { stdio: 'inherit' })\n }\n const log = join(homedir(), 'Library/Logs/agentx-desktop.err.log')\n const plist = desktopPlist({ executable: join(apps, DESKTOP_APP, 'Contents/MacOS/AgentXVoice'), cwd: process.cwd(), agent, url,\n helper: installedHelper(homedir()), cli: join(root, 'dist/cli.js'), node: process.execPath, log })\n const stagedPlist = join(stage, 'desktop.plist')\n writeFileSync(stagedPlist, plist, { mode: 0o600 })\n execFileSync('plutil', ['-lint', stagedPlist], { stdio: 'pipe' })\n await stop()\n mkdirSync(apps, { recursive: true })\n for (const [name, built, dest] of [['mac-voice', 'AgentX Voice.app', DESKTOP_APP], ['mac-helper', HELPER_APP, HELPER_APP]]) {\n cpSync(join(stage, name, 'build', built), join(apps, dest), { recursive: true })\n }\n mkdirSync(dirname(plistPath()), { recursive: true })\n mkdirSync(dirname(log), { recursive: true })\n writeFileSync(plistPath(), plist, { mode: 0o600 })\n start()\n console.log('Desktop assistant is running. Hold Option–Space to speak; Command–Option–V for smart paste.\\nAllow Microphone for the app and Accessibility / Screen Recording for the helper when macOS asks.\\nThe AgentX daemon and a speech transcription backend must also be available. Run agentx desktop status to inspect the login service.')\n } finally { rmSync(stage, { recursive: true, force: true }) }\n })\ndesktop.command('start').description('start the installed desktop assistant').action(() => { checkPlatform(); start(); console.log('Desktop assistant started.') })\ndesktop.command('stop').description('stop the desktop assistant until started again or next login').action(async () => { checkPlatform(); await stop(); console.log('Desktop assistant stopped.') })\ndesktop.command('status').description('show the desktop login service status').action(() => {\n checkPlatform()\n try { console.log(execFileSync('launchctl', ['print', launchTarget()], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] })) }\n catch { console.log(existsSync(plistPath()) ? 'Installed, but not running. Run agentx desktop start.' : 'Not installed. Run agentx desktop install.') }\n})\n","import { existsSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport const DESKTOP_LABEL = 'tn.acme.agentx.voice'\nexport const DESKTOP_APP = 'AgentX Desktop.app'\nexport const HELPER_APP = 'AgentX Helper.app'\nexport function desktopPlatformError(platform: string, arch: string, release: string): string | null {\n if (platform !== 'darwin' || arch !== 'arm64' || Number(release.split('.')[0]) < 23)\n return 'AgentX Desktop currently requires Apple Silicon and macOS 14 or newer.'\n return null\n}\nexport function selectDesktopAgent(agents: Record<string, unknown>, requested?: string): string {\n if (requested && !Object.hasOwn(agents, requested)) throw new Error(`Unknown agent: ${requested}. Run agentx agent list.`)\n const id = requested || Object.keys(agents)[0]\n if (!id) throw new Error('No agents configured. Run agentx setup first.')\n return id\n}\nexport function shellQuote(value: string): string { return `'${value.replace(/'/g, \"'\\\\''\")}'` }\nexport function desktopPlist(opts: { executable: string; cwd: string; agent: string; url: string; helper: string; cli: string; node: string; log: string }): string {\n const xml = (s: string) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"').replace(/'/g, ''')\n const env = {\n AGENTX_VOICE_AGENT: opts.agent,\n AGENTX_DAEMON_URL: opts.url,\n AGENTX_MAC_HELPER: opts.helper,\n AGENTX_PASTE_COMMAND: `cd ${shellQuote(opts.cwd)} && ${shellQuote(opts.node)} ${shellQuote(opts.cli)} paste`,\n }\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\"><dict>\n<key>Label</key><string>${DESKTOP_LABEL}</string>\n<key>ProgramArguments</key><array><string>${xml(opts.executable)}</string></array>\n<key>WorkingDirectory</key><string>${xml(opts.cwd)}</string>\n<key>EnvironmentVariables</key><dict>${Object.entries(env).map(([k,v]) => `<key>${k}</key><string>${xml(v)}</string>`).join('')}</dict>\n<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>\n<key>ProcessType</key><string>Interactive</string>\n<key>StandardErrorPath</key><string>${xml(opts.log)}</string>\n</dict></plist>\\n`\n}\nexport function installedHelper(home: string): string {\n return join(home, 'Applications', HELPER_APP, 'Contents/MacOS/agentx-mac-helper')\n}\nexport function resolveHelper(cwd: string, home: string, override?: string): string {\n if (override) return override\n const installed = installedHelper(home)\n return existsSync(installed) ? installed : join(cwd, 'apps/mac-helper/build/AgentX Helper.app/Contents/MacOS/agentx-mac-helper')\n}\n","import { Command } from \"commander\"\nimport { open } from \"fs/promises\"\nimport { registrationSchema, stopSchema } from \"@/daemon/session-monitor\"\nimport { configuredDaemonPort } from \"@/attach/install\"\n\nexport const monitor = new Command(\"monitor\").description(\"Register external CLI sessions and report ended runs to the briefing\")\nconst defaultUrl = process.env.AGENTX_DAEMON_URL || `http://127.0.0.1:${configuredDaemonPort()}`\nasync function post(url: string, path: string, body: unknown) {\n const token = process.env.MESH_TOKEN\n const res = await fetch(url.replace(/\\/$/, \"\") + \"/monitor/\" + path, {\n method: \"POST\", headers: { \"Content-Type\": \"application/json\", ...(token ? { Authorization: `Bearer ${token}` } : {}) },\n body: JSON.stringify(body), signal: AbortSignal.timeout(8000),\n })\n if (!res.ok) throw new Error(`Monitor HTTP ${res.status}: ${(await res.text()).slice(0, 300)}`)\n}\nmonitor.command(\"register\").requiredOption(\"--session <id>\", \"Native session ID\")\n .requiredOption(\"--runtime <name>\", \"claude, codex, gemini, opencode, or another CLI\")\n .requiredOption(\"--label <label>\", \"Human-readable task label\").option(\"--url <url>\", \"Daemon URL\", defaultUrl)\n .action(async opts => {\n try {\n await post(opts.url, \"register\", registrationSchema.parse({ id: opts.session, runtime: opts.runtime, label: opts.label }))\n console.log(\"Session registered. Report each stopped run with agentx monitor ended.\")\n } catch (e: any) { console.error(e.message); process.exitCode = 1 }\n })\nmonitor.command(\"ended\").requiredOption(\"--session <id>\", \"Registered session ID\")\n .requiredOption(\"--run <id>\", \"Stable unique turn ID; reuse this ID when retrying delivery\")\n .requiredOption(\"--transcript <file>\", \"Local transcript file; only the last 90 KB is submitted\")\n .option(\"--url <url>\", \"Daemon URL\", defaultUrl)\n .action(async opts => {\n try {\n const file = await open(opts.transcript, \"r\")\n let transcript: string\n try {\n const stat = await file.stat()\n if (!stat.isFile()) throw new Error(\"Transcript must be a regular file\")\n const bytes = Math.min(stat.size, 90000)\n const buffer = Buffer.alloc(bytes)\n const { bytesRead } = await file.read(buffer, 0, bytes, Math.max(0, stat.size - bytes))\n transcript = (stat.size > bytes ? \"[Transcript truncated: last 90 KB only]\\n\" : \"\") + buffer.subarray(0, bytesRead).toString(\"utf8\")\n } finally { await file.close() }\n await post(opts.url, \"ended\", stopSchema.parse({ sessionId: opts.session, runId: opts.run, transcript }))\n console.log(\"Run queued for review.\")\n } catch (e: any) { console.error(e.message); process.exitCode = 1 }\n })\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\"\nimport { homedir } from \"os\"\nimport { dirname, resolve } from \"path\"\n\n// --- Installing the attach hooks into Claude Code ---\n//\n// Attach mode needs four hook events wired into the human's own Claude Code\n// settings, not into an agent workspace: the whole point is that the session\n// you already have open becomes addressable. So these go to the USER scope\n// (~/.claude/settings.json) and apply to every session on the machine.\n//\n// That sounds invasive; it isn't. The hooks are dumb pipes. They post to the\n// daemon and forward whatever comes back. For the overwhelming majority of\n// sessions — the ones that never run `agentx attach` — the daemon has no\n// binding for them and answers with an empty body, which Claude Code treats\n// as \"carry on\". State lives in the daemon, never in the settings file, so\n// attaching and detaching is a runtime operation with no file edits and no\n// session restart.\n//\n// The same install also carries the PreToolUse guard hook. An attached\n// session answering as a production identity runs under the human's own\n// permissions rather than the agent workspace's settings.json, so without\n// this an attached `peer` would be LESS guarded than a spawned one. That\n// asymmetry is exactly the kind of thing that causes the incident the guard\n// was built for, so the installer refuses to leave it open.\n\nexport const ATTACH_MARKER = \"/attach/\"\nexport const GUARD_MARKER = \"/guard/check\"\n\ntype HookEntry = { matcher?: string; hooks: Array<{ type: string; command: string; timeout?: number }> }\n\n/** One-line curl to the daemon. `--data-binary @-` streams the hook's stdin\n * payload through unread; `|| true` means a stopped daemon degrades to \"no\n * opinion\" instead of erroring in the human's session. */\nfunction hookCommand(route: string, port: string, query = \"\"): string {\n const url = `http://127.0.0.1:${port}${route}${query}`\n return `curl -s --max-time 3 -H 'Content-Type: application/json' --data-binary @- '${url}' 2>/dev/null || true`\n}\n\nfunction entry(route: string, port: string, matcher?: string): HookEntry {\n const e: HookEntry = { hooks: [{ type: \"command\", command: hookCommand(route, port), timeout: 10 }] }\n if (matcher !== undefined) e.matcher = matcher\n return e\n}\n\n/** The hook block attach mode owns, keyed by event name. */\nexport function attachHookBlock(port: string): Record<string, HookEntry[]> {\n return {\n SessionStart: [entry(\"/attach/session-start\", port, \"\")],\n UserPromptSubmit: [entry(\"/attach/prompt\", port)],\n Stop: [entry(\"/attach/stop\", port)],\n SessionEnd: [entry(\"/attach/session-end\", port)],\n }\n}\n\n/** PreToolUse guard, user-scope. Mirrors the per-workspace form in\n * agents/workspace-setup.ts but without an `?agent=` — an attached session's\n * identity is a runtime binding, so the daemon resolves it per call. */\nexport function guardHookEntries(port: string): HookEntry[] {\n const command = hookCommand(\"/guard/check\", port)\n return [\n { matcher: \"Bash\", hooks: [{ type: \"command\", command, timeout: 10 }] },\n { matcher: \"Write|Edit\", hooks: [{ type: \"command\", command, timeout: 10 }] },\n ]\n}\n\nfunction isOurs(e: any, marker: string): boolean {\n return (\n Array.isArray(e?.hooks) &&\n e.hooks.some((h: any) => typeof h?.command === \"string\" && h.command.includes(marker))\n )\n}\n\nexport interface InstallResult {\n path: string\n changed: boolean\n events: string[]\n guardInstalled: boolean\n}\n\nexport function userSettingsPath(): string {\n return resolve(homedir(), \".claude/settings.json\")\n}\n\n/**\n * The port the hooks should call. Read from `node.bind` in agentx.json rather\n * than assumed: this is per-install (18800 on one node here, 19900 on\n * another), and a hook pointed at the wrong port fails silently — `|| true`\n * turns it into \"no opinion\", so a bad default would look like attach mode\n * simply never firing. Falls back to 19900 only when there is no config.\n */\nexport function configuredDaemonPort(root: string = process.cwd()): string {\n for (const dir of [root, resolve(root, \"..\")]) {\n const cfg = resolve(dir, \"agentx.json\")\n if (!existsSync(cfg)) continue\n try {\n const bind = JSON.parse(readFileSync(cfg, \"utf-8\"))?.node?.bind\n const port = String(bind ?? \"\").split(\":\")[1]\n if (port) return port\n } catch {\n /* fall through to the default */\n }\n }\n return \"19900\"\n}\n\n/**\n * Add (or refresh) the attach hooks. Idempotent: existing agentx entries are\n * replaced rather than appended, so a changed port self-heals instead of\n * stacking duplicates. Hooks belonging to anything else are preserved\n * untouched — this file is the human's, and we are a guest in it.\n */\nexport function installAttachHooks(\n port: string,\n opts: { path?: string; withGuard?: boolean } = {},\n): InstallResult {\n const path = opts.path ?? userSettingsPath()\n const withGuard = opts.withGuard !== false\n\n let settings: Record<string, any> = {}\n if (existsSync(path)) {\n try {\n settings = JSON.parse(readFileSync(path, \"utf-8\"))\n } catch (e: any) {\n throw new Error(`${path} is not valid JSON (${e?.message}) — refusing to overwrite it`)\n }\n }\n\n const before = JSON.stringify(settings)\n const hooks = (settings.hooks ??= {})\n const events: string[] = []\n\n for (const [event, desired] of Object.entries(attachHookBlock(port))) {\n const others = Array.isArray(hooks[event])\n ? hooks[event].filter((e: any) => !isOurs(e, ATTACH_MARKER))\n : []\n hooks[event] = [...others, ...desired]\n events.push(event)\n }\n\n let guardInstalled = false\n if (withGuard) {\n const others = Array.isArray(hooks.PreToolUse)\n ? hooks.PreToolUse.filter((e: any) => !isOurs(e, GUARD_MARKER))\n : []\n hooks.PreToolUse = [...others, ...guardHookEntries(port)]\n guardInstalled = true\n }\n\n const changed = JSON.stringify(settings) !== before\n if (changed) {\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, `${JSON.stringify(settings, null, 2)}\\n`)\n }\n return { path, changed, events, guardInstalled }\n}\n\n/** Remove every hook agentx installed. Leaves the rest of the file alone,\n * and drops hook events that end up empty rather than leaving `[]` behind. */\nexport function uninstallAttachHooks(opts: { path?: string; keepGuard?: boolean } = {}): InstallResult {\n const path = opts.path ?? userSettingsPath()\n if (!existsSync(path)) return { path, changed: false, events: [], guardInstalled: false }\n\n let settings: Record<string, any>\n try {\n settings = JSON.parse(readFileSync(path, \"utf-8\"))\n } catch (e: any) {\n throw new Error(`${path} is not valid JSON (${e?.message}) — refusing to rewrite it`)\n }\n\n const before = JSON.stringify(settings)\n const hooks = settings.hooks\n const events: string[] = []\n if (hooks && typeof hooks === \"object\") {\n for (const event of Object.keys(hooks)) {\n if (!Array.isArray(hooks[event])) continue\n const marker = event === \"PreToolUse\" ? GUARD_MARKER : ATTACH_MARKER\n if (event === \"PreToolUse\" && opts.keepGuard !== false) continue\n const kept = hooks[event].filter((e: any) => !isOurs(e, marker))\n if (kept.length !== hooks[event].length) events.push(event)\n if (kept.length === 0) delete hooks[event]\n else hooks[event] = kept\n }\n if (Object.keys(hooks).length === 0) delete settings.hooks\n }\n\n const changed = JSON.stringify(settings) !== before\n if (changed) writeFileSync(path, `${JSON.stringify(settings, null, 2)}\\n`)\n return { path, changed, events, guardInstalled: false }\n}\n\n/** Are our hooks currently present? Used by `agentx attach status` and doctor. */\nexport function attachHooksInstalled(path = userSettingsPath()): boolean {\n if (!existsSync(path)) return false\n try {\n const s = JSON.parse(readFileSync(path, \"utf-8\"))\n return Boolean(s?.hooks?.Stop?.some?.((e: any) => isOurs(e, ATTACH_MARKER)))\n } catch {\n return false\n }\n}\n","import { a2a } from \"@/commands/a2a\"\nimport { desktop } from \"@/commands/desktop\"\nimport { monitor as monitorCmd } from \"@/commands/monitor\"\nimport { Command } from \"commander\"\nimport { daemon } from \"@/commands/daemon\"\nimport { init } from \"@/commands/init\"\nimport { setup } from \"@/commands/setup\"\nimport { token } from \"@/commands/token\"\nimport { doctor } from \"@/commands/doctor\"\nimport { agent, channel, cron, mesh, skillCmd, references, hook, migrate, configCmd } from \"@/commands/manage\"\nimport { db as dbCmd } from \"@/commands/db\"\nimport { ledger as ledgerCmd } from \"@/commands/ledger\"\nimport { decisions as decisionsCmd } from \"@/commands/decisions\"\nimport { trace as traceCmd } from \"@/commands/trace\"\nimport { guard as guardCmd } from \"@/commands/guard\"\nimport { point as pointCmd } from \"@/commands/point\"\nimport { look as lookCmd } from \"@/commands/look\"\nimport { paste as pasteCmd } from \"@/commands/paste\"\nimport { notify as notifyCmd } from \"@/commands/notify\"\nimport { decide as decideCmd } from \"@/commands/decide\"\nimport { teach as teachCmd } from \"@/commands/teach\"\nimport { attach as attachCmd } from \"@/commands/attach\"\nimport { process_ as processCmd } from \"@/commands/process\"\nimport { rag as ragCmd } from \"@/commands/rag\"\nimport { backlog } from \"@/commands/backlog\"\nimport { schedule } from \"@/commands/schedule\"\nimport { connect } from \"@/commands/connect\"\nimport { usage } from \"@/commands/usage\"\nimport { board } from \"@/commands/board\"\nimport { wiki } from \"@/commands/wiki\"\nimport { graph } from \"@/commands/graph\"\nimport { procedure } from \"@/commands/procedure\"\nimport { workflow } from \"@/commands/workflow\"\nimport { webhook } from \"@/commands/webhook\"\nimport { business } from \"@/commands/business\"\nimport { plan } from \"@/commands/plan\"\nimport { notifications } from \"@/commands/notifications\"\nimport { retention } from \"@/commands/retention\"\nimport { actions as actionsCmd } from \"@/commands/actions\"\nimport { watch } from \"@/commands/watch\"\nimport { tui } from \"@/commands/tui\"\nimport { chat } from \"@/commands/chat\"\nimport { memory as memoryCmd } from \"@/commands/memory\"\nimport { serve } from \"@/commands/serve\"\nimport { demo } from \"@/commands/demo\"\nimport { whatsapp } from \"@/commands/whatsapp\"\nimport { plugin as pluginCmd } from \"@/commands/plugin\"\nimport { completion } from \"@/commands/completion\"\nimport { getPackageInfo } from \"@/utils/get-package-info\"\nimport { commandPath, recordSurfaceUse, shouldRecordCommand } from \"@/observability/surface-usage\"\n\n/**\n * Build the full commander tree. Shared between the CLI entrypoint and the\n * `completion` command (which walks the tree to emit a shell completion script).\n */\nexport async function buildProgram(): Promise<Command> {\n const packageInfo = await getPackageInfo()\n\n const program = new Command()\n .name(\"agentx\")\n .description(\n \"self-hosted multi-agent orchestrator — Telegram, WhatsApp, crons, A2A mesh, wiki knowledge\"\n )\n .version(\n packageInfo.version || \"1.0.0\",\n \"-v, --version\",\n \"display the version number\"\n )\n\n // Count which commands operators actually run. Names only — never args.\n // The 46-command surface has no usage data behind it, so decisions about\n // what to keep are currently opinion; this makes them evidence.\n // See docs/architecture/surface-reduction.md.\n program.hook(\"preAction\", (_thisCommand, actionCommand) => {\n const path = commandPath(actionCommand as any)\n if (shouldRecordCommand(path)) recordSurfaceUse(\"cli\", path)\n })\n\n // --- Core: what `agentx --help` shows -----------------------------------\n //\n // Getting set up, running the daemon, and the handful of things an operator\n // reaches for while the fleet is live.\n for (const cmd of [\n setup, init, connect, desktop, // get running\n daemon, doctor, // operate\n agent, channel, schedule, // configure the things that carry work\n attachCmd, monitorCmd, tui, // connect editor sessions and terminal UI\n guardCmd, // safety\n pointCmd, // computer use: point, never click\n lookCmd, // computer use: see state the tree cannot report\n pasteCmd, // clipboard, reshaped for where it lands\n notifyCmd, // tell the operator, unless they are in Focus\n decideCmd, // typed decisions, for agents\n teachCmd, // talk and point, at the same time\n usage, // what it cost, what gets used\n serve, // MCP\n token, configCmd, completion,\n ]) program.addCommand(cmd)\n\n // --- Advanced: registered, documented, hidden from the default help ------\n //\n // 268 commands and subcommands accumulated here. The evidence for cutting\n // the list down is unusually direct: on peer — the node carrying 95% of\n // fleet traffic — `~/.bash_history` contains ZERO `agentx <subcommand>`\n // invocations. Production is operated with systemctl, journalctl, a text\n // editor and the dashboard. The CLI is a development surface.\n //\n // So these are hidden, NOT removed. Every one still runs, still has its own\n // `--help`, and still completes in the shell; they just stop competing for\n // attention with the fifteen commands above. Hiding is reversible in a line\n // and costs nobody anything, which is the right trade while the usage soak\n // is still young — see docs/architecture/surface-reduction.md.\n //\n // The help footer below names them all, so nothing here is secret.\n for (const cmd of ADVANCED) program.addCommand(cmd, { hidden: true })\n\n program.addHelpText(\"after\", () => {\n const names = ADVANCED.map((c) => c.name()).sort()\n return [\n \"\",\n `Advanced (${names.length}, hidden — run \\`agentx <command> --help\\` for any of them):`,\n wrapNames(names, 74, \" \"),\n \"\",\n ].join(\"\\n\")\n })\n\n return program\n}\n\n/** Registered and fully functional, just not in the default help listing. */\nconst ADVANCED = [\n // Knowledge + memory\n wiki, graph, memoryCmd, procedure, references, ragCmd,\n // Workflow / BPM\n workflow, webhook, board, backlog, business, plan,\n // Observability + forensics\n ledgerCmd, decisionsCmd, traceCmd, processCmd, watch, dbCmd,\n // Fleet + extension\n mesh, a2a, skillCmd, pluginCmd, hook, actionsCmd,\n // Scheduling internals (`schedule` is the friendly front door)\n cron,\n // Housekeeping\n migrate, retention, notifications,\n // Channel-specific + demo\n whatsapp, demo,\n // Deprecated — superseded by `agentx attach`\n chat,\n]\n\n/** Pack names into indented lines of at most `width` characters. */\nfunction wrapNames(names: string[], width: number, indent: string): string {\n const lines: string[] = []\n let line = \"\"\n for (const n of names) {\n if (line && (line.length + n.length + 2) > width) {\n lines.push(indent + line)\n line = \"\"\n }\n line += (line ? \", \" : \"\") + n\n }\n if (line) lines.push(indent + line)\n return lines.join(\"\\n\")\n}\n","import { Command } from \"commander\"\nimport { AgentXDaemon } from \"@/daemon\"\nimport { loadDaemonConfig, validateWorkspaces } from \"@/daemon/config\"\nimport chalk from \"chalk\"\nimport { existsSync, readFileSync } from \"fs\"\n\n// --- agentx daemon: start/stop/status/logs ---\n\n/**\n * Best-effort check that a live PID is actually an agentx/node daemon rather\n * than an unrelated process the OS assigned our recycled PID to. Returns true\n * only when the process command line clearly looks like agentx; on any doubt\n * (unknown platform, ps failure) it errs toward true so we never spawn a\n * duplicate daemon on a healthy host.\n */\nasync function isLikelyAgentxProcess(pid: number): Promise<boolean> {\n try {\n const { execFileSync } = await import(\"child_process\")\n // `ps -p <pid> -o command=` works on both macOS and Linux and prints the\n // full command line with no header.\n const cmd = execFileSync(\"ps\", [\"-p\", String(pid), \"-o\", \"command=\"], {\n encoding: \"utf-8\",\n timeout: 2000,\n }).trim()\n if (!cmd) return false // no such process line — treat as stale\n // agentx daemons run as `node .../cli.js daemon ...` (or `agentx daemon`).\n return /\\bnode\\b/.test(cmd) || /agentx|agentix|cli\\.js/.test(cmd)\n } catch {\n // ps unavailable or errored — fall back to the conservative assumption\n // that the PID is a real daemon so we don't double-spawn.\n return true\n }\n}\n\nexport const daemon = new Command()\n .name(\"daemon\")\n .description(\"manage the agentx daemon — start, stop, status, logs\")\n\n// agentx daemon start\ndaemon\n .command(\"start\")\n .description(\"start the daemon (default if no subcommand)\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .option(\"-d, --detach\", \"run in background (detached)\")\n .option(\"--port <port>\", \"override bind port\")\n .action(async (opts) => {\n if (opts.detach) {\n const { spawn } = await import(\"child_process\")\n const { openSync, writeFileSync, existsSync } = await import(\"fs\")\n\n // Use the actual node binary + entrypoint that's running this command.\n // The previous version hardcoded `node dist/cli.js`, which broke for\n // npm-installed users (no dist/cli.js relative to their CWD): the spawn\n // succeeded with a PID, the child crashed immediately on missing module,\n // and stdio:\"ignore\" hid the failure — leaving the operator with a\n // \"Daemon started\" success line and a daemon that was never alive.\n const cli = process.argv[1]\n if (!cli || !existsSync(cli)) {\n console.error(chalk.red(` Cannot resolve agentx CLI entrypoint (process.argv[1]=${cli || \"?\"}).`))\n console.error(chalk.dim(` Try running without --detach to see the underlying error.`))\n process.exit(1)\n }\n const args = [cli, \"daemon\", \"start\"]\n if (opts.config) args.push(\"-c\", opts.config)\n if (opts.port) args.push(\"--port\", opts.port)\n\n // Open the log file and pipe child stdout+stderr into it. Without this\n // (the previous code did stdio:\"ignore\"), every detach-mode crash was\n // invisible — the user was told to `tail -f /tmp/agentx-daemon.log`,\n // but nothing ever wrote to that path, so the file didn't exist.\n const logPath = \"/tmp/agentx-daemon.log\"\n let logFd: number\n try {\n logFd = openSync(logPath, \"a\")\n } catch (e: any) {\n console.error(chalk.red(` Failed to open ${logPath} for writing: ${e.message}`))\n process.exit(1)\n }\n\n const child = spawn(process.execPath, args, {\n detached: true,\n stdio: [\"ignore\", logFd, logFd],\n cwd: process.cwd(),\n })\n child.unref()\n\n writeFileSync(\"/tmp/agentx-daemon.pid\", String(child.pid))\n console.log(chalk.green(`Daemon started in background (PID: ${child.pid})`))\n console.log(chalk.dim(` Logs: tail -f ${logPath}`))\n console.log(chalk.dim(` Stop: agentx daemon stop`))\n // Brief sanity probe — if the child died in the first 1s (e.g. claude\n // CLI missing, port already bound, config invalid), tell the operator\n // to look at the log file rather than letting them discover it after\n // `agentx daemon watch` fails 30 seconds later.\n await new Promise((ok) => setTimeout(ok, 1000))\n try {\n process.kill(child.pid!, 0)\n } catch {\n console.log()\n console.log(chalk.yellow(` Daemon exited within 1s — check ${logPath} for the error:`))\n console.log(chalk.dim(` tail -n 40 ${logPath}`))\n }\n return\n }\n\n // Single-instance guard — only one daemon can run at a time.\n // If another process is alive with the recorded PID, exit immediately.\n const { readFileSync, writeFileSync, mkdirSync, existsSync } = await import(\"fs\")\n const { resolve } = await import(\"path\")\n const lockDir = resolve(process.cwd(), \".agentx\")\n if (!existsSync(lockDir)) mkdirSync(lockDir, { recursive: true })\n const pidPath = resolve(lockDir, \"daemon.pid\")\n\n if (existsSync(pidPath)) {\n const oldPid = parseInt(readFileSync(pidPath, \"utf-8\").trim(), 10)\n if (oldPid && oldPid !== process.pid) {\n let alive = false\n try {\n process.kill(oldPid, 0) // throws if process doesn't exist\n alive = true\n } catch {\n // Old process is dead — we can proceed\n }\n // A bare kill(pid, 0) only proves *some* process holds that PID.\n // PIDs get recycled — the OS may have reassigned our old PID to an\n // unrelated process (e.g. a macOS system extension), which would\n // wedge startup forever behind a false \"already running\". Confirm\n // the live PID is actually a node/agentx process before yielding.\n if (alive && (await isLikelyAgentxProcess(oldPid))) {\n console.error(`Another agentx daemon is already running (PID ${oldPid}). Exiting.`)\n process.exit(0)\n }\n }\n }\n writeFileSync(pidPath, String(process.pid))\n\n // Auto-load .env from the working directory so `{{env.FOO}}` in\n // workflows + agent prompts just works without editing systemd\n // units. Existing process.env values win — we never overwrite what\n // the runtime was launched with.\n try { loadDotenv(resolve(process.cwd(), \".env\")) } catch { /* best effort */ }\n\n const d = new AgentXDaemon(opts.config)\n await d.start()\n })\n\n/** Minimal .env parser: KEY=VALUE lines. Quotes around the value are\n * stripped. Blank lines + comments ignored. No substitution, no export\n * keyword — we don't want to pull dotenv for this. Variables already in\n * process.env take precedence so a systemd override always wins. */\nfunction loadDotenv(path: string): void {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n if (!existsSync(path)) return\n const text = readFileSync(path, \"utf-8\")\n for (const raw of text.split(\"\\n\")) {\n const line = raw.trim()\n if (!line || line.startsWith(\"#\")) continue\n const eq = line.indexOf(\"=\")\n if (eq < 0) continue\n const key = line.slice(0, eq).trim()\n if (!key || process.env[key] !== undefined) continue\n let val = line.slice(eq + 1).trim()\n if ((val.startsWith(\"\\\"\") && val.endsWith(\"\\\"\")) || (val.startsWith(\"'\") && val.endsWith(\"'\"))) {\n val = val.slice(1, -1)\n }\n process.env[key] = val\n }\n}\n\n// agentx daemon stop\ndaemon\n .command(\"stop\")\n .description(\"stop the running daemon\")\n .action(async () => {\n const { readFileSync, existsSync, unlinkSync } = await import(\"fs\")\n const { resolve } = await import(\"path\")\n\n // Check both PID file locations\n const pidFiles = [\n resolve(process.cwd(), \".agentx/daemon.pid\"),\n \"/tmp/agentx-daemon.pid\",\n ]\n\n for (const pidFile of pidFiles) {\n if (!existsSync(pidFile)) continue\n try {\n const pid = parseInt(readFileSync(pidFile, \"utf-8\").trim(), 10)\n process.kill(pid, \"SIGTERM\")\n // Wait briefly for graceful shutdown\n await new Promise(r => setTimeout(r, 2000))\n try { unlinkSync(pidFile) } catch {}\n console.log(chalk.green(`Daemon stopped (PID: ${pid})`))\n return\n } catch {\n try { unlinkSync(pidFile) } catch {}\n }\n }\n\n // Fallback: kill by process name\n const { execSync } = await import(\"child_process\")\n try {\n execSync(\"pkill -f 'node dist/cli.js daemon'\", { stdio: \"ignore\" })\n console.log(chalk.green(\"Daemon stopped\"))\n } catch {\n console.log(chalk.yellow(\"No daemon process found\"))\n }\n })\n\n// agentx daemon status\ndaemon\n .command(\"status\")\n .alias(\"st\")\n .description(\"show daemon status, agents, crons, and mesh\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .option(\"--json\", \"output as JSON\")\n .action(async (opts) => {\n // Try connecting to running daemon first\n try {\n const config = loadDaemonConfig(opts.config)\n const [host, port] = config.node.bind.split(\":\")\n const url = `http://${host || \"127.0.0.1\"}:${port}/health`\n const res = await fetch(url, { signal: AbortSignal.timeout(3000) })\n const data = await res.json() as any\n\n if (opts.json) {\n console.log(JSON.stringify(data, null, 2))\n return\n }\n\n console.log()\n console.log(chalk.bold(` ${data.node.name}`) + chalk.dim(` (${data.node.id})`))\n console.log(chalk.green(\" Status: running\") + chalk.dim(` — uptime ${formatDuration(data.uptime)}`))\n console.log()\n\n // Agents\n console.log(chalk.bold(\" Agents:\"))\n for (const a of data.agents) {\n const active = a.active > 0 ? chalk.yellow(` [${a.active} active]`) : \"\"\n const errors = a.errors > 0 ? chalk.red(` (${a.errors} errors)`) : \"\"\n console.log(` ${chalk.cyan(a.name)} ${chalk.dim(`(${a.tier})`)}${active}${errors}`)\n console.log(chalk.dim(` ${a.workspace}`))\n }\n\n // Crons\n const enabledCrons = data.crons.filter((c: any) => c.enabled)\n if (data.crons.length) {\n console.log()\n console.log(chalk.bold(` Crons: ${enabledCrons.length} enabled / ${data.crons.length} total`))\n for (const c of data.crons) {\n const icon = c.enabled ? chalk.green(\"●\") : chalk.dim(\"○\")\n const next = c.nextRun ? chalk.dim(` next: ${new Date(c.nextRun).toLocaleTimeString()}`) : \"\"\n console.log(` ${icon} ${c.id}${next}`)\n }\n }\n\n // Mesh\n if (data.mesh?.length) {\n console.log()\n console.log(chalk.bold(\" Mesh:\"))\n for (const p of data.mesh) {\n const icon = p.healthy ? chalk.green(\"●\") : chalk.red(\"●\")\n const skills = p.skills?.length ? chalk.dim(` (${p.skills.length} agents)`) : \"\"\n console.log(` ${icon} ${p.peer} ${chalk.dim(p.peerUrl)}${skills}`)\n }\n }\n\n console.log()\n } catch (e: any) {\n if (e.cause?.code === \"ECONNREFUSED\" || e.name === \"TimeoutError\") {\n console.log(chalk.red(\" Daemon is not running\"))\n console.log(chalk.dim(\" Start with: agentx daemon start\"))\n } else {\n // No running daemon — show config info\n try {\n const config = loadDaemonConfig(opts.config)\n const warnings = validateWorkspaces(config)\n console.log()\n console.log(chalk.bold(` ${config.node.name}`) + chalk.dim(` (${config.node.id})`))\n console.log(chalk.yellow(\" Status: stopped\"))\n console.log(chalk.dim(` ${Object.keys(config.agents).length} agents, ${Object.keys(config.crons).length} crons configured`))\n if (warnings.length) {\n console.log()\n for (const w of warnings) console.log(chalk.yellow(` ⚠ ${w}`))\n }\n console.log()\n } catch (err: any) {\n console.log(chalk.red(` ${err.message}`))\n }\n }\n }\n })\n\n// agentx daemon logs\ndaemon\n .command(\"logs\")\n .description(\"tail daemon logs\")\n .option(\"-n, --lines <n>\", \"number of lines\", \"50\")\n .option(\"-f, --follow\", \"follow log output\", false)\n .action(async (opts) => {\n const { execSync, spawn: spawnProc } = await import(\"child_process\")\n const logFile = \"/tmp/agentx-daemon.log\"\n\n const { existsSync } = await import(\"fs\")\n if (!existsSync(logFile)) {\n console.log(chalk.yellow(\"No log file found at /tmp/agentx-daemon.log\"))\n return\n }\n\n if (opts.follow) {\n const tail = spawnProc(\"tail\", [\"-f\", \"-n\", opts.lines, logFile], { stdio: \"inherit\" })\n process.on(\"SIGINT\", () => { tail.kill(); process.exit(0) })\n } else {\n execSync(`tail -n ${opts.lines} ${logFile}`, { stdio: \"inherit\" })\n }\n })\n\n// agentx daemon watch — live stream of agent activity\ndaemon\n .command(\"watch\")\n .description(\"stream live agent activity (SSE)\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .action(async (opts) => {\n const config = loadDaemonConfig(opts.config)\n const bind = config.node.bind || \"127.0.0.1:18800\"\n const url = `http://${bind.replace(\"0.0.0.0\", \"127.0.0.1\")}/events`\n\n console.log(chalk.dim(` Connecting to ${url}...`))\n console.log(chalk.dim(\" Press Ctrl+C to stop\\n\"))\n\n try {\n const res = await fetch(url)\n if (!res.ok || !res.body) {\n console.log(chalk.red(` Failed: ${res.status}`))\n return\n }\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buffer = \"\"\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split(\"\\n\")\n buffer = lines.pop() || \"\"\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const data = JSON.parse(line.slice(6))\n const time = new Date(data.time).toLocaleTimeString()\n const msg = data.message?.replace(/^\\[agentx\\]\\s*/, \"\") || \"\"\n // Color-code by content\n if (msg.includes(\"executing\")) console.log(`${chalk.dim(time)} ${chalk.cyan(\"▶\")} ${msg}`)\n else if (msg.includes(\"completed\")) console.log(`${chalk.dim(time)} ${chalk.green(\"✓\")} ${msg}`)\n else if (msg.includes(\"error\") || msg.includes(\"Error\")) console.log(`${chalk.dim(time)} ${chalk.red(\"✗\")} ${msg}`)\n else if (msg.includes(\"Routing\")) console.log(`${chalk.dim(time)} ${chalk.yellow(\"→\")} ${msg}`)\n else if (msg.includes(\"mention\")) console.log(`${chalk.dim(time)} ${chalk.magenta(\"@\")} ${msg}`)\n else if (msg.includes(\"Skipping\")) console.log(`${chalk.dim(time)} ${chalk.dim(\"⊘\")} ${chalk.dim(msg)}`)\n else console.log(`${chalk.dim(time)} ${msg}`)\n } catch { /* skip malformed */ }\n } else if (line.startsWith(\"event: status\")) {\n // First event — show current state\n }\n }\n }\n } catch (e: any) {\n console.log(chalk.red(` Connection failed: ${e.message}`))\n console.log(chalk.dim(\" Is the daemon running? Diagnostic order:\"))\n console.log(chalk.dim(\" 1) agentx daemon status # is the daemon up?\"))\n console.log(chalk.dim(\" 2) tail -n 60 /tmp/agentx-daemon.log # detach-mode crash log\"))\n console.log(chalk.dim(\" 3) journalctl -u agentx -n 60 # systemd-managed installs\"))\n console.log(chalk.dim(\" If the log file is missing, the daemon never started — re-run without --detach\"))\n console.log(chalk.dim(\" to see the error in the foreground.\"))\n }\n })\n\n// agentx daemon send — send a task to an agent\ndaemon\n .command(\"send <agent> <message...>\")\n .description(\"send a task to an agent via the daemon API\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .option(\"--peer <peer>\", \"send to a mesh peer's agent\")\n .option(\"--json\", \"output raw JSON response\")\n .action(async (agent, messageParts, opts) => {\n const message = messageParts.join(\" \")\n\n try {\n const config = loadDaemonConfig(opts.config)\n const [host, port] = config.node.bind.split(\":\")\n const baseUrl = `http://${host || \"127.0.0.1\"}:${port}`\n\n let url: string\n let body: Record<string, unknown>\n\n if (opts.peer) {\n url = `${baseUrl}/mesh/task`\n body = { peer: opts.peer, message, agent }\n } else {\n url = `${baseUrl}/task`\n body = { agent, message }\n }\n\n console.log(chalk.dim(` Sending to ${opts.peer ? `${opts.peer}/${agent}` : agent}...`))\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n })\n\n const data = await res.json() as any\n\n if (opts.json) {\n console.log(JSON.stringify(data, null, 2))\n } else if (data.error) {\n console.log(chalk.red(` Error: ${data.error}`))\n } else {\n console.log()\n console.log(data.content || data.response || \"No response\")\n if (data.duration) {\n console.log(chalk.dim(`\\n (${(data.duration / 1000).toFixed(1)}s)`))\n }\n }\n } catch (e: any) {\n console.log(chalk.red(` Failed: ${e.message}`))\n console.log(chalk.dim(\" Is the daemon running? Try: agentx daemon status\"))\n }\n })\n\n// agentx daemon deploy — rsync dist to a remote server\ndaemon\n .command(\"deploy <host>\")\n .description(\"deploy agentx to a remote server via rsync\")\n .option(\"-i, --identity <key>\", \"SSH identity file\")\n .option(\"-u, --user <user>\", \"SSH user\", \"root\")\n .option(\"-p, --path <path>\", \"remote agentx path\", \"~/agentx\")\n .option(\"--restart\", \"restart remote daemon after deploy\", false)\n .option(\"--skip-checks\", \"skip build and test before deploy\", false)\n .action(async (host, opts) => {\n const { execSync } = await import(\"child_process\")\n const sshKey = opts.identity ? `-e \"ssh -i ${opts.identity}\"` : \"\"\n const remote = `${opts.user}@${host}:${opts.path}/dist/`\n\n // Pre-deploy checks\n if (!opts.skipChecks) {\n try {\n console.log(chalk.dim(\" Running tests...\"))\n execSync(\"npx vitest run --reporter=dot\", { stdio: \"pipe\", cwd: process.cwd() })\n console.log(chalk.green(\" ✓ Tests passed\"))\n } catch (e: any) {\n console.log(chalk.red(\" ✗ Tests failed — aborting deploy\"))\n console.log(chalk.dim(\" Use --skip-checks to deploy anyway\"))\n return\n }\n\n // Check dist exists and is recent\n const { existsSync, statSync } = await import(\"fs\")\n const { resolve } = await import(\"path\")\n const cliPath = resolve(process.cwd(), \"dist/cli.js\")\n if (!existsSync(cliPath)) {\n console.log(chalk.red(\" ✗ dist/ not found — run build first\"))\n return\n }\n const age = Date.now() - statSync(cliPath).mtimeMs\n if (age > 300_000) {\n console.log(chalk.yellow(\" ⚠ dist/ is older than 5 minutes — rebuilding...\"))\n execSync(\"npx tsup --no-dts\", { stdio: \"pipe\", cwd: process.cwd() })\n console.log(chalk.green(\" ✓ Build complete\"))\n }\n }\n\n console.log(chalk.dim(` Deploying to ${opts.user}@${host}:${opts.path}...`))\n\n try {\n execSync(`rsync -avzL --delete ${sshKey} dist/ ${remote}`, {\n stdio: \"inherit\",\n cwd: process.cwd(),\n })\n console.log(chalk.green(\" ✓ Deploy complete\"))\n\n if (opts.restart) {\n console.log(chalk.dim(\" Restarting remote daemon...\"))\n const ssh = opts.identity ? `ssh -i ${opts.identity}` : \"ssh\"\n execSync(\n `${ssh} ${opts.user}@${host} \"pkill -f 'node dist/cli.js daemon' 2>/dev/null; sleep 2; cd ${opts.path} && nohup node dist/cli.js daemon start > /tmp/agentx-daemon.log 2>&1 &\"`,\n { stdio: \"inherit\" },\n )\n console.log(chalk.green(\" Remote daemon restarted\"))\n }\n } catch (e: any) {\n console.log(chalk.red(` Deploy failed: ${e.message}`))\n }\n })\n\n// Default: `agentx daemon` without subcommand starts the daemon\ndaemon.action(async (opts) => {\n const d = new AgentXDaemon(opts.config)\n await d.start()\n})\n\nfunction formatDuration(seconds: number): string {\n if (seconds < 60) return `${Math.round(seconds)}s`\n if (seconds < 3600) return `${Math.round(seconds / 60)}m`\n if (seconds < 86400) return `${Math.round(seconds / 3600)}h ${Math.round((seconds % 3600) / 60)}m`\n return `${Math.round(seconds / 86400)}d ${Math.round((seconds % 86400) / 3600)}h`\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from \"fs\"\nimport { hostname } from \"os\"\nimport { resolve, join } from \"path\"\n\n// --- agentx init: interactive setup for new installations ---\n\nexport const init = new Command()\n .name(\"init\")\n .description(\"initialize agentx configuration in the current directory\")\n .option(\"--force\", \"overwrite existing config\")\n .action(async (opts) => {\n const cwd = process.cwd()\n const configPath = resolve(cwd, \"agentx.json\")\n const envPath = resolve(cwd, \".env\")\n const sessionsDir = resolve(cwd, \".agentx/sessions\")\n\n console.log()\n console.log(chalk.bold(\" agentx init\"))\n console.log()\n\n // Check existing config\n if (existsSync(configPath) && !opts.force) {\n console.log(chalk.yellow(` agentx.json already exists. Use --force to overwrite.`))\n console.log()\n return\n }\n\n // Find example config\n const examplePaths = [\n resolve(cwd, \"agentx.example.json\"),\n resolve(cwd, \"node_modules/agentix-cli/agentx.example.json\"),\n ]\n\n let example: string | undefined\n for (const p of examplePaths) {\n if (existsSync(p)) {\n example = readFileSync(p, \"utf-8\")\n break\n }\n }\n\n if (!example) {\n // Generate minimal config\n example = JSON.stringify({\n node: {\n id: hostname().toLowerCase().replace(/[^a-z0-9-]/g, \"-\"),\n name: hostname(),\n bind: \"127.0.0.1:18800\",\n },\n providers: {\n claude: { apiKey: \"${ANTHROPIC_API_KEY}\" },\n },\n agents: {\n assistant: {\n name: \"Assistant\",\n workspace: cwd,\n tier: \"claude-code\",\n model: \"claude-sonnet-4-6\",\n mentions: [\"@assistant\", \"assistant\"],\n maxConcurrent: 2,\n systemPrompt: \"You are a helpful assistant.\",\n permissionMode: \"default\",\n },\n },\n channels: {\n telegram: {\n enabled: false,\n accounts: {},\n policy: { dm: \"pair\", group: \"mention-required\" },\n },\n whatsapp: { enabled: false },\n },\n crons: {},\n mesh: {\n enabled: false,\n peers: [],\n discovery: \"static\",\n healthCheck: { interval: 60, timeout: 10 },\n },\n }, null, 2)\n }\n\n // Write config\n writeFileSync(configPath, example)\n console.log(chalk.green(` ✓ Created agentx.json`))\n\n // Create .env template\n if (!existsSync(envPath)) {\n writeFileSync(envPath, [\n \"# AgentX environment variables\",\n \"# ANTHROPIC_API_KEY=sk-ant-...\",\n \"# TG_BOT_TOKEN=123456:ABC...\",\n \"# MESH_TOKEN=your-mesh-secret\",\n \"\",\n ].join(\"\\n\"))\n console.log(chalk.green(` ✓ Created .env template`))\n }\n\n // Create session dir\n if (!existsSync(sessionsDir)) {\n mkdirSync(sessionsDir, { recursive: true })\n console.log(chalk.green(` ✓ Created .agentx/sessions/`))\n }\n\n // Create workspace .claude dir\n const claudeDir = resolve(cwd, \".claude\")\n if (!existsSync(claudeDir)) {\n mkdirSync(claudeDir, { recursive: true })\n console.log(chalk.green(` ✓ Created .claude/`))\n }\n\n console.log()\n console.log(chalk.bold(\" Next steps:\"))\n console.log(` 1. Edit ${chalk.cyan(\"agentx.json\")} — configure agents, channels, crons`)\n console.log(` 2. Edit ${chalk.cyan(\".env\")} — add API keys and bot tokens`)\n console.log(` 3. Run ${chalk.cyan(\"agentx daemon start\")} — start the daemon`)\n console.log(` 4. Run ${chalk.cyan(\"agentx daemon status\")} — verify everything`)\n console.log()\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { spawn } from \"child_process\"\nimport { existsSync } from \"fs\"\nimport { dirname, resolve } from \"path\"\nimport { fileURLToPath } from \"url\"\nimport { wizardState } from \"@/daemon/setup-wizard\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx setup: launch the web setup wizard ---\n//\n// The wizard itself is a web form served by the board-dashboard process (on\n// port 4202). This command starts that process (if it isn't already running)\n// and opens the wizard URL in the user's default browser — zero CLI prompts.\n\nexport const setup = new Command()\n .name(\"setup\")\n .description(\"open the web setup wizard to create or extend your AgentX install\")\n .option(\"--port <n>\", \"dashboard port (default: from agentx.json, else 4202)\")\n .option(\"--no-open\", \"don't try to open the browser\")\n .action(async (opts) => {\n const state = wizardState()\n const port = opts.port ? parseInt(opts.port, 10) : resolveDashboardPort()\n const url = `http://127.0.0.1:${port}/setup`\n\n console.log()\n if (state.configExists) {\n console.log(chalk.dim(` Found agentx.json — the wizard will extend your current install.`))\n } else {\n console.log(chalk.dim(` No agentx.json yet — the wizard will create one.`))\n }\n console.log(chalk.bold(` Opening ${url}`))\n console.log()\n\n // If the board server isn't already listening, start it in the background.\n const alreadyUp = await probe(url).catch(() => false)\n if (!alreadyUp) {\n console.log(chalk.dim(` Starting dashboard server on port ${port} (Ctrl-C to quit)…`))\n const cli = resolveCliEntry()\n const child = spawn(process.execPath, [cli, \"board\", \"serve\", \"--port\", String(port)], {\n stdio: \"inherit\",\n detached: false,\n })\n // Give the server a beat to bind before opening the browser.\n await new Promise((ok) => setTimeout(ok, 1200))\n if (opts.open !== false) openBrowser(url)\n // Stay attached so the user sees the server logs.\n await new Promise<void>((ok) => child.on(\"exit\", () => ok()))\n } else {\n console.log(chalk.dim(` Dashboard is already running.`))\n if (opts.open !== false) openBrowser(url)\n }\n })\n\nfunction resolveDashboardPort(): number {\n try {\n const cfg = loadDaemonConfig()\n return cfg.dashboard.port || 4202\n } catch {\n return 4202\n }\n}\n\nfunction resolveCliEntry(): string {\n // When installed via npm, this module runs from dist/; cli.js sits beside it.\n // The bundle is ESM, so CommonJS __dirname is not defined.\n // In dev, we fall back to the current script so `tsx` works too.\n const candidate = resolve(dirname(fileURLToPath(import.meta.url)), \"cli.js\")\n return existsSync(candidate) ? candidate : (process.argv[1] || candidate)\n}\n\nasync function probe(url: string): Promise<boolean> {\n try {\n const r = await fetch(url, { method: \"GET\" })\n return r.ok || r.status === 302\n } catch { return false }\n}\n\nfunction openBrowser(url: string): void {\n const cmd = process.platform === \"darwin\" ? \"open\"\n : process.platform === \"win32\" ? \"start\"\n : \"xdg-open\"\n try {\n // spawn() reports a missing binary (ENOENT) via an async \"error\" event on\n // the child, NOT a synchronous throw — so the try/catch alone wouldn't\n // catch it. Headless Linux servers commonly lack xdg-open; without the\n // listener the unhandled error propagates and kills the wizard process.\n const child = spawn(cmd, [url], { stdio: \"ignore\", detached: true })\n child.once(\"error\", () => {\n console.log(chalk.dim(` Couldn't auto-open the browser. Visit ${url} manually.`))\n })\n child.unref()\n } catch {\n console.log(chalk.dim(` Couldn't auto-open the browser. Visit ${url} manually.`))\n }\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { TokenStore } from \"@/daemon/token-store\"\n\n// --- agentx token: mint / list / revoke scoped API tokens ---\n\nexport const token = new Command()\n .name(\"token\")\n .description(\"scoped API tokens for external access (mesh peers, integrations)\")\n\ntoken\n .command(\"create\")\n .description(\"mint a new token — prints the secret once, store it somewhere safe\")\n .requiredOption(\"--name <name>\", \"human-readable label (e.g. 'Slack integration')\")\n .option(\"--scope <scopes>\", \"comma-separated scopes (default: dashboard:read)\", \"dashboard:read\")\n .option(\"--expires <days>\", \"expire after N days (default: no expiry)\")\n .action((opts) => {\n try {\n const store = new TokenStore()\n const scopes = String(opts.scope).split(\",\").map((s) => s.trim()).filter(Boolean)\n const days = opts.expires ? parseInt(opts.expires, 10) : undefined\n if (opts.expires && (!days || days < 1)) throw new Error(\"--expires must be a positive integer (days)\")\n const { token: secret, record } = store.create({ name: opts.name, scopes, expiresInDays: days })\n console.log()\n console.log(chalk.bold(\" Token created.\"))\n console.log()\n console.log(` id: ${chalk.cyan(record.id)}`)\n console.log(` name: ${record.name}`)\n console.log(` scopes: ${record.scopes.join(\", \")}`)\n console.log(` expires: ${record.expiresAt || chalk.dim(\"never\")}`)\n console.log()\n console.log(chalk.yellow(\" ⚠ This is the only time the full secret will be shown.\"))\n console.log()\n console.log(` ${chalk.green.bold(secret)}`)\n console.log()\n console.log(chalk.dim(\" Use it via the Authorization header:\"))\n console.log(chalk.dim(` curl -H \"Authorization: Bearer ${secret.slice(0, 16)}...\" ...`))\n console.log()\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\ntoken\n .command(\"list\")\n .alias(\"ls\")\n .description(\"show all issued tokens (secrets not included)\")\n .action(() => {\n try {\n const records = new TokenStore().list()\n if (records.length === 0) {\n console.log(chalk.dim(\"\\n No tokens issued.\\n\"))\n return\n }\n console.log()\n for (const r of records) {\n const status = r.revokedAt\n ? chalk.red(\"revoked\")\n : r.expiresAt && Date.parse(r.expiresAt) < Date.now()\n ? chalk.red(\"expired\")\n : chalk.green(\"active\")\n console.log(` ${chalk.cyan(r.id)} ${status} ${r.name}`)\n console.log(chalk.dim(` prefix: ${r.prefix}… scopes: ${r.scopes.join(\", \")}`))\n console.log(chalk.dim(` created: ${r.createdAt}${r.expiresAt ? ` expires: ${r.expiresAt}` : \"\"}${r.lastUsedAt ? ` last used: ${r.lastUsedAt}` : \"\"}`))\n }\n console.log()\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\ntoken\n .command(\"revoke <id>\")\n .description(\"immediately invalidate a token\")\n .action((id: string) => {\n try {\n const rec = new TokenStore().revoke(id)\n if (!rec) {\n console.log(chalk.red(` Token ${id} not found.`))\n process.exit(1)\n }\n console.log(chalk.green(`\\n ✓ Revoked ${id} (${rec.name})\\n`))\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport prompts from \"prompts\"\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, cpSync, readdirSync } from \"fs\"\nimport { resolve, join, dirname } from \"path\"\nimport { fileURLToPath } from \"url\"\nimport { loadDaemonConfig, validateWorkspaces } from \"@/daemon/config\"\nimport { applyConfigMutation } from \"@/daemon/config-mutator\"\n\n// --- agentx agent/channel/cron/mesh/skill/hook management commands ---\n\nfunction loadConfig(): any {\n const p = resolve(process.cwd(), \"agentx.json\")\n if (!existsSync(p)) throw new Error(\"No agentx.json found. Run: agentx init\")\n return JSON.parse(readFileSync(p, \"utf-8\"))\n}\n\n/**\n * Persist a mutated config. Goes through applyConfigMutation so every caller\n * gets pre-save Zod validation and an automatic daemon hot-reload when one is\n * running. Returns a promise; callers inside async .action handlers should\n * await it so the reload signal lands before the CLI process exits.\n */\nfunction saveConfig(config: any): Promise<void> {\n return applyConfigMutation((current) => {\n for (const k of Object.keys(current)) delete current[k]\n Object.assign(current, config)\n }).then((result) => {\n if (!result.success) {\n console.error(chalk.red(` Config save failed: ${result.error}`))\n return\n }\n if (result.reloaded) {\n console.error(chalk.dim(\" (daemon hot-reloaded)\"))\n } else if (result.reloadSkipped && !/ECONNREFUSED|unreachable|fetch failed/i.test(result.reloadSkipped)) {\n console.error(chalk.dim(` (daemon reload skipped: ${result.reloadSkipped})`))\n }\n })\n}\n\n// ==================== agentx agent ====================\n\nexport const agent = new Command()\n .name(\"agent\")\n .description(\"manage agents — add, list, remove\")\n\nagent\n .command(\"list\")\n .alias(\"ls\")\n .description(\"list configured agents\")\n .action(() => {\n const config = loadConfig()\n console.log()\n for (const [id, a] of Object.entries(config.agents || {}) as any) {\n const mentions = a.mentions?.join(\", \") || \"\"\n console.log(` ${chalk.cyan(id)} — ${a.name} (${a.tier})`)\n console.log(chalk.dim(` workspace: ${a.workspace}`))\n if (mentions) console.log(chalk.dim(` mentions: ${mentions}`))\n }\n console.log()\n })\n\nagent\n .command(\"add\")\n .description(\"add a new agent interactively\")\n .action(async () => {\n const config = loadConfig()\n\n const answers = await prompts([\n { type: \"text\", name: \"id\", message: \"Agent ID (kebab-case)\", validate: (v: string) => /^[a-z0-9-]+$/.test(v) || \"Use lowercase, numbers, hyphens\" },\n { type: \"text\", name: \"name\", message: \"Display name\" },\n { type: \"text\", name: \"workspace\", message: \"Workspace path\", initial: resolve(process.cwd(), \"agents/\") },\n { type: \"select\", name: \"tier\", message: \"Execution tier\", choices: [\n { title: \"claude-code (subscription, full features)\", value: \"claude-code\" },\n { title: \"codex-cli (OpenAI Codex CLI)\", value: \"codex-cli\" },\n { title: \"opencode (configured OpenCode providers)\", value: \"opencode\" },\n { title: \"sdk (API key, programmatic)\", value: \"sdk\" },\n { title: \"orchestrator (any provider)\", value: \"orchestrator\" },\n ]},\n { type: \"text\", name: \"model\", message: \"Model\", initial: \"claude-sonnet-4-6\" },\n { type: \"list\", name: \"mentions\", message: \"Mention patterns (comma-separated)\", separator: \",\" },\n { type: \"number\", name: \"maxConcurrent\", message: \"Max concurrent tasks\", initial: 2 },\n { type: \"text\", name: \"systemPrompt\", message: \"System prompt\" },\n ])\n\n if (!answers.id) return\n\n // Create workspace + .claude dir\n const ws = answers.workspace.endsWith(answers.id) ? answers.workspace : join(answers.workspace, answers.id)\n mkdirSync(resolve(ws, \".claude/skills\"), { recursive: true })\n\n const agentDef = {\n name: answers.name,\n workspace: ws,\n tier: answers.tier,\n model: answers.model,\n mentions: answers.mentions?.map((m: string) => m.trim()).filter(Boolean) || [],\n maxConcurrent: answers.maxConcurrent,\n systemPrompt: answers.systemPrompt,\n permissionMode: \"default\",\n }\n\n // Set up workspace with Claude Code best practices\n // (CLAUDE.md, AGENTS.md, .claude/settings.json, .claude/rules/)\n const { setupWorkspace } = await import(\"@/agents/workspace-setup\")\n const setup = setupWorkspace(answers.id, agentDef as any, \"19900\", (...args: unknown[]) => {\n console.log(chalk.dim(` ${args.join(\" \")}`))\n })\n\n // Install wiki skill\n const wikiSkillSrc = resolve(process.cwd(), \"src/wiki/SKILL.md\")\n const wikiSkillDist = resolve(dirname(fileURLToPath(import.meta.url)), \"../wiki/SKILL.md\")\n const skillSrc = existsSync(wikiSkillSrc) ? wikiSkillSrc : wikiSkillDist\n if (existsSync(skillSrc)) {\n mkdirSync(resolve(ws, \".claude/skills/wiki\"), { recursive: true })\n cpSync(skillSrc, resolve(ws, \".claude/skills/wiki/SKILL.md\"))\n }\n\n // Add to config\n config.agents = config.agents || {}\n config.agents[answers.id] = agentDef\n\n await saveConfig(config)\n console.log(chalk.green(`\\n Agent \"${answers.id}\" added`))\n console.log(chalk.dim(` Workspace: ${ws}`))\n console.log(chalk.dim(` Created: ${setup.created.length} files (CLAUDE.md, AGENTS.md, settings, rules)`))\n console.log()\n })\n\nagent\n .command(\"remove <id>\")\n .alias(\"rm\")\n .description(\"remove an agent from config (keeps workspace)\")\n .action(async (id) => {\n const config = loadConfig()\n if (!config.agents?.[id]) {\n console.log(chalk.red(` Agent \"${id}\" not found`))\n return\n }\n delete config.agents[id]\n await saveConfig(config)\n console.log(chalk.green(` Agent \"${id}\" removed from config (workspace preserved)`))\n })\n\n// agentx agent capability — set intents / maxDelegationDepth / contextReferences /\n// contextStrategy without hand-editing agentx.json. These are the Phase 5/8 fields\n// the second-pass parity audit flagged as CLI-only-via-JSON.\nagent\n .command(\"capability <id>\")\n .alias(\"caps\")\n .description(\"set agent capability flags (intents, maxDelegationDepth, contextReferences, contextStrategy)\")\n .option(\"--intents <csv>\", \"comma-separated intent allow-list (set to '-' to clear)\")\n .option(\"--max-delegation-depth <n>\", \"max distinct upstream agents on the same subject before refusal (0 disables)\")\n .option(\"--context-references <bool>\", \"render the deterministic [Verified References] block (true|false)\")\n .option(\"--context-strategy <name>\", \"per-agent override: layered | planner\")\n .option(\"--max-execution-minutes <n>\", \"wall-clock cap on a single Claude Code call (1–240)\")\n .option(\"--show\", \"just print the current capability fields\")\n .action(async (id: string, opts) => {\n const config = loadConfig()\n const a = config.agents?.[id]\n if (!a) { console.log(chalk.red(` Agent \"${id}\" not found`)); process.exit(1) }\n if (opts.show) {\n console.log()\n console.log(chalk.bold(` ${id}`))\n console.log(` intents ${(a.intents && a.intents.length) ? (a.intents as string[]).join(\", \") : chalk.dim(\"(any)\")}`)\n console.log(` maxDelegationDepth ${a.maxDelegationDepth ?? 5}`)\n console.log(` contextReferences ${a.contextReferences ? \"on\" : chalk.dim(\"off\")}`)\n console.log(` contextStrategy ${a.contextStrategy || chalk.dim(\"(global default)\")}`)\n console.log(` maxExecutionMinutes ${a.maxExecutionMinutes ?? 20}`)\n console.log()\n return\n }\n const changes: string[] = []\n if (opts.intents !== undefined) {\n if (opts.intents === \"-\" || opts.intents === \"\") {\n a.intents = []\n changes.push(\"intents cleared (permissive)\")\n } else {\n a.intents = String(opts.intents).split(\",\").map((s) => s.trim()).filter(Boolean)\n changes.push(`intents=[${a.intents.join(\", \")}]`)\n }\n }\n if (opts.maxDelegationDepth !== undefined) {\n const n = parseInt(opts.maxDelegationDepth, 10)\n if (!Number.isFinite(n) || n < 0 || n > 50) { console.log(chalk.red(\" --max-delegation-depth must be 0..50\")); process.exit(1) }\n a.maxDelegationDepth = n\n changes.push(`maxDelegationDepth=${n}`)\n }\n if (opts.contextReferences !== undefined) {\n const v = String(opts.contextReferences).toLowerCase()\n if (![\"true\", \"false\", \"on\", \"off\", \"1\", \"0\"].includes(v)) { console.log(chalk.red(\" --context-references must be true|false\")); process.exit(1) }\n a.contextReferences = v === \"true\" || v === \"on\" || v === \"1\"\n changes.push(`contextReferences=${a.contextReferences}`)\n }\n if (opts.contextStrategy !== undefined) {\n if (opts.contextStrategy === \"-\" || opts.contextStrategy === \"\") {\n delete (a as any).contextStrategy\n changes.push(\"contextStrategy cleared (uses global default)\")\n } else if (![\"layered\", \"planner\"].includes(opts.contextStrategy)) {\n console.log(chalk.red(\" --context-strategy must be layered|planner (or '-' to clear)\"))\n process.exit(1)\n } else {\n a.contextStrategy = opts.contextStrategy\n changes.push(`contextStrategy=${opts.contextStrategy}`)\n }\n }\n if (opts.maxExecutionMinutes !== undefined) {\n const n = parseInt(opts.maxExecutionMinutes, 10)\n if (!Number.isFinite(n) || n < 1 || n > 240) { console.log(chalk.red(\" --max-execution-minutes must be 1..240\")); process.exit(1) }\n a.maxExecutionMinutes = n\n changes.push(`maxExecutionMinutes=${n}`)\n }\n if (changes.length === 0) { console.log(chalk.yellow(\" no changes — pass at least one flag, or use --show\")); process.exit(1) }\n await saveConfig(config)\n console.log(chalk.green(` ✓ ${id}: ${changes.join(\", \")}`))\n console.log(chalk.dim(` Restart the daemon (or POST /reload) for the change to take effect.`))\n })\n\n// ==================== agentx agent integrations ====================\n//\n// Per-agent third-party integration registry. Declarations live in\n// agentx.json's agents[].integrations[]; secrets live in env vars / keyring.\n\nconst integrations = new Command()\n .name(\"integrations\")\n .alias(\"integ\")\n .description(\"manage per-agent third-party credentials (telegram-bot, hubspot, gitlab-user, gmail, etc.)\")\n\nintegrations\n .command(\"list <agentId>\")\n .alias(\"ls\")\n .description(\"list integrations declared on an agent\")\n .option(\"--json\", \"emit JSON\")\n .action(async (agentId: string, opts) => {\n const cfg = loadConfig()\n const a = cfg.agents?.[agentId]\n if (!a) { console.log(chalk.red(` Agent \"${agentId}\" not found`)); process.exit(1) }\n const list = (a.integrations as any[] | undefined) ?? []\n if (opts.json) { console.log(JSON.stringify(list, null, 2)); return }\n if (!list.length) {\n console.log(chalk.dim(`\\n ${agentId}: no integrations declared. Add one with: agentx agent integrations add ${agentId}\\n`))\n return\n }\n console.log()\n console.log(chalk.bold(` ${agentId}`))\n for (const i of list) {\n const enabled = i.enabled !== false\n const statusBits: string[] = []\n const creds = i.credentials ?? {}\n for (const [k, v] of Object.entries(creds)) {\n if (typeof v === \"string\" && /^[A-Z][A-Z0-9_]*$/.test(v)) {\n statusBits.push(process.env[v] ? chalk.green(`${k}:${v}=set`) : chalk.yellow(`${k}:${v}=UNSET`))\n } else if (k === \"auth\" && v === \"keyring\") {\n statusBits.push(chalk.dim(\"auth:keyring\"))\n } else if (k === \"sessionDir\" && typeof v === \"string\") {\n statusBits.push(chalk.dim(`sessionDir:${v}`))\n }\n }\n const meta = Object.entries(i.metadata ?? {})\n .map(([k, v]) => `${k}=${v}`)\n .join(\" \")\n console.log(` ${enabled ? chalk.cyan(i.kind.padEnd(14)) : chalk.dim(i.kind.padEnd(14))} ${chalk.bold(i.label)}`)\n if (statusBits.length) console.log(` ${statusBits.join(\" \")}`)\n if (meta) console.log(` ${chalk.dim(meta)}`)\n if (!enabled) console.log(` ${chalk.dim(\"(disabled)\")}`)\n }\n console.log()\n })\n\nintegrations\n .command(\"add <agentId>\")\n .description(\"declare a new integration on an agent\")\n .option(\"--kind <name>\", \"service kind (e.g. telegram-bot, hubspot, gitlab-user, gmail)\")\n .option(\"--label <text>\", \"human-readable label (must be unique within (agent, kind))\")\n .option(\"--token-env <name>\", \"env-var holding the secret (uppercase identifier)\")\n .option(\"--auth <mode>\", \"alternative to --token-env: 'keyring' for OS keyring\")\n .option(\"--session-dir <path>\", \"for whatsapp / mtproto: file-based session directory\")\n .option(\"--metadata <kvList>\", \"comma-separated key=value pairs (e.g. 'username=alex,email=alex@example.com')\")\n .option(\"--no-prompt\", \"fail instead of prompting for missing values\")\n .action(async (agentId: string, opts) => {\n const cfg = loadConfig()\n if (!cfg.agents?.[agentId]) { console.log(chalk.red(` Agent \"${agentId}\" not found`)); process.exit(1) }\n const interactive = opts.prompt !== false\n\n const { INTEGRATION_KINDS } = await import(\"@/daemon/config\")\n let kind = String(opts.kind || \"\").trim()\n if (!kind && interactive) {\n const r = await prompts({\n type: \"autocomplete\",\n name: \"kind\",\n message: \"Service kind\",\n choices: (INTEGRATION_KINDS as readonly string[]).map((k) => ({ title: k, value: k })),\n })\n kind = (r.kind || \"\").trim()\n }\n if (!kind) { console.log(chalk.red(\" --kind is required\")); process.exit(1) }\n\n let label = String(opts.label || \"\").trim()\n if (!label && interactive) {\n const r = await prompts({\n type: \"text\",\n name: \"label\",\n message: `Label (e.g. \"@cx_bot\", \"Acme CRM\", \"alex@example.com\")`,\n })\n label = (r.label || \"\").trim()\n }\n if (!label) { console.log(chalk.red(\" --label is required\")); process.exit(1) }\n\n let tokenEnv = String(opts.tokenEnv || \"\").trim()\n let auth = String(opts.auth || \"\").trim()\n let sessionDir = String(opts.sessionDir || \"\").trim()\n if (!tokenEnv && !auth && !sessionDir && interactive) {\n const r = await prompts({\n type: \"select\",\n name: \"scheme\",\n message: \"Credential scheme\",\n choices: [\n { title: \"Env var (e.g. HUBSPOT_TOKEN_CX)\", value: \"tokenEnv\" },\n { title: \"OS keyring\", value: \"keyring\" },\n { title: \"File-based session (whatsapp / mtproto)\", value: \"sessionDir\" },\n ],\n })\n if (r.scheme === \"tokenEnv\") {\n const t = await prompts({\n type: \"text\",\n name: \"tokenEnv\",\n message: \"Env var name (uppercase)\",\n initial: `${kind.replace(/-/g, \"_\").toUpperCase()}_${agentId.replace(/-/g, \"_\").toUpperCase()}`,\n })\n tokenEnv = (t.tokenEnv || \"\").trim()\n } else if (r.scheme === \"keyring\") {\n auth = \"keyring\"\n } else if (r.scheme === \"sessionDir\") {\n const s = await prompts({\n type: \"text\",\n name: \"sessionDir\",\n message: \"Session directory path\",\n initial: `.agentx/${kind}-sessions/${agentId}`,\n })\n sessionDir = (s.sessionDir || \"\").trim()\n }\n }\n\n let metadata: Record<string, string | number | boolean> = {}\n if (opts.metadata) {\n for (const pair of String(opts.metadata).split(\",\")) {\n const [k, ...rest] = pair.split(\"=\")\n if (!k) continue\n metadata[k.trim()] = rest.join(\"=\").trim()\n }\n } else if (interactive) {\n const r = await prompts({\n type: \"text\",\n name: \"metadata\",\n message: \"Metadata (k=v,k=v) — non-secret only, optional\",\n })\n if (r.metadata) {\n for (const pair of String(r.metadata).split(\",\")) {\n const [k, ...rest] = pair.split(\"=\")\n if (!k) continue\n metadata[k.trim()] = rest.join(\"=\").trim()\n }\n }\n }\n\n const credentials: Record<string, string> = {}\n if (tokenEnv) {\n if (!/^[A-Z][A-Z0-9_]*$/.test(tokenEnv)) {\n console.log(chalk.red(` --token-env must be uppercase identifier (got \"${tokenEnv}\")`)); process.exit(1)\n }\n credentials.tokenEnv = tokenEnv\n }\n if (auth === \"keyring\") credentials.auth = \"keyring\"\n if (sessionDir) credentials.sessionDir = sessionDir\n if (!Object.keys(credentials).length) { console.log(chalk.red(\" one of --token-env / --auth / --session-dir is required\")); process.exit(1) }\n\n cfg.agents[agentId].integrations = (cfg.agents[agentId].integrations as any[] | undefined) ?? []\n if (cfg.agents[agentId].integrations.find((i: any) => i.kind === kind && i.label === label)) {\n console.log(chalk.red(` Integration (${kind}, ${label}) already exists on ${agentId}`)); process.exit(1)\n }\n cfg.agents[agentId].integrations.push({ kind, label, credentials, metadata, enabled: true })\n await saveConfig(cfg)\n console.log(chalk.green(` ✓ ${agentId}: added ${kind} integration \"${label}\"`))\n if (tokenEnv && !process.env[tokenEnv]) {\n console.log(chalk.yellow(` ⚠ env var ${tokenEnv} is not set — set it on the daemon environment before use`))\n }\n })\n\nintegrations\n .command(\"remove <agentId> <kindOrLabel>\")\n .alias(\"rm\")\n .description(\"remove an integration (matched by kind, label, or 'kind:label')\")\n .action(async (agentId: string, target: string) => {\n const cfg = loadConfig()\n const a = cfg.agents?.[agentId]\n if (!a) { console.log(chalk.red(` Agent \"${agentId}\" not found`)); process.exit(1) }\n const list = (a.integrations as any[] | undefined) ?? []\n const [tk, tl] = target.includes(\":\") ? target.split(\":\", 2) : [target, \"\"]\n const idx = list.findIndex((i: any) => (i.kind === tk && (!tl || i.label === tl)) || i.label === target)\n if (idx === -1) { console.log(chalk.red(` No integration matched \"${target}\"`)); process.exit(1) }\n const removed = list.splice(idx, 1)[0]\n await saveConfig(cfg)\n console.log(chalk.green(` ✓ removed ${removed.kind} integration \"${removed.label}\" from ${agentId}`))\n })\n\nintegrations\n .command(\"test <agentId> [kindOrLabel]\")\n .description(\"validate env vars are set for one or all integrations on an agent\")\n .action(async (agentId: string, target?: string) => {\n const cfg = loadConfig()\n const a = cfg.agents?.[agentId]\n if (!a) { console.log(chalk.red(` Agent \"${agentId}\" not found`)); process.exit(1) }\n const list = (a.integrations as any[] | undefined) ?? []\n const filtered = target\n ? list.filter((i: any) => i.kind === target || i.label === target || `${i.kind}:${i.label}` === target)\n : list\n if (!filtered.length) { console.log(chalk.yellow(\" no integrations to test\")); return }\n let bad = 0\n console.log()\n for (const i of filtered) {\n const creds = i.credentials ?? {}\n const issues: string[] = []\n for (const [k, v] of Object.entries(creds)) {\n if (typeof v === \"string\" && /^[A-Z][A-Z0-9_]*$/.test(v) && !process.env[v]) {\n issues.push(`${k}: env var ${v} is unset`)\n }\n }\n if (issues.length) {\n bad += 1\n console.log(` ${chalk.red(\"✗\")} ${i.kind} \"${i.label}\"`)\n for (const issue of issues) console.log(` ${chalk.dim(issue)}`)\n } else {\n console.log(` ${chalk.green(\"✓\")} ${i.kind} \"${i.label}\"`)\n }\n }\n console.log()\n if (bad > 0) process.exit(1)\n })\n\nagent.addCommand(integrations)\n\n// ==================== agentx channel ====================\n\nexport const channel = new Command()\n .name(\"channel\")\n .description(\"manage channels — add telegram/whatsapp/gitlab, list\")\n\nchannel\n .command(\"list\")\n .alias(\"ls\")\n .description(\"list configured channels and bindings\")\n .action(() => {\n const config = loadConfig()\n console.log()\n\n // Telegram\n const tg = config.channels?.telegram\n if (tg?.enabled) {\n console.log(chalk.bold(\" Telegram:\"))\n for (const [name, acc] of Object.entries(tg.accounts || {}) as any) {\n console.log(` ${chalk.cyan(name)} -> agent: ${acc.agentBinding}`)\n }\n } else {\n console.log(chalk.dim(\" Telegram: disabled\"))\n }\n\n // WhatsApp\n const wa = config.channels?.whatsapp\n if (wa?.enabled) {\n console.log(chalk.bold(\" WhatsApp:\"))\n console.log(` default agent: ${wa.defaultAgent || \"(none)\"}`)\n console.log(` session: ${wa.sessionDir || \".agentx/whatsapp-sessions\"}`)\n for (const route of wa.routes || []) {\n const target = route.contact ? `contact ${route.contact}` : `group \"${route.group}\"`\n console.log(` ${target} -> agent: ${route.agent}`)\n }\n } else {\n console.log(chalk.dim(\" WhatsApp: disabled\"))\n }\n\n // GitLab\n const gl = config.channels?.gitlab\n if (gl?.enabled) {\n console.log(chalk.bold(\" GitLab:\"))\n console.log(` host: ${gl.host}`)\n console.log(` webhook: :${gl.webhookPort}`)\n for (const route of gl.routes || []) {\n console.log(` ${route.project} -> agent: ${route.agent}`)\n }\n } else {\n console.log(chalk.dim(\" GitLab: disabled\"))\n }\n\n console.log()\n })\n\nchannel\n .command(\"add\")\n .description(\"add a channel (telegram, whatsapp, or gitlab)\")\n .action(async () => {\n const config = loadConfig()\n const agentIds = Object.keys(config.agents || {})\n if (!agentIds.length) {\n console.log(chalk.red(\" No agents configured. Run: agentx agent add\"))\n return\n }\n\n const agentChoices = agentIds.map(id => ({ title: `${id} (${config.agents[id].name})`, value: id }))\n\n const { channelType } = await prompts({\n type: \"select\",\n name: \"channelType\",\n message: \"Channel type\",\n choices: [\n { title: \"Telegram — bot via BotFather token\", value: \"telegram\" },\n { title: \"WhatsApp — link via QR code (self-chat or contacts)\", value: \"whatsapp\" },\n { title: \"GitLab — webhook for issues, MRs, comments, pipelines\", value: \"gitlab\" },\n ],\n })\n\n if (!channelType) return\n\n config.channels = config.channels || {}\n\n // --- Telegram ---\n if (channelType === \"telegram\") {\n const answers = await prompts([\n { type: \"text\", name: \"accountName\", message: \"Account name (e.g. 'default', 'devops')\" },\n { type: \"text\", name: \"token\", message: \"Bot token (from @BotFather)\" },\n { type: \"select\", name: \"agentBinding\", message: \"Bind to agent\", choices: agentChoices },\n ])\n\n if (!answers.accountName || !answers.token) return\n\n try {\n const res = await fetch(`https://api.telegram.org/bot${answers.token}/getMe`)\n const data = await res.json() as any\n if (!data.ok) throw new Error(data.description)\n console.log(chalk.green(` Bot verified: @${data.result.username}`))\n\n const botHandle = `@${data.result.username}`\n const agentMentions = config.agents[answers.agentBinding].mentions || []\n if (!agentMentions.includes(botHandle)) {\n agentMentions.push(botHandle, data.result.username)\n config.agents[answers.agentBinding].mentions = agentMentions\n }\n } catch (e: any) {\n console.log(chalk.red(` Invalid token: ${e.message}`))\n return\n }\n\n config.channels.telegram = config.channels.telegram || { enabled: false, accounts: {}, policy: { dm: \"pair\", group: \"mention-required\" } }\n config.channels.telegram.enabled = true\n config.channels.telegram.accounts[answers.accountName] = {\n token: answers.token,\n agentBinding: answers.agentBinding,\n }\n\n await saveConfig(config)\n console.log(chalk.green(` Telegram \"${answers.accountName}\" added -> ${answers.agentBinding}`))\n }\n\n // --- WhatsApp ---\n if (channelType === \"whatsapp\") {\n const answers = await prompts([\n { type: \"select\", name: \"defaultAgent\", message: \"Default agent for WhatsApp messages\", choices: agentChoices },\n { type: \"text\", name: \"sessionDir\", message: \"Session directory\", initial: \".agentx/whatsapp-sessions\" },\n { type: \"confirm\", name: \"addRoute\", message: \"Add a contact/group route?\", initial: true },\n ])\n\n if (!answers.defaultAgent) return\n\n const routes: any[] = []\n let addMore = answers.addRoute\n\n while (addMore) {\n const route = await prompts([\n { type: \"select\", name: \"type\", message: \"Route type\", choices: [\n { title: \"Contact (phone number)\", value: \"contact\" },\n { title: \"Group (name match)\", value: \"group\" },\n ]},\n { type: \"text\", name: \"value\", message: (prev: string) => prev === \"contact\" ? \"Phone number (e.g. +10000000000)\" : \"Group name (partial match)\" },\n { type: \"select\", name: \"agent\", message: \"Route to agent\", choices: agentChoices },\n { type: \"confirm\", name: \"more\", message: \"Add another route?\", initial: false },\n ])\n\n if (route.value && route.agent) {\n routes.push({\n [route.type]: route.value,\n agent: route.agent,\n })\n }\n addMore = route.more\n }\n\n config.channels.whatsapp = {\n enabled: true,\n sessionDir: answers.sessionDir,\n defaultAgent: answers.defaultAgent,\n routes,\n }\n\n await saveConfig(config)\n mkdirSync(resolve(process.cwd(), answers.sessionDir), { recursive: true })\n console.log(chalk.green(` WhatsApp enabled (${routes.length} routes, default: ${answers.defaultAgent})`))\n console.log(chalk.dim(\" Start daemon to scan QR code: agentx daemon start\"))\n }\n\n // --- GitLab ---\n if (channelType === \"gitlab\") {\n const answers = await prompts([\n { type: \"text\", name: \"host\", message: \"GitLab instance URL\", initial: \"https://gitlab.example.com\" },\n { type: \"text\", name: \"token\", message: \"GitLab API token (PRIVATE-TOKEN)\" },\n { type: \"number\", name: \"webhookPort\", message: \"Webhook listen port\", initial: 18810 },\n { type: \"text\", name: \"webhookSecret\", message: \"Webhook secret (X-Gitlab-Token, optional)\" },\n { type: \"confirm\", name: \"addRoute\", message: \"Add a project route?\", initial: true },\n ])\n\n if (!answers.token) return\n\n const routes: any[] = []\n let addMore = answers.addRoute\n\n while (addMore) {\n const route = await prompts([\n { type: \"text\", name: \"project\", message: \"GitLab project path (e.g. group/project, or * for default)\" },\n { type: \"select\", name: \"agent\", message: \"Route to agent\", choices: agentChoices },\n { type: \"confirm\", name: \"more\", message: \"Add another route?\", initial: false },\n ])\n\n if (route.project && route.agent) {\n routes.push({ project: route.project, agent: route.agent })\n }\n addMore = route.more\n }\n\n config.channels.gitlab = {\n enabled: true,\n host: answers.host,\n token: answers.token,\n webhookPort: answers.webhookPort,\n webhookSecret: answers.webhookSecret || undefined,\n routes,\n }\n\n await saveConfig(config)\n console.log(chalk.green(` GitLab enabled (${routes.length} routes, webhook :${answers.webhookPort})`))\n console.log(chalk.dim(` Add webhook in GitLab: ${answers.host}/<project>/-/hooks`))\n console.log(chalk.dim(` URL: http://your-server:${answers.webhookPort}/`))\n if (answers.webhookSecret) {\n console.log(chalk.dim(` Secret token: ${answers.webhookSecret}`))\n }\n console.log(chalk.dim(\" Events: Comments, Issues, Merge requests, Pipeline\"))\n }\n\n console.log(chalk.dim(\" Restart daemon to apply: agentx daemon stop && agentx daemon start\"))\n console.log()\n })\n\n// ==================== agentx cron ====================\n\nexport const cron = new Command()\n .name(\"cron\")\n .description(\"manage cron jobs — add, list, enable, disable\")\n\ncron\n .command(\"list\")\n .alias(\"ls\")\n .description(\"list cron jobs\")\n .action(() => {\n const config = loadConfig()\n console.log()\n for (const [id, c] of Object.entries(config.crons || {}) as any) {\n const icon = c.enabled ? chalk.green(\"●\") : chalk.dim(\"○\")\n console.log(` ${icon} ${chalk.cyan(id)} — ${c.schedule} (${c.timezone})`)\n console.log(chalk.dim(` agent: ${c.agent} | timeout: ${c.timeout}s`))\n }\n if (!Object.keys(config.crons || {}).length) {\n console.log(chalk.dim(\" No cron jobs configured\"))\n }\n console.log()\n })\n\ncron\n .command(\"add\")\n .description(\"add a cron job\")\n .action(async () => {\n const config = loadConfig()\n const agentIds = Object.keys(config.agents || {})\n\n const answers = await prompts([\n { type: \"text\", name: \"id\", message: \"Job ID (kebab-case)\" },\n { type: \"text\", name: \"schedule\", message: \"Cron expression (e.g. '0 9 * * *')\" },\n { type: \"text\", name: \"timezone\", message: \"Timezone\", initial: \"UTC\" },\n { type: \"select\", name: \"agent\", message: \"Agent\", choices: agentIds.map(id => ({ title: id, value: id })) },\n { type: \"text\", name: \"prompt\", message: \"Task prompt\" },\n { type: \"number\", name: \"timeout\", message: \"Timeout (seconds)\", initial: 600 },\n { type: \"confirm\", name: \"enabled\", message: \"Enable now?\", initial: false },\n ])\n\n if (!answers.id || !answers.schedule) return\n\n config.crons = config.crons || {}\n config.crons[answers.id] = {\n enabled: answers.enabled,\n schedule: answers.schedule,\n timezone: answers.timezone,\n agent: answers.agent,\n prompt: answers.prompt,\n timeout: answers.timeout,\n onError: [\"log\"],\n }\n\n await saveConfig(config)\n console.log(chalk.green(` Cron \"${answers.id}\" added (${answers.enabled ? \"enabled\" : \"disabled\"})`))\n console.log()\n })\n\ncron\n .command(\"enable <id>\")\n .description(\"enable a cron job\")\n .action(async (id) => {\n const config = loadConfig()\n if (!config.crons?.[id]) { console.log(chalk.red(` Cron \"${id}\" not found`)); return }\n config.crons[id].enabled = true\n await saveConfig(config)\n console.log(chalk.green(` Cron \"${id}\" enabled`))\n })\n\ncron\n .command(\"disable <id>\")\n .description(\"disable a cron job\")\n .action(async (id) => {\n const config = loadConfig()\n if (!config.crons?.[id]) { console.log(chalk.red(` Cron \"${id}\" not found`)); return }\n config.crons[id].enabled = false\n await saveConfig(config)\n console.log(chalk.green(` Cron \"${id}\" disabled`))\n })\n\n// ==================== agentx mesh ====================\n\nexport const mesh = new Command()\n .name(\"mesh\")\n .description(\"manage mesh peers — add, list, remove\")\n\nmesh\n .command(\"list\")\n .alias(\"ls\")\n .description(\"list mesh peers\")\n .action(async () => {\n const config = loadConfig()\n console.log()\n if (!config.mesh?.enabled) {\n console.log(chalk.dim(\" Mesh: disabled\"))\n } else {\n console.log(chalk.bold(\" Mesh peers:\"))\n for (const peer of config.mesh.peers || []) {\n // Try health check\n let status = chalk.red(\"unreachable\")\n try {\n const res = await fetch(`${peer.url}/health`, { signal: AbortSignal.timeout(3000) })\n const data = await res.json() as any\n status = chalk.green(`healthy — ${data.agents?.length || 0} agents`)\n } catch {}\n console.log(` ${chalk.cyan(peer.name)} ${chalk.dim(peer.url)} ${status}`)\n }\n }\n console.log()\n })\n\nmesh\n .command(\"add\")\n .description(\"add a mesh peer (another agentx server)\")\n .action(async () => {\n const config = loadConfig()\n\n const answers = await prompts([\n { type: \"text\", name: \"name\", message: \"Peer name (e.g. 'server-2')\" },\n { type: \"text\", name: \"url\", message: \"Peer URL (e.g. 'http://100.64.0.11:18800')\" },\n { type: \"text\", name: \"token\", message: \"Auth token (optional, press enter to skip)\" },\n ])\n\n if (!answers.name || !answers.url) return\n\n // Verify connectivity\n try {\n const res = await fetch(`${answers.url}/.well-known/agent-card.json`, { signal: AbortSignal.timeout(5000) })\n const card = await res.json() as any\n console.log(chalk.green(` Connected: ${card.name} (${card.skills?.length || 0} agents)`))\n } catch {\n console.log(chalk.yellow(\" Could not reach peer (adding anyway)\"))\n }\n\n config.mesh = config.mesh || { enabled: false, peers: [], discovery: \"static\", healthCheck: { interval: 60, timeout: 10 } }\n config.mesh.enabled = true\n config.mesh.peers = config.mesh.peers || []\n config.mesh.peers.push({\n url: answers.url,\n name: answers.name,\n ...(answers.token ? { token: answers.token } : {}),\n })\n\n await saveConfig(config)\n console.log(chalk.green(` Peer \"${answers.name}\" added`))\n console.log()\n })\n\nmesh\n .command(\"remove <name>\")\n .alias(\"rm\")\n .description(\"remove a mesh peer\")\n .action(async (name) => {\n const config = loadConfig()\n if (!config.mesh?.peers) return\n config.mesh.peers = config.mesh.peers.filter((p: any) => p.name !== name)\n if (config.mesh.peers.length === 0) config.mesh.enabled = false\n await saveConfig(config)\n console.log(chalk.green(` Peer \"${name}\" removed`))\n })\n\n// agentx mesh health — tune the per-peer health-check cadence (heartbeat\n// interval + timeout). Intentionally narrow knob: lower interval if\n// you need fast peer-down detection, raise it on flaky / battery-\n// constrained mobile peers to reduce wake noise.\nmesh\n .command(\"health\")\n .description(\"tune mesh peer health checks (interval + timeout, in seconds)\")\n .option(\"--interval <s>\", \"seconds between health probes (default 60)\")\n .option(\"--timeout <s>\", \"per-probe timeout in seconds (default 10)\")\n .option(\"--show\", \"just print the current values\")\n .action(async (opts) => {\n const config = loadConfig() as any\n config.mesh = config.mesh || {}\n config.mesh.healthCheck = config.mesh.healthCheck || {}\n if (opts.show) {\n console.log(` interval ${config.mesh.healthCheck.interval ?? 60}s`)\n console.log(` timeout ${config.mesh.healthCheck.timeout ?? 10}s`)\n return\n }\n const changes: string[] = []\n if (opts.interval !== undefined) {\n const n = parseInt(opts.interval, 10)\n if (!Number.isFinite(n) || n < 5 || n > 3600) { console.log(chalk.red(\" --interval must be 5..3600 seconds\")); process.exit(1) }\n config.mesh.healthCheck.interval = n\n changes.push(`interval=${n}s`)\n }\n if (opts.timeout !== undefined) {\n const n = parseInt(opts.timeout, 10)\n if (!Number.isFinite(n) || n < 1 || n > 60) { console.log(chalk.red(\" --timeout must be 1..60 seconds\")); process.exit(1) }\n config.mesh.healthCheck.timeout = n\n changes.push(`timeout=${n}s`)\n }\n if (changes.length === 0) { console.log(chalk.yellow(\" no changes — pass --interval and/or --timeout, or --show\")); process.exit(1) }\n await saveConfig(config)\n console.log(chalk.green(` ✓ mesh.healthCheck: ${changes.join(\", \")}`))\n console.log(chalk.dim(\" Restart the daemon for the new cadence to take effect.\"))\n })\n\n// ==================== agentx skill ====================\n\nexport const skillCmd = new Command()\n .name(\"skill\")\n .description(\"manage skills — add to agent(s), list\")\n\nskillCmd\n .command(\"add <skillPath>\")\n .description(\"add a skill to agent(s)\")\n .option(\"-a, --agent <agents...>\", \"target agent ID(s)\")\n .option(\"--all\", \"add to all agents\")\n .action(async (skillPath, opts) => {\n const config = loadConfig()\n const srcPath = resolve(skillPath)\n\n if (!existsSync(srcPath)) {\n console.log(chalk.red(` Skill not found: ${srcPath}`))\n return\n }\n\n // Determine skill name\n const skillName = existsSync(join(srcPath, \"SKILL.md\"))\n ? srcPath.split(\"/\").pop()!\n : srcPath.replace(/\\/SKILL\\.md$/, \"\").split(\"/\").pop()!\n\n // Determine target agents\n let targets: string[]\n if (opts.all) {\n targets = Object.keys(config.agents || {})\n } else if (opts.agent) {\n targets = opts.agent\n } else {\n const agentIds = Object.keys(config.agents || {})\n const answer = await prompts({\n type: \"multiselect\",\n name: \"agents\",\n message: \"Install to which agents?\",\n choices: agentIds.map(id => ({ title: `${id} (${config.agents[id].name})`, value: id })),\n })\n targets = answer.agents || []\n }\n\n for (const agentId of targets) {\n const agent = config.agents[agentId]\n if (!agent) { console.log(chalk.yellow(` Agent \"${agentId}\" not found, skipping`)); continue }\n\n const destDir = resolve(agent.workspace, \".claude/skills\", skillName)\n mkdirSync(destDir, { recursive: true })\n\n if (existsSync(join(srcPath, \"SKILL.md\"))) {\n // Copy entire skill directory\n cpSync(srcPath, destDir, { recursive: true })\n } else if (srcPath.endsWith(\".md\")) {\n // Single SKILL.md file\n cpSync(srcPath, join(destDir, \"SKILL.md\"))\n }\n\n console.log(chalk.green(` ${skillName} -> ${agentId} (${agent.workspace})`))\n }\n console.log()\n })\n\nskillCmd\n .command(\"list\")\n .alias(\"ls\")\n .description(\"list skills per agent\")\n .action(() => {\n const config = loadConfig()\n console.log()\n for (const [id, a] of Object.entries(config.agents || {}) as any) {\n const skillsDir = resolve(a.workspace, \".claude/skills\")\n const skills = existsSync(skillsDir)\n ? readdirSync(skillsDir).filter((f: string) => !f.startsWith(\".\"))\n : []\n console.log(` ${chalk.cyan(id)}: ${skills.length ? skills.join(\", \") : chalk.dim(\"(none)\")}`)\n }\n console.log()\n })\n\n// --- skill sync ---\n// Redeploy a skill's SKILL.md from the source location to every agent\n// workspace in agentx.json. Prevents stale skill copies after the source\n// is updated — e.g. the wiki skill bumped from v3.0.0 → v3.1.0 in Phase 4\n// but deployed copies in 25 workspaces stayed on v3.0.0 until a manual\n// redeploy. Complements `skill add` (which copies one skill to selected\n// workspaces) with `skill sync` (which re-copies a skill to ALL workspaces\n// that already have it, or everyone if --all-workspaces).\nskillCmd\n .command(\"sync <name>\")\n .description(\"redeploy a skill's SKILL.md from source to agent workspaces (by default, only those that already have it)\")\n .option(\"--source <path>\", \"explicit source path (defaults to src/<name>/SKILL.md or skills/<name>/SKILL.md)\")\n .option(\"--agent <id>\", \"restrict to a single agent's workspace\")\n .option(\"--all-workspaces\", \"also seed into workspaces that don't have the skill yet\")\n .option(\"--dry-run\", \"report what would change, don't write\")\n .action(async (name, opts) => {\n const { createHash } = await import(\"node:crypto\")\n\n // Resolve source\n const cwd = process.cwd()\n const candidates = opts.source\n ? [opts.source]\n : [\n resolve(cwd, \"src\", name, \"SKILL.md\"),\n resolve(cwd, \"skills\", name, \"SKILL.md\"),\n ]\n const src = candidates.find(p => existsSync(p))\n if (!src) {\n console.log(chalk.red(` No SKILL.md found for \"${name}\". Searched:`))\n for (const c of candidates) console.log(chalk.dim(` ${c}`))\n return\n }\n const srcContent = readFileSync(src, \"utf-8\")\n const srcHash = createHash(\"sha256\").update(srcContent).digest(\"hex\").slice(0, 12)\n const srcVersion = (srcContent.match(/^version:\\s*(.+)$/m)?.[1] || \"?\").trim()\n\n let config\n try { config = loadDaemonConfig() } catch (e: any) {\n console.log(chalk.red(` Can't load agentx.json: ${e.message}`))\n return\n }\n\n const entries = Object.entries(config.agents || {}) as Array<[string, any]>\n const targets = opts.agent ? entries.filter(([id]) => id === opts.agent) : entries\n if (targets.length === 0) {\n console.log(chalk.yellow(opts.agent ? ` Agent \"${opts.agent}\" not in config.` : \" No agents in config.\"))\n return\n }\n\n console.log()\n console.log(chalk.bold(` Skill sync — ${name}`))\n console.log(chalk.dim(` Source: ${src}`))\n console.log(chalk.dim(` Version: ${srcVersion} · hash ${srcHash}`))\n console.log(chalk.dim(` Mode: ${opts.dryRun ? \"dry-run\" : \"commit\"}${opts.allWorkspaces ? \" · seed missing\" : \" · only-existing\"}`))\n console.log()\n\n let newN = 0, updatedN = 0, unchangedN = 0, skippedN = 0\n for (const [agentId, def] of targets) {\n const ws = def.workspace as string\n if (!ws || !existsSync(ws)) {\n console.log(` ${chalk.yellow(\"✗\")} ${agentId.padEnd(22)} ${chalk.dim(\"(workspace missing: \" + (ws || \"undefined\") + \")\")}`)\n skippedN++\n continue\n }\n const dstDir = resolve(ws, \".claude/skills\", name)\n const dst = resolve(dstDir, \"SKILL.md\")\n\n if (!existsSync(dst)) {\n if (!opts.allWorkspaces) {\n console.log(` ${chalk.dim(\"·\")} ${agentId.padEnd(22)} ${chalk.dim(\"(skipped — no existing copy; use --all-workspaces to seed)\")}`)\n skippedN++\n continue\n }\n if (!opts.dryRun) {\n mkdirSync(dstDir, { recursive: true })\n writeFileSync(dst, srcContent)\n }\n console.log(` ${chalk.green(\"+\")} ${agentId.padEnd(22)} ${chalk.dim(\"→ seeded v\" + srcVersion)}`)\n newN++\n continue\n }\n\n const dstContent = readFileSync(dst, \"utf-8\")\n const dstHash = createHash(\"sha256\").update(dstContent).digest(\"hex\").slice(0, 12)\n if (dstHash === srcHash) {\n console.log(` ${chalk.dim(\"=\")} ${agentId.padEnd(22)} ${chalk.dim(\"up to date (v\" + srcVersion + \")\")}`)\n unchangedN++\n continue\n }\n\n const dstVersion = (dstContent.match(/^version:\\s*(.+)$/m)?.[1] || \"?\").trim()\n if (!opts.dryRun) writeFileSync(dst, srcContent)\n console.log(` ${chalk.yellow(\"↻\")} ${agentId.padEnd(22)} ${chalk.dim(`v${dstVersion} → v${srcVersion}`)}`)\n updatedN++\n }\n\n console.log()\n const verb = opts.dryRun ? \"would\" : \"did\"\n console.log(chalk.dim(` Summary: ${verb} seed ${newN}, ${verb} update ${updatedN}, ${unchangedN} already current, ${skippedN} skipped.`))\n if (opts.dryRun && (newN > 0 || updatedN > 0)) {\n console.log(chalk.dim(\" Dry-run — rerun without --dry-run to write.\"))\n }\n console.log()\n })\n\n// --- skill audit ---\n// Lint every skill against the references registry: unresolved IDs, missing\n// delegate skills, raw infrastructure facts that should be cited from\n// references. Exits non-zero on any FAILING — wire it into CI.\nskillCmd\n .command(\"audit\")\n .description(\"lint installed skills against the references registry; exits non-zero on FAILING\")\n .option(\"--cwd <cwd>\", \"where to load skills from\", process.cwd())\n .option(\n \"--references-cwd <cwd>\",\n \"where to load references and recipes from (defaults to --cwd; useful when references live in the agentx repo and skills live under ~/.claude)\",\n )\n .option(\"--json\", \"emit JSON instead of a human report\")\n .option(\"--workspace <id>\", \"audit a single agent workspace by id (skills + references; overrides --cwd)\")\n .option(\n \"--all-workspaces\",\n \"audit every agent workspace in agentx.json; references default to the current cwd\",\n )\n .action(async (opts) => {\n const { loadLocalSkills } = await import(\"@/agent/skills/loader\")\n const { auditAll } = await import(\"@/agent/skills/audit\")\n const { loadReferences } = await import(\"@/agents/references/loader\")\n const { loadRecipes } = await import(\"@/agents/references/recipes\")\n\n const skillsRoots: string[] = []\n if (opts.workspace) {\n const config = loadConfig()\n const agent = config.agents?.[opts.workspace]\n if (!agent) {\n console.log(chalk.red(` Agent \"${opts.workspace}\" not found in agentx.json`))\n process.exit(1)\n }\n skillsRoots.push(resolve(agent.workspace))\n } else if (opts.allWorkspaces) {\n const config = loadConfig()\n for (const agent of Object.values(config.agents || {}) as any[]) {\n if (agent?.workspace) skillsRoots.push(resolve(agent.workspace))\n }\n } else {\n skillsRoots.push(resolve(opts.cwd))\n }\n const refsRoot = resolve(opts.referencesCwd || opts.cwd)\n\n const skillBatches = await Promise.all(skillsRoots.map(r => loadLocalSkills(r)))\n const skills = skillBatches.flat()\n const [references, recipes] = await Promise.all([\n loadReferences(refsRoot),\n loadRecipes(refsRoot),\n ])\n const results = auditAll({ skills, references, recipes })\n\n if (opts.json) {\n console.log(\n JSON.stringify(\n results.map(r => ({\n name: r.name,\n verdict: r.verdict,\n reasons: r.reasons,\n path: r.skill?.path,\n })),\n null,\n 2,\n ),\n )\n } else {\n const summary = { PASS: 0, REVIEW: 0, FAILING: 0 }\n for (const r of results) summary[r.verdict]++\n console.log()\n for (const r of results) {\n const tag =\n r.verdict === \"PASS\"\n ? chalk.green(\"PASS \")\n : r.verdict === \"REVIEW\"\n ? chalk.yellow(\"REVIEW \")\n : chalk.red(\"FAILING\")\n console.log(` ${tag} ${chalk.bold(r.name)}${r.skill?.path ? chalk.dim(` (${r.skill.path})`) : \"\"}`)\n for (const reason of r.reasons) console.log(` ${chalk.dim(\"·\")} ${reason}`)\n }\n console.log()\n console.log(\n ` ${chalk.green(`${summary.PASS} PASS`)} ${chalk.yellow(`${summary.REVIEW} REVIEW`)} ${chalk.red(`${summary.FAILING} FAILING`)}`,\n )\n console.log()\n }\n\n process.exit(results.some(r => r.verdict === \"FAILING\") ? 1 : 0)\n })\n\nskillCmd\n .command(\"suggest\")\n .description(\"rank an agent's skills against a task (suggests, never loads)\")\n .argument(\"<task>\", \"the task, in the words it arrived in\")\n .option(\"--agent <id>\", \"whose skills to rank\")\n .option(\"--min <p>\", \"minimum P(any skill applies)\", \"0.6\")\n .option(\"--json\", \"emit the ranking as JSON\")\n .action(async (task: string, opts: any) => {\n // Suggests, never loads.\n //\n // Deliberately NOT wired into per-turn context injection. The path it\n // would feed, getAutoInjectSkills(), is inert fleet-wide — 0 of 101\n // skill files across 10 agent workspaces set autoInject — so wiring it\n // in would change nothing today while adding a network call to every\n // turn. Measuring the ranking first is what decides whether turning\n // injection on is worth it at all.\n const config = loadConfig()\n const agents = Object.entries(config.agents || {}) as any[]\n const [agentId, agent] = opts.agent\n ? (agents.find(([id]) => id === opts.agent) ?? [])\n : (agents[0] ?? [])\n if (!agent) {\n console.log(chalk.red(` no such agent${opts.agent ? ` \"${opts.agent}\"` : \"\"}`))\n process.exit(1)\n }\n\n const { loadLocalSkills } = await import(\"@/agent/skills/loader\")\n const { pickSkillForTask } = await import(\"@/agent/skills/select\")\n const skills = await loadLocalSkills(agent.workspace)\n if (skills.length === 0) {\n console.log(chalk.yellow(` ${agentId} has no skills`))\n return\n }\n\n const pick = await pickSkillForTask(skills, task, {\n agent: agentId,\n minRelevant: Number(opts.min) || 0.6,\n })\n\n if (opts.json) {\n console.log(JSON.stringify({\n task, agent: agentId, skillsSeen: skills.length,\n picked: pick.skill?.frontmatter.name ?? null,\n anyRelevant: pick.anyRelevant, confidence: pick.confidence,\n judged: pick.judged, reason: pick.reason, shortlist: pick.shortlist,\n }, null, 2))\n return\n }\n\n console.log()\n if (!pick.skill) {\n console.log(` ${chalk.yellow(\"·\")} no skill for this ${chalk.dim(`— ${pick.reason}`)}`)\n } else {\n console.log(` ${chalk.green(\"→\")} ${chalk.bold(pick.skill.frontmatter.name)} ${chalk.dim(`· ${pick.reason}`)}`)\n console.log(` ${chalk.dim(pick.skill.frontmatter.description.slice(0, 140))}`)\n }\n if (pick.shortlist.length > 1) {\n console.log(chalk.dim(\"\\n shortlist (lexical -> judged)\"))\n for (const s of pick.shortlist.slice(0, 6)) {\n const judged = s.p === undefined ? \" - \" : s.p.toFixed(2)\n console.log(chalk.dim(` ${s.lexical.toFixed(2)} -> ${judged} ${s.name}`))\n }\n }\n if (!pick.judged) {\n console.log(chalk.dim(\"\\n (lexical only — set decisions.seats.skill-select.mode to judge)\"))\n }\n console.log()\n })\n\n// ==================== agentx references ====================\n//\n// Operator-private fact registry. Generic to any project — Acme runs Initech in\n// .agentx/references/initech/, the next operator runs their own clients the same\n// way. The engine ships only the schema + a generic example template.\n\nexport const references = new Command()\n .name(\"references\")\n .alias(\"refs\")\n .description(\"manage the deterministic references registry — facts cited by skills and resolved into agent context\")\n\nreferences\n .command(\"init <namespace>\")\n .description(\"scaffold .agentx/references/<namespace>/ from the example template (operator-private)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--force\", \"overwrite existing files\")\n .action((namespace: string, opts) => {\n if (!/^[a-z0-9][a-z0-9-]*$/.test(namespace)) {\n console.log(chalk.red(` Invalid namespace \"${namespace}\". Use lowercase letters, digits, and hyphens.`))\n process.exit(1)\n }\n const cwd = resolve(opts.cwd)\n const exampleRoot = resolve(cwd, \"references/example\")\n const exampleRecipe = resolve(cwd, \"references/recipes/example.yaml\")\n if (!existsSync(exampleRoot)) {\n console.log(chalk.red(` Example template not found at ${exampleRoot}. Are you running this from the agentx repo root?`))\n process.exit(1)\n }\n const targetRoot = resolve(cwd, \".agentx/references\", namespace)\n const targetRecipes = resolve(cwd, \".agentx/references/recipes\")\n mkdirSync(targetRoot, { recursive: true })\n mkdirSync(targetRecipes, { recursive: true })\n\n const exampleFiles = readdirSync(exampleRoot).filter(f => f.endsWith(\".yaml\") || f.endsWith(\".yml\"))\n let copied = 0\n let skipped = 0\n for (const file of exampleFiles) {\n const dest = join(targetRoot, file)\n if (existsSync(dest) && !opts.force) {\n console.log(chalk.dim(` skip ${dest} (exists; --force to overwrite)`))\n skipped++\n continue\n }\n // Re-namespace: replace `namespace: example.<x>` with `namespace: <ns>.<x>`\n const src = readFileSync(join(exampleRoot, file), \"utf-8\")\n const rewritten = src.replace(/^namespace:\\s*example\\./m, `namespace: ${namespace}.`)\n writeFileSync(dest, rewritten)\n console.log(chalk.green(` + ${dest}`))\n copied++\n }\n const recipeDest = join(targetRecipes, `${namespace}.yaml`)\n if (existsSync(recipeDest) && !opts.force) {\n console.log(chalk.dim(` skip ${recipeDest} (exists; --force to overwrite)`))\n skipped++\n } else if (existsSync(exampleRecipe)) {\n const src = readFileSync(exampleRecipe, \"utf-8\").replaceAll(\"example.\", `${namespace}.`)\n writeFileSync(recipeDest, src)\n console.log(chalk.green(` + ${recipeDest}`))\n copied++\n }\n console.log()\n console.log(chalk.dim(` ${copied} written, ${skipped} skipped. Edit the placeholders, then:`))\n console.log(chalk.dim(` 1. set contextReferences: true on the relevant agents in agentx.json`))\n console.log(chalk.dim(` 2. agentx skill audit # verify references resolve`))\n console.log(chalk.dim(` 3. systemctl restart agentx # pick up the new registry`))\n console.log()\n })\n\nreferences\n .command(\"discover <namespace>\")\n .description(\"scan installed skills and write detected facts to .agentx/references/<namespace>/\")\n .option(\"--cwd <cwd>\", \"where to scan for skills\", process.cwd())\n .option(\"--references-cwd <cwd>\", \"where to WRITE the YAML files (defaults to --cwd; useful when skills live under ~/.claude and references live in the agentx repo)\")\n .option(\"--from <skills>\", \"comma-separated skill name/tag substrings to filter by (default: namespace itself)\")\n .option(\"--gitlab-host <url>\", \"validate project URLs against this host (e.g. https://gitlab.example.com)\")\n .option(\"--write\", \"write the YAML files (default: dry-run preview)\")\n .option(\"--force\", \"overwrite existing files when --write is set\")\n .action(async (namespace: string, opts) => {\n if (!/^[a-z0-9][a-z0-9-]*$/.test(namespace)) {\n console.log(chalk.red(` Invalid namespace \"${namespace}\". Use lowercase letters, digits, and hyphens.`))\n process.exit(1)\n }\n const { loadLocalSkills } = await import(\"@/agent/skills/loader\")\n const { discoverFromSkills, renderDiscovery } = await import(\"@/agents/references/discover\")\n const cwd = resolve(opts.cwd)\n const filter = (opts.from\n ? String(opts.from)\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(Boolean)\n : [namespace])\n const skills = await loadLocalSkills(cwd)\n const result = discoverFromSkills(skills, {\n namespace,\n filter,\n gitlabHost: opts.gitlabHost,\n })\n\n console.log()\n if (result.scannedSkills.length === 0) {\n console.log(chalk.yellow(` No skills matched filter [${filter.join(\", \")}] under ${cwd}`))\n console.log(chalk.dim(\" Tip: pass --from <skill-name>,<other> to widen the filter.\"))\n console.log()\n return\n }\n console.log(chalk.dim(` Scanned skills: ${result.scannedSkills.join(\", \")}`))\n const counts = Object.fromEntries(\n Object.entries(result.byKind).map(([k, v]) => [k, v.length]),\n )\n console.log(` Discovered: ssh=${counts.ssh} gitlab=${counts.gitlab} paths=${counts.path} contacts=${counts.contact}`)\n\n const files = renderDiscovery(result, namespace)\n const writeRoot = resolve(opts.referencesCwd || opts.cwd)\n const targetDir = resolve(writeRoot, \".agentx/references\", namespace)\n\n if (!opts.write) {\n console.log()\n console.log(chalk.dim(` Dry-run — would write to ${targetDir}/`))\n for (const [name, content] of Object.entries(files)) {\n console.log(chalk.cyan(`\\n --- ${name} ---`))\n console.log(content.split(\"\\n\").slice(0, 30).map(l => ` ${l}`).join(\"\\n\"))\n if (content.split(\"\\n\").length > 30) console.log(chalk.dim(` … (${content.split(\"\\n\").length - 30} more lines truncated in preview)`))\n }\n console.log()\n console.log(chalk.dim(` Re-run with --write to commit these to ${targetDir}/`))\n console.log()\n return\n }\n\n mkdirSync(targetDir, { recursive: true })\n let written = 0\n let skipped = 0\n for (const [name, content] of Object.entries(files)) {\n const dest = join(targetDir, name)\n if (existsSync(dest) && !opts.force) {\n console.log(chalk.dim(` skip ${dest} (exists; --force to overwrite)`))\n skipped++\n continue\n }\n writeFileSync(dest, content)\n console.log(chalk.green(` + ${dest}`))\n written++\n }\n console.log()\n console.log(chalk.dim(` ${written} written, ${skipped} skipped. Review every card — flagged ones (tags include \"needs-review\") are best-effort guesses.`))\n console.log(chalk.dim(` Then: agentx skill audit → set contextReferences: true on the relevant agents → systemctl restart agentx`))\n console.log()\n })\n\nreferences\n .command(\"list\")\n .alias(\"ls\")\n .description(\"list every loaded reference (debug)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--json\", \"emit JSON\")\n .action(async (opts) => {\n const { loadReferences } = await import(\"@/agents/references/loader\")\n const idx = await loadReferences(resolve(opts.cwd))\n const cards = [...idx.byId.values()].sort((a, b) => a.id.localeCompare(b.id))\n if (opts.json) {\n console.log(JSON.stringify(cards, null, 2))\n return\n }\n console.log()\n if (cards.length === 0) {\n console.log(chalk.dim(\" (no references loaded — try `agentx references init <namespace>`)\"))\n console.log()\n return\n }\n for (const card of cards) {\n const src = idx.sourceById.get(card.id)\n console.log(` ${chalk.cyan(card.id)} ${chalk.dim(`(${card.kind})`)}`)\n console.log(` ${card.summary}`)\n if (src) console.log(chalk.dim(` ${src}`))\n }\n console.log()\n console.log(chalk.dim(` ${cards.length} reference(s) loaded.`))\n console.log()\n })\n\n// ==================== agentx hook ====================\n\nexport const hook = new Command()\n .name(\"hook\")\n .description(\"manage hooks — add to agent workspace\")\n\nhook\n .command(\"add <agent>\")\n .description(\"add a hook to an agent's workspace settings\")\n .action(async (agentId) => {\n const config = loadConfig()\n const agent = config.agents?.[agentId]\n if (!agent) { console.log(chalk.red(` Agent \"${agentId}\" not found`)); return }\n\n const settingsPath = resolve(agent.workspace, \".claude/settings.json\")\n const settings = existsSync(settingsPath) ? JSON.parse(readFileSync(settingsPath, \"utf-8\")) : {}\n\n const answers = await prompts([\n { type: \"select\", name: \"event\", message: \"Hook event\", choices: [\n { title: \"PreToolUse — before any tool runs\", value: \"PreToolUse\" },\n { title: \"PostToolUse — after any tool runs\", value: \"PostToolUse\" },\n { title: \"SessionStart — when session begins\", value: \"SessionStart\" },\n { title: \"Notification — on notifications\", value: \"Notification\" },\n { title: \"Stop — before session stops\", value: \"Stop\" },\n ]},\n { type: \"select\", name: \"type\", message: \"Hook type\", choices: [\n { title: \"command — run a shell command\", value: \"command\" },\n { title: \"http — POST to a URL\", value: \"http\" },\n ]},\n { type: \"text\", name: \"value\", message: (prev: any) => prev === \"command\" ? \"Shell command\" : \"URL\" },\n { type: \"text\", name: \"matcher\", message: \"Matcher regex (optional, e.g. 'Bash' to match tool)\" },\n ])\n\n if (!answers.event || !answers.value) return\n\n settings.hooks = settings.hooks || {}\n settings.hooks[answers.event] = settings.hooks[answers.event] || []\n\n const hookDef: any = {\n type: answers.type,\n ...(answers.type === \"command\" ? { command: answers.value } : { url: answers.value }),\n }\n\n const entry: any = { hooks: [hookDef] }\n if (answers.matcher) entry.matcher = answers.matcher\n\n settings.hooks[answers.event].push(entry)\n\n mkdirSync(resolve(agent.workspace, \".claude\"), { recursive: true })\n writeFileSync(settingsPath, JSON.stringify(settings, null, 2))\n console.log(chalk.green(` Hook added to ${agentId}: ${answers.event} -> ${answers.type}`))\n console.log()\n })\n\n// ==================== agentx migrate ====================\n\nexport const migrate = new Command()\n .name(\"migrate\")\n .description(\"import configuration from OpenClaw or other tools\")\n\nmigrate\n .command(\"openclaw [configPath]\")\n .description(\"import agents, channels, and crons from OpenClaw config\")\n .option(\"--dry-run\", \"show what would be imported without writing\")\n .action(async (configPath, opts) => {\n // Find OpenClaw config\n const searchPaths = [\n configPath,\n resolve(process.env.HOME || \"\", \".openclaw/openclaw.json\"),\n resolve(process.env.HOME || \"\", \".openclaw/peerbot.json\"),\n ].filter(Boolean)\n\n let ocPath: string | undefined\n for (const p of searchPaths) {\n if (p && existsSync(p)) { ocPath = p; break }\n }\n\n if (!ocPath) {\n console.log(chalk.red(\" OpenClaw config not found. Pass the path: agentx migrate openclaw /path/to/config.json\"))\n return\n }\n\n console.log(chalk.dim(` Reading: ${ocPath}`))\n const oc = JSON.parse(readFileSync(ocPath, \"utf-8\"))\n\n const config = existsSync(resolve(process.cwd(), \"agentx.json\"))\n ? loadConfig()\n : { node: { id: \"imported\", name: \"Imported\", bind: \"127.0.0.1:18800\" }, providers: {}, agents: {}, channels: { telegram: { enabled: false, accounts: {}, policy: { dm: \"pair\", group: \"mention-required\" } }, whatsapp: { enabled: false } }, crons: {}, mesh: { enabled: false, peers: [] } }\n\n // Import agents\n const agents = oc.agents?.list || []\n const bindings = oc.bindings || []\n const bindMap: Record<string, string> = {}\n for (const b of bindings) {\n if (b.match?.channel === \"telegram\") {\n bindMap[b.match.accountId] = b.agentId\n }\n }\n // Default account -> main agent\n if (agents.find((a: any) => a.id === \"main\" || a.default)) {\n bindMap[\"default\"] = \"main\"\n }\n\n let agentCount = 0\n for (const a of agents) {\n if (a.workspace?.startsWith(\"/data\")) continue // skip remote devices\n\n const axId = a.id.replace(/-agent$/, \"\").replace(/^main$/, \"main-agent\")\n const mentions = a.groupChat?.mentionPatterns || []\n if (!mentions.some((m: string) => m === axId)) mentions.push(axId)\n\n config.agents[axId] = {\n name: a.name,\n workspace: a.workspace,\n tier: \"claude-code\",\n model: \"claude-sonnet-4-6\",\n mentions,\n maxConcurrent: a.id === \"main\" ? 2 : 1,\n systemPrompt: `You are ${a.name} on AgentX.`,\n permissionMode: \"bypassPermissions\",\n }\n agentCount++\n\n if (!opts.dryRun) {\n mkdirSync(resolve(a.workspace, \".claude/skills\"), { recursive: true })\n // Set up workspace with Claude Code best practices\n const { setupWorkspace } = await import(\"@/agents/workspace-setup\")\n setupWorkspace(axId, config.agents[axId] as any)\n }\n }\n console.log(` ${chalk.green(agentCount)} agents imported (workspaces set up with Claude Code best practices)`)\n\n // Import Telegram accounts\n const tgAccounts = oc.channels?.telegram?.accounts || {}\n let tgCount = 0\n for (const [name, acc] of Object.entries(tgAccounts) as any) {\n if (!acc.botToken) continue\n const boundAgent = bindMap[name]\n const axAgentId = boundAgent?.replace(/-agent$/, \"\").replace(/^main$/, \"main-agent\") || \"default\"\n\n config.channels.telegram.accounts[name] = {\n token: acc.botToken,\n agentBinding: axAgentId,\n }\n config.channels.telegram.enabled = true\n tgCount++\n }\n console.log(` ${chalk.green(tgCount)} Telegram accounts imported`)\n\n // Import cron jobs (from separate file if exists)\n const cronPath = resolve(ocPath, \"../cron/jobs.json\")\n if (existsSync(cronPath)) {\n const cronData = JSON.parse(readFileSync(cronPath, \"utf-8\"))\n let cronCount = 0\n for (const job of cronData.jobs || []) {\n const axId = job.name || job.id\n const agentId = job.agentId?.replace(/-agent$/, \"\").replace(/^main$/, \"main-agent\") || \"default\"\n config.crons[axId] = {\n enabled: job.enabled || false,\n schedule: job.schedule?.expr || \"0 9 * * *\",\n timezone: job.schedule?.tz || \"UTC\",\n agent: agentId,\n prompt: job.payload?.message || \"\",\n timeout: job.payload?.timeoutSeconds || 600,\n onError: [\"log\"],\n }\n cronCount++\n }\n console.log(` ${chalk.green(cronCount)} cron jobs imported`)\n }\n\n if (opts.dryRun) {\n console.log(chalk.yellow(\"\\n Dry run — nothing written\"))\n console.log(JSON.stringify(config, null, 2))\n } else {\n await saveConfig(config)\n console.log(chalk.green(\"\\n Migration complete! Review agentx.json and run: agentx daemon start\"))\n }\n console.log()\n })\n\n// ==================== agentx config ====================\n\nexport const configCmd = new Command()\n .name(\"config\")\n .description(\"validate and inspect configuration\")\n\nconfigCmd\n .command(\"check\")\n .description(\"validate agentx.json and check all workspaces\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .action(async (opts) => {\n console.log()\n try {\n const config = loadDaemonConfig(opts.config)\n console.log(chalk.green(\" ✓ Config valid\"))\n console.log(chalk.dim(` Node: ${config.node.name} (${config.node.id})`))\n console.log(chalk.dim(` Bind: ${config.node.bind}`))\n console.log(chalk.dim(` Agents: ${Object.keys(config.agents).length}`))\n console.log(chalk.dim(` Crons: ${Object.keys(config.crons).length}`))\n console.log(chalk.dim(` Mesh peers: ${config.mesh.peers.length}`))\n\n // Channels\n const tgAccounts = Object.keys(config.channels.telegram.accounts).length\n console.log(chalk.dim(` Telegram: ${config.channels.telegram.enabled ? `${tgAccounts} accounts` : \"disabled\"}`))\n console.log(chalk.dim(` WhatsApp: ${config.channels.whatsapp.enabled ? `${config.channels.whatsapp.routes.length} routes` : \"disabled\"}`))\n\n // Warnings\n const warnings = validateWorkspaces(config)\n if (warnings.length) {\n console.log()\n console.log(chalk.yellow(\" Warnings:\"))\n for (const w of warnings) {\n console.log(chalk.yellow(` ⚠ ${w}`))\n }\n } else {\n console.log(chalk.green(\" ✓ All workspaces valid\"))\n }\n\n // Check agent workspaces\n console.log()\n for (const [id, agent] of Object.entries(config.agents)) {\n const ws = agent.workspace\n const hasClaudeDir = existsSync(resolve(ws, \".claude\"))\n const hasClaudeMd = existsSync(resolve(ws, \"CLAUDE.md\"))\n const hasSettings = existsSync(resolve(ws, \".claude/settings.json\"))\n const skillCount = existsSync(resolve(ws, \".claude/skills\"))\n ? readdirSync(resolve(ws, \".claude/skills\")).filter(f => !f.startsWith(\".\")).length\n : 0\n\n const checks = [\n hasClaudeDir ? chalk.green(\"✓\") : chalk.red(\"✗\"),\n \".claude\",\n hasClaudeMd ? chalk.green(\"✓\") : chalk.yellow(\"○\"),\n \"CLAUDE.md\",\n hasSettings ? chalk.green(\"✓\") : chalk.yellow(\"○\"),\n \"settings\",\n `${skillCount} skills`,\n ]\n console.log(` ${chalk.cyan(id)}: ${checks.join(\" \")}`)\n }\n } catch (e: any) {\n console.log(chalk.red(` ✗ ${e.message}`))\n }\n console.log()\n })\n\nconfigCmd\n .command(\"show\")\n .description(\"print the resolved configuration\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .action((opts) => {\n try {\n const config = loadDaemonConfig(opts.config)\n console.log(JSON.stringify(config, null, 2))\n } catch (e: any) {\n console.log(chalk.red(e.message))\n }\n })\n\n// --- config get/set/unset — dot-path edits with Zod validation + hot-reload ---\n\nfunction parseValue(raw: string, asString: boolean): unknown {\n if (asString) return raw\n // Try JSON first — handles numbers, booleans, arrays, objects, quoted strings.\n try { return JSON.parse(raw) } catch { /* fall through */ }\n // Treat \"a,b,c\" as an array of trimmed strings (common shorthand).\n if (raw.includes(\",\") && !raw.includes(\" \")) {\n return raw.split(\",\").map(s => s.trim()).filter(Boolean)\n }\n return raw\n}\n\nfunction formatValue(v: unknown): string {\n if (v === undefined) return chalk.dim(\"(unset)\")\n if (typeof v === \"string\") return v\n return JSON.stringify(v, null, 2)\n}\n\nconfigCmd\n .command(\"get <path>\")\n .description(\"read a config value by dot-path (e.g. agents.devops.model)\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .option(\"--raw\", \"show ${VAR} tokens instead of env-expanded values\")\n .option(\"--json\", \"output as JSON (for scripting)\")\n .action(async (path: string, opts) => {\n const { readFileSync, existsSync } = await import(\"fs\")\n const { resolve } = await import(\"path\")\n const { getAtPath } = await import(\"@/daemon/config-mutator\")\n const { expandEnvVars } = await import(\"@/daemon/config\")\n\n const cfgPath = opts.config || resolve(process.cwd(), \"agentx.json\")\n if (!existsSync(cfgPath)) {\n console.log(chalk.red(` No config at ${cfgPath}`))\n process.exit(1)\n }\n const raw = JSON.parse(readFileSync(cfgPath, \"utf-8\"))\n const source = opts.raw ? raw : expandEnvVars(raw)\n const value = getAtPath(source, path)\n if (opts.json) {\n console.log(JSON.stringify(value))\n } else {\n console.log(formatValue(value))\n }\n })\n\nconfigCmd\n .command(\"set <path> <value>\")\n .description(\"write a config value by dot-path; validates against schema and hot-reloads the daemon\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .option(\"--string\", \"treat the value as a literal string (skip JSON parsing)\")\n .option(\"--dry-run\", \"validate and diff without writing\")\n .action(async (path: string, value: string, opts) => {\n const { applyConfigMutation, setAtPath, getAtPath } = await import(\"@/daemon/config-mutator\")\n const parsed = parseValue(value, !!opts.string)\n\n const result = await applyConfigMutation((cfg) => {\n setAtPath(cfg, path, parsed)\n }, { configPath: opts.config, dryRun: !!opts.dryRun })\n\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n\n const written = getAtPath(result.after, path)\n if (opts.dryRun) {\n console.log(chalk.yellow(` (dry-run) ${chalk.cyan(path)} would become: ${formatValue(written)}`))\n } else {\n console.log(chalk.green(` ✓ ${chalk.cyan(path)} = ${formatValue(written)}`))\n if (result.reloaded) {\n console.log(chalk.dim(\" Daemon hot-reloaded.\"))\n } else if (result.reloadSkipped && !/ECONNREFUSED|unreachable|fetch failed/i.test(result.reloadSkipped)) {\n console.log(chalk.dim(` (daemon reload skipped: ${result.reloadSkipped})`))\n }\n }\n })\n\nconfigCmd\n .command(\"unset <path>\")\n .description(\"remove a config value by dot-path (validates + hot-reloads)\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .option(\"--dry-run\", \"validate without writing\")\n .action(async (path: string, opts) => {\n const { applyConfigMutation, getAtPath, unsetAtPath } = await import(\"@/daemon/config-mutator\")\n\n const result = await applyConfigMutation((cfg) => {\n if (getAtPath(cfg, path) === undefined) {\n // No-op — still succeeds, writes nothing meaningful, but keeps the\n // caller's flow consistent.\n return\n }\n unsetAtPath(cfg, path)\n }, { configPath: opts.config, dryRun: !!opts.dryRun })\n\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n\n const stillThere = getAtPath(result.after, path)\n if (stillThere !== undefined) {\n console.log(chalk.dim(` (no-op) ${chalk.cyan(path)} was not set`))\n return\n }\n\n if (opts.dryRun) {\n console.log(chalk.yellow(` (dry-run) ${chalk.cyan(path)} would be removed`))\n } else {\n console.log(chalk.green(` ✓ ${chalk.cyan(path)} removed`))\n if (result.reloaded) {\n console.log(chalk.dim(\" Daemon hot-reloaded.\"))\n }\n }\n })\n\n// --- agentx config governance ---\n//\n// Read-only view of the governance flags that admit dispatches into the\n// ledger pipeline. v1 is read-only because every flag is read once at\n// daemon startup; flipping in place would require restart anyway. The\n// view answers the question operators ask first when something doesn't\n// dispatch: \"is governance even enabled, and at what level?\"\n\nconfigCmd\n .command(\"governance\")\n .description(\"show resolved governance flags (read-only; flags read once at startup)\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n let businessEnabled = false\n let projectsCount = 0\n let configError: string | undefined\n try {\n const cfg = loadDaemonConfig(opts.config)\n businessEnabled = !!(cfg as any).business?.enabled\n projectsCount = ((cfg as any).business?.projects ?? []).length\n } catch (e: any) {\n configError = e?.message ?? String(e)\n }\n\n const ledgerMode = (process.env.INTENT_LEDGER_MODE || \"off\").toLowerCase()\n const pmGateRaw = (process.env.INTENT_PM_GATE_ENABLED || \"\").toLowerCase()\n const pmGate = pmGateRaw === \"true\" || pmGateRaw === \"1\" || pmGateRaw === \"yes\"\n const pmGateActive = pmGate && businessEnabled\n const ledgerValid = [\"off\", \"shadow\", \"authoritative\"].includes(ledgerMode)\n\n if (opts.json) {\n console.log(JSON.stringify({\n ledger: { mode: ledgerMode, valid: ledgerValid },\n pmGate: {\n envSet: pmGate,\n businessEnabled,\n active: pmGateActive,\n projects: projectsCount,\n },\n configError,\n }, null, 2))\n return\n }\n\n console.log()\n console.log(chalk.bold(\" Governance flags\"))\n console.log()\n if (configError) {\n console.log(chalk.yellow(` Note: agentx.json couldn't be loaded — ${configError}`))\n console.log()\n }\n\n const modeColor = ledgerMode === \"authoritative\" ? chalk.green\n : ledgerMode === \"shadow\" ? chalk.cyan\n : ledgerMode === \"off\" ? chalk.dim\n : chalk.red\n console.log(` INTENT_LEDGER_MODE ${modeColor(ledgerMode)}${ledgerValid ? \"\" : chalk.red(\" (invalid — must be off|shadow|authoritative)\")}`)\n\n const pmStatus = pmGateActive\n ? chalk.green(\"active\")\n : pmGate\n ? chalk.yellow(\"env=true but business.enabled=false → inactive\")\n : chalk.dim(\"disabled\")\n console.log(` INTENT_PM_GATE_ENABLED ${pmStatus}`)\n console.log(chalk.dim(` business.enabled ${businessEnabled ? chalk.green(\"true\") : chalk.dim(\"false\")}`))\n console.log(chalk.dim(` business.projects[] ${projectsCount}`))\n\n console.log()\n console.log(chalk.dim(\" These flags are read once at daemon startup. Flipping requires a restart.\"))\n console.log(chalk.dim(\" See: https://github.com/anis-marrouchi/agentx/blob/main/docs/architecture/research-rescue-plan.md\"))\n console.log()\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { resolve } from \"path\"\nimport { existsSync } from \"fs\"\nimport { openDb } from \"@/storage/sqlite\"\n\n// --- agentx db ---\n//\n// Read-only CLI for exploring the operational SQLite at .agentx/db.sqlite\n// (built by the Move 2 storage layer). Named queries for the data the\n// daemon's bus subscribers persist. The escape hatch `agentx db query`\n// runs raw SQL for anything not exposed as a named subcommand.\n//\n// Defaults to human-readable column output; `--json` emits a JSON array\n// per row (one row per object) for piping into jq / dashboards.\n\nexport const db = new Command()\n .name(\"db\")\n .description(\"explore the operational SQLite store at .agentx/db.sqlite\")\n\nfunction openReadOnly(cwd: string) {\n const path = resolve(cwd, \".agentx/db.sqlite\")\n if (!existsSync(path)) {\n console.log(chalk.red(` No SQLite at ${path}`))\n console.log(chalk.dim(` Make sure the daemon has started since Move 2 shipped — the file is created on first boot.`))\n process.exit(1)\n }\n const handle = openDb({ path })\n if (!handle) {\n console.log(chalk.red(` Could not open ${path}`))\n console.log(chalk.dim(` If you see \"NODE_MODULE_VERSION mismatch\", run \\`pnpm rebuild better-sqlite3\\` under the daemon's Node version.`))\n process.exit(1)\n }\n return handle\n}\n\nfunction emit(rows: any[], asJson: boolean): void {\n if (asJson) {\n console.log(JSON.stringify(rows, null, 2))\n return\n }\n if (rows.length === 0) {\n console.log(chalk.dim(\" (no rows)\"))\n return\n }\n // Column rendering: compute widths + print a header / separator / rows.\n const cols = Object.keys(rows[0])\n const widths = cols.map(c =>\n Math.max(c.length, ...rows.map(r => String(r[c] ?? \"\").length))\n )\n const fmt = (cells: any[]) =>\n cells.map((v, i) => String(v ?? \"\").padEnd(widths[i])).join(\" \")\n console.log(fmt(cols))\n console.log(cols.map((_, i) => \"-\".repeat(widths[i])).join(\" \"))\n for (const row of rows) console.log(fmt(cols.map(c => row[c])))\n}\n\n// --- db tasks ---\n\ndb\n .command(\"tasks\")\n .description(\"recent task_history rows (one per agent task)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"-a, --agent <id>\", \"filter by agent id\")\n .option(\"-d, --day <YYYY-MM-DD>\", \"filter by start day (UTC)\")\n .option(\"-s, --status <status>\", \"ok | error\")\n .option(\"-n, --limit <n>\", \"max rows\", \"20\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const handle = openReadOnly(resolve(opts.cwd))\n const where: string[] = []\n const params: Record<string, any> = {}\n if (opts.agent) { where.push(\"agent_id = @agent\"); params.agent = opts.agent }\n if (opts.day) { where.push(\"started_at LIKE @day\"); params.day = `${opts.day}%` }\n if (opts.status) { where.push(\"status = @status\"); params.status = opts.status }\n const sql = `\n SELECT agent_id, channel, status, duration_ms,\n input_tokens, output_tokens,\n substr(message_preview, 1, 60) AS message,\n started_at\n FROM task_history\n ${where.length ? \"WHERE \" + where.join(\" AND \") : \"\"}\n ORDER BY started_at DESC\n LIMIT @limit\n `\n const rows = handle.prepare(sql).all({ ...params, limit: Number(opts.limit) })\n emit(rows, !!opts.json)\n })\n\n// --- db rotations ---\n\ndb\n .command(\"rotations\")\n .description(\"session rotation events (stale | tier-2 | max-turns)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"-a, --agent <id>\", \"filter by agent id\")\n .option(\"-r, --reason <r>\", \"stale | tier-2 | max-turns\")\n .option(\"-n, --limit <n>\", \"max rows\", \"20\")\n .option(\"--summary\", \"group by agent + reason\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const handle = openReadOnly(resolve(opts.cwd))\n const where: string[] = []\n const params: Record<string, any> = {}\n if (opts.agent) { where.push(\"agent_id = @agent\"); params.agent = opts.agent }\n if (opts.reason) { where.push(\"reason = @reason\"); params.reason = opts.reason }\n const whereSql = where.length ? \"WHERE \" + where.join(\" AND \") : \"\"\n const sql = opts.summary\n ? `\n SELECT agent_id, reason, COUNT(*) AS n,\n ROUND(AVG(last_turn_input_tokens)) AS avg_input_tokens,\n MAX(last_turn_input_tokens) AS max_input_tokens\n FROM rotations\n ${whereSql}\n GROUP BY agent_id, reason\n ORDER BY n DESC\n `\n : `\n SELECT agent_id, channel, reason, last_turn_input_tokens, rotated_at\n FROM rotations\n ${whereSql}\n ORDER BY rotated_at DESC\n LIMIT @limit\n `\n const rows = handle.prepare(sql).all({ ...params, limit: Number(opts.limit) })\n emit(rows, !!opts.json)\n })\n\n// --- db usage ---\n\ndb\n .command(\"usage\")\n .description(\"token usage rolled up per (agent, model, day)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"-a, --agent <id>\", \"filter by agent id\")\n .option(\"-d, --day <YYYY-MM-DD>\", \"filter by day (UTC)\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const handle = openReadOnly(resolve(opts.cwd))\n const where: string[] = []\n const params: Record<string, any> = {}\n if (opts.agent) { where.push(\"agent_id = @agent\"); params.agent = opts.agent }\n if (opts.day) { where.push(\"day = @day\"); params.day = opts.day }\n const sql = `\n SELECT day, agent_id, model, tasks,\n input_tokens AS in_tok, output_tokens AS out_tok,\n cache_read_tokens AS cache_read, cache_create_tokens AS cache_create\n FROM usage_daily\n ${where.length ? \"WHERE \" + where.join(\" AND \") : \"\"}\n ORDER BY day DESC, agent_id\n `\n const rows = handle.prepare(sql).all(params)\n emit(rows, !!opts.json)\n })\n\n// --- db routes ---\n\ndb\n .command(\"routes\")\n .description(\"inbound routing decisions captured by the pipeline trace\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"-c, --channel <ch>\", \"filter by channel (telegram, gitlab, github, ...)\")\n .option(\"-k, --kind <k>\", \"match | drop\")\n .option(\"-n, --limit <n>\", \"max rows\", \"20\")\n .option(\"--summary\", \"group by channel + kind + deciding stage\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const handle = openReadOnly(resolve(opts.cwd))\n const where: string[] = []\n const params: Record<string, any> = {}\n if (opts.channel) { where.push(\"channel = @channel\"); params.channel = opts.channel }\n if (opts.kind) { where.push(\"kind = @kind\"); params.kind = opts.kind }\n const whereSql = where.length ? \"WHERE \" + where.join(\" AND \") : \"\"\n const sql = opts.summary\n ? `\n SELECT channel, kind, deciding_stage, COUNT(*) AS n\n FROM route_traces\n ${whereSql}\n GROUP BY channel, kind, deciding_stage\n ORDER BY n DESC\n `\n : `\n SELECT channel, chat_id, kind, deciding_stage, agent_id,\n substr(reason, 1, 60) AS reason, at\n FROM route_traces\n ${whereSql}\n ORDER BY at DESC\n LIMIT @limit\n `\n const rows = handle.prepare(sql).all({ ...params, limit: Number(opts.limit) })\n emit(rows, !!opts.json)\n })\n\n// --- db errors ---\n\ndb\n .command(\"errors\")\n .description(\"failed tasks (status='error') with their error message\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"-a, --agent <id>\", \"filter by agent id\")\n .option(\"-n, --limit <n>\", \"max rows\", \"20\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const handle = openReadOnly(resolve(opts.cwd))\n const where: string[] = [\"status = 'error'\"]\n const params: Record<string, any> = {}\n if (opts.agent) { where.push(\"agent_id = @agent\"); params.agent = opts.agent }\n const sql = `\n SELECT agent_id, channel, duration_ms,\n substr(error, 1, 120) AS error,\n started_at\n FROM task_history\n WHERE ${where.join(\" AND \")}\n ORDER BY started_at DESC\n LIMIT @limit\n `\n const rows = handle.prepare(sql).all({ ...params, limit: Number(opts.limit) })\n emit(rows, !!opts.json)\n })\n\n// --- db tables / schema ---\n\ndb\n .command(\"tables\")\n .description(\"list tables + row counts\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const handle = openReadOnly(resolve(opts.cwd))\n const tables = handle\n .prepare(\"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name\")\n .all() as { name: string }[]\n const rows = tables.map(t => ({\n table: t.name,\n rows: (handle.prepare(`SELECT COUNT(*) AS c FROM ${t.name}`).get() as { c: number }).c,\n }))\n emit(rows, !!opts.json)\n })\n\n// --- db query ---\n\ndb\n .command(\"query <sql>\")\n .description(\"run an arbitrary read-only SQL query (escape hatch)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--json\", \"emit JSON\")\n .action((sql, opts) => {\n const handle = openReadOnly(resolve(opts.cwd))\n // Best-effort guard against accidental writes — read-only flag isn't on\n // (we share the daemon's open() helper). Reject the obvious DDL/DML.\n if (/^\\s*(insert|update|delete|drop|alter|create|attach|vacuum|pragma)\\b/i.test(sql)) {\n console.log(chalk.red(\" Refusing to run a write/DDL statement via `agentx db query`.\"))\n console.log(chalk.dim(\" Use `sqlite3 .agentx/db.sqlite` directly if you really mean it.\"))\n process.exit(2)\n }\n try {\n const rows = handle.prepare(sql).all()\n emit(rows, !!opts.json)\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { mkdtempSync } from \"fs\"\nimport { tmpdir } from \"os\"\nimport { resolve, join } from \"path\"\nimport { existsSync } from \"fs\"\nimport Database from \"better-sqlite3\"\nimport { IntentLedger } from \"@/intent/ledger\"\nimport { replay } from \"@/intent/replay\"\nimport type { IntentDecision, IntentEvent, IntentResolution } from \"@/intent/types\"\n\n// --- agentx ledger ---\n//\n// Read-only triage CLI for the intent ledger at .agentx/intent/ledger.sqlite,\n// the canonical record of every dispatch decision (Phase 1 of the\n// architectural rescue, see docs/architecture/research-rescue-plan.md).\n//\n// Built for the 1b shadow-mode soak: an operator runs these commands\n// against a freshly-rsync'd copy of the ledger to inspect divergences,\n// in-flight dispatches, and source-by-source activity. The CLI does not\n// modify the ledger — opens read-only.\n//\n// Use `--path` to point at an alternate ledger (e.g., one rsync'd\n// locally from peer-server). Default is .agentx/intent/ledger.sqlite\n// in the cwd.\n\nexport const ledger = new Command()\n .name(\"ledger\")\n .description(\"inspect the intent ledger (.agentx/intent/ledger.sqlite)\")\n\ninterface OpenOpts {\n cwd?: string\n path?: string\n}\n\nfunction openReadOnly(opts: OpenOpts) {\n const root = resolve(opts.cwd ?? process.cwd())\n const path = resolve(root, opts.path ?? \".agentx/intent/ledger.sqlite\")\n if (!existsSync(path)) {\n console.log(chalk.red(` No ledger at ${path}`))\n console.log(chalk.dim(` Make sure the daemon has run with INTENT_LEDGER_MODE != \"off\". The file is created on first ledger write.`))\n process.exit(1)\n }\n try {\n return new Database(path, { readonly: true })\n } catch (e: any) {\n console.log(chalk.red(` Could not open ${path}: ${e.message}`))\n if (/NODE_MODULE_VERSION/.test(e.message)) {\n console.log(chalk.dim(` Run \\`pnpm rebuild better-sqlite3\\` under the daemon's Node version.`))\n }\n process.exit(1)\n }\n}\n\nfunction emit(rows: any[], asJson: boolean): void {\n if (asJson) {\n console.log(JSON.stringify(rows, null, 2))\n return\n }\n if (rows.length === 0) {\n console.log(chalk.dim(\" (no rows)\"))\n return\n }\n const cols = Object.keys(rows[0])\n const widths = cols.map((c) =>\n Math.max(c.length, ...rows.map((r) => String(r[c] ?? \"\").length)),\n )\n const fmt = (cells: any[]) =>\n cells.map((v, i) => String(v ?? \"\").padEnd(widths[i])).join(\" \")\n console.log(fmt(cols))\n console.log(cols.map((_, i) => \"-\".repeat(widths[i])).join(\" \"))\n for (const row of rows) console.log(fmt(cols.map((c) => row[c])))\n}\n\n/** Convert a duration string (\"1h\", \"30m\", \"7d\") to milliseconds.\n * Returns null if unparseable. */\nfunction durationToMs(input: string): number | null {\n const m = /^(\\d+)\\s*([smhd])$/.exec(input.trim())\n if (!m) return null\n const n = Number(m[1])\n const unit = m[2]\n const factor = unit === \"s\" ? 1000 : unit === \"m\" ? 60_000 : unit === \"h\" ? 3600_000 : 86_400_000\n return n * factor\n}\n\nfunction parseSince(input: string | undefined): number | undefined {\n if (!input) return undefined\n const ms = durationToMs(input)\n if (ms === null) {\n // Maybe an absolute ms epoch\n const n = Number(input)\n if (Number.isFinite(n) && n > 0) return n\n console.log(chalk.red(` Invalid --since \"${input}\". Use a duration like \"1h\", \"30m\", \"7d\", or an ms epoch.`))\n process.exit(1)\n }\n return Date.now() - ms\n}\n\n// ---------------------------------------------------------------------------\n// agentx ledger stats\n// ---------------------------------------------------------------------------\n\nledger\n .command(\"stats\")\n .description(\"overview: events by source, decisions, divergences, in-flight count\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--path <path>\", \"ledger path relative to cwd\", \".agentx/intent/ledger.sqlite\")\n .option(\"--since <duration>\", \"limit to events newer than (e.g. 1h, 24h, 7d)\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const db = openReadOnly(opts)\n const since = parseSince(opts.since)\n const sinceClause = since !== undefined ? \"WHERE ts >= @since\" : \"\"\n const sinceClauseDecisions = since !== undefined ? \"WHERE decided_at >= @since\" : \"\"\n const sinceClauseDivergences = sinceClause\n\n const eventsBySource = db\n .prepare(`SELECT source, COUNT(*) as n FROM intent_events ${sinceClause} GROUP BY source ORDER BY n DESC`)\n .all({ since })\n const totalDecisions = (db\n .prepare(`SELECT COUNT(*) as n FROM intent_decisions ${sinceClauseDecisions}`)\n .get({ since }) as { n: number }).n\n const decisionsByOutcome = db\n .prepare(`SELECT outcome, COUNT(*) as n FROM intent_decisions ${sinceClauseDecisions} GROUP BY outcome ORDER BY n DESC`)\n .all({ since })\n const totalDivergences = (db\n .prepare(`SELECT COUNT(*) as n FROM intent_divergences ${sinceClauseDivergences}`)\n .get({ since }) as { n: number }).n\n const divergencesBySource = db\n .prepare(`SELECT source, COUNT(*) as n FROM intent_divergences ${sinceClauseDivergences} GROUP BY source ORDER BY n DESC`)\n .all({ since })\n const inFlight = (db\n .prepare(`\n SELECT COUNT(*) as n FROM intent_decisions d\n LEFT JOIN intent_resolutions r\n ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by\n WHERE d.outcome = 'dispatched' AND r.decision_event_id IS NULL\n `)\n .get() as { n: number }).n\n\n if (opts.json) {\n console.log(JSON.stringify({\n since: since ?? null,\n eventsBySource, totalDecisions, decisionsByOutcome,\n totalDivergences, divergencesBySource, inFlight,\n }, null, 2))\n return\n }\n\n console.log(chalk.bold(\"Events by source\"))\n emit(eventsBySource, false)\n console.log()\n console.log(chalk.bold(`Decisions: ${totalDecisions}`))\n emit(decisionsByOutcome, false)\n console.log()\n console.log(chalk.bold(`Divergences: ${totalDivergences}`))\n emit(divergencesBySource, false)\n console.log()\n console.log(chalk.bold(`In-flight (dispatched, no resolution): ${inFlight}`))\n })\n\n// ---------------------------------------------------------------------------\n// agentx ledger divergences\n// ---------------------------------------------------------------------------\n\nledger\n .command(\"divergences\")\n .description(\"recent divergence rows (newest first)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--path <path>\", \"ledger path relative to cwd\", \".agentx/intent/ledger.sqlite\")\n .option(\"-s, --source <name>\", \"filter by source (telegram, gitlab, workflow, cron, mesh, github)\")\n .option(\"--since <duration>\", \"limit to divergences newer than (e.g. 1h, 24h)\")\n .option(\"-n, --limit <n>\", \"max rows\", \"50\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const db = openReadOnly(opts)\n const since = parseSince(opts.since)\n const where: string[] = []\n const params: Record<string, any> = { limit: Number(opts.limit) }\n if (opts.source) { where.push(\"source = @source\"); params.source = opts.source }\n if (since !== undefined) { where.push(\"ts >= @since\"); params.since = since }\n const whereSql = where.length ? `WHERE ${where.join(\" AND \")}` : \"\"\n const rows = db\n .prepare(`\n SELECT\n datetime(ts/1000, 'unixepoch') AS at,\n source,\n decided_by,\n ledger_outcome AS L_outcome,\n COALESCE(ledger_agent_id, '-') AS L_agent,\n legacy_outcome AS X_outcome,\n COALESCE(legacy_agent_id, '-') AS X_agent,\n substr(COALESCE(legacy_reason, ledger_reason, ''), 1, 60) AS reason\n FROM intent_divergences\n ${whereSql}\n ORDER BY ts DESC\n LIMIT @limit\n `)\n .all(params)\n emit(rows, !!opts.json)\n })\n\n// ---------------------------------------------------------------------------\n// agentx ledger active\n// ---------------------------------------------------------------------------\n\nledger\n .command(\"active\")\n .description(\"currently in-flight dispatched decisions (no resolution yet)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--path <path>\", \"ledger path relative to cwd\", \".agentx/intent/ledger.sqlite\")\n .option(\"-s, --source <name>\", \"filter by source\")\n .option(\"-n, --limit <n>\", \"max rows\", \"50\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const db = openReadOnly(opts)\n const where: string[] = [\"d.outcome = 'dispatched'\", \"r.decision_event_id IS NULL\"]\n const params: Record<string, any> = { limit: Number(opts.limit) }\n if (opts.source) { where.push(\"e.source = @source\"); params.source = opts.source }\n const rows = db\n .prepare(`\n SELECT\n datetime(d.decided_at/1000, 'unixepoch') AS dispatched_at,\n e.source,\n d.decided_by,\n COALESCE(d.agent_id, '-') AS agent,\n COALESCE(e.project, '-') AS project,\n COALESCE(e.subject, '-') AS subject,\n ROUND((strftime('%s', 'now')*1000 - d.decided_at) / 1000.0) AS age_s\n FROM intent_decisions d\n JOIN intent_events e ON e.id = d.event_id\n LEFT JOIN intent_resolutions r\n ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by\n WHERE ${where.join(\" AND \")}\n ORDER BY d.decided_at DESC\n LIMIT @limit\n `)\n .all(params)\n emit(rows, !!opts.json)\n })\n\n// ---------------------------------------------------------------------------\n// agentx ledger events\n// ---------------------------------------------------------------------------\n\nledger\n .command(\"events\")\n .description(\"recent events (newest first)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--path <path>\", \"ledger path relative to cwd\", \".agentx/intent/ledger.sqlite\")\n .option(\"-s, --source <name>\", \"filter by source\")\n .option(\"-p, --project <name>\", \"filter by project\")\n .option(\"--since <duration>\", \"limit to newer than (e.g. 1h, 24h)\")\n .option(\"-n, --limit <n>\", \"max rows\", \"30\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const db = openReadOnly(opts)\n const since = parseSince(opts.since)\n const where: string[] = []\n const params: Record<string, any> = { limit: Number(opts.limit) }\n if (opts.source) { where.push(\"source = @source\"); params.source = opts.source }\n if (opts.project) { where.push(\"project = @project\"); params.project = opts.project }\n if (since !== undefined) { where.push(\"ts >= @since\"); params.since = since }\n const whereSql = where.length ? `WHERE ${where.join(\" AND \")}` : \"\"\n const rows = db\n .prepare(`\n SELECT\n datetime(ts/1000, 'unixepoch') AS at,\n source,\n COALESCE(project, '-') AS project,\n COALESCE(subject, '-') AS subject,\n COALESCE(intent, '-') AS intent\n FROM intent_events\n ${whereSql}\n ORDER BY ts DESC\n LIMIT @limit\n `)\n .all(params)\n emit(rows, !!opts.json)\n })\n\n// ---------------------------------------------------------------------------\n// agentx ledger lineage\n// ---------------------------------------------------------------------------\n//\n// Walk the (project, subject) correlation for an event and print every\n// decision + resolution that landed on the same subject in chronological\n// order. Answers \"what's the dispatch lineage of this event?\" without\n// the operator having to write SQL. Foundation for a future in-product\n// diff viewer (deferred); the CLI version is the 80/20.\n\nledger\n .command(\"lineage <eventOrSubject>\")\n .description(\"walk the dispatch chain on the same (project, subject) and print every decision + resolution\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--path <path>\", \"ledger path relative to cwd\", \".agentx/intent/ledger.sqlite\")\n .option(\"--by-subject\", \"treat the argument as `<project>:<subject>` instead of an event id\")\n .option(\"--json\", \"emit JSON\")\n .action((eventOrSubject: string, opts) => {\n const db = openReadOnly(opts)\n\n let project: string | null = null\n let subject: string | null = null\n\n if (opts.bySubject) {\n const idx = eventOrSubject.indexOf(\":\")\n if (idx < 0) {\n console.log(chalk.red(` --by-subject expects \"<project>:<subject>\"`))\n process.exit(1)\n }\n project = eventOrSubject.slice(0, idx)\n subject = eventOrSubject.slice(idx + 1)\n } else {\n const row = db\n .prepare(`SELECT project, subject FROM intent_events WHERE id = ?`)\n .get(eventOrSubject) as { project: string | null; subject: string | null } | undefined\n if (!row) {\n console.log(chalk.red(` no event with id ${eventOrSubject}`))\n process.exit(1)\n }\n project = row.project\n subject = row.subject\n if (project === null || subject === null) {\n console.log(chalk.yellow(` event ${eventOrSubject} has no (project, subject) — lineage requires both`))\n if (project) console.log(chalk.dim(` project: ${project}`))\n if (subject) console.log(chalk.dim(` subject: ${subject}`))\n process.exit(1)\n }\n }\n\n // All events sharing this (project, subject), ordered by ts.\n const events = db\n .prepare(\n `SELECT id, ts, source, COALESCE(intent, '-') AS intent, COALESCE(source_event_id, '-') AS source_event_id\n FROM intent_events WHERE project = ? AND subject = ? ORDER BY ts ASC`,\n )\n .all(project, subject) as Array<{\n id: string; ts: number; source: string; intent: string; source_event_id: string\n }>\n\n if (events.length === 0) {\n console.log(chalk.dim(` (no events for ${project}:${subject})`))\n return\n }\n\n // All decisions + resolutions for those events, grouped by event_id.\n const eventIds = events.map((e) => e.id)\n const placeholders = eventIds.map((_, i) => `@id${i}`).join(\", \")\n const params = Object.fromEntries(eventIds.map((id, i) => [`id${i}`, id]))\n\n const decisions = db\n .prepare(`\n SELECT d.event_id, d.decided_at, d.decided_by, d.agent_id, d.outcome, d.reason,\n r.resolved_at, r.status AS resolution_status, r.duration_ms, r.result_summary\n FROM intent_decisions d\n LEFT JOIN intent_resolutions r\n ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by\n WHERE d.event_id IN (${placeholders})\n ORDER BY d.decided_at ASC\n `)\n .all(params) as Array<{\n event_id: string; decided_at: number; decided_by: string; agent_id: string | null;\n outcome: string; reason: string | null;\n resolved_at: number | null; resolution_status: string | null;\n duration_ms: number | null; result_summary: string | null;\n }>\n\n if (opts.json) {\n const grouped = events.map((e) => ({\n event: e,\n decisions: decisions.filter((d) => d.event_id === e.id),\n }))\n console.log(JSON.stringify({ project, subject, lineage: grouped }, null, 2))\n return\n }\n\n const distinctAgents = new Set<string>()\n for (const d of decisions) {\n if (d.outcome === \"dispatched\" && d.agent_id) distinctAgents.add(d.agent_id)\n }\n\n console.log()\n console.log(chalk.bold(` Lineage for ${chalk.cyan(project + \":\" + subject)}`))\n console.log(chalk.dim(` ${events.length} event(s), ${decisions.length} decision(s), ${distinctAgents.size} distinct agent(s) dispatched`))\n console.log()\n\n for (const e of events) {\n const dt = new Date(e.ts).toISOString().slice(0, 19).replace(\"T\", \" \")\n console.log(` ${chalk.dim(dt)} ${chalk.bold(e.id)} ${chalk.dim(`(${e.source}/${e.intent})`)}`)\n const evDecisions = decisions.filter((d) => d.event_id === e.id)\n if (evDecisions.length === 0) {\n console.log(chalk.dim(` (no decisions yet)`))\n continue\n }\n for (const d of evDecisions) {\n const outcome = d.outcome === \"dispatched\"\n ? chalk.green(d.outcome)\n : d.outcome === \"dropped\"\n ? chalk.dim(d.outcome)\n : chalk.yellow(d.outcome)\n const agent = d.agent_id ? chalk.cyan(d.agent_id) : chalk.dim(\"-\")\n const reason = d.reason ? chalk.dim(` — ${d.reason.slice(0, 60)}`) : \"\"\n console.log(` ${chalk.dim(d.decided_by)} → ${outcome} ${agent}${reason}`)\n if (d.resolution_status) {\n const status = d.resolution_status === \"ok\"\n ? chalk.green(d.resolution_status)\n : chalk.red(d.resolution_status)\n const dur = d.duration_ms ? `${(d.duration_ms / 1000).toFixed(1)}s` : \"-\"\n console.log(` ${chalk.dim(\"resolved\")} ${status} ${chalk.dim(dur)}`)\n } else if (d.outcome === \"dispatched\") {\n console.log(` ${chalk.yellow(\"(in-flight, no resolution)\")}`)\n }\n }\n }\n console.log()\n })\n\n// ---------------------------------------------------------------------------\n// agentx ledger replay\n// ---------------------------------------------------------------------------\n//\n// Reads (events, decisions, resolutions) from the source ledger and\n// replays them onto a fresh tmp ledger via src/intent/replay.ts.\n// Reports any divergences. The Phase 7 regression test in CLI form.\n//\n// Usage:\n// agentx ledger replay # all rows\n// agentx ledger replay --since 24h # last 24h only\n// agentx ledger replay --source gitlab # one source only\n// agentx ledger replay --path /tmp/peer-ledger/ledger.sqlite\n\nledger\n .command(\"replay\")\n .description(\"replay the source ledger onto a fresh tmp ledger; report divergences\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--path <path>\", \"ledger path relative to cwd\", \".agentx/intent/ledger.sqlite\")\n .option(\"--since <duration>\", \"limit to events newer than (e.g. 1h, 24h, 7d)\")\n .option(\"-s, --source <name>\", \"filter to one source\")\n .option(\"-n, --limit <n>\", \"max events to replay (defaults to all)\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const sourceDb = openReadOnly(opts)\n const since = parseSince(opts.since)\n\n // Pull events from the source ledger as IntentEvent[].\n const eventWhere: string[] = []\n const eventParams: Record<string, any> = {}\n if (opts.source) { eventWhere.push(\"source = @source\"); eventParams.source = opts.source }\n if (since !== undefined) { eventWhere.push(\"ts >= @since\"); eventParams.since = since }\n const eventLimit = opts.limit ? `LIMIT ${Number(opts.limit)}` : \"\"\n const events: IntentEvent[] = (sourceDb\n .prepare(`\n SELECT id, ts, source, source_event_id, project, subject, intent, raw_json\n FROM intent_events\n ${eventWhere.length ? \"WHERE \" + eventWhere.join(\" AND \") : \"\"}\n ORDER BY ts ASC\n ${eventLimit}\n `)\n .all(eventParams) as Array<any>)\n .map((r) => ({\n id: r.id, ts: r.ts, source: r.source,\n sourceEventId: r.source_event_id, project: r.project, subject: r.subject,\n intent: r.intent, rawJson: r.raw_json,\n }))\n\n // Pull decisions + resolutions for those events. Joining by event id\n // keeps the snapshot internally consistent — no orphan rows.\n if (events.length === 0) {\n console.log(chalk.dim(\" (no events match filter)\"))\n return\n }\n const eventIds = new Set(events.map((e) => e.id))\n const placeholders = events.map((_, i) => `@id${i}`).join(\", \")\n const eventIdParams: Record<string, any> = Object.fromEntries(\n events.map((e, i) => [`id${i}`, e.id]),\n )\n\n const decisions: IntentDecision[] = (sourceDb\n .prepare(`\n SELECT event_id, decided_at, decided_by, agent_id, outcome, reason\n FROM intent_decisions\n WHERE event_id IN (${placeholders})\n `)\n .all(eventIdParams) as Array<any>)\n .map((r) => ({\n eventId: r.event_id, decidedAt: r.decided_at, decidedBy: r.decided_by,\n agentId: r.agent_id, outcome: r.outcome, reason: r.reason,\n }))\n\n const resolutions: IntentResolution[] = (sourceDb\n .prepare(`\n SELECT decision_event_id, decision_decided_by, resolved_at, status, duration_ms, result_summary\n FROM intent_resolutions\n WHERE decision_event_id IN (${placeholders})\n `)\n .all(eventIdParams) as Array<any>)\n .map((r) => ({\n decisionEventId: r.decision_event_id, decisionDecidedBy: r.decision_decided_by,\n resolvedAt: r.resolved_at, status: r.status,\n durationMs: r.duration_ms, resultSummary: r.result_summary,\n }))\n\n void eventIds // for clarity; not used directly\n\n // Open a fresh tmp ledger and run the replay.\n const tmpDir = mkdtempSync(join(tmpdir(), \"agentx-ledger-replay-\"))\n const target = new IntentLedger({ path: join(tmpDir, \"target.sqlite\") })\n try {\n const result = replay(target, events, decisions, resolutions)\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2))\n return\n }\n\n console.log(chalk.bold(`Replayed ${result.eventsCount} events, ${result.decisionsCount} decisions, ${resolutions.length} resolutions`))\n if (result.divergences.length === 0) {\n console.log(chalk.green(` ✓ 0 divergences — ledger mechanics are deterministic on this snapshot`))\n } else {\n console.log(chalk.red(` ✗ ${result.divergences.length} divergences`))\n emit(\n result.divergences.map((d) => ({\n event_id: d.eventId,\n decided_by: d.decidedBy,\n recorded: `${d.expected.outcome}/${d.expected.agentId ?? \"-\"}`,\n replayed: `${d.actual.outcome}/${d.actual.agentId ?? \"-\"}`,\n reason: d.reason.slice(0, 80),\n })),\n false,\n )\n }\n } finally {\n target.close()\n }\n })\n","import { decideAndCommit, type DispatchPolicy, type PolicyDecision } from \"./decide\"\nimport type { IntentLedger } from \"./ledger\"\nimport type { IntentDecision, IntentEvent, IntentEventInput, IntentResolution } from \"./types\"\n\n// Ledger replay — Phase 7 of the architectural rescue.\n//\n// Given a snapshot of events + decisions from a source ledger, replay\n// each event through `decideAndCommit` on a fresh target ledger and\n// compare the resulting decisions against what was originally\n// recorded.\n//\n// This validates Inv-Idempotence + Inv-ActiveTaskSafety operationally:\n// if 30 days of production traffic replay identically, decideAndCommit\n// is deterministic given ledger state (the formal property checked\n// statically by Phase 2's TLA+ spec).\n//\n// Replay is also the foundation for counterfactuals: \"if I'd dispatched\n// to agent B instead of A at decision row X, what would the rest of\n// the ledger look like?\" That extension lives in `counterfactual.ts`\n// (deferred to a follow-up commit).\n//\n// **Policy reconstruction.** Replay needs to call `decideAndCommit`,\n// which needs a `DispatchPolicy`. Real policies are runtime objects\n// keyed by `decidedBy` string; we don't store them. The replay reuses\n// the recorded decision as the policy's output — i.e., the\n// \"playback policy\" returns whatever was originally decided. This lets\n// the ledger's mechanics (idempotency, active-task safety) re-fire\n// independently and surface any divergence in those mechanics, which\n// is the exact scope of the regression test.\n//\n// **What replay does NOT verify.** Real policy disagreement (the policy\n// would decide differently today than it did originally) is invisible\n// to playback because we feed it the historical answer. Catching\n// real policy drift requires re-running the actual policies, which\n// the live shadow soak does — that's a complementary signal, not a\n// replacement for replay.\n\nexport interface ReplayDivergence {\n eventId: string\n decidedBy: string\n expected: { agentId: string | null; outcome: string }\n actual: { agentId: string | null; outcome: string }\n /** Free-form narrative of what diverged. Useful for triage. */\n reason: string\n}\n\nexport interface ReplayResult {\n /** Number of events replayed. */\n eventsCount: number\n /** Number of decisions replayed (one per (event, decidedBy) pair). */\n decisionsCount: number\n /** Decisions whose replayed outcome did not match the recorded one. */\n divergences: ReplayDivergence[]\n /** Decisions skipped because the recorded `decidedBy` does not exist\n * on the target ledger's policy registry — useful when replaying a\n * ledger from a code base that has since dropped a decider. Empty\n * when not applicable. */\n skipped: ReplayDivergence[]\n}\n\n/**\n * Replay a snapshot of (events, decisions, resolutions) onto `target`\n * (which should be empty). Returns an equivalence report.\n *\n * Decisions and resolutions are merged into a single timeline ordered\n * by their original timestamps so the ledger's active-task safety\n * lookup reproduces the original behavior: a resolution that arrived\n * between two decisions in the source will be applied at the same\n * point in the replay, freeing the slot for the second decision the\n * same way it did originally.\n *\n * Resolutions arrive without a separate replay decision (resolutions\n * are unconditional `recordResolution` writes) — they're just\n * forwarded to the target. Decisions are replayed via `decideAndCommit`\n * so the ledger's mechanics (idempotency, active-task safety) re-fire\n * and any divergence in those mechanics surfaces.\n */\nexport function replay(\n target: IntentLedger,\n events: IntentEvent[],\n decisions: IntentDecision[],\n resolutions: IntentResolution[] = [],\n): ReplayResult {\n // Index events by id so playback can find them when iterating decisions.\n const eventById = new Map<string, IntentEvent>()\n for (const e of events) eventById.set(e.id, e)\n\n // Build a single timeline of decisions + resolutions, sorted by\n // their original timestamp. Same-timestamp ties: decisions before\n // resolutions (a decision recorded at T cannot be resolved before T).\n type Entry =\n | { kind: \"decision\"; ts: number; decision: IntentDecision }\n | { kind: \"resolution\"; ts: number; resolution: IntentResolution }\n const timeline: Entry[] = []\n for (const d of decisions) timeline.push({ kind: \"decision\", ts: d.decidedAt, decision: d })\n for (const r of resolutions) timeline.push({ kind: \"resolution\", ts: r.resolvedAt, resolution: r })\n timeline.sort((a, b) => {\n if (a.ts !== b.ts) return a.ts - b.ts\n if (a.kind === b.kind) return 0\n return a.kind === \"decision\" ? -1 : 1\n })\n\n const divergences: ReplayDivergence[] = []\n let decisionsCount = 0\n\n for (const entry of timeline) {\n if (entry.kind === \"resolution\") {\n // Resolutions just forward to the target. If the corresponding\n // decision wasn't replayed (skipped because of missing event),\n // the FK in `intent_resolutions` will throw — caught and recorded\n // as a divergence to keep replay non-fatal.\n try {\n target.recordResolution(entry.resolution)\n } catch (e: any) {\n divergences.push({\n eventId: entry.resolution.decisionEventId,\n decidedBy: entry.resolution.decisionDecidedBy,\n expected: { agentId: null, outcome: \"resolved\" },\n actual: { agentId: null, outcome: \"resolution-failed\" },\n reason: `recordResolution threw: ${e?.message ?? e}`,\n })\n }\n continue\n }\n\n const recorded = entry.decision\n const event = eventById.get(recorded.eventId)\n if (!event) {\n // Decision with no matching event in the snapshot — the snapshot\n // is incomplete.\n divergences.push({\n eventId: recorded.eventId,\n decidedBy: recorded.decidedBy,\n expected: { agentId: recorded.agentId, outcome: recorded.outcome },\n actual: { agentId: null, outcome: \"skipped\" },\n reason: \"decision references event not in snapshot\",\n })\n continue\n }\n\n const policy = buildPlaybackPolicy(recorded)\n const eventInput: IntentEventInput = {\n // Preserve the source's event id so resolutions (which reference\n // the original event id) FK-resolve correctly in the target.\n // Without this, recordEvent generates a fresh ULID and the\n // resolution's FK fails.\n id: event.id,\n ts: event.ts,\n source: event.source,\n sourceEventId: event.sourceEventId,\n project: event.project,\n subject: event.subject,\n intent: event.intent,\n rawJson: event.rawJson,\n }\n\n const replayed = decideAndCommit(target, eventInput, policy, () => recorded.decidedAt)\n decisionsCount += 1\n\n if (\n replayed.outcome !== recorded.outcome ||\n replayed.agentId !== recorded.agentId\n ) {\n divergences.push({\n eventId: event.id,\n decidedBy: recorded.decidedBy,\n expected: { agentId: recorded.agentId, outcome: recorded.outcome },\n actual: { agentId: replayed.agentId, outcome: replayed.outcome },\n reason: classifyDivergence(recorded, replayed),\n })\n }\n }\n\n return {\n eventsCount: events.length,\n decisionsCount,\n divergences,\n skipped: [],\n }\n}\n\n/** Build a \"playback policy\" that reproduces the recorded decision. The\n * policy is consulted only when the ledger's mechanics don't force the\n * outcome (active-task safety can override → \"deduped\"). When the\n * recorded outcome is \"deduped\", the policy returns null because that\n * outcome is ledger-managed and never produced by a policy. */\nfunction buildPlaybackPolicy(recorded: IntentDecision): DispatchPolicy {\n return {\n decidedBy: recorded.decidedBy,\n decide: (): PolicyDecision | null => {\n if (recorded.outcome === \"deduped\") return null\n return {\n agentId: recorded.agentId,\n outcome: recorded.outcome as PolicyDecision[\"outcome\"],\n reason: recorded.reason,\n }\n },\n }\n}\n\n/** Categorize the kind of replay divergence for triage. Not exhaustive\n * — operators add new categories by reading the divergence rows. */\nfunction classifyDivergence(\n recorded: IntentDecision,\n replayed: IntentDecision,\n): string {\n if (recorded.outcome === \"dispatched\" && replayed.outcome === \"deduped\") {\n return \"active-task-safety-now-fires (slot held by earlier decision)\"\n }\n if (recorded.outcome === \"deduped\" && replayed.outcome === \"halted\") {\n return \"policy-returned-null (recorded as deduped means the live system\" +\n \" hit active-task safety; playback policy returned null because\" +\n \" deduped is illegal at the policy layer — investigate whether the\" +\n \" in-flight decision is present in the snapshot)\"\n }\n if (recorded.agentId !== replayed.agentId) {\n return `agent-changed (recorded=${recorded.agentId} replayed=${replayed.agentId})`\n }\n if (recorded.outcome !== replayed.outcome) {\n return `outcome-changed (recorded=${recorded.outcome} replayed=${replayed.outcome})`\n }\n return \"unknown\"\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { existsSync } from \"fs\"\nimport { resolve } from \"path\"\nimport { DecisionStore, type GradedRowFilter } from \"@/decisions/store\"\nimport { calibrationReport, coverageCurve } from \"@/decisions/calibration\"\nimport { compareCalibrators } from \"@/decisions/recalibrate\"\nimport { measureConsistency } from \"@/decisions/consistency\"\nimport { getDecisionBackend, listDecisionBackends } from \"@/decisions/backend\"\nimport { registerBuiltinDecisionBackends } from \"@/decisions\"\nimport { choice, noul } from \"@/decisions/questions\"\nimport { backfillMonitorLabels } from \"@/decisions/seats/monitor-prefilter\"\nimport Database from \"better-sqlite3\"\n\n// --- agentx decisions ---\n//\n// Read-mostly triage CLI for the shadow store at\n// .agentx/decisions/decisions.sqlite. Built for the soak that has to happen\n// before any seat is promoted from `shadow` to `active`.\n//\n// `calibrate` is the command that decides whether a seat gets promoted, and\n// `coverage` is the one that says what threshold to promote it at. The rest\n// exist to feed those two.\n//\n// Only `label` writes. Everything else opens read-only.\n\nexport const decisions = new Command()\n .name(\"decisions\")\n .description(\"inspect the typed-decision shadow store (.agentx/decisions/decisions.sqlite)\")\n\nconst DEFAULT_PATH = \".agentx/decisions/decisions.sqlite\"\n\ninterface OpenOpts {\n cwd?: string\n path?: string\n}\n\nfunction storePath(opts: OpenOpts): string {\n return resolve(resolve(opts.cwd ?? process.cwd()), opts.path ?? DEFAULT_PATH)\n}\n\nfunction open(opts: OpenOpts, writable = false): DecisionStore {\n const path = storePath(opts)\n if (!existsSync(path)) {\n console.log(chalk.red(` No decision store at ${path}`))\n console.log(\n chalk.dim(\n ` Set decisions.enabled and give a seat mode \"shadow\" (or export ` +\n `AGENTX_DECISION_SEAT_<SEAT>=shadow). The file is created on the first recorded call.`,\n ),\n )\n process.exit(1)\n }\n try {\n return new DecisionStore({ path, readonly: !writable })\n } catch (e: any) {\n console.log(chalk.red(` Could not open ${path}: ${e.message}`))\n if (/NODE_MODULE_VERSION/.test(e.message)) {\n console.log(chalk.dim(` Run \\`pnpm rebuild better-sqlite3\\` under the daemon's Node version.`))\n }\n process.exit(1)\n }\n}\n\nfunction emit(rows: any[], asJson: boolean): void {\n if (asJson) {\n console.log(JSON.stringify(rows, null, 2))\n return\n }\n if (rows.length === 0) {\n console.log(chalk.dim(\" (no rows)\"))\n return\n }\n const cols = Object.keys(rows[0])\n const widths = cols.map((c) => Math.max(c.length, ...rows.map((r) => String(r[c] ?? \"\").length)))\n const fmt = (cells: any[]) => cells.map((v, i) => String(v ?? \"\").padEnd(widths[i])).join(\" \")\n console.log(chalk.bold(fmt(cols)))\n for (const row of rows) console.log(fmt(cols.map((c) => row[c])))\n}\n\n/** `--since 7d` / `12h` / `30m`, or an ISO date. */\nfunction parseSince(value?: string): number | undefined {\n if (!value) return undefined\n const rel = value.match(/^(\\d+)([dhm])$/)\n if (rel) {\n const n = Number(rel[1])\n const ms = rel[2] === \"d\" ? 86_400_000 : rel[2] === \"h\" ? 3_600_000 : 60_000\n return Date.now() - n * ms\n }\n const parsed = Date.parse(value)\n return Number.isNaN(parsed) ? undefined : parsed\n}\n\nfunction filterFrom(opts: any): GradedRowFilter {\n return {\n seat: opts.seat,\n question: opts.question,\n backend: opts.backend,\n model: opts.model,\n structureMode: opts.structureMode,\n since: parseSince(opts.since),\n labeledOnly: Boolean(opts.labeled),\n exploredOnly: Boolean(opts.explored),\n limit: opts.limit ? Number(opts.limit) : undefined,\n }\n}\n\ndecisions\n .command(\"stats\")\n .description(\"per-seat call counts, failure rate, repair rate and latency\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .option(\"--since <window>\", \"e.g. 7d, 12h, or an ISO date\")\n .option(\"--json\", \"raw JSON\")\n .action((opts) => {\n const store = open(opts)\n const since = parseSince(opts.since) ?? 0\n const rows = store.db\n .prepare(\n `SELECT seat, mode, backend, model, structure_mode AS structureMode,\n COUNT(*) AS calls,\n SUM(CASE WHEN error IS NOT NULL THEN 1 ELSE 0 END) AS failed,\n SUM(retries) AS retries,\n SUM(truncated) AS truncated,\n ROUND(AVG(latency_ms)) AS avgMs,\n SUM(input_tokens) AS inTokens\n FROM decision_calls\n WHERE ts >= ?\n GROUP BY seat, mode, backend, model, structure_mode\n ORDER BY calls DESC`,\n )\n .all(since)\n emit(rows, opts.json)\n\n const policy = store.db\n .prepare(\n `SELECT seat, mode, COALESCE(action,'(none)') AS action, explored, COUNT(*) AS calls\n FROM decision_calls WHERE ts >= ? GROUP BY seat, mode, action, explored\n ORDER BY calls DESC`,\n )\n .all(since) as Array<Record<string, unknown>>\n if (!opts.json && policy.length > 0) {\n console.log(chalk.bold(\"\\n policy\"))\n emit(policy, false)\n console.log(\n chalk.dim(\n \"\\n explored=1 means the policy wanted to skip and the expensive path ran anyway.\\n\" +\n \" Those are the only rows in the skip region that can ever be graded.\",\n ),\n )\n }\n store.close()\n })\n\ndecisions\n .command(\"calls\")\n .description(\"recent calls\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .option(\"--seat <seat>\")\n .option(\"--since <window>\")\n .option(\"--limit <n>\", \"default 20\", \"20\")\n .option(\"--json\")\n .action((opts) => {\n const store = open(opts)\n const where: string[] = [\"ts >= ?\"]\n const params: unknown[] = [parseSince(opts.since) ?? 0]\n if (opts.seat) (where.push(\"seat = ?\"), params.push(opts.seat))\n const rows = store.db\n .prepare(\n `SELECT id, datetime(ts/1000, 'unixepoch') AS at, seat, mode, backend, model,\n structure_mode AS structure, latency_ms AS ms, retries, truncated, error\n FROM decision_calls WHERE ${where.join(\" AND \")}\n ORDER BY ts DESC LIMIT ?`,\n )\n .all(...params, Number(opts.limit))\n emit(rows, opts.json)\n store.close()\n })\n\ndecisions\n .command(\"answers <callId>\")\n .description(\"every answer on one call, with its incumbent and label\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .option(\"--json\")\n .action((callId, opts) => {\n const store = open(opts)\n const rows = store.gradedRows({}).filter((r) => r.callId === callId)\n if (rows.length === 0) {\n console.log(chalk.dim(` (no answers for ${callId} — check \\`decisions calls\\`)`))\n store.close()\n return\n }\n emit(\n rows.map((r) => ({\n question: r.question,\n type: r.type,\n predicted: r.predicted,\n confidence: r.confidence.toFixed(3),\n incumbent: r.incumbent ?? \"\",\n truth: r.truth ?? \"\",\n })),\n opts.json,\n )\n store.close()\n })\n\ndecisions\n .command(\"label <callId> <question> <value>\")\n .description(\"attach ground truth to one answer (append-only; newest wins)\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .option(\"--kind <kind>\", \"human | outcome | replay\", \"human\")\n .option(\"--by <who>\")\n .option(\"--note <text>\")\n .action((callId, question, value, opts) => {\n const store = open(opts, true)\n store.label(callId, question, value, {\n kind: opts.kind,\n labeledBy: opts.by,\n note: opts.note,\n })\n console.log(chalk.green(` labeled ${callId}.${question} = ${value}`))\n store.close()\n })\n\ndecisions\n .command(\"unlabeled\")\n .description(\"lowest-confidence unlabeled answers first — the most informative to label\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .option(\"--seat <seat>\")\n .option(\"--limit <n>\", \"default 20\", \"20\")\n .option(\"--json\")\n .action((opts) => {\n const store = open(opts)\n const rows = store\n .gradedRows({ seat: opts.seat })\n .filter((r) => r.truth === undefined)\n .sort((a, b) => a.confidence - b.confidence)\n .slice(0, Number(opts.limit))\n emit(\n rows.map((r) => ({\n callId: r.callId,\n question: r.question,\n predicted: r.predicted,\n confidence: r.confidence.toFixed(3),\n incumbent: r.incumbent ?? \"\",\n })),\n opts.json,\n )\n store.close()\n })\n\ndecisions\n .command(\"backfill-labels\")\n .description(\"derive ground truth from what actually happened (monitor-prefilter seat)\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .option(\"--db <file>\", \"observability db holding session_reviews\", \".agentx/db.sqlite\")\n .action((opts) => {\n const store = open(opts, true)\n const dbPath = resolve(process.cwd(), opts.db)\n if (!existsSync(dbPath)) {\n console.log(chalk.red(` No observability db at ${dbPath}`))\n store.close()\n process.exit(1)\n }\n const db = new Database(dbPath, { readonly: true })\n try {\n const n = backfillMonitorLabels(db, store)\n console.log(chalk.green(` wrote ${n} label(s)`))\n if (n === 0) {\n console.log(\n chalk.dim(\n \" Rows whose outcome is genuinely ambiguous stay unlabeled on purpose —\\n\" +\n \" label those by hand: agentx decisions unlabeled --seat monitor-prefilter\",\n ),\n )\n }\n } finally {\n db.close()\n store.close()\n }\n })\n\ndecisions\n .command(\"calibrate\")\n .description(\"is this seat's confidence worth anything? reliability, ECE, Brier, temperature\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .requiredOption(\"--seat <seat>\")\n .option(\"--question <name>\")\n .option(\"--backend <name>\", \"grade one backend in isolation\")\n .option(\"--model <id>\")\n .option(\"--structure-mode <mode>\", \"never pool verbalized and logprob rows\")\n .option(\"--since <window>\")\n .option(\"--explored\", \"only rows the policy wanted to skip — the unbiased skip-region sample\")\n .option(\"--min-n <n>\", \"refuse to report below this many labeled rows\", \"100\")\n .option(\"--bins <n>\", \"default 10\", \"10\")\n .option(\"--json\")\n .action((opts) => {\n const store = open(opts)\n const rows = store.gradedRows(filterFrom(opts))\n const report = calibrationReport(rows, {\n minN: Number(opts.minN),\n bins: Number(opts.bins),\n })\n\n if (opts.json) {\n console.log(JSON.stringify(report, null, 2))\n store.close()\n return\n }\n\n console.log(chalk.bold(`\\n ${opts.seat}${opts.question ? `.${opts.question}` : \"\"}`))\n console.log(\n ` ${report.n} answers, ${report.nLabeled} labeled` +\n (report.agreement.n > 0\n ? `, ${report.agreement.n} with an incumbent (agree ${(report.agreement.rate * 100).toFixed(1)}%, kappa ${report.agreement.kappa.toFixed(3)})`\n : \"\"),\n )\n\n if (report.insufficient) {\n console.log(\n chalk.yellow(\n `\\n Not enough ground truth: ${report.nLabeled} labeled rows, need ${report.minN}.`,\n ),\n )\n console.log(\n chalk.dim(\n ` An ECE on this little data is noise, and a noisy number on a dashboard gets acted on.`,\n ),\n )\n console.log(chalk.dim(` Label the most informative rows: agentx decisions unlabeled --seat ${opts.seat}`))\n store.close()\n return\n }\n\n console.log(`\\n accuracy ${(report.accuracy! * 100).toFixed(1)}%`)\n console.log(\n ` ECE ${report.ece!.toFixed(4)} ` +\n chalk.dim(`[95% CI ${report.eceInterval!.lo.toFixed(4)}–${report.eceInterval!.hi.toFixed(4)}]`),\n )\n console.log(` ECE (mass) ${report.eceEqualMass!.toFixed(4)} ${chalk.dim(\"equal-mass bins\")}`)\n console.log(` MCE ${report.mce!.toFixed(4)} ${chalk.dim(\"worst single bin\")}`)\n console.log(` Brier ${report.brier!.toFixed(4)} ${chalk.dim(\"proper score, lower is better\")}`)\n console.log(` log loss ${report.logLoss!.toFixed(4)}`)\n\n const fit = report.temperature!\n console.log(\n `\\n fitted temperature ${fit.temperature} ` +\n chalk.dim(`(NLL ${fit.nllBefore.toFixed(4)} → ${fit.nll.toFixed(4)})`),\n )\n if (fit.temperature > 1.15) {\n console.log(\n chalk.dim(\n ` T > 1 means the backend is overconfident. Set decisions.seats.${opts.seat}.temperature = ${fit.temperature}.`,\n ),\n )\n }\n\n const skipRegion = rows.filter((r) => r.action === \"skip\")\n const gradeable = skipRegion.filter((r) => r.explored && r.truth !== undefined)\n if (skipRegion.length > 0) {\n console.log(\n `\\n skip region ${skipRegion.length} answers ` +\n `(${((skipRegion.length / rows.length) * 100).toFixed(1)}% of traffic), ` +\n `${gradeable.length} gradeable`,\n )\n if (gradeable.length === 0) {\n console.log(\n chalk.yellow(\n \" Nothing in the skip region has been graded. Everything below describes\\n\" +\n \" only the decisions this policy chose NOT to skip — it cannot tell you\\n\" +\n \" what skipping would cost. Raise decisions.seats.<seat>.explore.\",\n ),\n )\n }\n }\n\n console.log(chalk.bold(\"\\n reliability (equal-width bins)\"))\n emit(\n report.bins!.map((b) => ({\n bin: `${b.lo.toFixed(2)}–${b.hi.toFixed(2)}`,\n n: b.n,\n claimed: b.meanConfidence.toFixed(3),\n actual: b.accuracy.toFixed(3),\n gap: (b.accuracy - b.meanConfidence).toFixed(3),\n })),\n false,\n )\n store.close()\n })\n\ndecisions\n .command(\"recalibrate\")\n .description(\"is one global temperature enough, or does calibration differ by group?\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .requiredOption(\"--seat <seat>\")\n .option(\"--question <name>\")\n .option(\"--since <window>\")\n .option(\"--by <names>\", \"comma-separated covariates\", \"agent,question\")\n .option(\"--folds <n>\", \"cross-validation folds\", \"5\")\n .option(\"--min-n <n>\", \"default 100\", \"100\")\n .option(\"--json\")\n .action((opts) => {\n const store = open(opts)\n const rows = store.gradedRows(filterFrom(opts))\n const covariates = String(opts.by).split(\",\").map((c: string) => c.trim()).filter(Boolean)\n const result = compareCalibrators(rows, { covariates }, {\n folds: Number(opts.folds),\n minN: Number(opts.minN),\n })\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2))\n store.close()\n return\n }\n\n if (result.insufficient) {\n console.log(\n chalk.yellow(` ${result.n} labeled rows, need ${result.minN}.`),\n )\n store.close()\n return\n }\n\n console.log(chalk.bold(`\\n ${opts.seat} — held-out comparison (${result.folds}-fold, n=${result.n})`))\n console.log(chalk.dim(\" Cross-validated, because more parameters always fit training data better.\\n\"))\n emit(\n result.scores.map((s) => ({\n model: s.name,\n logLoss: s.logLoss.toFixed(4),\n brier: s.brier.toFixed(4),\n best: s.name === result.best ? \"<-\" : \"\",\n })),\n false,\n )\n\n if (result.best === \"covariate\") {\n console.log(\n chalk.green(\n `\\n Calibration differs by ${covariates.join(\"/\")} — a single temperature averages groups`,\n ),\n )\n console.log(chalk.dim(\" that need different corrections.\"))\n } else if (result.best === \"temperature\") {\n console.log(\n chalk.dim(\n `\\n One global temperature is enough. ${covariates.join(\"/\")} carries no calibration signal here.`,\n ),\n )\n } else {\n console.log(\n chalk.dim(\"\\n Neither correction beats the raw confidence out of sample. Leave it alone.\"),\n )\n }\n store.close()\n })\n\ndecisions\n .command(\"coverage\")\n .description(\"accuracy at each threshold against the traffic it keeps — read this to pick one\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .requiredOption(\"--seat <seat>\")\n .option(\"--question <name>\")\n .option(\"--since <window>\")\n .option(\"--explored\", \"only rows the policy wanted to skip\")\n .option(\"--steps <n>\", \"default 20\", \"20\")\n .option(\"--json\")\n .action((opts) => {\n const store = open(opts)\n const rows = store.gradedRows({ ...filterFrom(opts), labeledOnly: true })\n const curve = coverageCurve(rows, Number(opts.steps))\n if (curve.length === 0) {\n console.log(chalk.yellow(` No labeled rows for seat \"${opts.seat}\".`))\n store.close()\n return\n }\n emit(\n curve.map((p) => ({\n threshold: p.threshold.toFixed(2),\n coverage: `${(p.coverage * 100).toFixed(1)}%`,\n accuracy: `${(p.accuracy * 100).toFixed(1)}%`,\n n: p.n,\n })),\n opts.json,\n )\n store.close()\n })\n\ndecisions\n .command(\"consistency\")\n .description(\"does the question hold still? resample one recorded state N times\")\n .option(\"--path <file>\", \"store path\", DEFAULT_PATH)\n .requiredOption(\"--seat <seat>\")\n .option(\"--backend <name>\", \"default: the backend that recorded the row\")\n .option(\"--model <id>\")\n .option(\"--call <id>\", \"a specific call id; default is the newest with stored state\")\n .option(\"-n, --samples <n>\", \"default 15\", \"15\")\n .option(\"--json\")\n .action(async (opts) => {\n registerBuiltinDecisionBackends()\n const store = open(opts)\n const row = store.db\n .prepare(\n `SELECT id, backend, model, state_json, questions_json FROM decision_calls\n WHERE seat = ? AND state_json IS NOT NULL AND error IS NULL\n ${opts.call ? \"AND id = ?\" : \"\"}\n ORDER BY ts DESC LIMIT 1`,\n )\n .get(...(opts.call ? [opts.seat, opts.call] : [opts.seat])) as\n | { id: string; backend: string; model: string; state_json: string; questions_json: string }\n | undefined\n\n if (!row) {\n console.log(chalk.yellow(` No recorded call with stored state for seat \"${opts.seat}\".`))\n console.log(chalk.dim(\" State is kept for the first `keepStateRows` per seat; see decisions.redactState.\"))\n store.close()\n return\n }\n\n const backend = opts.backend ?? row.backend\n // The store records the RESOLVED model (\"typesafe/jev-1.13-20260917\"),\n // which is not a valid request id anywhere except the backend that\n // resolved it — the direct TypeSafe API 400s on OpenRouter's form. So\n // only reuse it when resampling on the same backend; otherwise let the\n // target backend apply its own default.\n const model = opts.model ?? (backend === row.backend ? row.model : undefined)\n const report = await measureConsistency(\n backend,\n JSON.parse(row.state_json),\n JSON.parse(row.questions_json),\n { samples: Number(opts.samples), model },\n )\n\n if (opts.json) {\n console.log(JSON.stringify(report, null, 2))\n store.close()\n return\n }\n\n console.log(chalk.bold(`\\n ${opts.seat} on ${report.backend} (${report.model})`))\n console.log(\n chalk.dim(\n ` ${report.samples} samples of call ${row.id}, ${report.totalMs}ms, ` +\n `${report.usage.inputTokens.toLocaleString()} input tokens\\n`,\n ),\n )\n emit(\n report.questions.map((q) => ({\n question: q.question,\n mean: q.mean.toFixed(4),\n stdev: q.stdev.toFixed(4),\n min: q.min.toFixed(3),\n max: q.max.toFixed(3),\n answers: q.distinctAnswers.join(\"/\"),\n band: q.bands.join(\"/\"),\n stable: q.crossesThreshold ? chalk.red(\"NO\") : \"yes\",\n })),\n false,\n )\n console.log(`\\n mean stdev ${report.meanStdev.toFixed(4)}`)\n console.log(\n chalk.dim(\" TypeSafe publish 0.0102 for jev across a 14-question rubric, as a reference.\"),\n )\n if (report.unstable.length > 0) {\n console.log(\n chalk.red(\n `\\n Unstable: ${report.unstable.join(\", \")} — identical calls disagree about what to DO,`,\n ),\n )\n console.log(\n chalk.dim(\n \" not merely by how much. Usually a compound question: one name, several questions.\\n\" +\n \" Split it, or narrow it to a single clause in the state's own vocabulary.\",\n ),\n )\n } else {\n console.log(chalk.green(\"\\n Every question held its decision across all samples.\"))\n }\n console.log(\n chalk.dim(\n \"\\n Stability is not correctness. A question can hold perfectly still and be\\n\" +\n \" perfectly wrong — that is what `decisions calibrate` is for.\",\n ),\n )\n store.close()\n })\n\ndecisions\n .command(\"backends\")\n .description(\"registered decision backends and what they claim\")\n .action(() => {\n registerBuiltinDecisionBackends()\n const rows = listDecisionBackends().map((name) => {\n const caps = getDecisionBackend(name).capabilities\n return {\n backend: name,\n source: caps.probabilitySource,\n calibrated: caps.calibratedProbabilities ? \"yes\" : \"no\",\n maxOptions: caps.maxChoiceOptions,\n maxStateChars: caps.maxStateChars,\n }\n })\n emit(rows, false)\n console.log(\n chalk.dim(\n `\\n source where the numbers come from. \"verbalized\" means the model wrote them\\n` +\n ` into its answer; \"logits\" means they were read off its next-token\\n` +\n ` distribution. Logits are the model's actual posterior — verbalized\\n` +\n ` ones are quantized at round values and are not.\\n` +\n ` calibrated whether an answer given 0.8 is right about 80% of the time ON YOUR\\n` +\n ` traffic. Reading real logits does not buy this: a posterior can be\\n` +\n ` confidently wrong. It comes from a recalibrator fitted on your own\\n` +\n ` labeled rows — see \\`agentx decisions recalibrate\\`.`,\n ),\n )\n })\n\ndecisions\n .command(\"ask\")\n .description(\"one-off smoke test against a backend (does not record)\")\n .requiredOption(\"--state <text>\", \"the state to evaluate\")\n .option(\"--backend <name>\", \"default mock\", \"mock\")\n .option(\"--model <id>\")\n .option(\"--choice <labels>\", \"comma-separated options for a choice question\")\n .option(\"--noul <question>\", \"a yes/no question\")\n .action(async (opts) => {\n registerBuiltinDecisionBackends()\n const questions: Record<string, any> = {}\n if (opts.choice) {\n const criteria: Record<string, null> = {}\n for (const label of String(opts.choice).split(\",\").map((s) => s.trim())) {\n if (label) criteria[label] = null\n }\n questions.answer = choice(criteria, \"Which option fits this state?\")\n }\n if (opts.noul) questions.verdict = noul(String(opts.noul))\n if (Object.keys(questions).length === 0) {\n console.log(chalk.red(\" Give at least one of --choice or --noul.\"))\n process.exit(1)\n }\n\n const backend = getDecisionBackend(opts.backend)\n const res = await backend.decide({ state: opts.state, questions, model: opts.model })\n console.log(JSON.stringify(res, null, 2))\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { resolve } from \"path\"\nimport { existsSync } from \"fs\"\nimport Database from \"better-sqlite3\"\nimport { getTrace, listTraces, type TraceRecord, type TraceStepRecord } from \"@/storage/traces\"\n\n// --- agentx trace ---\n//\n// Read-only triage CLI for the per-task execution traces persisted at\n// .agentx/db.sqlite (improvement plan #2). Pairs with the\n// HTTP endpoints (GET /traces, GET /traces/:taskId) — same store, two\n// access surfaces. Operators in a hurry tail this; dashboard consumers\n// hit the HTTP routes.\n//\n// Use `--path` to point at an alternate db (e.g., one rsync'd from\n// a remote daemon). Default is .agentx/db.sqlite in the cwd.\n\nexport const trace = new Command()\n .name(\"trace\")\n .description(\"inspect per-task execution traces (.agentx/db.sqlite)\")\n\ninterface OpenOpts {\n cwd?: string\n path?: string\n}\n\nfunction openReadOnly(opts: OpenOpts) {\n const root = resolve(opts.cwd ?? process.cwd())\n const path = resolve(root, opts.path ?? \".agentx/db.sqlite\")\n if (!existsSync(path)) {\n console.log(chalk.red(` No db at ${path}`))\n console.log(chalk.dim(` The file is created on first SQLite write — start the daemon and run a task.`))\n process.exit(1)\n }\n try {\n return new Database(path, { readonly: true })\n } catch (e: any) {\n console.log(chalk.red(` Could not open ${path}: ${e.message}`))\n if (/NODE_MODULE_VERSION/.test(e.message)) {\n console.log(chalk.dim(` Run \\`pnpm rebuild better-sqlite3\\` under the daemon's Node version.`))\n }\n process.exit(1)\n }\n}\n\nfunction durationToMs(input: string): number | null {\n const m = /^(\\d+)\\s*([smhd])$/.exec(input.trim())\n if (!m) return null\n const n = Number(m[1])\n const unit = m[2]\n const factor = unit === \"s\" ? 1000 : unit === \"m\" ? 60_000 : unit === \"h\" ? 3600_000 : 86_400_000\n return n * factor\n}\n\nfunction parseSince(input: string | undefined): number | undefined {\n if (!input) return undefined\n const ms = durationToMs(input)\n if (ms === null) {\n const n = Number(input)\n if (Number.isFinite(n) && n > 0) return n\n console.log(chalk.red(` Invalid --since \"${input}\". Use \"1h\", \"30m\", \"7d\", or an ms epoch.`))\n process.exit(1)\n }\n return Date.now() - ms!\n}\n\nfunction fmtAge(ms: number): string {\n const s = Math.round((Date.now() - ms) / 1000)\n if (s < 60) return `${s}s ago`\n if (s < 3600) return `${Math.round(s / 60)}m ago`\n if (s < 86400) return `${Math.round(s / 3600)}h ago`\n return `${Math.round(s / 86400)}d ago`\n}\n\nfunction statusColor(s: string): (text: string) => string {\n if (s === \"ok\") return chalk.green\n if (s === \"error\" || s === \"timeout\") return chalk.red\n if (s === \"in-flight\") return chalk.yellow\n return chalk.dim\n}\n\n// ---------------------------------------------------------------------------\n// agentx trace list\n// ---------------------------------------------------------------------------\n\ntrace\n .command(\"list\")\n .description(\"list recent traces (newest first)\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--path <path>\", \"db path relative to cwd\", \".agentx/db.sqlite\")\n .option(\"--agent <id>\", \"filter by agentId\")\n .option(\"--channel <name>\", \"filter by channel (telegram|whatsapp|gitlab|...)\")\n .option(\"--chat <id>\", \"filter by chatId\")\n .option(\"--workflow <runId>\", \"filter by workflowRunId\")\n .option(\"--status <s>\", \"filter by status (in-flight|ok|error|timeout)\")\n .option(\"--since <duration>\", \"limit to traces newer than (e.g. 1h, 24h, 7d)\")\n .option(\"--limit <n>\", \"max rows\", \"50\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const db = openReadOnly(opts)\n const traces = listTraces(db, {\n agentId: opts.agent,\n channel: opts.channel,\n chatId: opts.chat,\n workflowRunId: opts.workflow,\n status: opts.status,\n since: parseSince(opts.since),\n limit: parseInt(opts.limit, 10) || 50,\n })\n\n if (opts.json) {\n console.log(JSON.stringify(traces, null, 2))\n return\n }\n if (traces.length === 0) {\n console.log(chalk.dim(\" (no traces)\"))\n return\n }\n\n for (const t of traces) {\n const status = statusColor(t.status)(t.status.padEnd(9))\n const dur = t.durationMs != null ? `${(t.durationMs / 1000).toFixed(2)}s` : \"—\"\n const wf = t.workflowRunId ? chalk.cyan(` wf=${t.workflowRunId}`) : \"\"\n const tokens = t.inputTokens != null\n ? chalk.dim(` ${t.inputTokens}/${t.outputTokens ?? 0} tok`)\n : \"\"\n console.log(\n `${chalk.dim(t.taskId)} ${status} ${chalk.bold(t.agentId)}` +\n `${chalk.dim(` ${t.channel ?? \"—\"}:${t.chatId ?? \"—\"}`)}${wf}` +\n ` ${chalk.dim(\"·\")} ${dur}${tokens} ${chalk.dim(fmtAge(t.startedAt))}`,\n )\n if (t.error) console.log(` ${chalk.red(\"error:\")} ${t.error}`)\n }\n })\n\n// ---------------------------------------------------------------------------\n// agentx trace show <taskId>\n// ---------------------------------------------------------------------------\n\ntrace\n .command(\"show <taskId>\")\n .description(\"show one trace with its full ordered step log\")\n .option(\"--cwd <cwd>\", \"working directory\", process.cwd())\n .option(\"--path <path>\", \"db path relative to cwd\", \".agentx/db.sqlite\")\n .option(\"--json\", \"emit JSON\")\n .action((taskId: string, opts) => {\n const db = openReadOnly(opts)\n const rec = getTrace(db, taskId)\n if (!rec) {\n console.log(chalk.red(` No trace at ${taskId}`))\n process.exit(1)\n }\n if (opts.json) {\n console.log(JSON.stringify(rec, null, 2))\n return\n }\n printTrace(rec.task, rec.steps)\n })\n\nfunction printTrace(t: TraceRecord, steps: TraceStepRecord[]): void {\n const status = statusColor(t.status)(t.status)\n console.log(chalk.bold(`Trace ${t.taskId}`))\n console.log(` ${chalk.dim(\"agent\")} ${t.agentId}`)\n console.log(` ${chalk.dim(\"channel\")} ${t.channel ?? \"—\"}:${t.chatId ?? \"—\"}`)\n if (t.workflowRunId) {\n const wfPart = [t.workflowId, t.workflowNodeId].filter(Boolean).join(\"/\")\n console.log(` ${chalk.dim(\"workflow\")} ${chalk.cyan(t.workflowRunId)}${wfPart ? chalk.dim(` (${wfPart})`) : \"\"}`)\n }\n if (t.intentEventId) {\n console.log(` ${chalk.dim(\"intent\")} ${t.intentEventId} ${chalk.dim(`(${t.intentDecidedBy ?? \"?\"})`)}`)\n }\n if (t.model) console.log(` ${chalk.dim(\"model\")} ${t.model}`)\n if (t.resumeSessionId) console.log(` ${chalk.dim(\"resume\")} ${t.resumeSessionId.slice(0, 12)}…`)\n if (t.finalSessionId) console.log(` ${chalk.dim(\"final\")} ${t.finalSessionId.slice(0, 12)}…`)\n console.log(` ${chalk.dim(\"status\")} ${status}`)\n if (t.durationMs != null) {\n console.log(` ${chalk.dim(\"duration\")} ${(t.durationMs / 1000).toFixed(2)}s`)\n }\n if (t.inputTokens != null || t.outputTokens != null) {\n console.log(` ${chalk.dim(\"tokens\")} in=${t.inputTokens ?? 0} out=${t.outputTokens ?? 0} ` +\n `cache_read=${t.cacheReadTokens ?? 0} cache_create=${t.cacheCreateTokens ?? 0}`)\n }\n if (t.error) console.log(` ${chalk.red(\"error\")} ${t.error}`)\n if (t.messagePreview) console.log(` ${chalk.dim(\"message\")} ${t.messagePreview}`)\n console.log()\n\n if (steps.length === 0) {\n console.log(chalk.dim(` (no recorded steps — task may have been on a non-streaming tier or completed before any tool call)`))\n return\n }\n console.log(chalk.bold(`Steps (${steps.length}):`))\n for (const s of steps) {\n const stepStatus = s.status ? statusColor(s.status)(s.status) : chalk.dim(\"—\")\n const action = s.action ? chalk.cyan(s.action) : \"\"\n console.log(` ${chalk.dim(`#${s.seq}`)} ${chalk.bold(s.name)}${action ? \" \" + action : \"\"} ${stepStatus}` +\n `${s.ms != null ? chalk.dim(` ${s.ms}ms`) : \"\"}`)\n if (s.inputSummary) {\n const lines = s.inputSummary.split(\"\\n\").slice(0, 8)\n console.log(lines.map((l) => ` ${chalk.dim(\"→\")} ${l}`).join(\"\\n\"))\n if (s.inputSummary.split(\"\\n\").length > 8) console.log(` ${chalk.dim(\"…\")}`)\n }\n if (s.outputSummary) {\n const lines = s.outputSummary.split(\"\\n\").slice(0, 8)\n console.log(lines.map((l) => ` ${chalk.dim(\"←\")} ${l}`).join(\"\\n\"))\n if (s.outputSummary.split(\"\\n\").length > 8) console.log(` ${chalk.dim(\"…\")}`)\n }\n if (s.error) console.log(` ${chalk.red(\"error:\")} ${s.error}`)\n }\n}\n\n// --- agentx trace replay <taskId> [--diff] ----------------------------------\n//\n// Handoff item #11. Loads a recorded task by id, re-fires it via the daemon's\n// POST /task with the same agent + a fresh session, and prints the new run's\n// reply. With --diff, shows a side-by-side comparison of original input,\n// original output (if captured), and the new output — directly answers\n// \"did my prompt change fix it?\" without rerunning by hand.\n//\n// Replay reads the trace from a local SQLite db (or one rsync'd from a\n// remote daemon via --path). Old rows pre-migration-v8 fall back to\n// messagePreview (capped 200 chars), with a warning that the input\n// may be truncated relative to the original.\n\ntrace\n .command(\"replay <taskId>\")\n .description(\"re-run a recorded task against the current agent config (handoff item #11)\")\n .option(\"--cwd <dir>\", \"project root\", process.cwd())\n .option(\"--path <p>\", \"sqlite db path (relative to --cwd)\", \".agentx/db.sqlite\")\n .option(\"--daemon <url>\", \"daemon API base URL\", \"http://127.0.0.1:18800\")\n .option(\"--diff\", \"show original input + output vs new output side-by-side\")\n .option(\"--no-fresh\", \"do NOT freshSession (default is fresh — required for clean replay)\")\n .action(async (taskId: string, opts) => {\n const db = openReadOnly(opts)\n const trace = getTrace(db, taskId)\n if (!trace) {\n console.log(chalk.red(` task not found: ${taskId}`))\n console.log(chalk.dim(` agentx trace list — see what's available`))\n process.exit(1)\n }\n const t = trace.task\n const message = t.originalMessage ?? t.messagePreview\n if (!message) {\n console.log(chalk.red(` task ${taskId} has no recorded input message — cannot replay`))\n process.exit(1)\n }\n const truncated = !t.originalMessage && t.messagePreview != null\n if (truncated) {\n console.log(chalk.yellow(` ⚠ pre-migration-v8 row: input message was capped at 200 chars; replay uses the preview`))\n }\n\n console.log()\n console.log(chalk.bold(` replay ${chalk.cyan(taskId)}`))\n console.log(chalk.dim(` agent=${t.agentId} channel=${t.channel ?? \"—\"} chatId=${t.chatId ?? \"—\"}`))\n console.log(chalk.dim(` original status=${t.status} duration=${t.durationMs ?? \"?\"}ms tokens=in:${t.inputTokens ?? 0}/out:${t.outputTokens ?? 0}`))\n console.log()\n\n const base = String(opts.daemon).replace(/\\/+$/, \"\")\n const body = {\n agent: t.agentId,\n message,\n freshSession: opts.fresh !== false,\n context: {\n channel: t.channel ?? \"api\",\n // Per-replay chatId so the new run doesn't pollute (or get polluted by)\n // the original conversation's session. Operators can pin to the original\n // chatId via --no-fresh + a different invocation if they want continuity.\n chatId: `replay-${taskId.toLowerCase().slice(-8)}-${Date.now().toString(36)}`,\n },\n }\n const startedAt = Date.now()\n let res: Response\n try {\n res = await fetch(`${base}/task`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n })\n } catch (e: any) {\n console.log(chalk.red(` daemon unreachable at ${base}: ${e.message || e}`))\n process.exit(1)\n }\n const reply = await res.json().catch(() => ({})) as {\n content?: string\n error?: string\n duration?: number\n usage?: { inputTokens?: number; outputTokens?: number }\n }\n const durationMs = Date.now() - startedAt\n\n if (!res.ok) {\n console.log(chalk.red(` replay failed (${res.status}): ${reply.error || \"unknown error\"}`))\n process.exit(1)\n }\n\n if (opts.diff) {\n console.log(chalk.bold(\" INPUT (replayed verbatim)\"))\n console.log()\n printBlock(message)\n console.log()\n console.log(chalk.bold(` ORIGINAL OUTPUT ${chalk.dim(`status=${t.status} ${t.durationMs ?? \"?\"}ms`)}`))\n console.log()\n if (t.finalResponse) {\n printBlock(t.finalResponse)\n } else {\n console.log(chalk.yellow(` (not captured — pre-migration-v8 row, or response was empty)`))\n }\n console.log()\n console.log(chalk.bold(` CURRENT OUTPUT ${chalk.dim(`status=${reply.error ? \"error\" : \"ok\"} ${durationMs}ms tokens=in:${reply.usage?.inputTokens ?? 0}/out:${reply.usage?.outputTokens ?? 0}`)}`))\n console.log()\n printBlock(reply.content ?? \"(empty reply)\")\n if (reply.error) console.log(chalk.red(` error: ${reply.error}`))\n console.log()\n // Quick literal-diff signal — true when the two strings differ.\n // This is intentionally simple (no character-level diff) — operators\n // skim for \"did anything change?\" before deep-reading both blocks.\n const same = (t.finalResponse ?? \"\").trim() === (reply.content ?? \"\").trim()\n if (t.finalResponse) {\n console.log(same\n ? chalk.dim(\" outputs are identical\")\n : chalk.yellow(\" outputs differ — read both blocks to see what changed\"))\n console.log()\n }\n } else {\n console.log(chalk.green(` ✓ replayed in ${durationMs}ms`))\n console.log()\n printBlock(reply.content ?? \"(empty reply)\")\n if (reply.error) console.log(chalk.red(`\\n error: ${reply.error}`))\n console.log()\n console.log(chalk.dim(` agentx trace replay ${taskId} --diff to compare against the original output`))\n console.log()\n }\n })\n\n/** Print a multi-line block with consistent indent + a left bar so the block\n * visually separates from surrounding chrome. Caps very long blocks at 60\n * lines with a \"…+N more\" footer; the full content is still in the trace\n * store for those who need it. */\nfunction printBlock(text: string): void {\n const lines = text.split(\"\\n\")\n const max = 60\n const shown = lines.slice(0, max)\n for (const l of shown) console.log(` ${chalk.dim(\"│\")} ${l}`)\n if (lines.length > max) {\n console.log(` ${chalk.dim(\"│\")} ${chalk.dim(`…+${lines.length - max} more lines`)}`)\n }\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { existsSync, mkdirSync, writeFileSync } from \"fs\"\nimport { resolve, join, dirname } from \"path\"\nimport {\n runGuard,\n runCheckFromStdin,\n listDecisions,\n loadPolicy,\n guessInstallRoot,\n GUARDRAILS_DIR,\n type GuardMode,\n type Verdict,\n} from \"@/guard\"\nimport { SEED_FILES } from \"@/guard/seeds\"\n\n// --- agentx guard ---\n//\n// Destructive-action guardrails (PRD: AgentX Destructive-Action Guardrails).\n// `check` is the PreToolUse hook entrypoint (stdin -> stdout). The rest are\n// operator tools: dry-run a command (`test`), read the audit trail (`log`),\n// scaffold policy (`init`), and ping the daemon (`reload`).\n\nexport const guard = new Command().name(\"guard\").description(\"destructive-action guardrails — policy, checks, audit\")\n\nfunction actionColor(a: string): (s: string) => string {\n if (a === \"deny\") return chalk.red\n if (a === \"escalate\" || a === \"ask\") return chalk.yellow\n if (a === \"warn\") return chalk.magenta\n return chalk.green\n}\n\nfunction rootOf(opts: { root?: string }): string {\n return opts.root ? resolve(opts.root) : guessInstallRoot()\n}\n\n// ---------------------------------------------------------------------------\n// agentx guard check (PreToolUse hook entrypoint — reads stdin)\n// ---------------------------------------------------------------------------\nguard\n .command(\"check\")\n .description(\"PreToolUse hook entrypoint: read a tool-call payload on stdin, emit a Claude Code decision\")\n .option(\"--agent <id>\", \"agent id this workspace belongs to\")\n .option(\"--root <dir>\", \"AgentX install root (holds .agentx/guardrails + .agentx/db.sqlite)\")\n .option(\"--env <name>\", \"environment scope (e.g. production)\")\n .action(async (opts) => {\n await runCheckFromStdin({ root: rootOf(opts), agentId: opts.agent, env: opts.env })\n // Always exit 0 — the guard fails open at the hook layer; real blocking is\n // via the JSON decision on stdout, never a nonzero exit.\n process.exit(0)\n })\n\n// ---------------------------------------------------------------------------\n// agentx guard test \"<command>\" (dry-run through the engine)\n// ---------------------------------------------------------------------------\nguard\n .command(\"test <command>\")\n .description(\"dry-run a command through the policy engine and print the verdict\")\n .option(\"--agent <id>\", \"evaluate as this agent\")\n .option(\"--env <name>\", \"environment scope\")\n .option(\"--tool <name>\", \"tool name\", \"Bash\")\n .option(\"--cwd <dir>\", \"workspace cwd for $VAR/.env resolution\", process.cwd())\n .option(\"--root <dir>\", \"AgentX install root (policy source)\")\n .option(\"--enforce\", \"evaluate as if mode=enforce (show what WOULD block)\")\n .option(\"--json\", \"emit JSON\")\n .action((command: string, opts) => {\n const root = rootOf(opts)\n const modeOverride: GuardMode | undefined = opts.enforce ? \"enforce\" : undefined\n const { verdict, mode, ms } = runGuard(\n { tool: opts.tool, command, cwd: opts.cwd, agentId: opts.agent, env: opts.env },\n { root, agentId: opts.agent, env: opts.env, modeOverride, noAudit: true },\n )\n if (opts.json) {\n console.log(JSON.stringify({ verdict, mode, ms }, null, 2))\n return\n }\n printVerdict(verdict, mode, ms)\n })\n\nfunction printVerdict(v: Verdict, mode: string, ms: number) {\n const col = actionColor(v.action)\n console.log()\n console.log(` policy verdict ${col(v.action.toUpperCase())}${v.matched ? \"\" : chalk.dim(\" (no rule matched)\")}`)\n console.log(` enforced as ${actionColor(v.effectiveAction)(v.effectiveAction)} ${chalk.dim(`(mode=${mode})`)}`)\n if (v.ruleId) console.log(` rule ${chalk.cyan(v.ruleId)}${v.severity ? chalk.dim(` [${v.severity}]`) : \"\"}`)\n if (v.resolvedTarget) console.log(` resolved target ${chalk.yellow(v.resolvedTarget)}`)\n if (v.message) console.log(` message ${v.message}`)\n console.log(` ${chalk.dim(`evaluated in ${ms}ms`)}`)\n console.log()\n}\n\n// ---------------------------------------------------------------------------\n// agentx guard log (read the audit trail)\n// ---------------------------------------------------------------------------\nguard\n .command(\"log\")\n .description(\"read the guardrail decision audit trail (newest first)\")\n .option(\"--root <dir>\", \"AgentX install root (holds .agentx/db.sqlite)\")\n .option(\"--verdict <v>\", \"filter by verdict (deny|escalate|warn|allow)\")\n .option(\"--agent <id>\", \"filter by agent\")\n .option(\"--task <id>\", \"filter by task id\")\n .option(\"-n, --limit <n>\", \"max rows\", \"30\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const rows = listDecisions({\n root: rootOf(opts),\n verdict: opts.verdict,\n agentId: opts.agent,\n taskId: opts.task,\n limit: parseInt(opts.limit, 10) || 30,\n })\n if (opts.json) {\n console.log(JSON.stringify(rows, null, 2))\n return\n }\n if (rows.length === 0) {\n console.log(chalk.dim(\" (no guardrail decisions recorded yet)\"))\n return\n }\n for (const r of rows) {\n const when = new Date(r.ts).toISOString().replace(\"T\", \" \").slice(0, 19)\n const col = actionColor(r.verdict)\n const eff = r.effective_action !== r.verdict ? chalk.dim(`->${r.effective_action}`) : \"\"\n console.log(\n ` ${chalk.dim(when)} ${col(r.verdict.toUpperCase().padEnd(8))}${eff} ` +\n `${chalk.cyan((r.agent_id ?? \"?\").padEnd(16))} ${chalk.dim((r.matched_rule ?? \"-\").padEnd(24))} ` +\n `${(r.command ?? \"\").slice(0, 70)}`,\n )\n if (r.resolved_target) console.log(chalk.dim(` target: ${r.resolved_target}`))\n }\n })\n\n// ---------------------------------------------------------------------------\n// agentx guard init (scaffold .agentx/guardrails/)\n// ---------------------------------------------------------------------------\nguard\n .command(\"init\")\n .description(\"scaffold .agentx/guardrails/ with a starter policy + protected-resource example\")\n .option(\"--root <dir>\", \"where to create .agentx/guardrails/\", process.cwd())\n .option(\"--force\", \"overwrite existing files\")\n .action((opts) => {\n const base = join(resolve(opts.root), GUARDRAILS_DIR)\n let created = 0\n for (const f of SEED_FILES) {\n const path = join(base, f.relPath)\n if (existsSync(path) && !opts.force) {\n console.log(chalk.dim(` skip (exists) ${f.relPath}`))\n continue\n }\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, f.content)\n console.log(chalk.green(` created ${f.relPath}`))\n created++\n }\n console.log()\n console.log(` Guardrails scaffolded under ${chalk.cyan(base)}`)\n console.log(chalk.dim(` Edit environments/production.yaml with YOUR prod hosts/URLs, then`))\n console.log(chalk.dim(` \\`agentx guard test \"<cmd>\" --enforce\\` to preview, and flip mode: enforce when ready.`))\n })\n\n// ---------------------------------------------------------------------------\n// agentx guard reload (ping the daemon; policy is read live regardless)\n// ---------------------------------------------------------------------------\nguard\n .command(\"reload\")\n .description(\"signal the daemon to reload (note: guard policy is read live per tool call already)\")\n .option(\"--url <url>\", \"daemon base url\", process.env.AGENTX_DAEMON_URL || \"http://localhost:19900\")\n .action(async (opts) => {\n try {\n const res = await fetch(`${String(opts.url).replace(/\\/$/, \"\")}/reload`, { method: \"POST\" })\n if (res.ok) console.log(chalk.green(` daemon reloaded (${opts.url})`))\n else console.log(chalk.yellow(` daemon reachable but returned ${res.status}`))\n } catch (e: any) {\n console.log(chalk.dim(` daemon not reachable (${e.message}). Policy files are still read live on each check.`))\n }\n })\n\n// ---------------------------------------------------------------------------\n// agentx guard policy (show the resolved policy for an agent)\n// ---------------------------------------------------------------------------\nguard\n .command(\"policy\")\n .description(\"print the resolved (merged) policy for an agent\")\n .option(\"--agent <id>\", \"agent id\")\n .option(\"--root <dir>\", \"AgentX install root\")\n .action((opts) => {\n const p = loadPolicy(rootOf(opts), opts.agent)\n console.log(JSON.stringify(p, null, 2))\n })\n","// Seed policy templates for `agentx guard init`. Kept as strings (not files)\n// so the CLI can scaffold `.agentx/guardrails/` on any node without shipping\n// example files in the npm tarball. The repo's own `.agentx/guardrails/` is a\n// committed instance of these for the local (MacBook) node.\n\nexport const SEED_POLICY_YAML = `# AgentX destructive-action guardrails — global policy\n#\n# This file + environments/*.yaml + agents/<id>.yaml are deep-merged\n# (most specific wins). The built-in catalog (prisma / rm -rf / docker /\n# terraform / git push --force ... patterns) is ALWAYS applied underneath.\n# The guard reads policy live on every tool call — edits take effect on the\n# next command, no daemon restart needed.\nversion: 1\n\n# warn = compute + audit but never block (Phase 1 rollout stance).\n# enforce = honor the verdict (deny blocks; escalate asks).\n# off = kill-switch, allow everything.\n# Flip to enforce once \\`agentx guard log\\` shows an acceptable false-positive rate.\nmode: warn\n\ndefaults:\n fail_mode: closed # guard error on a protected-target command => deny\n unmatched: allow # commands no rule matches run freely (keep routine work fast)\n\n# Extra global rules beyond the catalog go here. Example:\n# rules:\n# - id: no-prod-ssh\n# match: { tool: Bash, command_regex: \"ssh \", target_in: production }\n# action: escalate\n# severity: high\nrules: []\n`\n\nexport const SEED_PRODUCTION_YAML = `# Production protected resources.\n#\n# The catalog rules reference \\`target_in: production\\`, so DECLARING this set is\n# what arms them. \\`resolve_env: true\\` expands $VAR / \\${VAR} and reads .env* in\n# the workspace before matching — so \\`--shadow-database-url $DATABASE_URL\\` is\n# caught even though the literal string \"production\" never appears in the command\n# (this is exactly the 2026-07-21 incident class).\nprotected_resources:\n production:\n resolve_env: true\n db_urls:\n - \"\\${PROD_DATABASE_URL}\"\n hosts:\n - \"api.demosite.example.com\"\n - \"203.0.113.12\"\n # buckets:\n # - \"my-prod-uploads\"\n # contexts: # k8s contexts, droplet ids, cluster names\n # - \"do-fra1-prod\"\n\n# Production-only rules beyond the catalog:\nrules: []\n`\n\nexport const SEED_CODER_AGENT_YAML = `# Per-agent override for coder-agent. Top-level rules here are auto-scoped to\n# this agent (the filename names it). coder agents never touch production.\nrules:\n - id: coder-no-prod\n match:\n target_in: production\n action: deny\n severity: critical\n message: \"coder-agent is not permitted to run commands against production.\"\n`\n\nexport interface SeedFile {\n relPath: string\n content: string\n}\n\nexport const SEED_FILES: SeedFile[] = [\n { relPath: \"policy.yaml\", content: SEED_POLICY_YAML },\n { relPath: \"environments/production.yaml\", content: SEED_PRODUCTION_YAML },\n { relPath: \"agents/coder-agent.yaml\", content: SEED_CODER_AGENT_YAML },\n]\n","import { Command } from \"commander\"\nimport { execFile } from \"child_process\"\nimport { promisify } from \"util\"\nimport { existsSync } from \"fs\"\nimport { resolve } from \"path\"\nimport chalk from \"chalk\"\nimport { askSeat } from \"@/decisions/seat\"\nimport {\n UI_ELEMENT_SEAT,\n uiElementQuestions,\n uiElementState,\n toSelection,\n type UICandidate,\n type UIElementAnswers,\n} from \"@/decisions/seats/ui-element\"\nimport { HELPER, readScreen, rectFor } from \"@/computer-use/screen\"\n\nconst run = promisify(execFile)\n\n// --- `agentx point \"<what you mean>\"` ---\n//\n// Reads the focused window's accessibility tree, asks the ui-element seat\n// which control the request names, and moves the cursor there with a\n// highlight. It does NOT click.\n//\n// This lives in agentx rather than inside the voice widget on purpose: the\n// capability then belongs to every agent — the secretary by voice, devops\n// over WhatsApp, a cron job — instead of to one app. Swift owns only the\n// parts Node cannot reach.\n\n\n\ninterface Snapshot {\n app: string\n window?: string | null\n elements: Array<UICandidate & { x: number; y: number; width: number; height: number }>\n truncated: boolean\n note?: string | null\n}\n\n/** Controls a person could plausibly mean. The raw tree is mostly groups\n * and static text scaffolding; handing forty of those to a model buys\n * nothing and crowds out the real candidates. */\n\n\nexport const point = new Command()\n .name(\"point\")\n .description(\"point at the on-screen control matching a description (does not click)\")\n .argument(\"<request>\", 'what you mean, e.g. \"the send button\"')\n .option(\"--max <n>\", \"candidates to consider\", \"40\")\n .option(\"--json\", \"emit the decision as JSON instead of pointing\")\n .option(\"--min-present <p>\", \"refuse below this P(control exists)\", \"0.5\")\n .action(async (request: string, opts) => {\n if (!existsSync(HELPER)) {\n console.log(chalk.red(` helper not built — run apps/mac-helper/build.sh`))\n process.exit(1)\n }\n\n let screen\n try {\n // Reads the accessibility tree, and falls back to local OCR when the\n // tree is too thin to choose from — which is the only thing that\n // makes Electron apps addressable at all.\n screen = await readScreen({ max: Number(opts.max) || 40 })\n } catch (e: any) {\n console.log(chalk.red(` could not read the screen: ${e?.message ?? e}`))\n process.exit(1)\n }\n const candidates = screen.candidates\n\n if (candidates.length === 0) {\n console.log(chalk.yellow(` ${screen.app} exposes no usable controls and no readable text`))\n process.exit(2)\n }\n if (candidates.length === 1) {\n const only = rectFor(screen, candidates[0].id)\n if (only) {\n console.log(chalk.yellow(` ${screen.app} exposes exactly one target — pointing at it: `) +\n chalk.bold(candidates[0].label))\n await run(HELPER, [\"point\", \"--x\", String(only.x), \"--y\", String(only.y),\n \"--w\", String(only.width), \"--h\", String(only.height),\n \"--label\", candidates[0].label])\n }\n return\n }\n\n const result = await askSeat(\n UI_ELEMENT_SEAT,\n uiElementState({ request, app: screen.app, window: screen.window, candidates }),\n uiElementQuestions(candidates),\n { features: { app: screen.app, candidates: candidates.length, ocr: screen.usedOCR } },\n )\n if (!result) {\n console.log(chalk.red(` the ui-element seat is unavailable — set decisions.seats.${UI_ELEMENT_SEAT}.mode`))\n process.exit(1)\n }\n\n const sel = toSelection(result.answers as UIElementAnswers, candidates)\n const chosen = rectFor(screen, sel.id)\n const chosenLabel = candidates.find((c) => c.id === sel.id)?.label ?? \"\"\n const fromOCR = screen.ocrRects.has(sel.id)\n\n // `present` is read BEFORE `target`, always. A Choice over a candidate\n // set will always name something; this is the question that can say\n // the thing simply is not on screen.\n const minPresent = Number(opts.minPresent) || 0.5\n if (sel.present < minPresent || !chosen) {\n console.log(\n chalk.yellow(` nothing on screen matches \"${request}\"`) +\n chalk.dim(` (P(exists)=${sel.present.toFixed(2)} below ${minPresent})`),\n )\n process.exit(2)\n }\n\n if (opts.json) {\n console.log(JSON.stringify({\n app: screen.app, request, chosen: { ...chosen, label: chosenLabel, fromOCR }, present: sel.present,\n confidence: sel.confidence,\n ranked: sel.ranked.slice(0, 5).map((r) => ({\n ...r, label: candidates.find((c) => c.id === r.id)?.label,\n })),\n }, null, 2))\n return\n }\n\n const name = chosenLabel\n console.log(\n ` ${chalk.green(\"→\")} ${chalk.bold(name)} ` +\n chalk.dim(`(${fromOCR ? \"read from screen\" : \"control\"}, confidence ${sel.confidence.toFixed(2)}, P(exists) ${sel.present.toFixed(2)})`),\n )\n await run(HELPER, [\n \"point\",\n \"--x\", String(chosen.x), \"--y\", String(chosen.y),\n \"--w\", String(chosen.width), \"--h\", String(chosen.height),\n \"--label\", name,\n ])\n })\n\nfunction tryError(stdout: string): string {\n try { return JSON.parse(stdout).error ?? stdout } catch { return stdout }\n}\n","import { choice, noul } from \"../questions\"\nimport type { AnswersFor, ChoiceAnswer, NoulAnswer, StateValue } from \"../types\"\n\n// Picking a UI control from an accessibility tree.\n//\n// Deliberately the same shape as wiki-rerank, because it is the same\n// problem: a bounded candidate set, scored against one query, where the\n// per-option probabilities ARE the ranking. That shape is the one this\n// codebase has actually measured a decision model to be good at — the\n// failures were on arithmetic and on questions with no stated boundary,\n// neither of which this is.\n//\n// The companion Noul is what keeps it honest, and it is not optional. A\n// Choice must return something: asked which of forty controls means \"send\n// the invoice\" on a screen that has no such control, it will name one,\n// with a confident-looking probability. `present` is the question that can\n// say no, and the caller reads it FIRST.\n\nexport const UI_ELEMENT_SEAT = \"ui-element\"\n\n/** Enough to identify a control, small enough that forty of them fit in\n * one request. Position is deliberately excluded — a model should choose\n * by meaning, and coordinates invite it to guess geometrically. */\nexport interface UICandidate {\n id: number\n role: string\n label: string\n value?: string | null\n enabled: boolean\n}\n\n/** Something already attempted on this screen, and what came of it. */\nexport interface PriorAttempt {\n /** The control that was chosen, as it was labelled. */\n tried: string\n /** Did the screen actually change afterwards? Straight from the\n * before/after comparison, not from whether the call returned. */\n changed: boolean\n /** Optional detail — \"refused: focus is a link\", \"not found\". */\n note?: string\n}\n\nexport interface UIElementInput {\n /** What the user asked for, in their words. */\n request: string\n app: string\n window?: string | null\n candidates: UICandidate[]\n /** What has already been tried on this screen, most recent last.\n *\n * Without it every lookup is the model's first: it re-picks the control\n * that just did nothing, and a failed step repeats until something\n * times out. With it, \"I clicked Search and the screen did not change\"\n * is evidence that the next answer should differ. */\n priorAttempts?: PriorAttempt[]\n}\n\nexport function uiElementState(input: UIElementInput): StateValue {\n const prior = (input.priorAttempts ?? []).slice(-4)\n return {\n request: input.request,\n app: input.app,\n window: input.window ?? null,\n // Only when there is something to say. An empty array in the state is\n // noise the model has to read past on the common first attempt.\n ...(prior.length\n ? {\n alreadyTried: prior.map((p) => ({\n control: clip(p.tried, 80),\n screenChanged: p.changed,\n note: p.note ? clip(p.note, 120) : null,\n })),\n }\n : {}),\n controls: input.candidates.map((c) => ({\n id: String(c.id),\n role: humanRole(c.role),\n label: clip(c.label, 120),\n value: c.value ? clip(c.value, 80) : null,\n enabled: c.enabled,\n })),\n }\n}\n\n/** Built per call — the option set IS the candidate set. */\nexport function uiElementQuestions(candidates: UICandidate[]) {\n const criteria: Record<string, string> = {}\n for (const c of candidates) {\n const name = c.label || c.value || \"(unlabelled)\"\n criteria[String(c.id)] = `${humanRole(c.role)}: ${clip(name, 80)}`\n }\n return {\n target: choice(\n criteria,\n \"Which control does the request refer to? If `alreadyTried` shows a control was \" +\n \"clicked and the screen did not change, that one did not work — choose differently.\",\n ),\n present: noul(\n \"The screen actually contains a control matching the request.\",\n {\n true: \"One of the listed controls is plainly the thing the request names, or is the obvious way to perform it.\",\n false:\n \"Nothing listed corresponds to the request — the right control is on another screen, behind a menu, not yet visible, or this application simply cannot do what was asked.\",\n },\n ),\n }\n}\n\nexport type UIElementAnswers = AnswersFor<ReturnType<typeof uiElementQuestions>>\n\nexport interface UISelection {\n id: number\n confidence: number\n /** P(the request corresponds to anything on screen at all). */\n present: number\n ranked: Array<{ id: number; score: number }>\n}\n\nexport function toSelection(\n answers: UIElementAnswers,\n candidates: UICandidate[],\n): UISelection {\n const target = answers.target as ChoiceAnswer\n const ranked = candidates\n .map((c) => ({ id: c.id, score: target.probabilities[String(c.id)] ?? 0 }))\n .sort((a, b) => b.score - a.score)\n return {\n id: Number(target.choice),\n confidence: target.confidence,\n present: (answers.present as NoulAnswer).noul,\n ranked,\n }\n}\n\n/** AXButton -> button. The raw role names are an implementation detail of\n * the accessibility API and read as noise in a prompt. */\nfunction humanRole(role: string): string {\n return role.replace(/^AX/, \"\").replace(/([a-z])([A-Z])/g, \"$1 $2\").toLowerCase()\n}\n\nfunction clip(text: string, max: number): string {\n const flat = String(text ?? \"\").replace(/\\s+/g, \" \").trim()\n return flat.length > max ? flat.slice(0, max) : flat\n}\n","import { homedir } from \"node:os\"\nimport { resolveHelper } from \"@/desktop/install\"\nimport { execFile } from \"child_process\"\nimport { promisify } from \"util\"\nimport { existsSync } from \"fs\"\nimport { resolve } from \"path\"\nimport { buildCandidates, type RawElement } from \"./candidates\"\nimport type { UICandidate } from \"@/decisions/seats/ui-element\"\n\nconst run = promisify(execFile)\n\nexport const HELPER = resolveHelper(process.cwd(), homedir(), process.env.AGENTX_MAC_HELPER)\n\n// --- Reading the screen, with a fallback that changes what is possible ---\n//\n// The accessibility tree is the primary surface: structured, verifiable,\n// and it distinguishes a button from its own caption. Its failure mode is\n// that some apps expose nothing at all, and an empty tree is\n// indistinguishable from a screen with nothing on it.\n//\n// Measured on the same VS Code window, at the same moment:\n//\n// accessibility tree 5 elements, 3 controls, 1 of them labelled\n// OCR 133 readable strings\n//\n// That is the difference between \"this app cannot be driven\" and \"this\n// app can be driven\". So when the tree comes back thin, the pixels get\n// read — locally, by Apple's Vision framework, with nothing uploaded.\n//\n// OCR candidates are marked, not silently mixed in. Text is weaker\n// evidence than a control: it says what is written and where, and nothing\n// about whether it can be pressed. A caller that needs to click should\n// prefer a real element when one exists.\n\nexport interface ScreenRead {\n app: string\n window: string | null\n candidates: UICandidate[]\n elements: Array<RawElement>\n /** True when OCR was consulted because the tree was too thin. */\n usedOCR: boolean\n /** Screen rects for OCR-derived candidates, keyed by candidate id. */\n ocrRects: Map<number, { x: number; y: number; width: number; height: number }>\n}\n\n/** Below this many usable candidates, the tree is not worth trusting on\n * its own. Six is enough for a real toolbar and far more than the one\n * labelled control VS Code offers. */\nconst THIN_TREE = 6\n\nexport async function readScreen(opts: { max?: number; ocr?: boolean } = {}): Promise<ScreenRead> {\n if (!existsSync(HELPER)) throw new Error(\"helper not built — run apps/mac-helper/build.sh\")\n\n const { stdout } = await run(HELPER, [\"read\", \"--max\", \"400\"])\n const snap = JSON.parse(stdout) as {\n app: string\n window?: string | null\n elements: RawElement[]\n }\n const candidates = buildCandidates(snap.elements, opts.max ?? 60)\n const ocrRects = new Map<number, { x: number; y: number; width: number; height: number }>()\n\n const wantOCR = opts.ocr !== false && candidates.length < THIN_TREE\n if (!wantOCR) {\n return {\n app: snap.app, window: snap.window ?? null,\n candidates, elements: snap.elements, usedOCR: false, ocrRects,\n }\n }\n\n try {\n const { stdout: raw } = await run(HELPER, [\"ocr\"], { maxBuffer: 8 * 1024 * 1024 })\n const read = JSON.parse(raw) as {\n hits: Array<{ text: string; x: number; y: number; width: number; height: number; confidence: number }>\n }\n // Ids continue past the tree's, so a candidate id still identifies\n // exactly one thing across both sources.\n let nextId = Math.max(0, ...snap.elements.map((e) => e.id)) + 1\n const textCandidates: UICandidate[] = []\n for (const hit of read.hits) {\n // Low-confidence OCR is usually icon edges read as punctuation.\n if (hit.confidence < 0.5 || hit.text.length < 2) continue\n const id = nextId++\n ocrRects.set(id, { x: hit.x, y: hit.y, width: hit.width, height: hit.height })\n textCandidates.push({\n id,\n // A distinct role, so the model is told this is text that was READ\n // off the screen rather than a control the app declared.\n role: \"OCRText\",\n label: hit.text,\n value: null,\n enabled: true,\n })\n if (textCandidates.length >= (opts.max ?? 60)) break\n }\n return {\n app: snap.app, window: snap.window ?? null,\n candidates: [...candidates, ...textCandidates],\n elements: snap.elements, usedOCR: textCandidates.length > 0, ocrRects,\n }\n } catch {\n // OCR is the fallback; if it fails the tree's answer still stands.\n return {\n app: snap.app, window: snap.window ?? null,\n candidates, elements: snap.elements, usedOCR: false, ocrRects,\n }\n }\n}\n\n/** Resolve a chosen candidate id to a screen rect, from either source. */\nexport function rectFor(\n read: ScreenRead,\n id: number,\n): { x: number; y: number; width: number; height: number } | null {\n const el = read.elements.find((e) => e.id === id)\n if (el) return { x: el.x, y: el.y, width: el.width, height: el.height }\n return read.ocrRects.get(id) ?? null\n}\n","import type { UICandidate } from \"@/decisions/seats/ui-element\"\n\n// --- Choosing what the model is allowed to pick from ---\n//\n// In a browser the accessibility tree holds two unrelated interfaces: the\n// page, and the browser wrapped around it. Ask for \"the search box\" on X\n// with both in scope and \"Address and search bar\" wins at 0.97 confidence\n// — Chrome's URL bar, and the wrong answer given confidently. Ask for\n// \"the Latest tab\" and Chrome's \"New Tab\" button wins.\n//\n// No prompt fixes that, because neither answer is unreasonable in\n// isolation. The candidate set is what is wrong: a question about a page\n// should never have been shown the browser's own furniture.\n//\n// So when the tree contains a web area, the page wins and the chrome is\n// dropped. When it does not — a native app — everything stays.\n\nexport interface RawElement {\n id: number\n role: string\n label: string\n value?: string | null\n enabled: boolean\n parent: number\n x: number\n y: number\n width: number\n height: number\n}\n\nexport const INTERESTING_ROLE =\n /^AX(Button|MenuItem|MenuButton|TextField|TextArea|CheckBox|RadioButton|PopUpButton|Link|Tab|Row|Cell|ComboBox|SearchField|Slider|Disclosure|Toolbar|StaticText)/\n\n/**\n * Restrict to page content when this is a browser.\n *\n * Identified structurally by the presence of a web area, not by app name:\n * name matching would miss every browser nobody thought to list.\n */\nexport function scopeToPage(elements: RawElement[]): RawElement[] {\n const byId = new Map(elements.map((e) => [e.id, e]))\n const rootIds = new Set(elements.filter((e) => e.role === \"AXWebArea\").map((e) => e.id))\n if (rootIds.size === 0) return elements\n\n const isDescendant = (e: RawElement): boolean => {\n let cur: RawElement | undefined = e\n // Bounded walk: a malformed parent chain must not spin forever.\n for (let hops = 0; cur && hops < 64; hops++) {\n if (rootIds.has(cur.id)) return true\n if (cur.parent < 0) return false\n cur = byId.get(cur.parent)\n }\n return false\n }\n const page = elements.filter(isDescendant)\n // If scoping leaves nothing usable the web area was empty, and the\n // browser chrome is genuinely all there is — better than offering\n // nothing at all.\n return page.length >= 2 ? page : elements\n}\n\n/**\n * The set handed to the model: page-scoped, interesting roles only,\n * visible, capped.\n *\n * Unlabelled controls are kept and described by role — window buttons\n * carry no label on macOS, and dropping everything unnamed removes the\n * controls people most often ask for.\n */\nexport function buildCandidates(elements: RawElement[], max = 60): UICandidate[] {\n // Rank before capping.\n //\n // Slicing in tree order drops whatever appears late, and on x.com the\n // search input sits after a sidebar full of navigation links — so the\n // one element every search question is about was never shown to the\n // model at all, and it confidently picked a nav link instead.\n //\n // Text inputs first, then things you press, then labels. Within a tier\n // the tree order is kept, so reading position still breaks ties.\n const rank = (role: string): number => {\n if (/^AX(TextField|TextArea|SearchField|ComboBox)/.test(role)) return 0\n if (/^AX(Button|MenuItem|MenuButton|PopUpButton|CheckBox|RadioButton|Tab|Link)/.test(role)) return 1\n if (/^AX(Row|Cell|Slider|Disclosure|Toolbar)/.test(role)) return 2\n return 3\n }\n return scopeToPage(elements)\n .filter((e) => INTERESTING_ROLE.test(e.role))\n .filter((e) => e.width >= 1 && e.height >= 1)\n .map((e, i) => ({ e, i }))\n .sort((a, b) => rank(a.e.role) - rank(b.e.role) || a.i - b.i)\n .map(({ e }) => e)\n .slice(0, max)\n .map((e, i) => ({\n id: e.id,\n role: e.role,\n label: (e.label || e.value || \"\").trim() || `${e.role.replace(/^AX/, \"\")} ${i + 1}`,\n value: e.value ?? null,\n enabled: e.enabled,\n }))\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { look as lookAtScreen, type Region } from \"@/computer-use/look\"\nimport { verify } from \"@/computer-use/verify\"\n\n// --- `agentx look \"<what you want to know>\"` ---\n//\n// The third sense, next to `read` (the accessibility tree) and the OCR\n// fallback inside `point`. Use it for what the other two cannot answer:\n// whether something is covering something else, whether a page has\n// finished loading, whether a toggle is on, whether an action visibly\n// happened.\n//\n// Two modes, and the difference is whether a judgement is wanted:\n//\n// agentx look \"is the compose box covering the timeline?\"\n// -> reports what is visible.\n//\n// agentx look --verify \"a recording is in progress\"\n// -> takes a CLAIM and answers confirmed / refuted / unknown,\n// exiting non-zero for the last two so a script can rely on it.\n//\n// Exit codes are the contract: 0 confirmed, 3 refuted, 4 unknown. `unknown`\n// is deliberately not 0. This whole path exists because a run once reported\n// success for a recording that never started, and the way that happened was\n// treating \"could not tell\" as \"fine\".\n\nexport const look = new Command()\n .name(\"look\")\n .description(\"look at the screen with a vision model — for state the tree and OCR cannot see\")\n .argument(\"<question>\", 'what you want to know, e.g. \"is a dialog covering the page?\"')\n .option(\"--verify\", \"treat the argument as a claim and judge it (exit 3 refuted, 4 unknown)\")\n .option(\"--menubar\", \"capture the menu bar instead of the focused window\")\n .option(\"--screen\", \"capture the whole screen instead of the focused window\")\n .option(\"--rect <x,y,w,h>\", \"capture an explicit region\")\n .option(\"--model <id>\", \"vision model to use\")\n .option(\"--json\", \"emit the result as JSON\")\n .action(async (question: string, opts) => {\n let region: Region = { kind: \"window\" }\n if (opts.menubar) region = { kind: \"menubar\" }\n else if (opts.screen) region = { kind: \"screen\" }\n else if (opts.rect) {\n const parts = String(opts.rect).split(\",\").map(Number)\n if (parts.length !== 4 || parts.some(Number.isNaN)) {\n console.log(chalk.red(\" --rect wants x,y,w,h\"))\n process.exit(1)\n }\n region = { kind: \"rect\", x: parts[0], y: parts[1], width: parts[2], height: parts[3] }\n }\n\n try {\n if (opts.verify) {\n const v = await verify(question, { region, model: opts.model })\n if (opts.json) {\n console.log(JSON.stringify({\n claim: v.claim, outcome: v.outcome, ok: v.ok,\n observable: v.observable, holds: v.holds, calibrated: v.calibrated,\n reason: v.reason, evidence: v.sighting.evidence, probes: v.probes,\n observation: v.sighting.observation, shot: v.sighting.shot.path,\n model: v.sighting.model, latencyMs: v.sighting.latencyMs,\n }, null, 2))\n } else {\n const mark = v.outcome === \"confirmed\" ? chalk.green(\"✓\")\n : v.outcome === \"refuted\" ? chalk.red(\"✗\")\n : chalk.yellow(\"?\")\n console.log(` ${mark} ${chalk.bold(v.claim)}`)\n console.log(` ${v.reason}`)\n if (!v.calibrated) {\n console.log(chalk.dim(` (screen-state seat off — set AGENTX_DECISION_SEAT_SCREEN_STATE=active)`))\n }\n console.log(chalk.dim(` ${v.sighting.model} · ${v.sighting.latencyMs}ms · ${v.sighting.shot.path}`))\n }\n process.exit(v.outcome === \"confirmed\" ? 0 : v.outcome === \"refuted\" ? 3 : 4)\n }\n\n const s = await lookAtScreen(question, { region, model: opts.model })\n if (opts.json) {\n console.log(JSON.stringify(s, null, 2))\n return\n }\n console.log(` ${chalk.bold(s.observation)}`)\n if (s.evidence) console.log(chalk.dim(` evidence: ${s.evidence}`))\n console.log(` reading: ${readingColour(s.reading)}`)\n console.log(chalk.dim(\n ` ${s.model} · ${s.latencyMs}ms · ${Math.round(s.shot.bytes / 1024)}KB · ${s.shot.path}`,\n ))\n } catch (e: any) {\n console.log(chalk.red(` ${e?.message ?? e}`))\n process.exit(1)\n }\n })\n\nfunction readingColour(r: string): string {\n if (r === \"yes\") return chalk.green(r)\n if (r === \"no\") return chalk.red(r)\n return chalk.yellow(r)\n}\n","import { execFile } from \"child_process\"\nimport { promisify } from \"util\"\nimport { existsSync, readFileSync } from \"fs\"\nimport { homedir, tmpdir } from \"os\"\nimport { join } from \"path\"\nimport { HELPER } from \"./screen\"\n\nconst run = promisify(execFile)\n\n// --- Looking at the screen, as opposed to reading it ---\n//\n// Three ways to find out what is on a screen, and they answer different\n// questions:\n//\n// accessibility tree what EXISTS, and where. Structured and exact.\n// Silent about anything an app does not publish.\n// OCR what is WRITTEN, and where. Local and cheap.\n// Says nothing about anything that is not text.\n// this file what it LOOKS LIKE. A recording indicator, a\n// spinner, a toggle that is on, a red badge, a\n// window that is covering another one.\n//\n// The third was missing and the gap was not academic. A lesson told Screen\n// Studio to start recording; Screen Studio did not start recording; the\n// tree reported one element and OCR read the picker's labels, so nothing\n// in the pipeline could tell the difference between \"recording\" and \"not\n// recording\". The run continued and reported success. An instruction whose\n// effect cannot be observed is an instruction that cannot be trusted, and\n// every verification we had was really a check that a function returned.\n//\n// The cost of this one is real — pixels leave the machine — so it is not\n// the default sense. The tree is tried first, then OCR, and this is for\n// the questions neither can answer.\n//\n// It reports an OBSERVATION, not a verdict. A vision model asked \"is it\n// recording\" will very often say yes because an app that records is on\n// screen, which is a guess about the world dressed as a reading of the\n// pixels. So it is asked to name the visible evidence, and to answer\n// `unclear` when the deciding detail is not in frame. Turning that\n// observation into a calibrated probability is a separate step, in\n// seats/screen-state.ts, because those are separate skills.\n\nexport type Region =\n | { kind: \"window\" }\n | { kind: \"screen\"; index?: number }\n | { kind: \"menubar\"; index?: number }\n | { kind: \"rect\"; x: number; y: number; width: number; height: number }\n\nexport interface Shot {\n path: string\n region: { x: number; y: number; width: number; height: number }\n bytes: number\n}\n\nexport interface Sighting {\n question: string\n /** What is visible, factually, in the captured region. */\n observation: string\n /** The specific visual detail the answer rests on. Empty when none was\n * found — which is the honest outcome when a question cannot be\n * settled by looking. */\n evidence: string\n /** The vision model's plain reading. NOT calibrated: it is one model's\n * yes or no, and the caller should prefer the seat's probability when\n * one is available. */\n reading: \"yes\" | \"no\" | \"unclear\"\n shot: Shot\n model: string\n latencyMs: number\n usage: { inputTokens: number; outputTokens: number }\n}\n\n/** Total pixels allowed in an image sent to the model.\n *\n * A budget on AREA rather than width, because cost tracks area and a\n * width cap shrinks small regions for no saving. A menu bar strip\n * (2880x52 here) passes through untouched; a full Retina screen (5.2M\n * pixels) gets scaled to fit.\n *\n * Resolution is not only a cost knob. Measured on this machine: macOS\n * draws the screen-recording indicator as a ~6 point dot, and halving\n * the resolution of a menu bar capture is the difference between a dot\n * and a smudge. Keep what is cheap to keep. */\nconst MAX_PIXELS = 1_200_000\n\nconst OPENROUTER = \"https://openrouter.ai/api/v1/chat/completions\"\n\n/** Vision-capable and quick. Overridable because this is the kind of\n * choice that should not need a code change to revisit. */\nexport const DEFAULT_VISION_MODEL =\n process.env.AGENTX_VISION_MODEL ?? \"anthropic/claude-sonnet-5\"\n\n/** Capture a region to a downscaled PNG. */\nexport async function capture(region: Region = { kind: \"window\" }, maxPixels = MAX_PIXELS): Promise<Shot> {\n if (!existsSync(HELPER)) throw new Error(\"helper not built — run apps/mac-helper/build.sh\")\n\n const out = join(tmpdir(), `agentx-look-${Date.now()}.png`)\n const args = [\"capture\", \"--out\", out, \"--max-pixels\", String(maxPixels)]\n if (region.kind === \"menubar\") args.push(\"--menubar\")\n if (region.kind === \"screen\") args.push(\"--screen-full\")\n if (region.kind === \"screen\" || region.kind === \"menubar\") {\n if (region.index !== undefined) args.push(\"--screen\", String(region.index))\n }\n if (region.kind === \"rect\") {\n args.push(\"--x\", String(region.x), \"--y\", String(region.y),\n \"--w\", String(region.width), \"--h\", String(region.height))\n }\n\n const { stdout } = await run(HELPER, args)\n const res = JSON.parse(stdout) as {\n ok: boolean\n error?: string\n path: string\n region: { x: number; y: number; w: number; h: number }\n }\n if (!res.ok) throw new Error(res.error ?? \"capture failed\")\n\n const bytes = readFileSync(res.path).length\n return {\n path: res.path,\n region: { x: res.region.x, y: res.region.y, width: res.region.w, height: res.region.h },\n bytes,\n }\n}\n\nconst SYSTEM = `You are reading a screenshot of a macOS screen to answer one question about what is CURRENTLY TRUE on it.\n\nReport only what is visible in this image.\n\nThe failure that matters: an application that performs an action is on screen, and you report that the action is happening. Those are different claims. A recorder being open is not a recording in progress. A button existing is not a button that has been pressed. A dialog offering a choice is not a choice that was made.\n\nState indicators are usually small and specific: a coloured dot, a pill or badge in the menu bar, an elapsed timer, a filled or highlighted toggle, a progress bar, a changed icon. If the question turns on such an indicator, say whether you can see it and what it looks like.\n\nAnswer \"unclear\" when the deciding detail is not in frame, too small to read, or covered. \"unclear\" is a useful answer. A confident guess is not.`\n\n/** Ask a vision model what it sees. */\nasync function describe(question: string, shot: Shot, model: string, timeoutMs: number) {\n const apiKey = resolveOpenRouterKey()\n if (!apiKey) {\n throw new Error(\n \"no OPENROUTER_API_KEY — looking at the screen needs a vision model (set it, or ~/.agentx/openrouter-key.txt)\",\n )\n }\n\n const b64 = readFileSync(shot.path).toString(\"base64\")\n const body = {\n model,\n max_tokens: 700,\n messages: [{\n role: \"user\",\n content: [\n { type: \"text\", text: `Question: ${question}\\n\\nThe image is the region ${describeRegion(shot)}.` },\n { type: \"image_url\", image_url: { url: `data:image/png;base64,${b64}` } },\n ],\n }],\n system: SYSTEM,\n tools: [{\n type: \"function\",\n function: {\n name: \"report\",\n description: \"Report what is visible and how it bears on the question\",\n parameters: {\n type: \"object\",\n properties: {\n observation: {\n type: \"string\",\n description: \"What is visible in the image, factually, in one or two sentences.\",\n },\n evidence: {\n type: \"string\",\n description:\n \"The specific visible detail that decides the question — where it is and what it looks like. Empty string if no such detail is visible.\",\n },\n reading: {\n type: \"string\",\n enum: [\"yes\", \"no\", \"unclear\"],\n description: \"Answer to the question, or unclear if the pixels do not settle it.\",\n },\n },\n required: [\"observation\", \"evidence\", \"reading\"],\n },\n },\n }],\n tool_choice: { type: \"function\", function: { name: \"report\" } },\n }\n\n const ctrl = new AbortController()\n const timer = setTimeout(() => ctrl.abort(), timeoutMs)\n let res: Response\n try {\n res = await fetch(OPENROUTER, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n // OpenRouter attributes traffic by these; without them calls land\n // in an unnamed bucket and cost cannot be traced back here.\n \"HTTP-Referer\": \"https://github.com/acme/agentx\",\n \"X-Title\": \"agentx\",\n },\n body: JSON.stringify(body),\n signal: ctrl.signal,\n })\n } finally {\n clearTimeout(timer)\n }\n\n if (!res.ok) {\n const detail = await res.text().catch(() => \"\")\n throw new Error(`vision model ${res.status}: ${detail.slice(0, 300)}`)\n }\n\n const json = (await res.json()) as any\n const call = json?.choices?.[0]?.message?.tool_calls?.[0]\n if (!call?.function?.arguments) {\n throw new Error(\"vision model returned no structured report\")\n }\n const parsed = JSON.parse(call.function.arguments) as {\n observation?: string\n evidence?: string\n reading?: string\n }\n const reading = parsed.reading === \"yes\" || parsed.reading === \"no\" ? parsed.reading : \"unclear\"\n return {\n observation: (parsed.observation ?? \"\").trim(),\n evidence: (parsed.evidence ?? \"\").trim(),\n reading: reading as Sighting[\"reading\"],\n model: typeof json.model === \"string\" ? json.model : model,\n usage: {\n inputTokens: json?.usage?.prompt_tokens ?? 0,\n outputTokens: json?.usage?.completion_tokens ?? 0,\n },\n }\n}\n\nexport interface LookOptions {\n region?: Region\n model?: string\n maxPixels?: number\n timeoutMs?: number\n}\n\n/** Capture a region and report what is visible, against one question. */\nexport async function look(question: string, opts: LookOptions = {}): Promise<Sighting> {\n const started = Date.now()\n const shot = await capture(opts.region ?? { kind: \"window\" }, opts.maxPixels ?? MAX_PIXELS)\n const seen = await describe(question, shot, opts.model ?? DEFAULT_VISION_MODEL, opts.timeoutMs ?? 45_000)\n return {\n question,\n observation: seen.observation,\n evidence: seen.evidence,\n reading: seen.reading,\n shot,\n model: seen.model,\n latencyMs: Date.now() - started,\n usage: seen.usage,\n }\n}\n\nfunction describeRegion(shot: Shot): string {\n const { x, y, width, height } = shot.region\n // 40 points tall and starting at the top is the menu bar, and saying so\n // helps: a bare strip of icons is much harder to place than a labelled one.\n if (y <= 1 && height <= 40) return \"the macOS menu bar at the top of the screen\"\n return `x=${Math.round(x)} y=${Math.round(y)} ${Math.round(width)}x${Math.round(height)} points`\n}\n\nlet cachedKey: string | null | undefined\nfunction resolveOpenRouterKey(): string | undefined {\n if (process.env.OPENROUTER_API_KEY) return process.env.OPENROUTER_API_KEY\n if (cachedKey !== undefined) return cachedKey ?? undefined\n try {\n const raw = readFileSync(join(homedir(), \".agentx\", \"openrouter-key.txt\"), \"utf-8\").trim()\n cachedKey = raw.length > 0 ? raw : null\n } catch {\n cachedKey = null\n }\n return cachedKey ?? undefined\n}\n","import { execFile } from \"child_process\"\nimport { promisify } from \"util\"\n\nconst run = promisify(execFile)\n\n// Cheap, deterministic facts about the machine, to be weighed against what\n// a model thinks it saw.\n//\n// This exists because of a measured failure. Asked whether the screen was\n// being recorded, a vision model looked at a menu bar, found an ordinary\n// circular app icon and reported it as \"the macOS screen recording\n// indicator\" — twice, in different words, with evidence that read as\n// specific and was invented. The decision seat then agreed at 76%, because\n// the seat is blind: it only ever sees the OBSERVATION, so a confident\n// wrong description is indistinguishable to it from a confident right one.\n//\n// No prompt fixes that. The observation is the only evidence in play, so\n// something else has to be in play.\n//\n// A probe is a fact obtained by asking the system instead of looking at\n// it: a process list, a file's size, a window's existence. It is narrow\n// and it is certain, which is exactly the counterweight a confident\n// narrative needs. Where it cannot settle something, it says so — and that\n// admission is itself evidence, because it tells the seat the question is\n// not answerable from this capture rather than leaving it to infer\n// otherwise.\n\nexport interface Probe {\n /** What was checked, in plain words. */\n checked: string\n /** What came back. */\n found: string\n}\n\n/** Processes whose mere existence proves a capture is under way.\n *\n * `screencapture -v` exists only while it is recording, so finding it is\n * the whole answer. Kept separate from the apps below, because that\n * distinction is the difference between evidence and a hint — an earlier\n * cut lumped them together and also listed ffmpeg, which is running on\n * this machine for unrelated transcoding and would have \"proved\" a\n * recording that was not happening. */\nconst CAPTURING_WHEN_RUNNING = [\"screencapture\"]\n\n/** Apps that RECORD but are also just left open. Their presence settles\n * nothing, and saying so is the point — this is the Screen Studio case. */\nconst MIGHT_BE_RECORDING = [\"Screen Studio\", \"OBS\", \"QuickTime Player\", \"Zoom\"]\n\n/**\n * Deterministic facts relevant to `claim`, or an empty list when none apply.\n *\n * Keyword-triggered on purpose. A probe that ran for every claim would be\n * mostly noise in the state, and a seat reading irrelevant facts is a seat\n * being taught that facts are irrelevant.\n */\nexport async function probe(claim: string): Promise<Probe[]> {\n const text = claim.toLowerCase()\n const probes: Probe[] = []\n\n if (/record|recording|capturing|screen ?capture|screencast/.test(text)) {\n probes.push(await recordingProbe())\n }\n return probes\n}\n\n/**\n * Whether anything visible from here is capturing the screen.\n *\n * Three outcomes, and they are deliberately worded very differently,\n * because an earlier version used one hedging paragraph for all of them.\n * It buried a decisive finding — a live capture process — under a caveat\n * about what the check cannot see, and the seat read the caveat and\n * answered \"cannot tell\" while the answer was sitting in the same string.\n * A qualification attached to a fact that does not need it is not caution,\n * it is noise that outweighs the fact.\n */\nasync function recordingProbe(): Promise<Probe> {\n const capturing = await running(CAPTURING_WHEN_RUNNING)\n if (capturing.length) {\n return {\n checked: \"running screen-capture processes (pgrep)\",\n found:\n `A screen capture is definitely in progress: ${capturing.join(\", \")}. ` +\n `This process only exists while it is recording, so this settles the question on its own.`,\n }\n }\n\n const maybe = await running(MIGHT_BE_RECORDING)\n if (maybe.length) {\n return {\n checked: \"running screen-capture processes (pgrep)\",\n found:\n `No standalone capture process. A recorder application IS open (${maybe.join(\", \")}), but ` +\n `its process exists whether or not it is recording, so this neither confirms nor denies. ` +\n `macOS does not expose in-app recording state to this tool, and the menu bar indicator is ` +\n `about six points — measured as below what the vision models here resolve reliably. ` +\n `Unless something else settles it, this claim cannot be verified.`,\n }\n }\n\n return {\n checked: \"running screen-capture processes (pgrep)\",\n found:\n `No screen-capture process is running and no recorder application is open. Nothing that ` +\n `records the screen from outside an app is active.`,\n }\n}\n\n/** pgrep exits non-zero when nothing matches, which is an answer, not an error. */\nasync function running(names: string[]): Promise<string[]> {\n const found: string[] = []\n for (const name of names) {\n try {\n const { stdout } = await run(\"pgrep\", [\"-x\", name])\n const pid = stdout.trim().split(\"\\n\")[0]\n if (pid) found.push(`${name} (pid ${pid})`)\n } catch {\n /* not running */\n }\n }\n return found\n}\n","import { look, type LookOptions, type Sighting } from \"./look\"\nimport { probe, type Probe } from \"./probes\"\nimport { askSeat } from \"@/decisions/seat\"\nimport {\n SCREEN_STATE_SEAT,\n screenStateQuestions,\n screenStateState,\n toVerdict,\n} from \"@/decisions/seats/screen-state\"\n\n// Checking that an instruction actually took effect.\n//\n// The rule this enforces: an action is not done because the call that\n// performed it returned. It is done when the effect has been OBSERVED.\n// Everything that used to pass for verification here — a helper exiting 0,\n// a pixel diff around the cursor, a tree containing the element we asked\n// for — confirms that something was attempted, not that anything happened.\n//\n// Three outcomes, and the third is the point:\n//\n// confirmed the effect is visible\n// refuted the effect is visibly absent — stop, and say what was seen\n// unknown the capture could not settle it — ALSO stop\n//\n// `unknown` is not a soft pass. A verifier that treats \"I could not tell\"\n// as \"fine\" is worse than no verifier, because it launders a guess into a\n// check. Callers are expected to treat anything other than `confirmed` as\n// a reason not to continue, which is why `ok` is defined the way it is.\n//\n// The decision seat is fail-OPEN by contract: askSeat returns null when the\n// seat is off or the backend is unreachable. That default is wrong here —\n// it would turn a missing verifier into a pass — so a null seat falls back\n// to the vision model's own reading and the result is marked uncalibrated,\n// with `unclear` mapping to `unknown` rather than to success.\n\nexport type Outcome = \"confirmed\" | \"refuted\" | \"unknown\"\n\nexport interface Verification {\n claim: string\n outcome: Outcome\n /** True only for `confirmed`. The single thing a caller should branch on. */\n ok: boolean\n /** P(the gathered evidence settles the claim). Null when no seat answered. */\n observable: number | null\n /** P(the claim holds). Null when no seat answered. */\n holds: number | null\n /** False when the seat was unavailable and the vision model's own\n * uncalibrated reading was used instead. */\n calibrated: boolean\n /** Plain-words explanation, suitable for showing a person. */\n reason: string\n sighting: Sighting\n /** Deterministic facts weighed alongside the image. */\n probes: Probe[]\n}\n\n/** Below this, nothing gathered could settle the question, and the answer\n * to `holds` is noise regardless of how confident it looks. */\nconst OBSERVABLE_FLOOR = 0.6\nconst HOLDS_TRUE = 0.7\nconst HOLDS_FALSE = 0.3\n\nexport interface VerifyOptions extends LookOptions {\n /** What the accessibility tree said, to corroborate the observation. */\n treeNote?: string\n /** Lets a caller demand more certainty for a costly or risky step. */\n observableFloor?: number\n}\n\n/**\n * Look at the screen and report whether a claim about it is true.\n *\n * `claim` is a statement, not a question: \"the search field contains\n * from:naval\", \"a recording is in progress\", \"the compose dialog is\n * covering the timeline\".\n */\nexport async function verify(claim: string, opts: VerifyOptions = {}): Promise<Verification> {\n // Both sources, gathered before either is judged. The probes are the\n // only thing in the state that a confident wrong observation cannot\n // talk its way past.\n const [sighting, probes] = await Promise.all([\n look(claim, opts),\n probe(claim).catch((): Probe[] => []),\n ])\n const floor = opts.observableFloor ?? OBSERVABLE_FLOOR\n\n const seat = await askSeat(\n SCREEN_STATE_SEAT,\n screenStateState({\n claim,\n observation: sighting.observation,\n evidence: sighting.evidence,\n reading: sighting.reading,\n region: regionWords(sighting),\n treeNote: opts.treeNote,\n probes,\n }),\n screenStateQuestions,\n {\n // What the code would have concluded without the seat, so agreement\n // and eventual promotion stay measurable.\n incumbent: { holds: sighting.reading === \"yes\" ? 1 : 0 },\n features: { model: sighting.model, region: sighting.shot.region.height <= 40 ? \"menubar\" : \"window\" },\n },\n )\n\n if (!seat) {\n // No seat: the vision model's reading is all there is, and it is not\n // calibrated. `unclear` must not become a pass.\n const outcome: Outcome =\n sighting.reading === \"yes\" ? \"confirmed\" : sighting.reading === \"no\" ? \"refuted\" : \"unknown\"\n return {\n claim, outcome, ok: outcome === \"confirmed\",\n observable: null, holds: null, calibrated: false,\n reason: uncalibratedReason(outcome, sighting),\n sighting, probes,\n }\n }\n\n const { observable, holds } = toVerdict(seat.answers)\n if (observable < floor) {\n return {\n claim, outcome: \"unknown\", ok: false,\n observable, holds, calibrated: true,\n reason:\n `Could not tell from the screenshot or the system checks (${pct(observable)} that the evidence settles it). ` +\n `Seen: ${sighting.observation || \"nothing conclusive\"}`,\n sighting, probes,\n }\n }\n\n const outcome: Outcome = holds >= HOLDS_TRUE ? \"confirmed\" : holds <= HOLDS_FALSE ? \"refuted\" : \"unknown\"\n return {\n claim, outcome, ok: outcome === \"confirmed\",\n observable, holds, calibrated: true,\n reason: calibratedReason(outcome, holds, sighting),\n sighting, probes,\n }\n}\n\nfunction calibratedReason(outcome: Outcome, holds: number, s: Sighting): string {\n const detail = s.evidence || s.observation || \"no specific detail\"\n if (outcome === \"confirmed\") return `Confirmed (${pct(holds)}). ${detail}`\n if (outcome === \"refuted\") return `Not true (${pct(1 - holds)} it is false). ${detail}`\n return `Inconclusive (${pct(holds)}, between the thresholds). ${detail}`\n}\n\nfunction uncalibratedReason(outcome: Outcome, s: Sighting): string {\n const detail = s.evidence || s.observation || \"no specific detail\"\n const caveat = \" — uncalibrated, the screen-state seat is off\"\n if (outcome === \"unknown\") return `Could not tell${caveat}. ${detail}`\n return `${outcome === \"confirmed\" ? \"Looks true\" : \"Looks false\"}${caveat}. ${detail}`\n}\n\nfunction regionWords(s: Sighting): string {\n const r = s.shot.region\n if (r.y <= 1 && r.height <= 40) return \"the macOS menu bar\"\n return `a ${Math.round(r.width)}x${Math.round(r.height)} region of the screen`\n}\n\nconst pct = (p: number) => `${Math.round(p * 100)}%`\n","import { noul } from \"../questions\"\nimport type { AnswersFor, NoulAnswer, StateValue } from \"../types\"\n\n// Turning \"what I see\" into \"whether it is so\".\n//\n// Perception and judgement are split on purpose. A vision model is good at\n// saying what is on a screen and bad at knowing when that settles a\n// question — asked \"is it recording\", it will read a recorder's window and\n// answer yes, which is an inference about the world presented as a reading\n// of the pixels. So computer-use/look.ts gets the observation, and the\n// verdict is taken here against a stated boundary.\n//\n// `observable` is the question that matters and it is read FIRST.\n//\n// The whole handicap this seat exists to remove is that the system had no\n// way to say \"I cannot tell\". A lesson told Screen Studio to record, it did\n// not record, and every check in the pipeline was really a check that a\n// function had returned — so the run continued and reported success. A\n// verifier that can only answer yes or no will answer one of them when the\n// evidence is absent, which is the same failure wearing a probability.\n//\n// Measured limits, so nobody trusts this further than it goes. On\n// 2026-09-20, against a screen that WAS recording, asked whether a\n// recording was in progress from a menu bar capture:\n//\n// claude-sonnet-5 no (missed it, native resolution)\n// qwen3-vl-235b-a22b-instruct no (missed it)\n// qwen3-vl-30b-a3b-instruct yes — but cited \"the red dot\", and\n// macOS draws that indicator in purple,\n// so the right answer came from a prior\n// rather than from the image\n//\n// macOS draws it at about six points. That is below what these models\n// resolve reliably, and \"a model said yes\" is not the same as \"a model saw\n// it\". Small status indicators are a known blind spot; ask a process or a\n// file for those, and keep this for what is plainly visible — a dialog\n// covering a field, a page that has loaded, a field with text in it, a\n// toggle that is plainly on.\n\nexport const SCREEN_STATE_SEAT = \"screen-state\"\n\nexport const screenStateQuestions = {\n /** Read first. Whether the evidence gathered settles the claim AT ALL.\n *\n * About ALL the evidence, not only the image. A system check can settle\n * a question the screenshot cannot — a capture process in the process\n * list decides \"is it recording\" outright — and an earlier cut of this\n * seat asked only about the image, so it answered 10% and returned\n * \"cannot tell\" while a deterministic probe was holding the answer. */\n observable: noul(\n \"The evidence gathered — the screenshot and the system checks together — is enough to settle the claim, either way.\",\n {\n true:\n \"Something in the evidence decides it. Either the observation names a specific visible detail that bears on the claim and was legible, or a system check directly establishes the claim true or false. A system check alone is sufficient: it does not need the image to agree with it, or the image to have shown anything at all.\",\n false:\n \"Nothing decides it. The deciding detail is not in frame, too small or blurred, or covered; the observation only describes context — which application is open, what the screen generally shows — without the detail itself; and no system check settles it either. Absence of evidence in a capture that could not have shown the evidence is not evidence of absence. This is also false when a check says the question is not answerable from a screenshot and the observation nonetheless claims to have seen it: that is a guess, however specific it sounds.\",\n },\n ),\n /** Only meaningful when `observable` is high. */\n holds: noul(\n \"The claim is true of the screen right now.\",\n {\n true:\n \"The visible evidence shows the claimed state is in effect: the indicator is present, the text is there, the element is visible and unobstructed, the action has plainly already happened.\",\n false:\n \"The visible evidence shows the claimed state is NOT in effect. An application being open, capable of the action, or offering it, is not the action having happened — a recorder on screen is not a recording, an unpressed button is not a pressed one, an offered dialog is not a chosen one. A system check that directly contradicts the observation outweighs it: the checks are deterministic readings of the machine, the observation is a model's reading of an image.\",\n },\n ),\n}\n\nexport type ScreenStateAnswers = AnswersFor<typeof screenStateQuestions>\n\nexport interface ScreenStateInput {\n /** What is being asserted about the screen, in plain words. */\n claim: string\n /** What the vision model reported seeing. */\n observation: string\n /** The specific detail it rested on, if any. */\n evidence: string\n /** Its own uncalibrated reading. Included as a data point, and named as\n * one, so it informs the judgement without becoming it. */\n reading: \"yes\" | \"no\" | \"unclear\"\n /** Which part of the screen was captured, in words. */\n region: string\n /** What the accessibility tree said, when it said anything. A tree that\n * lists the control corroborates an observation that mentions it. */\n treeNote?: string\n /** Deterministic facts from the system — a process list, a file size.\n *\n * The seat cannot see the screen, so an observation is otherwise the\n * only evidence it has and a confident wrong one is indistinguishable\n * from a confident right one. These are the facts that can contradict\n * it, including the fact that something is not knowable from here. */\n probes?: Array<{ checked: string; found: string }>\n}\n\nexport function screenStateState(input: ScreenStateInput): StateValue {\n return {\n claim: input.claim,\n capturedRegion: input.region,\n whatWasSeen: input.observation,\n decidingDetail: input.evidence || null,\n visionModelReading: input.reading,\n ...(input.treeNote ? { accessibilityTree: input.treeNote } : {}),\n ...(input.probes?.length ? { systemChecks: input.probes } : {}),\n }\n}\n\nexport interface Verdict {\n /** P(the image could settle it). */\n observable: number\n /** P(the claim holds). Only meaningful when `observable` is high. */\n holds: number\n}\n\nexport function toVerdict(answers: ScreenStateAnswers): Verdict {\n return {\n observable: (answers.observable as NoulAnswer).noul,\n holds: (answers.holds as NoulAnswer).noul,\n }\n}\n","import { Command } from \"commander\"\nimport { execFile } from \"child_process\"\nimport { promisify } from \"util\"\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from \"fs\"\nimport { homedir } from \"os\"\nimport { join, dirname } from \"path\"\nimport chalk from \"chalk\"\nimport { askSeat } from \"@/decisions/seat\"\nimport {\n PASTE_TRANSFORM_SEAT,\n pasteQuestions,\n pasteState,\n toPasteChoice,\n type PasteAnswers,\n} from \"@/decisions/seats/paste-transform\"\nimport { applicable, previewFor, looksSecret, TRANSFORMS } from \"@/clipboard/transforms\"\nimport { HELPER } from \"@/computer-use/screen\"\n\nconst run = promisify(execFile)\n\n// --- `agentx paste` — put the clipboard in the shape the destination wants ---\n//\n// Reads the clipboard, sees where the caret is, asks the paste-transform\n// seat which shape fits, and applies a DETERMINISTIC transform. No model\n// writes any of the text that lands.\n//\n// Three orderings that are load bearing:\n//\n// 1. The secret check runs in code, before anything is sent anywhere.\n// The clipboard is where passwords and tokens live for the seconds\n// between copy and paste. \"Do not mangle my password\" is not a\n// judgement to delegate, and a preview of one should not leave the\n// machine to ask.\n// 2. `worthChanging` is read before `shape`. A Choice always returns\n// something; the Noul is what can say \"paste it exactly as copied\",\n// which is the right answer most of the time.\n// 3. The original is printed whenever it is replaced, so a surprising\n// transform is recoverable without an undo stack.\n//\n// Default is a dry run. Nothing touches the clipboard without --apply.\n\nexport const paste = new Command()\n .name(\"paste\")\n .description(\"reshape the clipboard to fit where it is being pasted\")\n .option(\"--apply\", \"write the result back to the clipboard\")\n .option(\"--paste\", \"apply, then press cmd-V into the focused control\")\n .option(\"--as <id>\", `force a transform (${TRANSFORMS.map((t) => t.id).join(\", \")})`)\n // 0.45 sits between the measured cases: a shell command scored 0.07 and\n // the four shapes this exists for scored 0.47-0.50. Provisional, from\n // five samples on one machine — it is a policy knob, not a calibrated\n // number, and `agentx decisions recalibrate` is what would replace it.\n // A wrong call is cheap because the original is stashed; see --undo.\n .option(\"--min <p>\", \"minimum P(worth changing) before transforming\", \"0.45\")\n .option(\"--undo\", \"restore the clipboard as it was before the last apply\")\n .option(\"--json\", \"emit the decision as JSON\")\n .action(async (opts) => {\n if (opts.undo) {\n const previous = takeStash()\n if (previous === null) {\n console.log(chalk.yellow(\" nothing to undo\"))\n process.exit(2)\n }\n await writeClipboard(previous)\n console.log(` ${chalk.green(\"→\")} clipboard restored`)\n return\n }\n\n const text = await readClipboard()\n if (!text) {\n console.log(chalk.yellow(\" clipboard is empty\"))\n process.exit(2)\n }\n\n // Before anything else, and before any preview leaves this process.\n if (looksSecret(text)) {\n report(opts, {\n applied: \"asIs\", reason: \"looks like a credential — left untouched\", worthChanging: 0,\n })\n return\n }\n\n const options = applicable(text)\n const destination = await focusedDestination()\n\n if (opts.as) {\n const forced = options.find((o) => o.transform.id === opts.as)\n if (!forced) {\n console.log(chalk.red(` \"${opts.as}\" does not apply to this clipboard`))\n console.log(chalk.dim(` available: ${options.map((o) => o.transform.id).join(\", \")}`))\n process.exit(1)\n }\n await finish(opts, forced.transform.id, forced.result, text, \"forced\", 1)\n return\n }\n\n // Only asIs applies: there is nothing to decide.\n if (options.length < 2) {\n await finish(opts, \"asIs\", text, text, \"nothing else applies\", 0)\n return\n }\n\n const result = await askSeat(\n PASTE_TRANSFORM_SEAT,\n pasteState({\n preview: previewFor(text),\n length: text.length,\n lineCount: text.split(\"\\n\").length,\n app: destination.app,\n destination: destination.role,\n destinationLabel: destination.label,\n }),\n pasteQuestions(options.map((o) => o.transform)),\n {\n // Without the seat this command pastes unchanged, which is also\n // the incumbent it has to beat.\n incumbent: { shape: \"asIs\" },\n features: { app: destination.app, options: options.length, chars: text.length },\n },\n )\n\n if (!result) {\n await finish(opts, \"asIs\", text, text, `seat unavailable — set decisions.seats.${PASTE_TRANSFORM_SEAT}.mode`, 0)\n return\n }\n\n const chosen = toPasteChoice(result.answers as PasteAnswers)\n const min = Number(opts.min) || 0.6\n if (chosen.worthChanging < min) {\n await finish(opts, \"asIs\", text, text,\n `paste as copied (P(worth changing) ${chosen.worthChanging.toFixed(2)} below ${min})`,\n chosen.worthChanging)\n return\n }\n\n const picked = options.find((o) => o.transform.id === chosen.id)\n if (!picked) {\n // The seat named something outside the option set. Refuse rather\n // than guess — a transform nobody offered is not a transform.\n await finish(opts, \"asIs\", text, text, `seat chose \"${chosen.id}\", which was not offered`, chosen.worthChanging)\n return\n }\n await finish(opts, picked.transform.id, picked.result, text,\n `${picked.transform.label} (confidence ${chosen.confidence.toFixed(2)})`,\n chosen.worthChanging)\n })\n\nasync function finish(\n opts: any, id: string, result: string, original: string, reason: string, worth: number,\n) {\n const changed = result !== original\n if (changed && (opts.apply || opts.paste)) {\n // Stash BEFORE overwriting. This command is the only thing that will\n // take the original away, so it is the only thing that can hand it\n // back — and being able to hand it back is what makes a lower\n // threshold defensible.\n stash(original)\n await writeClipboard(result)\n }\n\n report(opts, { applied: id, reason, worthChanging: worth, result, original, changed })\n\n if (opts.paste) {\n // Into whatever has focus. The helper's own gate still applies.\n await run(HELPER, [\"key\", \"--name\", \"v\", \"--mod\", \"command\"]).catch((e: any) => {\n console.log(chalk.red(` could not paste: ${e?.message ?? e}`))\n })\n }\n}\n\nfunction report(opts: any, r: any) {\n if (opts.json) {\n console.log(JSON.stringify(r, null, 2))\n return\n }\n if (!r.changed) {\n console.log(` ${chalk.dim(\"→\")} ${chalk.bold(\"unchanged\")} ${chalk.dim(`· ${r.reason}`)}`)\n return\n }\n console.log(` ${chalk.green(\"→\")} ${chalk.bold(r.applied)} ${chalk.dim(`· ${r.reason}`)}`)\n console.log(chalk.dim(\" ─── before ───\"))\n console.log(chalk.dim(clip(r.original)))\n console.log(chalk.dim(\" ─── after ────\"))\n console.log(clip(r.result))\n if (!opts.apply && !opts.paste) console.log(chalk.dim(\"\\n (dry run — pass --apply to write it back)\"))\n}\n\nconst clip = (s: string, max = 400) =>\n (s.length > max ? `${s.slice(0, max)}…` : s).split(\"\\n\").map((l) => ` ${l}`).join(\"\\n\")\n\n/** Where the pre-transform clipboard is kept, for exactly one undo. */\nconst STASH = join(homedir(), \".agentx\", \"paste-undo.txt\")\n\nfunction stash(text: string): void {\n try {\n mkdirSync(dirname(STASH), { recursive: true })\n writeFileSync(STASH, text, { mode: 0o600 })\n } catch {\n /* an undo that cannot be saved must not fail the paste */\n }\n}\n\n/** Reads and clears: an undo restores one step, not a history. */\nfunction takeStash(): string | null {\n try {\n const text = readFileSync(STASH, \"utf-8\")\n writeFileSync(STASH, \"\", { mode: 0o600 })\n return text.length ? text : null\n } catch {\n return null\n }\n}\n\nasync function readClipboard(): Promise<string> {\n const { stdout } = await run(\"pbpaste\", [], { maxBuffer: 16 * 1024 * 1024 })\n return stdout\n}\n\nasync function writeClipboard(text: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = execFile(\"pbcopy\", [], (err) => (err ? reject(err) : resolve()))\n child.stdin?.end(text)\n })\n}\n\n/** Where the caret is. Unknown is a fine answer — it just makes the\n * destination carry less weight in the decision. */\nasync function focusedDestination(): Promise<{ app: string; role: string; label: string | null }> {\n if (!existsSync(HELPER)) return { app: \"unknown\", role: \"an unknown control\", label: null }\n try {\n const { stdout } = await run(HELPER, [\"focused\"])\n const f = JSON.parse(stdout) as {\n ok?: boolean; app?: string; role?: string; label?: string; editable?: boolean\n }\n // \"nothing focused\" is a successful answer to a different question.\n if (f.ok === false || !f.role) return { app: \"unknown\", role: \"an unknown control\", label: null }\n return {\n app: f.app ?? \"unknown\",\n role: humanRole(f.role ?? \"\", f.editable),\n label: f.label || null,\n }\n } catch {\n return { app: \"unknown\", role: \"an unknown control\", label: null }\n }\n}\n\nfunction humanRole(role: string, editable?: boolean): string {\n const map: Record<string, string> = {\n AXTextField: \"a single-line text field\",\n AXTextArea: \"a multi-line text area\",\n AXSearchField: \"a search field\",\n AXComboBox: \"a combo box\",\n AXSecureTextField: \"a password field\",\n }\n return map[role] ?? (editable ? \"an editable control\" : `a ${role || \"unknown\"} control`)\n}\n","import { choice, noul } from \"../questions\"\nimport type { AnswersFor, ChoiceAnswer, NoulAnswer, StateValue } from \"../types\"\nimport type { Transform } from \"@/clipboard/transforms\"\n\n// Which shape a paste should arrive in.\n//\n// The same shape as voice-narration and ui-element, because it is the same\n// problem: a bounded set of options, scored against one situation, where\n// the per-option probabilities ARE the ranking. Jev writes nothing here.\n// It picks, and deterministic code in clipboard/transforms.ts does the\n// work — so nothing generated ever lands in the clipboard.\n//\n// The companion Noul is not optional and is read FIRST. A Choice must\n// return something: asked how to reshape a password on its way into a\n// login field, it will name a transform, with a confident-looking\n// probability. `worthChanging` is the question that can say \"paste it\n// exactly as it is\", which is the right answer almost every time.\n//\n// What makes the choice informed rather than a guess about text in the\n// abstract is the DESTINATION. The same three lines want to be a bullet\n// list in a markdown editor, a quote in a message, and left strictly alone\n// in a terminal. We already know where the caret is — the helper's\n// `focused` verb reports the role and label of whatever has keyboard\n// focus, built for the type-safety gate — so the destination costs nothing\n// extra to include and is most of the signal.\n\nexport const PASTE_TRANSFORM_SEAT = \"paste-transform\"\n\nexport interface PasteInput {\n /** A bounded preview of the clipboard, never the whole of it. */\n preview: string\n /** Full length, so the model knows what the preview stands for. */\n length: number\n lineCount: number\n /** Where it is going. */\n app: string\n /** Role of the focused control, in plain words: \"a text field\". */\n destination: string\n /** The focused control's own label, when it has one. */\n destinationLabel?: string | null\n}\n\nexport function pasteState(input: PasteInput): StateValue {\n return {\n pastingInto: {\n app: input.app,\n control: input.destination,\n label: input.destinationLabel || null,\n },\n clipboard: {\n characters: input.length,\n lines: input.lineCount,\n preview: input.preview,\n },\n }\n}\n\n/** Built per call — the option set IS the set of transforms that apply. */\nexport function pasteQuestions(options: Transform[]) {\n const criteria: Record<string, string> = {}\n for (const option of options) criteria[option.id] = option.criterion\n\n return {\n // State the boundary, not a preference.\n //\n // An earlier version of `false` read \"this is the default and the safe\n // answer\". That is an instruction to answer false, not a description of\n // when false is true, and it behaved exactly as told: a URL heavy with\n // utm parameters going into a markdown note scored 0.18, and prose\n // hard-wrapped out of a PDF scored 0.20. Both are cases this seat\n // exists for. A criterion that argues for its own side stops measuring\n // anything.\n worthChanging: noul(\n \"The text is in the wrong shape for where it is being pasted, and a mechanical reshaping would fix it.\",\n {\n true:\n \"The destination renders or stores formatted text, and the clipboard arrived in a shape that will not come out right: lines hard-wrapped mid-sentence going into prose, a link carrying campaign or tracking parameters, JSON collapsed onto one line, separate items going somewhere that renders a list, text padded with stray whitespace from a web page. The fix is mechanical and is what the person would have done by hand after pasting.\",\n false:\n \"The text is already in the right shape for this destination, OR its exact bytes carry meaning that reformatting would destroy — a credential, a command, a path, code, an identifier, a search query — OR the destination is a terminal, a password field, a URL bar or a code editor, where introduced formatting would corrupt what is pasted.\",\n },\n ),\n shape: choice(criteria, \"What shape should this paste arrive in?\"),\n }\n}\n\nexport type PasteAnswers = AnswersFor<ReturnType<typeof pasteQuestions>>\n\nexport interface PasteChoice {\n /** P(reshaping this paste is right). Read before `id`. */\n worthChanging: number\n /** Chosen transform id. */\n id: string\n /** Derived from the shape of the probabilities, never self-reported. */\n confidence: number\n ranked: Array<{ id: string; p: number }>\n}\n\nexport function toPasteChoice(answers: PasteAnswers): PasteChoice {\n const worth = answers.worthChanging as NoulAnswer\n const shape = answers.shape as ChoiceAnswer\n const ranked = Object.entries(shape.probabilities ?? {})\n .map(([id, p]) => ({ id, p: Number(p) || 0 }))\n .sort((a, b) => b.p - a.p)\n return {\n worthChanging: worth.noul,\n id: shape.choice,\n confidence: shape.confidence,\n ranked,\n }\n}\n","// What a paste can become.\n//\n// Every transform here is DETERMINISTIC code. No model rewrites the text —\n// a model only picks which of these to run, and the picking is the whole\n// of its job. That split matters for three reasons:\n//\n// 1. Jev writes no prose. It chooses. A \"smart paste\" built on a\n// generative rewrite is a different, slower, more expensive product\n// that happens to have a decision model bolted on.\n// 2. The clipboard holds passwords, tokens and private messages. Pasting\n// should not ship them to an API, and here only a short preview ever\n// leaves the machine — see previewFor().\n// 3. A deterministic transform can be reviewed, tested and undone. A\n// generated one cannot be any of those.\n//\n// A transform returns null when it does not apply, and an inapplicable\n// option is never offered. Same discipline as the ui-element candidate\n// set: a model asked to choose from options that cannot work will choose\n// one anyway.\n\nexport interface Transform {\n id: string\n /** Shown to the model as the criterion for picking this one. */\n criterion: string\n /** Shown to a person, in the widget and the CLI. */\n label: string\n /** The transformed text, or null when this does not apply. */\n apply: (text: string) => string | null\n}\n\n/** Tracking parameters worth removing. Deliberately a fixed list rather\n * than a heuristic: dropping a query parameter that turns out to be load\n * bearing breaks the link silently, and a link that merely carries a\n * campaign tag still works. */\nconst TRACKING = new Set([\n \"utm_source\", \"utm_medium\", \"utm_campaign\", \"utm_term\", \"utm_content\",\n \"utm_id\", \"gclid\", \"fbclid\", \"mc_cid\", \"mc_eid\", \"igshid\", \"ref_src\",\n \"ref_url\", \"s\", \"si\", \"spm\", \"scid\", \"twclid\", \"yclid\", \"_hsenc\", \"_hsmi\",\n])\n\nconst looksLikeUrl = (t: string) => /^https?:\\/\\/\\S+$/i.test(t.trim())\n\nexport const TRANSFORMS: Transform[] = [\n {\n id: \"asIs\",\n criterion:\n \"Paste it unchanged. The text is already in the right shape for where it is going, or it is something whose exact bytes matter — a password, a token, a command, code, an identifier.\",\n label: \"unchanged\",\n apply: (t) => t,\n },\n {\n id: \"unwrap\",\n criterion:\n \"Join lines that were hard-wrapped back into continuous paragraphs, keeping blank lines as paragraph breaks. For text copied out of a PDF, an email or a terminal, where every line ends at a fixed width mid-sentence.\",\n label: \"unwrap lines\",\n apply: (t) => {\n // Only when there is real wrapping to undo: several consecutive\n // lines that end without sentence punctuation.\n const lines = t.split(\"\\n\")\n if (lines.length < 3) return null\n let wrapped = 0\n for (let i = 0; i < lines.length - 1; i++) {\n const cur = lines[i].trim(), next = lines[i + 1].trim()\n if (cur.length > 40 && next.length > 0 && !/[.!?:;]$/.test(cur)) wrapped++\n }\n if (wrapped < 2) return null\n return t\n .split(/\\n\\s*\\n/)\n .map((para) => para.split(\"\\n\").map((l) => l.trim()).filter(Boolean).join(\" \"))\n .filter(Boolean)\n .join(\"\\n\\n\")\n },\n },\n {\n id: \"bullets\",\n criterion:\n \"Turn the lines into a markdown bullet list. For several short lines that are plainly separate items, going somewhere that renders markdown.\",\n label: \"bullet list\",\n apply: (t) => {\n const lines = t.split(\"\\n\").map((l) => l.trim()).filter(Boolean)\n if (lines.length < 2) return null\n // Already a list — nothing to do.\n if (lines.every((l) => /^([-*+]|\\d+[.)])\\s/.test(l))) return null\n return lines.map((l) => `- ${l}`).join(\"\\n\")\n },\n },\n {\n id: \"quote\",\n criterion:\n \"Prefix every line with a markdown blockquote marker. For quoting someone else's words into a document, an issue or a message.\",\n label: \"blockquote\",\n apply: (t) => {\n const lines = t.split(\"\\n\")\n if (lines.every((l) => l.startsWith(\">\") || !l.trim())) return null\n return lines.map((l) => (l.trim() ? `> ${l}` : \">\")).join(\"\\n\")\n },\n },\n {\n id: \"codeFence\",\n criterion:\n \"Wrap it in a fenced code block. For code, a command, a log line or structured output going somewhere that renders markdown.\",\n label: \"code block\",\n apply: (t) => {\n if (t.trim().startsWith(\"```\")) return null\n return \"```\\n\" + t.replace(/\\n+$/, \"\") + \"\\n```\"\n },\n },\n {\n id: \"prettyJson\",\n criterion:\n \"Re-indent it as readable JSON. Only for text that already parses as JSON.\",\n label: \"format JSON\",\n apply: (t) => {\n const trimmed = t.trim()\n if (!/^[[{]/.test(trimmed)) return null\n try {\n const parsed = JSON.parse(trimmed)\n const out = JSON.stringify(parsed, null, 2)\n return out === trimmed ? null : out\n } catch {\n return null\n }\n },\n },\n {\n id: \"cleanUrl\",\n criterion:\n \"Strip campaign and tracking parameters from the link, keeping the rest of it intact. For a URL copied out of a share sheet, a newsletter or a social post.\",\n label: \"clean the link\",\n apply: (t) => {\n const trimmed = t.trim()\n if (!looksLikeUrl(trimmed)) return null\n try {\n const url = new URL(trimmed)\n let removed = 0\n for (const key of [...url.searchParams.keys()]) {\n if (TRACKING.has(key.toLowerCase())) {\n url.searchParams.delete(key)\n removed++\n }\n }\n if (removed === 0) return null\n // Drop a '?' left behind with nothing after it.\n return url.toString().replace(/\\?$/, \"\")\n } catch {\n return null\n }\n },\n },\n {\n id: \"slug\",\n criterion:\n \"Convert to a lowercase hyphenated slug. For a title or phrase going into a branch name, a filename or a URL path.\",\n label: \"slug\",\n apply: (t) => {\n const trimmed = t.trim()\n if (trimmed.includes(\"\\n\") || trimmed.length > 90 || trimmed.length < 3) return null\n const slug = trimmed\n .normalize(\"NFKD\").replace(/[̀-ͯ]/g, \"\")\n .toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\")\n return slug && slug !== trimmed ? slug : null\n },\n },\n {\n id: \"collapseSpace\",\n criterion:\n \"Collapse runs of whitespace and trim the ends, leaving one clean line. For text copied out of a web page that arrived padded with stray spaces, tabs and newlines.\",\n label: \"tidy whitespace\",\n apply: (t) => {\n const out = t.replace(/[ \\t]+/g, \" \").replace(/\\s*\\n\\s*/g, \"\\n\").trim()\n return out === t ? null : out\n },\n },\n]\n\n/** The transforms that actually do something to this text. */\nexport function applicable(text: string): Array<{ transform: Transform; result: string }> {\n const out: Array<{ transform: Transform; result: string }> = []\n for (const transform of TRANSFORMS) {\n const result = transform.apply(text)\n // asIs always applies and is always the fallback; the rest have to earn\n // their place by producing something different from the input.\n if (result === null) continue\n if (transform.id !== \"asIs\" && result === text) continue\n out.push({ transform, result })\n }\n return out\n}\n\n/**\n * What the decision model is allowed to see of the clipboard.\n *\n * The clipboard is the most sensitive buffer on the machine — it is where\n * passwords and tokens are, for the seconds between copy and paste. The\n * seat needs to know the SHAPE of the text to choose a transform, not its\n * contents, so it gets a bounded head and tail and never the middle.\n */\nexport function previewFor(text: string, budget = 320): string {\n if (text.length <= budget) return text\n const head = Math.floor(budget * 0.7)\n const tail = budget - head\n return `${text.slice(0, head)}\\n…[${text.length - budget} more characters]…\\n${text.slice(-tail)}`\n}\n\n/** True when the text looks like something that must never be altered.\n *\n * Checked in code, before any model is asked, because \"do not mangle my\n * password\" is not a judgement call to delegate. */\nexport function looksSecret(text: string): boolean {\n const t = text.trim()\n if (t.includes(\"\\n\") || t.length > 200) return false\n return (\n /^(sk|pk|ghp|gho|ghs|glpat|xox[abps])[-_][A-Za-z0-9_-]{16,}$/.test(t) ||\n /^[A-Za-z0-9+/]{40,}={0,2}$/.test(t) ||\n /^eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\./.test(t) ||\n // High-entropy single token with no spaces and mixed classes.\n (t.length >= 20 && !/\\s/.test(t) && /[A-Z]/.test(t) && /[a-z]/.test(t) && /\\d/.test(t) &&\n !/^https?:\\/\\//i.test(t) && !/\\.(com|org|net|io|ai|tn)$/i.test(t))\n )\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport {\n notify as sendNotification,\n flushHeld,\n readFocus,\n focusLabel,\n NotificationQueue,\n playSound,\n type Sender,\n} from \"@/notify\"\n\n// --- `agentx notify \"<message>\"` ---\n//\n// A shoulder tap for the person running the fleet, routed so that it never\n// arrives during a Focus they explicitly turned on.\n//\n// It goes through the daemon rather than talking to ntfy directly, because\n// the daemon already owns the channel router — the same path that POST\n// /send, cron failure pings and channel.reply all use. A second delivery\n// path would mean a second place for the topic, the token and the retry\n// behaviour to drift.\n\nconst DAEMON = process.env.AGENTX_DAEMON_URL ?? \"http://127.0.0.1:18800\"\n\n/** Push through the daemon's channel router.\n *\n * The ntfy adapter takes its TITLE FROM THE FIRST LINE of the text — a\n * separate `title` field is ignored — so the title is prepended rather\n * than passed alongside. Sending it as its own field looked like it\n * worked: the push arrived, with the default title, and the real one\n * silently discarded. */\nfunction daemonSender(defaultChannel: string, defaultChatId: string): Sender {\n return async ({ title, message, channel, chatId }) => {\n const text = title && !message.startsWith(title) ? `${title}\\n${message}` : message\n const res = await fetch(`${DAEMON}/send`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n // A held entry remembers where it was going; anything else uses the\n // channel this invocation was given.\n body: JSON.stringify({\n channel: channel ?? defaultChannel,\n chatId: chatId ?? defaultChatId,\n text,\n }),\n })\n if (!res.ok) {\n throw new Error(`daemon ${res.status}: ${(await res.text().catch(() => \"\")).slice(0, 200)}`)\n }\n }\n}\n\nexport const notify = new Command()\n .name(\"notify\")\n .description(\"tell the operator something, holding it if they are in Focus\")\n .argument(\"[message]\", \"what to say\")\n .option(\"--from <who>\", \"who is speaking\", \"agentx\")\n .option(\"--title <text>\", \"notification title\", \"Secretary\")\n .option(\"--priority <n>\", \"1 (min) to 5 (max)\", \"4\")\n .option(\"--urgent\", \"deliver even during Focus\")\n .option(\"--channel <name>\", \"delivery channel\", \"ntfy\")\n .option(\"--chat-id <id>\", \"channel address\", \"default\")\n .option(\"--no-sound\", \"do not play a sound on this machine\")\n .option(\"--status\", \"show Focus state and anything being held\")\n .option(\"--flush\", \"deliver everything held, as one message\")\n .option(\"--json\", \"emit the result as JSON\")\n .action(async (message: string | undefined, opts) => {\n const queue = new NotificationQueue()\n const state = readFocus()\n const sound = opts.sound === false ? false : undefined\n\n if (opts.status) {\n const waiting = queue.list()\n if (opts.json) {\n console.log(JSON.stringify({ focus: state, held: waiting }, null, 2))\n return\n }\n console.log(` ${state.active ? chalk.yellow(\"◐\") : chalk.green(\"○\")} ${focusLabel(state)} ${chalk.dim(`· ${state.reason}`)}`)\n console.log(` ${waiting.length} held`)\n for (const w of waiting.slice(0, 8)) {\n const when = new Date(w.at).toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" })\n console.log(chalk.dim(` ${when} ${w.from}: ${w.message.slice(0, 70)}`))\n }\n return\n }\n\n const send = daemonSender(opts.channel, opts.chatId)\n\n if (opts.flush) {\n const n = await flushHeld(send, { queue, sound })\n console.log(n ? chalk.green(` delivered ${n} held notification(s)`) : chalk.dim(\" nothing was held\"))\n return\n }\n\n if (!message?.trim()) {\n console.log(chalk.red(\" nothing to say — pass a message, or use --status / --flush\"))\n process.exit(1)\n }\n\n try {\n const result = await sendNotification(\n {\n message: message.trim(),\n from: opts.from,\n title: opts.title,\n priority: Number(opts.priority) || 4,\n urgent: Boolean(opts.urgent),\n channel: opts.channel,\n chatId: opts.chatId,\n },\n send,\n { queue, sound, focus: state },\n )\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2))\n return\n }\n const mark = result.delivered ? chalk.green(\"→\") : chalk.yellow(\"⏸\")\n console.log(` ${mark} ${result.reason}`)\n if (result.held) {\n console.log(chalk.dim(\" it will arrive with the others when Focus ends\"))\n }\n } catch (e: any) {\n console.log(chalk.red(` ${e?.message ?? e}`))\n // A failed push should still make a noise on this machine rather\n // than failing completely silently.\n if (sound !== false) playSound()\n process.exit(1)\n }\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { readFileSync } from \"fs\"\nimport { askSeat, seatEnvVar, configureDecisions } from \"@/decisions/seat\"\nimport { registerBuiltinDecisionBackends } from \"@/decisions\"\nimport { DecisionStore } from \"@/decisions/store\"\nimport { validateQuestions } from \"@/decisions/questions\"\nimport type { AnyQuestion, StateValue } from \"@/decisions/types\"\n\n// --- `agentx decide` — the general-purpose typed decision, for agents ---\n//\n// `decisions ask` is a smoke test: it does not record, it cannot express a\n// boundary, and it defaults to the mock backend. This is the one an agent\n// is meant to reach for, so it records by default and takes questions in\n// their real shape.\n//\n// WHY AN AGENT SHOULD USE THIS AT ALL.\n//\n// An agent asked to classify two hundred items will otherwise reason about\n// each one in its own context — slowly, expensively, and with an answer\n// that is prose rather than a number. Routing that judgment here returns a\n// typed answer with a probability, in a few hundred milliseconds, for a\n// fraction of a cent, and writes a row that can be calibrated later. The\n// agent keeps the workflow; only the judgment moves.\n//\n// Reads a spec on stdin or from --file:\n//\n// {\n// \"seat\": \"youtube-demand\",\n// \"state\": { \"title\": \"...\", \"views\": 120000, \"channelSubs\": 800000 },\n// \"questions\": {\n// \"trending\": {\n// \"type\": \"noul\",\n// \"instructions\": \"This video is being watched unusually heavily right now.\",\n// \"criteria\": {\n// \"true\": \"Views in the first week already exceed the channel's typical view count.\",\n// \"false\": \"Views are in line with or below what this channel usually gets.\"\n// }\n// }\n// }\n// }\n//\n// Several questions in one spec run in ONE request and cannot see each\n// other's answers, which is what makes them cheap — ask everything\n// independent together.\n\nexport const decide = new Command()\n .name(\"decide\")\n .description(\"ask a typed question about some state and get a calibrated answer back\")\n .option(\"--file <path>\", \"spec JSON file (default: stdin)\")\n .option(\"--backend <name>\", \"decision backend\", \"typesafe\")\n .option(\"--seat <name>\", \"seat name the answers are recorded under\", \"adhoc\")\n .option(\"--no-record\", \"answer without writing a row\")\n .option(\"--timeout <ms>\", \"abandon the call after this long\", \"20000\")\n .action(async (opts) => {\n let raw: string\n try {\n raw = opts.file ? readFileSync(opts.file, \"utf8\") : await readStdin()\n } catch (e: any) {\n fail(`could not read the spec: ${e?.message ?? e}`)\n return\n }\n if (!raw.trim()) return fail(\"no spec given — pipe JSON on stdin or pass --file\")\n\n let spec: { seat?: string; state?: StateValue; questions?: Record<string, AnyQuestion> }\n try {\n spec = JSON.parse(raw)\n } catch (e: any) {\n return fail(`spec is not valid JSON: ${e?.message ?? e}`)\n }\n if (!spec.state) return fail(\"spec needs a `state`\")\n if (!spec.questions || Object.keys(spec.questions).length === 0) {\n return fail(\"spec needs at least one entry in `questions`\")\n }\n // Fail here rather than after a round trip — a choice with one option\n // or a score with one level is a spec bug, not a model problem.\n try {\n validateQuestions(spec.questions)\n } catch (e: any) {\n return fail(e?.message ?? String(e))\n }\n\n const seat = spec.seat || opts.seat\n registerBuiltinDecisionBackends()\n\n // Ad-hoc seats are not in agentx.json, and a seat nobody configured is\n // \"off\". The per-seat env override is read before config precisely so\n // a caller can turn one on for its own process.\n process.env[seatEnvVar(seat)] = \"active\"\n\n let store: DecisionStore | null = null\n if (opts.record !== false) {\n try {\n store = new DecisionStore({})\n } catch (e: any) {\n // Recording is the nice-to-have; answering is the job.\n process.stderr.write(`[decide] not recording (${e?.message ?? e})\\n`)\n }\n }\n configureDecisions({\n enabled: true,\n defaultBackend: opts.backend,\n store,\n seats: { [seat]: { mode: \"active\", backend: opts.backend } },\n })\n\n const result = await askSeat(seat, spec.state, spec.questions, {\n timeoutMs: Number(opts.timeout) || 20_000,\n features: { via: \"cli\" },\n })\n\n if (!result) {\n return fail(\n `the ${opts.backend} backend did not answer — check the key and that the seat is reachable`,\n )\n }\n\n // One JSON object on stdout, because the caller is a program.\n console.log(JSON.stringify({ ok: true, seat, callId: result.callId, answers: result.answers }, null, 2))\n store?.close()\n })\n\nfunction fail(message: string): void {\n console.log(JSON.stringify({ ok: false, error: message }, null, 2))\n process.exitCode = 1\n}\n\nasync function readStdin(): Promise<string> {\n if (process.stdin.isTTY) return \"\"\n const chunks: Buffer[] = []\n for await (const c of process.stdin) chunks.push(Buffer.from(c))\n return Buffer.concat(chunks).toString(\"utf8\")\n}\n","import { Command } from \"commander\"\nimport { execFile, spawn, type ChildProcess } from \"child_process\"\nimport { promisify } from \"util\"\nimport { existsSync, readFileSync, writeFileSync, unlinkSync, statSync } from \"fs\"\nimport { resolve, join } from \"path\"\nimport { tmpdir } from \"os\"\nimport chalk from \"chalk\"\nimport { askSeat } from \"@/decisions/seat\"\nimport {\n UI_ELEMENT_SEAT,\n uiElementQuestions,\n uiElementState,\n toSelection,\n type UICandidate,\n type UIElementAnswers,\n type PriorAttempt,\n} from \"@/decisions/seats/ui-element\"\nimport { HELPER, readScreen, rectFor } from \"@/computer-use/screen\"\nimport { verify as verifyClaim } from \"@/computer-use/verify\"\nimport { LESSONS, type Lesson, type LessonStep } from \"@/teach/lessons\"\n\nconst run = promisify(execFile)\n\n// --- `agentx teach <lesson>` — talk and point, at the same time ---\n//\n// The difference between this and `agentx point` is when the talking\n// happens. An assistant that works in silence and then reports is a tool;\n// one that says what it is about to show you WHILE showing you is\n// something you can learn from. So each step speaks first, then points at\n// the thing it just named, and the label stays on screen while the next\n// sentence plays.\n//\n// Deliberately read-only: it points, it never clicks or types. The person\n// keeps the keyboard, which is what makes it teaching rather than a\n// demonstration you watch.\n\n\n\n\n\nexport const teach = new Command()\n .name(\"teach\")\n .description(\"walk through something on screen, speaking and pointing as it goes\")\n .argument(\"[lesson]\", \"lesson id (omit to list)\")\n .option(\"--voice <id>\", \"ElevenLabs voice id\")\n .option(\"--no-speak\", \"point only, print the narration\")\n .option(\"--no-hud\", \"skip the on-screen callout\")\n .option(\"--record\", \"record the screen (screencapture) around the lesson\")\n .option(\"--record-dir <path>\", \"where to write the recording\")\n .action(async (lessonId: string | undefined, opts) => {\n if (!lessonId) {\n console.log(chalk.bold(\"\\n lessons\\n\"))\n for (const l of LESSONS) {\n console.log(` ${chalk.cyan(l.id.padEnd(22))} ${l.title}`)\n console.log(` ${\" \".repeat(22)} ${chalk.dim(l.appHint)}\\n`)\n }\n return\n }\n const lesson = LESSONS.find((l) => l.id === lessonId)\n if (!lesson) {\n console.log(chalk.red(` no lesson \"${lessonId}\" — run \\`agentx teach\\` to list them`))\n process.exit(1)\n }\n if (!existsSync(HELPER)) {\n console.log(chalk.red(\" helper not built — run apps/mac-helper/build.sh\"))\n process.exit(1)\n }\n\n console.log(chalk.bold(`\\n ${lesson.title}`))\n console.log(chalk.dim(` ${lesson.appHint}\\n`))\n\n // Recording uses screencapture, not Screen Studio.\n //\n // Screen Studio's ⌘⌥3 DOES fire — it opens a picker, with a \"Start\n // Recording\" window and a display highlighter. But the picker needs\n // confirming, Return does not confirm it, and the window exposes no\n // accessibility children at all (it is Electron, like VS Code), so\n // there is nothing to locate and click. Driving it would mean clicking\n // blind at a hardcoded offset, which breaks the first time the app\n // moves a button.\n //\n // screencapture ships with macOS, takes a path, and either produces a\n // file or does not. Opt-in either way: a tool that silently starts\n // capturing the screen is not one anybody should have to think twice\n // about.\n let recorder: ChildProcess | null = null\n let recordingPath: string | null = null\n if (opts.record) {\n recordingPath = join(\n opts.recordDir || process.cwd(),\n `teach-${lesson.id}-${new Date().toISOString().slice(11, 19).replace(/:/g, \"\")}.mov`,\n )\n console.log(chalk.dim(` recording → ${recordingPath}`))\n // -v video, -x silent (no shutter sound in the take), -C shows the\n // cursor, which is the entire point of a pointing lesson.\n recorder = spawn(\"/usr/sbin/screencapture\", [\"-v\", \"-x\", \"-C\", recordingPath], {\n stdio: [\"pipe\", \"ignore\", \"ignore\"],\n })\n // The first frames land before capture is actually running.\n await sleep(2000)\n }\n\n // A callout that persists while the speech moves on. Spawned once and\n // fed lines, not respawned per step — a fresh window each time would\n // flash and lose its place.\n const hud: ChildProcess | null = opts.hud === false\n ? null\n : spawn(HELPER, [\"hud\"], { stdio: [\"pipe\", \"ignore\", \"ignore\"] })\n // `avoid` carries the rectangle about to be highlighted, so the\n // callout steps out of its way. Without it the callout sat on top of\n // the very control the lesson was pointing at — invisible to a click,\n // and completely in the way of a person.\n const setState = (\n title: string, body: string, state: string,\n avoid?: { x: number; y: number; w: number; h: number },\n ) => {\n try {\n hud?.stdin?.write(JSON.stringify({ title, body, state, avoid }) + \"\\n\")\n } catch { /* HUD is optional */ }\n }\n\n // What has been tried on this screen, carried between lookups.\n const attempts: PriorAttempt[] = []\n /** Set when a verify step refused to confirm, so the ending does not\n * claim success and the exit code says so. */\n let stopped = false\n\n for (const [i, step] of lesson.steps.entries()) {\n console.log(` ${chalk.dim(String(i + 1).padStart(2))} ${step.say}`)\n setState(`Step ${i + 1} of ${lesson.steps.length}`, step.say, \"talking\")\n\n // Speak first, then point. Saying \"look at the search box\" AFTER\n // highlighting it is backwards — the eye has already moved and the\n // sentence arrives as confirmation instead of direction.\n const speaking = opts.speak === false\n ? Promise.resolve()\n : speak(step.say, opts.voice)\n\n // Locate while the sentence is still playing, so the highlight\n // lands as the sentence ends rather than after a pause.\n const target = step.find ? await locate(step.find, attempts) : null\n if (step.find && !target) {\n attempts.push({ tried: step.find, changed: false, note: \"not found on screen\" })\n // Say so rather than silently skipping: a lesson that points at\n // nothing and carries on is worse than one that admits the screen\n // is not where it expected.\n console.log(chalk.yellow(` (couldn't find \"${step.find}\" — narrating only)`))\n }\n await speaking\n\n if (target) {\n setState(`Step ${i + 1} of ${lesson.steps.length}`, step.say, \"pointing\",\n { x: target.x, y: target.y, w: target.width, h: target.height })\n await run(HELPER, [\n \"point\",\n \"--x\", String(target.x), \"--y\", String(target.y),\n \"--w\", String(target.width), \"--h\", String(target.height),\n \"--label\", step.label ?? step.find ?? \"\",\n // Short hold when something follows immediately — the highlight\n // should not still be up while text is being typed elsewhere.\n \"--hold\", String(step.click || step.type ? 0.5 : step.holdSeconds ?? 2.6),\n ]).catch(() => {})\n if (step.click) {\n const { error: err, changed } = await act([\"click\"])\n if (err) console.log(chalk.red(` ✗ ${err}`))\n // What actually happened feeds the next lookup, so a control\n // that did nothing is not chosen again.\n attempts.push({\n tried: step.label ?? step.find ?? \"control\",\n changed: changed !== false,\n note: err ?? undefined,\n })\n if (changed === false) {\n console.log(chalk.yellow(` · clicked, but the screen did not change`))\n }\n // Clicking a link navigates. Give the page a beat, then the next\n // step re-reads the screen rather than acting on a stale tree.\n await sleep(step.afterClickWaitMs ?? 1500)\n }\n }\n\n // Errors here are REPORTED, never swallowed.\n //\n // These calls used to end in .catch(() => {}), so the focus gate\n // refusing to type looked exactly like typing successfully: the\n // lesson narrated \"watch me type this\", typed nothing, and carried\n // on. A safety check whose refusal is invisible teaches the operator\n // that the feature is broken rather than that it was protected.\n if (step.type) {\n setState(`Step ${i + 1} of ${lesson.steps.length}`, step.type, \"typing\")\n const { error: err } = await act([\"type\", \"--text\", step.type])\n if (err) {\n console.log(chalk.red(` ✗ ${err}`))\n setState(\"Blocked\", err, \"waiting\")\n attempts.push({ tried: `type into ${step.label ?? \"the field\"}`, changed: false, note: err })\n await sleep(2000)\n }\n }\n if (step.key) {\n setState(`Step ${i + 1} of ${lesson.steps.length}`, `↵ ${step.key}`, \"typing\")\n const { error: err } = await act([\"key\", \"--name\", step.key])\n if (err) {\n console.log(chalk.red(` ✗ ${err}`))\n setState(\"Blocked\", err, \"waiting\")\n attempts.push({ tried: `press ${step.key}`, changed: false, note: err })\n await sleep(2000)\n }\n }\n if (!target && !step.type && !step.key) await sleep((step.holdSeconds ?? 1.2) * 1000)\n else if (step.holdSeconds) await sleep(step.holdSeconds * 1000)\n\n // Did it actually work?\n //\n // Everything above reports whether a CALL succeeded. This is the\n // only thing in the loop that asks whether the screen agrees, and it\n // runs last so the page has settled. A refuted or inconclusive claim\n // stops the lesson: continuing would narrate a result nobody\n // verified, which is the failure this whole path exists to prevent.\n if (step.verify) {\n setState(`Step ${i + 1} of ${lesson.steps.length}`, \"Checking that worked…\", \"waiting\")\n let checked\n try {\n checked = await verifyClaim(step.verify)\n } catch (e: any) {\n checked = null\n console.log(chalk.yellow(` ? could not check: ${e?.message ?? e}`))\n }\n if (checked) {\n const mark = checked.outcome === \"confirmed\" ? chalk.green(\"✓\")\n : checked.outcome === \"refuted\" ? chalk.red(\"✗\") : chalk.yellow(\"?\")\n console.log(` ${mark} ${chalk.dim(checked.reason)}`)\n if (!checked.ok && !step.verifyOptional) {\n setState(\"Stopped\", `That did not work: ${step.verify}`, \"waiting\")\n console.log(chalk.red(`\\n stopping: could not confirm — ${step.verify}`))\n console.log(chalk.dim(` ${checked.reason}`))\n console.log(chalk.dim(` screenshot: ${checked.sighting.shot.path}`))\n await sleep(2500)\n try { hud?.stdin?.end() } catch { /* already gone */ }\n stopped = true\n break\n }\n }\n }\n }\n if (!stopped) {\n setState(\"Done\", lesson.title, \"done\")\n await sleep(1200)\n try { hud?.stdin?.end() } catch { /* already gone */ }\n }\n\n if (recorder && recordingPath) {\n // screencapture -v stops cleanly on SIGINT and finalises the file;\n // SIGTERM leaves an unplayable container.\n recorder.kill(\"SIGINT\")\n await sleep(2500)\n try {\n const { size } = statSync(recordingPath)\n console.log(chalk.green(` recorded ${(size / 1_048_576).toFixed(1)} MB → ${recordingPath}`))\n } catch {\n console.log(chalk.yellow(\" recording produced no file — check Screen Recording permission\"))\n }\n }\n // The recording is finalised either way — a take of the failure is\n // more useful than no take at all.\n if (stopped) {\n console.log(chalk.red(` lesson stopped before the end.\\n`))\n process.exitCode = 3\n return\n }\n console.log(chalk.green(`\\n done.\\n`))\n })\n\n/** Run a helper verb. Returns the error message, or null on success, plus\n * whether the screen actually changed when the verb reports it. */\nasync function act(argv: string[]): Promise<{ error: string | null; changed?: boolean }> {\n try {\n const { stdout } = await run(HELPER, argv)\n const parsed = JSON.parse(stdout || \"{}\")\n if (parsed.ok === false) return { error: String(parsed.error ?? \"refused\") }\n return { error: null, changed: parsed.changed }\n } catch (e: any) {\n // A non-zero exit still carries the JSON on stdout.\n try {\n const parsed = JSON.parse(e?.stdout || \"{}\")\n if (parsed.error) return { error: String(parsed.error) }\n } catch { /* not JSON */ }\n return { error: e?.message ?? \"failed\" }\n }\n}\n\ninterface Located { x: number; y: number; width: number; height: number }\n\n/** Read the screen and ask which control the description names.\n *\n * Uses the same reader as `agentx point`, so a lesson gets the OCR\n * fallback too. Before this, teach read the tree directly: it had the\n * attempt history but no eyes, while point had eyes and no history, and\n * neither had both. */\nasync function locate(description: string, priorAttempts: PriorAttempt[] = []): Promise<Located | null> {\n try {\n const screen = await readScreen({ max: 45 })\n if (screen.candidates.length < 2) return null\n\n const result = await askSeat(\n UI_ELEMENT_SEAT,\n uiElementState({\n request: description,\n app: screen.app,\n window: screen.window,\n candidates: screen.candidates,\n priorAttempts,\n }),\n uiElementQuestions(screen.candidates),\n { features: { app: screen.app, via: \"teach\", ocr: screen.usedOCR } },\n )\n if (!result) return null\n const sel = toSelection(result.answers as UIElementAnswers, screen.candidates)\n // The `present` Noul first, always — a Choice will name something even\n // when the thing is not on screen.\n if (sel.present < 0.5) return null\n return rectFor(screen, sel.id)\n } catch {\n return null\n }\n}\n\n/** ElevenLabs, falling back to `say` — the lesson matters more than the voice. */\nasync function speak(text: string, voiceId?: string): Promise<void> {\n const key = elevenLabsKey()\n if (key) {\n try {\n const voice = voiceId || process.env.AGENTX_VOICE_ID || \"21m00Tcm4TlvDq8ikWAM\"\n const res = await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${voice}`, {\n method: \"POST\",\n headers: { \"xi-api-key\": key, \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ text, model_id: \"eleven_turbo_v2_5\" }),\n })\n if (res.ok) {\n const file = join(tmpdir(), `agentx-teach-${Date.now()}.mp3`)\n writeFileSync(file, Buffer.from(await res.arrayBuffer()))\n await run(\"/usr/bin/afplay\", [file])\n try { unlinkSync(file) } catch { /* temp file */ }\n return\n }\n } catch { /* fall through to say */ }\n }\n await run(\"/usr/bin/say\", [text]).catch(() => {})\n}\n\nfunction elevenLabsKey(): string | null {\n if (process.env.ELEVENLABS_API_KEY) return process.env.ELEVENLABS_API_KEY\n for (const p of [\n `${process.env.HOME}/.elevenlabs/key`,\n `${process.env.HOME}/.agentx/elevenlabs-key.txt`,\n ]) {\n try {\n const v = readFileSync(p, \"utf8\").trim()\n if (v) return v\n } catch { /* next */ }\n }\n return null\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))\nexport type { Lesson, LessonStep }\n","// Lessons for `agentx teach`.\n//\n// A lesson is a sequence of things to SAY, each optionally paired with\n// something to POINT AT. The narration is written to be heard, not read:\n// short sentences, no jargon before it is explained, and no URLs — the\n// same constraints the voice path has everywhere else.\n//\n// `find` is a description, not a selector. It goes to the ui-element seat,\n// which picks from what is actually on screen — so a lesson keeps working\n// when a site moves its buttons, and fails honestly when the screen is not\n// where it expected rather than pointing confidently at the wrong thing.\n\nexport interface LessonStep {\n /** Spoken aloud, printed, and shown in the on-screen callout. */\n say: string\n /** What to point at, in plain words. Omit for narration only. */\n find?: string\n /** Overrides the label shown on the highlight pill. */\n label?: string\n /** Click the located element. Requires `find`. */\n click?: boolean\n /** Type this after locating (and clicking) — paced like a hand. */\n type?: string\n /** Press a named key afterwards, e.g. \"return\" to submit. Separate from\n * `type` so committing a form is always its own deliberate step. */\n key?: string\n holdSeconds?: number\n /** Pause after a click, for pages that navigate. */\n afterClickWaitMs?: number\n /**\n * A claim that must be TRUE once this step has run, checked by looking\n * at the screen.\n *\n * This exists because every other check in a lesson confirms that a call\n * returned, not that anything happened. A run once narrated a whole\n * recording session that never started, and nothing in the pipeline\n * disagreed. A step that claims an effect should state it here, and the\n * lesson stops when the claim is refuted OR cannot be settled — an\n * inconclusive look is not a pass.\n *\n * Write claims about things plainly visible: text in a field, a page\n * that has loaded, a panel covering something. Not about small status\n * glyphs — a menu bar recording dot is about six points, and the vision\n * models tested both missed a real one and reported one that was not\n * there. See seats/screen-state.ts for the measurements.\n */\n verify?: string\n /** Log the check but keep going when it fails. For claims worth\n * recording that are not worth stopping over. */\n verifyOptional?: boolean\n}\n\nexport interface Lesson {\n id: string\n title: string\n /** What should be on screen before starting. */\n appHint: string\n steps: LessonStep[]\n}\n\n/**\n * X advanced search operators.\n *\n * Chosen because the gap between what people do and what is possible is\n * unusually wide here. Almost everyone types words into the search box and\n * scrolls. Almost nobody knows the box accepts operators — and one of them,\n * min_faves, turns the search into \"show me this person's best work\", which\n * is the thing people actually want and have no other way to get.\n */\nconst xAdvancedSearch: Lesson = {\n id: \"x-advanced-search\",\n title: \"X search: find anyone's best posts\",\n appHint: \"Open x.com in Chrome first, signed in.\",\n steps: [\n {\n say: \"Here's something about X search that almost nobody uses. It takes ten seconds and it changes what the site is good for.\",\n },\n {\n say: \"Let's open search. This is it in the sidebar.\",\n find: \"the search and explore link in the sidebar\",\n label: \"Search\",\n click: true,\n // x.com navigates here; the input only exists on the page that loads.\n afterClickWaitMs: 2600,\n },\n {\n say: \"Here's the box itself. Most people type a few words here and scroll. But it accepts commands, not just words.\",\n find: \"the search query input field where you type\",\n label: \"search field\",\n click: true,\n afterClickWaitMs: 900,\n },\n {\n // One `type`, not two.\n //\n // Split across two steps, only the second survived: x.com is a SPA\n // and its search field re-rendered between them, discarding the\n // first. The take showed q=min_faves:500 with \"from:naval\" gone and\n // an error on the results page. Any field with autocomplete or\n // controlled state can do this, so a single query goes in a single\n // call and the narration carries the explanation instead.\n say: \"Watch. From colon, then a username, limits it to that person. Then min underscore faves, colon, five hundred — only posts with at least five hundred likes.\",\n type: \"from:naval min_faves:500\",\n holdSeconds: 1.8,\n },\n {\n say: \"And submit.\",\n key: \"return\",\n holdSeconds: 3.2,\n // The one claim in this lesson worth checking: the query actually\n // reached the page. It is a text question about a loaded page, which\n // is what looking at the screen is reliable for.\n // Worded to avoid \"X search results\", which reads two ways: X is the\n // site, but a model sees \"X results\" as a placeholder for a number\n // and goes looking for a result count that x.com does not display.\n // Measured: the observation came back correct and the evidence\n // argued against it, landing the claim at 0.07. A claim is only as\n // good as its least ambiguous reading.\n verify: \"the x.com page is displaying search results for the query from:naval min_faves:500, with at least one post visible\",\n },\n {\n say: \"There it is. That person's greatest hits — everything they wrote that actually landed. No scrolling through years of replies.\",\n holdSeconds: 2,\n },\n {\n say: \"Two more that pair well with it. Until colon, and since colon, with a date, pin it to a time period. Useful when you half remember something from a particular month.\",\n },\n {\n say: \"And filter colon links, or filter colon media, narrows it to posts that shared something, which is usually where the substance is.\",\n },\n {\n say: \"After you search, check the Latest tab. Top is ranked, Latest is chronological, and for research you almost always want chronological.\",\n find: \"the Latest tab\",\n label: \"Latest\",\n },\n {\n say: \"That's it. From colon someone, min underscore faves colon five hundred. It works on your own account too, which is a quick way to see what people actually responded to.\",\n },\n ],\n}\n\n/**\n * Bookmark folders. Shipped quietly, still largely unknown, and the\n * closest thing X has to a research tool.\n */\nconst xBookmarkFolders: Lesson = {\n id: \"x-bookmark-folders\",\n title: \"X bookmarks: turn the pile into folders\",\n appHint: \"Open x.com in Chrome first, signed in.\",\n steps: [\n {\n say: \"Most people's bookmarks on X are a single pile they never open again. There's a fix that takes a minute.\",\n },\n {\n say: \"Bookmarks live here in the sidebar. By default everything you save lands in one list, in the order you saved it.\",\n find: \"the Bookmarks link in the sidebar\",\n label: \"Bookmarks\",\n },\n {\n say: \"But bookmarks support folders. Open bookmarks and look for the add folder control, usually a small plus at the top right.\",\n find: \"the add folder button\",\n label: \"new folder\",\n },\n {\n say: \"The trick is what you name them. Not topics like design or tech, which you'll never search for. Name them after decisions you're going to make, like hiring, or pricing.\",\n holdSeconds: 2,\n },\n {\n say: \"Then when you save a post, hold the bookmark button instead of tapping it, and it asks which folder. That one gesture is the whole difference between a pile and a library.\",\n },\n ],\n}\n\nexport const LESSONS: Lesson[] = [xAdvancedSearch, xBookmarkFolders]\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport {\n installAttachHooks,\n uninstallAttachHooks,\n attachHooksInstalled,\n userSettingsPath,\n configuredDaemonPort,\n} from \"@/attach/install\"\nimport { DELIVERY_MODES, isDeliveryMode, type AttachSession, type DeliveryMode } from \"@/attach\"\n\n// --- agentx attach ---\n//\n// Wear an agentx identity in the Claude Code session you already have open.\n//\n// Normally the daemon spawns a `claude` subprocess per task. Attach inverts\n// that: this session registers as the agent, and channel messages addressed\n// to it are queued here instead of spawning anything. agentx keeps doing what\n// it is actually good at — identity, routing, memory, guard, channels — and\n// the loop is the one you are already typing into.\n//\n// Binding is a runtime operation against the daemon. The hooks (installed\n// once, at user scope) are dumb pipes that ask the daemon on every event, so\n// attach/detach takes effect immediately with no file edits and no restart.\n\nexport const attach = new Command()\n .name(\"attach\")\n .description(\"wear an agentx agent identity in this Claude Code session\")\n\nconst DEFAULT_URL =\n process.env.AGENTX_DAEMON_URL || `http://127.0.0.1:${configuredDaemonPort()}`\n\n/** Claude Code exports its session id into the shell of every Bash tool call.\n * That is what lets `agentx attach` bind the exact session it is running\n * inside rather than guessing from cwd. It is undocumented, so `--session`\n * stays available and the error text explains the fallback. */\nfunction currentSessionId(explicit?: string): string | undefined {\n return explicit || process.env.CLAUDE_CODE_SESSION_ID || undefined\n}\n\nasync function api(url: string, path: string, body?: unknown): Promise<any> {\n const res = await fetch(`${url}${path}`, {\n method: body ? \"POST\" : \"GET\",\n headers: { \"Content-Type\": \"application/json\" },\n body: body ? JSON.stringify(body) : undefined,\n })\n const text = await res.text()\n let json: any = null\n try {\n json = text ? JSON.parse(text) : null\n } catch {\n /* non-JSON body */\n }\n if (!res.ok) throw new Error(json?.error || text || `HTTP ${res.status}`)\n return json\n}\n\nfunction daemonHint(e: unknown): string {\n const msg = (e as any)?.message ?? String(e)\n if (/ECONNREFUSED|fetch failed/i.test(msg)) {\n return `daemon not reachable — start it with ${chalk.cyan(\"agentx daemon start\")}`\n }\n return msg\n}\n\nfunction modeColor(m: DeliveryMode): (s: string) => string {\n if (m === \"auto\") return chalk.yellow\n if (m === \"manual\") return chalk.gray\n return chalk.green\n}\n\nfunction printSession(s: AttachSession & { pending?: number }, mark = false): void {\n const who = s.agentIds.length ? s.agentIds.join(\", \") : chalk.gray(\"(not bound)\")\n const pending = s.pending ? chalk.yellow(`${s.pending} pending`) : chalk.gray(\"empty\")\n const here = mark ? chalk.cyan(\" ← this session\") : \"\"\n console.log(\n ` ${chalk.bold(who)} ${modeColor(s.mode)(s.mode)} ${pending} ${chalk.gray(s.sessionId)}${here}`,\n )\n if (s.cwd) console.log(` ${chalk.gray(s.cwd)}`)\n}\n\n// ---------------------------------------------------------------------------\n// agentx attach <agent> — bind this session\n// ---------------------------------------------------------------------------\nattach\n .command(\"as <agent>\", { isDefault: true })\n .description(\"bind this Claude Code session to an agent identity\")\n .option(\"-m, --mode <mode>\", `delivery mode: ${DELIVERY_MODES.join(\" | \")}`, \"notify\")\n .option(\"--session <id>\", \"Claude Code session id (defaults to $CLAUDE_CODE_SESSION_ID)\")\n .option(\"--url <url>\", \"daemon base url\", DEFAULT_URL)\n .action(async (agent: string, opts) => {\n const sessionId = currentSessionId(opts.session)\n if (!sessionId) {\n console.error(chalk.red(\"Could not determine the Claude Code session id.\"))\n console.error(\n `Run this inside a Claude Code session, or pass ${chalk.cyan(\"--session <id>\")} ` +\n `(list them with ${chalk.cyan(\"agentx attach list\")}).`,\n )\n process.exit(1)\n }\n if (!isDeliveryMode(opts.mode)) {\n console.error(chalk.red(`Invalid mode \"${opts.mode}\". Expected one of: ${DELIVERY_MODES.join(\", \")}`))\n process.exit(1)\n }\n\n if (!attachHooksInstalled()) {\n console.error(chalk.yellow(\"Attach hooks are not installed yet.\"))\n console.error(`Run ${chalk.cyan(\"agentx attach install\")} once, then try again.`)\n process.exit(1)\n }\n\n try {\n const r = await api(opts.url, \"/attach/bind\", {\n sessionId,\n agentId: agent,\n mode: opts.mode,\n cwd: process.cwd(),\n })\n console.log(\n `${chalk.green(\"✓\")} This session is now wearing ${chalk.bold(agent)} ` +\n `(${modeColor(opts.mode)(opts.mode)}).`,\n )\n const pending = Number(r?.pending ?? 0)\n if (pending > 0) {\n console.log(chalk.yellow(` ${pending} message(s) already queued for it.`))\n }\n console.log(\n chalk.gray(\n opts.mode === \"auto\"\n ? \" Queued messages will be answered automatically at the end of each turn.\"\n : opts.mode === \"notify\"\n ? \" You'll be told when messages arrive; run /inbox to answer them.\"\n : \" Nothing will interrupt you; run /inbox to check for messages.\",\n ),\n )\n } catch (e) {\n console.error(chalk.red(`Bind failed: ${daemonHint(e)}`))\n process.exit(1)\n }\n })\n\n// ---------------------------------------------------------------------------\n// agentx attach detach\n// ---------------------------------------------------------------------------\nattach\n .command(\"detach\")\n .description(\"stop wearing an identity in this session (queued work falls back to spawned agents)\")\n .option(\"--agent <id>\", \"release only this identity (default: all)\")\n .option(\"--session <id>\", \"Claude Code session id (defaults to $CLAUDE_CODE_SESSION_ID)\")\n .option(\"--url <url>\", \"daemon base url\", DEFAULT_URL)\n .action(async (opts) => {\n const sessionId = currentSessionId(opts.session)\n if (!sessionId) {\n console.error(chalk.red(\"Could not determine the Claude Code session id. Pass --session <id>.\"))\n process.exit(1)\n }\n try {\n await api(opts.url, \"/attach/detach\", { sessionId, agentId: opts.agent })\n console.log(`${chalk.green(\"✓\")} Detached. New messages will spawn agents the normal way.`)\n } catch (e) {\n console.error(chalk.red(`Detach failed: ${daemonHint(e)}`))\n process.exit(1)\n }\n })\n\n// ---------------------------------------------------------------------------\n// agentx attach list / status\n// ---------------------------------------------------------------------------\nattach\n .command(\"list\")\n .alias(\"status\")\n .description(\"show every attached session on this machine\")\n .option(\"--url <url>\", \"daemon base url\", DEFAULT_URL)\n .option(\"--json\", \"raw JSON output\")\n .action(async (opts) => {\n const here = currentSessionId()\n try {\n const r = await api(opts.url, \"/attach/sessions\")\n const sessions: Array<AttachSession & { pending: number }> = r?.sessions ?? []\n if (opts.json) {\n console.log(JSON.stringify({ hooksInstalled: attachHooksInstalled(), sessions }, null, 2))\n return\n }\n\n console.log()\n console.log(\n attachHooksInstalled()\n ? `${chalk.green(\"✓\")} Attach hooks installed ${chalk.gray(userSettingsPath())}`\n : `${chalk.yellow(\"!\")} Attach hooks not installed — run ${chalk.cyan(\"agentx attach install\")}`,\n )\n console.log()\n\n const bound = sessions.filter((s) => s.agentIds.length > 0)\n if (bound.length === 0) {\n console.log(chalk.gray(\" No session is wearing an identity right now.\"))\n } else {\n for (const s of bound) printSession(s, s.sessionId === here)\n }\n const idle = sessions.length - bound.length\n if (idle > 0) console.log(chalk.gray(`\\n ${idle} registered session(s) with no binding.`))\n console.log()\n } catch (e) {\n console.error(chalk.red(`Could not read attach state: ${daemonHint(e)}`))\n process.exit(1)\n }\n })\n\n// ---------------------------------------------------------------------------\n// agentx attach install / uninstall\n// ---------------------------------------------------------------------------\nattach\n .command(\"install\")\n .description(\"wire the attach hooks into ~/.claude/settings.json (one time, all sessions)\")\n .option(\"--port <n>\", \"daemon port the hooks should call (default: node.bind in agentx.json)\")\n .option(\"--path <file>\", \"settings file to patch (default: ~/.claude/settings.json)\")\n .option(\"--no-guard\", \"skip the PreToolUse guard hook (not recommended)\")\n .action((opts) => {\n try {\n const port = String(opts.port || configuredDaemonPort())\n const r = installAttachHooks(port, { path: opts.path, withGuard: opts.guard })\n console.log(\n r.changed\n ? `${chalk.green(\"✓\")} Installed attach hooks in ${chalk.gray(r.path)}`\n : `${chalk.green(\"✓\")} Attach hooks already up to date in ${chalk.gray(r.path)}`,\n )\n console.log(chalk.gray(` Events: ${r.events.join(\", \")} → 127.0.0.1:${port}`))\n if (r.guardInstalled) {\n console.log(chalk.gray(\" PreToolUse guard installed at user scope.\"))\n console.log(\n chalk.gray(\n \" (An attached session runs under your permissions, not the agent's workspace\\n\" +\n \" settings — without this an attached production identity would be less\\n\" +\n \" guarded than a spawned one.)\",\n ),\n )\n } else {\n console.log(\n chalk.yellow(\n \" ! Guard hook skipped. An attached production identity will run unguarded.\",\n ),\n )\n }\n console.log()\n console.log(`Next: ${chalk.cyan(\"agentx attach <agent>\")} inside a Claude Code session.`)\n } catch (e: any) {\n console.error(chalk.red(`Install failed: ${e?.message ?? e}`))\n process.exit(1)\n }\n })\n\nattach\n .command(\"uninstall\")\n .description(\"remove the attach hooks from ~/.claude/settings.json\")\n .option(\"--path <file>\", \"settings file to patch (default: ~/.claude/settings.json)\")\n .option(\"--remove-guard\", \"also remove the PreToolUse guard hook\")\n .action((opts) => {\n try {\n const r = uninstallAttachHooks({ path: opts.path, keepGuard: !opts.removeGuard })\n console.log(\n r.changed\n ? `${chalk.green(\"✓\")} Removed attach hooks from ${chalk.gray(r.path)} (${r.events.join(\", \")})`\n : `${chalk.gray(\"Nothing to remove.\")}`,\n )\n if (!opts.removeGuard) {\n console.log(chalk.gray(\" PreToolUse guard left in place — pass --remove-guard to drop it too.\"))\n }\n } catch (e: any) {\n console.error(chalk.red(`Uninstall failed: ${e?.message ?? e}`))\n process.exit(1)\n }\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx process — operator surface for the persistent claude registry ---\n//\n// Two subcommands:\n// agentx process list list every live handle\n// agentx process kill <agentId> <channel> <chatId> force-rotate one handle\n//\n// Both talk to the local daemon's HTTP API. The registry is in-memory\n// (no SQLite persistence) so a daemon restart fully resets it; this CLI\n// is the only mid-flight operator surface short of a restart.\n\nexport const process_ = new Command()\n .name(\"process\")\n .description(\"inspect / rotate persistent claude processes (--persistentProcess agents)\")\n\ninterface ResolvedDaemon {\n baseUrl: string\n token: string\n}\n\nfunction resolveDaemon(opts: { node?: string; token?: string; config?: string }): ResolvedDaemon {\n let baseUrl = typeof opts.node === \"string\" ? opts.node : \"\"\n let token = typeof opts.token === \"string\" ? opts.token : \"\"\n if (!baseUrl || !token) {\n try {\n const cfg = loadDaemonConfig(opts.config)\n if (!baseUrl) baseUrl = cfg.dashboard?.daemonUrl || \"\"\n if (!token) token = cfg.dashboard?.token || \"\"\n } catch { /* fall back to defaults */ }\n }\n if (!baseUrl) baseUrl = \"http://localhost:18800\"\n return { baseUrl: baseUrl.replace(/\\/+$/, \"\"), token }\n}\n\nfunction authHeaders(token: string, contentType?: string): Record<string, string> {\n const h: Record<string, string> = {}\n if (token) h[\"Authorization\"] = `Bearer ${token}`\n if (contentType) h[\"Content-Type\"] = contentType\n return h\n}\n\nfunction fmtAge(ms: number): string {\n const s = Math.round((Date.now() - ms) / 1000)\n if (s < 60) return `${s}s`\n if (s < 3600) return `${Math.round(s / 60)}m`\n if (s < 86400) return `${Math.round(s / 3600)}h`\n return `${Math.round(s / 86400)}d`\n}\n\nfunction stateColor(s: string): (text: string) => string {\n if (s === \"busy\") return chalk.magenta\n if (s === \"warm-hot\") return chalk.green\n if (s === \"warm-cold\") return chalk.cyan\n if (s === \"idle\") return chalk.yellow\n if (s === \"dead\") return chalk.red\n return chalk.dim\n}\n\n// ---------------------------------------------------------------------------\n// agentx process list\n// ---------------------------------------------------------------------------\n\nprocess_\n .command(\"list\")\n .description(\"list every live persistent claude process\")\n .option(\"-c, --config <path>\", \"daemon config file\")\n .option(\"--node <url>\", \"daemon URL (defaults to dashboard.daemonUrl)\")\n .option(\"--token <token>\", \"bearer token (defaults to dashboard.token)\")\n .option(\"--json\", \"emit JSON\")\n .action(async (opts) => {\n const { baseUrl, token } = resolveDaemon(opts)\n let res: Response\n try {\n res = await fetch(`${baseUrl}/api/processes`, { headers: authHeaders(token) })\n } catch (e: any) {\n console.log(chalk.red(` could not reach daemon at ${baseUrl}: ${e.message || e}`))\n process.exit(1)\n }\n if (res.status === 503) {\n console.log(chalk.dim(` daemon at ${baseUrl} has no agents with persistentProcess: true`))\n return\n }\n if (!res.ok) {\n console.log(chalk.red(` HTTP ${res.status} from ${baseUrl}/processes`))\n process.exit(1)\n }\n const body = (await res.json()) as { processes: Array<Record<string, any>> }\n const procs = body.processes ?? []\n\n if (opts.json) {\n console.log(JSON.stringify(procs, null, 2))\n return\n }\n if (procs.length === 0) {\n console.log(chalk.dim(` (no processes)`))\n return\n }\n\n for (const p of procs) {\n const state = stateColor(p.state)(p.state.padEnd(9))\n const age = fmtAge(p.spawnedAt)\n const lastTurn = p.lastTurnAt ? fmtAge(p.lastTurnAt) + \" ago\" : \"—\"\n const tokens = p.lastInputTokens ? chalk.dim(`last_in=${p.lastInputTokens} tok`) : \"\"\n const session = p.claudeSessionId ? chalk.dim(`sess=${p.claudeSessionId.slice(0, 8)}…`) : chalk.dim(\"sess=—\")\n const pending = p.pendingTaskId ? chalk.cyan(`task=${String(p.pendingTaskId).slice(0, 12)}`) : \"\"\n console.log(\n `${state} ${chalk.bold(p.key.agentId)}${chalk.dim(\":\" + p.key.channel + \":\" + p.key.chatId)}` +\n ` ${chalk.dim(\"·\")} pid=${p.pid ?? \"?\"} age=${age} turn#${p.turnCount} last=${lastTurn} ${session} ${tokens} ${pending}`,\n )\n if (p.deadReason) console.log(` ${chalk.red(\"dead:\")} ${p.deadReason}`)\n }\n })\n\n// ---------------------------------------------------------------------------\n// agentx process kill\n// ---------------------------------------------------------------------------\n\nprocess_\n .command(\"kill <agentId> <channel> <chatId>\")\n .description(\"force-kill one persistent process (the next dispatch will spawn fresh)\")\n .option(\"-c, --config <path>\", \"daemon config file\")\n .option(\"--node <url>\", \"daemon URL (defaults to dashboard.daemonUrl)\")\n .option(\"--token <token>\", \"bearer token (defaults to dashboard.token)\")\n .option(\"-r, --reason <reason>\", \"kill reason (recorded on the dead-process snapshot)\", \"operator-cli\")\n .action(async (agentId: string, channel: string, chatId: string, opts) => {\n const { baseUrl, token } = resolveDaemon(opts)\n let res: Response\n try {\n res = await fetch(`${baseUrl}/api/processes/kill`, {\n method: \"POST\",\n headers: authHeaders(token, \"application/json\"),\n body: JSON.stringify({ agentId, channel, chatId, reason: opts.reason }),\n })\n } catch (e: any) {\n console.log(chalk.red(` could not reach daemon at ${baseUrl}: ${e.message || e}`))\n process.exit(1)\n }\n if (res.status === 503) {\n console.log(chalk.dim(` daemon has no persistent-process registry`))\n return\n }\n if (!res.ok) {\n let msg = `HTTP ${res.status}`\n try { const body = (await res.json()) as { error?: string }; if (body.error) msg += ` — ${body.error}` } catch { /* */ }\n console.log(chalk.red(` ${msg}`))\n process.exit(1)\n }\n console.log(chalk.green(` killed ${agentId}:${channel}:${chatId}`))\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { existsSync, rmSync } from \"fs\"\nimport { resolve } from \"path\"\nimport { buildIndex, indexInfo, lexicalSearch } from \"@/rag/lexical-index\"\n\n// --- agentx rag ---\n//\n// Improvement plan #7 — embedding-free retrieval-augmented context.\n//\n// agentx rag add <agentId> <glob>... build/refresh an agent's index\n// agentx rag list list every agent's index status\n// agentx rag search <agentId> <query> query the index (debug surface)\n// agentx rag clear <agentId> delete the index\n//\n// Index format is JSON-serialized minisearch state. Tiny, portable,\n// rsyncable. Lives at .agentx/rag/<agentId>/index.json.\n\nexport const rag = new Command()\n .name(\"rag\")\n .description(\"manage per-agent lexical (BM25) RAG indexes (improvement plan #7)\")\n\nrag\n .command(\"add <agentId>\")\n .description(\"build or refresh an agent's lexical index from one or more globs\")\n .argument(\"<globs...>\", \"glob patterns relative to cwd (e.g. './docs/**/*.md')\")\n .option(\"-v, --verbose\", \"log each indexed file\")\n .action(async (agentId: string, globs: string[], opts) => {\n if (globs.length === 0) {\n console.log(chalk.red(` No globs provided. Example: agentx rag add ${agentId} './docs/**/*.md'`))\n process.exit(1)\n }\n const verbose = !!opts.verbose\n const start = Date.now()\n const r = await buildIndex(agentId, globs, { verbose })\n const ms = Date.now() - start\n console.log(chalk.green(` ✓ indexed ${r.docs} doc(s) for ${chalk.bold(agentId)} in ${ms}ms`))\n console.log(chalk.dim(` → ${r.path}`))\n })\n\nrag\n .command(\"list\")\n .description(\"list every agent's index, sizes, paths\")\n .option(\"-c, --cwd <path>\", \"search root\", process.cwd())\n .action(async (opts) => {\n const root = resolve(opts.cwd, \".agentx\", \"rag\")\n if (!existsSync(root)) {\n console.log(chalk.dim(\" (no indexes yet — try `agentx rag add <agentId> <glob>`)\"))\n return\n }\n const { readdirSync } = await import(\"fs\")\n const agents = readdirSync(root).filter((d) => existsSync(resolve(root, d, \"index.json\")))\n if (agents.length === 0) {\n console.log(chalk.dim(\" (no indexes)\"))\n return\n }\n for (const a of agents.sort()) {\n const info = indexInfo(a)\n console.log(` ${chalk.bold(a)} ${info.docs} doc(s) ${chalk.dim(info.path)}`)\n }\n })\n\nrag\n .command(\"search <agentId> <query>\")\n .description(\"query an agent's index — useful for debugging recall before the agent calls rag.lexical\")\n .option(\"-k, --k <n>\", \"top-k results\", \"5\")\n .option(\"--json\", \"emit JSON\")\n .action((agentId: string, query: string, opts) => {\n const k = parseInt(opts.k, 10) || 5\n const hits = lexicalSearch(agentId, query, { k })\n if (opts.json) {\n console.log(JSON.stringify(hits, null, 2))\n return\n }\n if (hits.length === 0) {\n const info = indexInfo(agentId)\n if (!info.exists) {\n console.log(chalk.red(` no index for ${agentId} — run \\`agentx rag add ${agentId} <glob>\\` first`))\n } else {\n console.log(chalk.dim(` (no hits in ${info.docs} indexed docs)`))\n }\n return\n }\n for (const h of hits) {\n console.log(` ${chalk.bold(h.title)} ${chalk.dim(`(${h.score.toFixed(2)})`)}`)\n console.log(` ${chalk.dim(h.path)}`)\n console.log(` ${chalk.dim(h.snippet.slice(0, 200))}`)\n }\n })\n\nrag\n .command(\"clear <agentId>\")\n .description(\"delete an agent's index\")\n .action((agentId: string) => {\n const path = resolve(process.cwd(), \".agentx\", \"rag\", agentId)\n if (!existsSync(path)) {\n console.log(chalk.dim(` no index for ${agentId} — nothing to clear`))\n return\n }\n rmSync(path, { recursive: true, force: true })\n console.log(chalk.green(` ✓ cleared index for ${agentId}`))\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport prompts from \"prompts\"\nimport { loadDaemonConfig, type DaemonConfig } from \"@/daemon/config\"\nimport { BacklogStore, sourceBacklogId, type BacklogItem, type BacklogSource } from \"@/business/backlog-store\"\nimport { syncBacklogItemToSource, resolveAssigneesForSource } from \"@/business/backlog-sync\"\n\nexport const backlog = new Command()\n .name(\"backlog\")\n .description(\"manage the local backlog used by business workSource=backlog\")\n\n// ---------- Helpers ----------\n\ninterface Daemon {\n config: DaemonConfig\n storePath: string\n store: BacklogStore\n}\n\nfunction loadCtx(configPath?: string): Daemon {\n const config = loadDaemonConfig(configPath)\n const ws = (config as any).business?.workSource\n const storePath = ws?.type === \"backlog\" ? ws.path : \".agentx/backlog.md\"\n return { config, storePath, store: new BacklogStore(storePath) }\n}\n\nfunction fmtSource(s: BacklogItem[\"source\"]): string {\n if (!s) return chalk.dim(\"manual\")\n return chalk.cyan(`${s.type}:${s.project}#${s.iid}`)\n}\n\nfunction fmtStatus(status: BacklogItem[\"status\"]): string {\n return ({\n todo: chalk.gray(\"todo\"),\n doing: chalk.yellow(\"doing\"),\n blocked: chalk.red(\"blocked\"),\n done: chalk.green(\"done\"),\n })[status]\n}\n\n// ---------- list ----------\n\nbacklog\n .command(\"list\", { isDefault: true })\n .description(\"list backlog items\")\n .option(\"--status <status>\", \"filter by status (todo|doing|blocked|done)\")\n .option(\"--assignee <agent>\", \"filter by assignee\")\n .option(\"--source <type>\", \"filter by source.type (gitlab|github|manual)\")\n .option(\"-c, --config <path>\", \"config path\")\n .action(async (opts: { status?: string; assignee?: string; source?: string; config?: string }) => {\n const { store } = loadCtx(opts.config)\n let items = store.list()\n if (opts.status) items = items.filter((i) => i.status === opts.status)\n if (opts.assignee) items = items.filter((i) => i.assignee === opts.assignee)\n if (opts.source) {\n items = items.filter((i) =>\n opts.source === \"manual\" ? !i.source : i.source?.type === opts.source,\n )\n }\n\n if (!items.length) {\n console.log(chalk.dim(\" (no items)\"))\n return\n }\n\n console.log()\n for (const it of items) {\n const assignee = it.assignee ? chalk.magenta(`@${it.assignee}`) : chalk.dim(\"unassigned\")\n console.log(` ${fmtStatus(it.status).padEnd(7)} ${fmtSource(it.source)} ${assignee} ${it.title}`)\n if (it.source?.url) console.log(chalk.dim(` ${it.source.url}`))\n }\n console.log()\n console.log(chalk.dim(` ${items.length} item${items.length === 1 ? \"\" : \"s\"} — ${store.jsonPath()}`))\n })\n\n// ---------- claim ----------\n\nbacklog\n .command(\"claim <id> <agent>\")\n .description(\"assign an item to an agent and set status=doing\")\n .option(\"-c, --config <path>\", \"config path\")\n .action(async (id: string, agent: string, opts: { config?: string }) => {\n const ctx = loadCtx(opts.config)\n const item = ctx.store.findById(id)\n if (!item) {\n console.error(chalk.red(` item ${id} not found`))\n process.exit(1)\n }\n const updated = ctx.store.update(id, { assignee: agent, status: \"doing\" })\n console.log(chalk.green(` claimed: ${updated.title} -> ${agent}`))\n\n if (updated.source) {\n const usernames = resolveAssigneesForSource([agent], updated.source, ctx.config)\n const result = await syncBacklogItemToSource(updated, {\n assigneeUsernames: usernames,\n addLabels: [\"Doing\"],\n removeLabels: [\"To Do\"],\n }, ctx.config, (...a) => console.log(chalk.dim(\" sync:\"), ...a))\n console.log(result.ok\n ? chalk.dim(` synced -> ${result.url ?? updated.source.type}`)\n : chalk.yellow(` sync failed: ${result.error}`),\n )\n }\n })\n\n// ---------- done ----------\n\nbacklog\n .command(\"done <id>\")\n .description(\"mark an item as done; closes the upstream issue if linked\")\n .option(\"--note <text>\", \"comment to post upstream\")\n .option(\"--close\", \"also close the upstream issue (default: only labels change)\", false)\n .option(\"-c, --config <path>\", \"config path\")\n .action(async (id: string, opts: { note?: string; close?: boolean; config?: string }) => {\n const ctx = loadCtx(opts.config)\n const item = ctx.store.findById(id)\n if (!item) {\n console.error(chalk.red(` item ${id} not found`))\n process.exit(1)\n }\n const updated = ctx.store.update(id, { status: \"done\" })\n console.log(chalk.green(` done: ${updated.title}`))\n\n if (updated.source) {\n const result = await syncBacklogItemToSource(updated, {\n addLabels: [\"Done\"],\n removeLabels: [\"Doing\"],\n state: opts.close ? \"closed\" : undefined,\n note: opts.note,\n }, ctx.config, (...a) => console.log(chalk.dim(\" sync:\"), ...a))\n console.log(result.ok\n ? chalk.dim(` synced -> ${result.url ?? updated.source.type}`)\n : chalk.yellow(` sync failed: ${result.error}`),\n )\n }\n })\n\n// ---------- remove ----------\n\nbacklog\n .command(\"remove <id>\")\n .description(\"remove an item from the local backlog (does NOT touch upstream)\")\n .option(\"-c, --config <path>\", \"config path\")\n .action(async (id: string, opts: { config?: string }) => {\n const { store } = loadCtx(opts.config)\n const removed = store.remove(id)\n if (!removed) {\n console.error(chalk.red(` item ${id} not found`))\n process.exit(1)\n }\n console.log(chalk.green(` removed ${id}`))\n })\n\n// ---------- import ----------\n\nbacklog\n .command(\"import\")\n .description(\"import open issues from gitlab/github into the backlog (interactive)\")\n .option(\"--source <type>\", \"source type (gitlab|github)\")\n .option(\"--project <id>\", \"project id (group/repo for gitlab, owner/repo for github)\")\n .option(\"--assignee <agent>\", \"assign all imported items to this agentId\")\n .option(\"-c, --config <path>\", \"config path\")\n .action(async (opts: { source?: string; project?: string; assignee?: string; config?: string }) => {\n const ctx = loadCtx(opts.config)\n\n // Resolve which sources are configured.\n const gitlabReady = !!ctx.config.channels.gitlab?.token\n const githubReady = !!ctx.config.channels.github?.token\n if (!gitlabReady && !githubReady) {\n console.error(chalk.red(\" no source configured — set channels.gitlab.token or channels.github.token in agentx.json\"))\n process.exit(1)\n }\n\n let source = opts.source\n if (!source) {\n const choices = [\n gitlabReady && { title: \"GitLab\", value: \"gitlab\" },\n githubReady && { title: \"GitHub\", value: \"github\" },\n ].filter(Boolean) as Array<{ title: string; value: string }>\n const ans = await prompts({ type: \"select\", name: \"source\", message: \"Source\", choices })\n source = ans.source\n if (!source) return\n }\n\n if (source === \"gitlab\" && !gitlabReady) {\n console.error(chalk.red(\" channels.gitlab.token not configured\"))\n process.exit(1)\n }\n if (source === \"github\" && !githubReady) {\n console.error(chalk.red(\" channels.github.token not configured\"))\n process.exit(1)\n }\n\n // Project.\n let project = opts.project\n if (!project) {\n const candidates = source === \"gitlab\"\n ? collectGitlabProjects(ctx.config)\n : collectGithubProjects(ctx.config)\n if (candidates.length) {\n const ans = await prompts({\n type: \"autocomplete\",\n name: \"project\",\n message: \"Project (type to filter, or pick + then Enter for custom)\",\n choices: [\n ...candidates.map((p) => ({ title: p, value: p })),\n { title: \"(custom — type below)\", value: \"__CUSTOM__\" },\n ],\n })\n project = ans.project\n if (project === \"__CUSTOM__\") {\n const c = await prompts({ type: \"text\", name: \"p\", message: source === \"gitlab\" ? \"Group/path\" : \"owner/repo\" })\n project = c.p\n }\n } else {\n const c = await prompts({\n type: \"text\",\n name: \"p\",\n message: source === \"gitlab\" ? \"Group/path\" : \"owner/repo\",\n })\n project = c.p\n }\n }\n if (!project) return\n\n // Optional search filter pre-fetch (server-side).\n const searchAns = await prompts({\n type: \"text\",\n name: \"search\",\n message: \"Search filter (optional — leave empty for all open)\",\n })\n const search = (searchAns.search || \"\").trim()\n\n console.log(chalk.dim(` fetching open issues from ${source}:${project}${search ? ` (search: ${search})` : \"\"}…`))\n const issues = source === \"gitlab\"\n ? await fetchGitlabIssues(ctx.config, project, search)\n : await fetchGithubIssues(ctx.config, project, search)\n\n if (!issues.length) {\n console.log(chalk.yellow(\" no open issues matched\"))\n return\n }\n console.log(chalk.dim(` ${issues.length} open issue${issues.length === 1 ? \"\" : \"s\"}`))\n\n const projectId = project\n // Mark already-imported items so the user can see them.\n const existing = new Set(ctx.store.list().map((i) => i.id))\n const choices = issues.map((iss) => {\n const id = sourceBacklogId({ type: source as any, project: projectId, iid: iss.iid, url: iss.url })\n const already = existing.has(id)\n const labels = iss.labels.length ? ` [${iss.labels.slice(0, 3).join(\",\")}]` : \"\"\n return {\n title: `#${iss.iid} ${iss.title}${labels}${already ? chalk.dim(\" (already imported)\") : \"\"}`,\n value: iss,\n disabled: already,\n }\n })\n\n const pick = await prompts({\n type: \"autocompleteMultiselect\",\n name: \"selected\",\n message: \"Pick issues to import (space to toggle, Enter to confirm)\",\n instructions: false,\n choices,\n min: 1,\n })\n\n const selected = (pick.selected || []) as ImportIssue[]\n if (!selected.length) {\n console.log(chalk.dim(\" nothing selected\"))\n return\n }\n\n const toAdd = selected.map((iss): Omit<BacklogItem, \"createdAt\" | \"updatedAt\"> => {\n const src: BacklogSource = {\n type: source as \"gitlab\" | \"github\",\n host: source === \"gitlab\" ? hostnameFromGitlab(ctx.config) : undefined,\n project: projectId,\n iid: iss.iid,\n url: iss.url,\n }\n return {\n id: sourceBacklogId(src),\n title: iss.title,\n description: iss.description,\n assignee: opts.assignee || iss.assignee,\n labels: iss.labels,\n milestone: iss.milestone,\n status: \"todo\",\n source: src,\n importedAt: new Date().toISOString(),\n }\n })\n\n const added = ctx.store.addMany(toAdd)\n console.log(chalk.green(` imported ${added.length} item${added.length === 1 ? \"\" : \"s\"}`))\n for (const it of added) {\n console.log(chalk.dim(` ${it.id} — ${it.title}`))\n }\n })\n\n// ---------- Source helpers ----------\n\ninterface ImportIssue {\n iid: number\n title: string\n description?: string\n labels: string[]\n milestone?: string\n assignee?: string\n url: string\n}\n\nfunction hostnameFromGitlab(daemon: DaemonConfig): string | undefined {\n const host = daemon.channels.gitlab?.host\n if (!host) return undefined\n return host.replace(/^https?:\\/\\//, \"\").replace(/\\/+$/, \"\")\n}\n\nfunction collectGitlabProjects(daemon: DaemonConfig): string[] {\n const set = new Set<string>()\n for (const r of daemon.channels.gitlab?.routes ?? []) if (r.project && r.project !== \"*\") set.add(r.project)\n const ws = (daemon as any).business?.workSource\n if (ws?.type === \"gitlab\") for (const p of ws.projects ?? []) set.add(p)\n for (const p of (daemon as any).business?.projects ?? []) {\n if (p?.id && p.id.includes(\"/\")) set.add(p.id)\n }\n return [...set].sort()\n}\n\nfunction collectGithubProjects(daemon: DaemonConfig): string[] {\n const set = new Set<string>()\n for (const r of daemon.channels.github?.routes ?? []) if (r.repo && r.repo !== \"*\") set.add(r.repo)\n return [...set].sort()\n}\n\nasync function fetchGitlabIssues(daemon: DaemonConfig, project: string, search: string): Promise<ImportIssue[]> {\n const gl = daemon.channels.gitlab!\n const params = new URLSearchParams({\n state: \"opened\",\n scope: \"all\",\n per_page: \"100\",\n order_by: \"updated_at\",\n sort: \"desc\",\n })\n if (search) params.set(\"search\", search)\n\n const res = await fetch(\n `${gl.host}/api/v4/projects/${encodeURIComponent(project)}/issues?${params}`,\n { headers: { \"PRIVATE-TOKEN\": gl.token! } },\n )\n if (!res.ok) {\n throw new Error(`GitLab ${res.status}: ${await res.text().catch(() => \"\")}`)\n }\n const arr: any = await res.json()\n if (!Array.isArray(arr)) return []\n return arr.map((i: any): ImportIssue => ({\n iid: i.iid,\n title: i.title,\n description: i.description || undefined,\n labels: Array.isArray(i.labels) ? i.labels.map((l: any) => (typeof l === \"string\" ? l : l.name)) : [],\n milestone: i.milestone?.title || undefined,\n assignee: i.assignee?.username || i.assignees?.[0]?.username || undefined,\n url: i.web_url,\n }))\n}\n\nasync function fetchGithubIssues(daemon: DaemonConfig, project: string, search: string): Promise<ImportIssue[]> {\n const gh = daemon.channels.github!\n const headers = {\n \"Authorization\": `Bearer ${gh.token!}`,\n \"Accept\": \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n }\n\n // GitHub: separate `search` API for text filter (covers title+body); without\n // a query, list issues directly. Search API includes pull requests in `issues`,\n // so filter `is:issue` explicitly.\n let url: string\n if (search) {\n const q = `repo:${project} is:issue is:open ${search}`\n url = `https://api.github.com/search/issues?q=${encodeURIComponent(q)}&per_page=100&sort=updated&order=desc`\n const res = await fetch(url, { headers })\n if (!res.ok) throw new Error(`GitHub ${res.status}: ${await res.text().catch(() => \"\")}`)\n const data: any = await res.json()\n const items: any[] = data.items ?? []\n return items.map(githubMap)\n }\n\n url = `https://api.github.com/repos/${project}/issues?state=open&per_page=100&sort=updated&direction=desc`\n const res = await fetch(url, { headers })\n if (!res.ok) throw new Error(`GitHub ${res.status}: ${await res.text().catch(() => \"\")}`)\n const arr: any = await res.json()\n if (!Array.isArray(arr)) return []\n // /issues returns PRs too; drop them.\n return arr.filter((i: any) => !i.pull_request).map(githubMap)\n}\n\nfunction githubMap(i: any): ImportIssue {\n return {\n iid: i.number,\n title: i.title,\n description: i.body || undefined,\n labels: Array.isArray(i.labels) ? i.labels.map((l: any) => (typeof l === \"string\" ? l : l.name)) : [],\n milestone: i.milestone?.title || undefined,\n assignee: i.assignee?.login || i.assignees?.[0]?.login || undefined,\n url: i.html_url,\n }\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { existsSync, readFileSync } from \"fs\"\nimport { resolve } from \"path\"\nimport prompts from \"prompts\"\nimport { applyConfigMutation, setAtPath, getAtPath, unsetAtPath } from \"@/daemon/config-mutator\"\nimport { expandEnvVars } from \"@/daemon/config\"\nimport { parseEnglishToCron, slugifyScheduleId } from \"@/utils/nl-cron\"\n\n// --- agentx schedule — natural-language cron layer ---\n//\n// Writes the same `crons.<id>` shape the low-level `agentx cron` command\n// manages, but takes English phrases and a --do prompt instead of raw cron\n// syntax. Both verbs coexist; `cron` is the escape hatch.\n\ntype OnErrorValue = \"log\" | \"notify\" | \"disable\"\n\nfunction loadRawConfig(configPath?: string): any {\n const p = configPath || resolve(process.cwd(), \"agentx.json\")\n if (!existsSync(p)) {\n console.log(chalk.red(` No config at ${p}. Run: agentx init`))\n process.exit(1)\n }\n return JSON.parse(readFileSync(p, \"utf-8\"))\n}\n\nfunction parseOnError(flag: string | undefined): OnErrorValue[] {\n if (!flag) return [\"log\"]\n return flag\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter((s): s is OnErrorValue => s === \"log\" || s === \"notify\" || s === \"disable\")\n}\n\nasync function resolveNotifyTarget(\n flag: string | undefined,\n cfg: any,\n): Promise<{ channel: string; chatId: string; accountId?: string } | undefined> {\n if (!flag) return undefined\n if (flag === \"me\") {\n const dest = cfg?.notifications?.destination\n if (dest?.channel && dest?.chatId) {\n return { channel: dest.channel, chatId: dest.chatId, accountId: dest.accountId }\n }\n console.log(chalk.yellow(\" --notify me: no notifications.destination set yet.\"))\n const { channel, chatId, accountId } = await prompts([\n { type: \"text\", name: \"channel\", message: \"Destination channel (telegram/whatsapp):\" },\n { type: \"text\", name: \"chatId\", message: \"Destination chatId:\" },\n { type: \"text\", name: \"accountId\", message: \"Account id (optional):\" },\n ])\n if (!channel || !chatId) return undefined\n return { channel, chatId, accountId: accountId || undefined }\n }\n // shorthand channel:chatId[:account]\n const parts = flag.split(\":\")\n if (parts.length >= 2) {\n return { channel: parts[0], chatId: parts[1], accountId: parts[2] }\n }\n console.log(chalk.red(` Unrecognized --notify value: ${flag} (use \"me\" or \"channel:chatId[:account]\")`))\n return undefined\n}\n\nexport const schedule = new Command()\n .name(\"schedule\")\n .description(\"schedule agents with natural-language cron: \\\"every morning at 9\\\" --agent devops --do \\\"Post standup\\\"\")\n\n// ── agentx schedule \"every morning at 9\" --agent X --do \"...\" [--notify me] ──\nschedule\n .argument(\"[when]\", 'natural-language schedule, e.g. \"every morning at 9\"')\n .option(\"--agent <id>\", \"agent to run\")\n .option(\"--do <prompt>\", \"prompt to run at each tick (required unless --id exists)\")\n .option(\"--id <name>\", \"explicit cron id (default: auto-slug of <when>-<agent>)\")\n .option(\"--notify <target>\", '\"me\" (use notifications.destination) or \"channel:chatId[:accountId]\"')\n .option(\"--on-error <modes>\", 'comma list of \"log|notify|disable\" (default: log; notify implies \"notify\")')\n .option(\"--timezone <tz>\", \"IANA timezone (default: Africa/Tunis)\", \"Africa/Tunis\")\n .option(\"--timeout <seconds>\", \"max run time\", \"600\")\n .option(\"--model <model>\", \"override model\")\n .option(\"--disabled\", \"create but leave disabled\")\n .option(\"--dry-run\", \"print what would be written without writing\")\n .action(async (when: string | undefined, opts) => {\n if (!when) {\n schedule.help()\n return\n }\n if (!opts.agent) {\n console.log(chalk.red(' --agent is required. Try: agentx schedule \"every morning at 9\" --agent devops --do \"...\"'))\n process.exit(1)\n }\n if (!opts.do && !opts.id) {\n console.log(chalk.red(' --do \"<prompt>\" is required'))\n process.exit(1)\n }\n\n const parsed = parseEnglishToCron(when)\n if (!parsed) {\n console.log(chalk.red(` Couldn't parse: \"${when}\"`))\n console.log(chalk.dim(` Try: \"every morning at 9\", \"weekdays at 6pm\", \"every 15 minutes\",`))\n console.log(chalk.dim(` \"every monday at 10am\", \"1st of every month at noon\",`))\n console.log(chalk.dim(` \"daily at 9:30am\", \"every hour\", \"hourly\"`))\n process.exit(1)\n }\n\n const cfg = loadRawConfig(opts.config)\n const expanded = expandEnvVars(cfg)\n\n // Validate agent exists\n if (!cfg.agents?.[opts.agent]) {\n console.log(chalk.red(` Agent \"${opts.agent}\" not found in agentx.json`))\n console.log(chalk.dim(` Available: ${Object.keys(cfg.agents || {}).join(\", \") || \"(none)\"}`))\n process.exit(1)\n }\n\n const onErrorModes = parseOnError(opts.onError)\n const notify = await resolveNotifyTarget(opts.notify, expanded)\n // If --notify is set and user didn't explicitly ask for \"notify\" in onError, add it.\n if (notify && !onErrorModes.includes(\"notify\")) onErrorModes.push(\"notify\")\n\n const id: string = opts.id || slugifyScheduleId(parsed.matched, opts.agent)\n\n const job: any = {\n enabled: !opts.disabled,\n schedule: parsed.cron,\n timezone: opts.timezone,\n agent: opts.agent,\n prompt: opts.do,\n timeout: parseInt(opts.timeout, 10),\n onError: onErrorModes,\n }\n if (opts.model) job.model = opts.model\n if (notify) job.notify = notify\n\n const result = await applyConfigMutation(\n (c) => setAtPath(c, `crons.${id}`, job),\n { configPath: opts.config, dryRun: !!opts.dryRun },\n )\n\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n\n const verb = opts.dryRun ? \"would add\" : \"Added\"\n console.log(chalk.green(` ✓ ${verb} cron ${chalk.cyan(id)}`))\n console.log(chalk.dim(` Schedule: ${parsed.cron} (${parsed.human}, ${opts.timezone})`))\n console.log(chalk.dim(` Agent: ${opts.agent}`))\n if (notify) console.log(chalk.dim(` Notify: ${notify.channel} ${notify.chatId}`))\n if (onErrorModes.length) console.log(chalk.dim(` On error: ${onErrorModes.join(\", \")}`))\n if (!opts.dryRun && result.reloaded) console.log(chalk.dim(\" Daemon hot-reloaded.\"))\n })\n\n// ── agentx schedule list ──\nschedule\n .command(\"list\")\n .alias(\"ls\")\n .description(\"list all scheduled jobs with human-readable descriptions\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .action(async (opts) => {\n const cfg = loadRawConfig(opts.config)\n const crons = cfg.crons || {}\n const entries = Object.entries(crons)\n if (!entries.length) {\n console.log(chalk.dim(\" No scheduled jobs\"))\n return\n }\n console.log()\n for (const [id, def] of entries as any) {\n const tag = def.enabled ? chalk.green(\"●\") : chalk.dim(\"○\")\n let human = def.schedule\n try {\n const cronstrue = (await import(\"cronstrue\")).default\n human = cronstrue.toString(def.schedule, { use24HourTimeFormat: false })\n } catch { /* keep raw */ }\n console.log(` ${tag} ${chalk.cyan(id.padEnd(32))} ${chalk.dim(def.schedule.padEnd(14))} ${chalk.dim(\"→\")} ${def.agent}`)\n console.log(chalk.dim(` ${human} (${def.timezone || \"UTC\"})`))\n if (def.notify) {\n console.log(chalk.dim(` notify: ${def.notify.channel} ${def.notify.chatId}`))\n }\n }\n console.log()\n })\n\n// ── agentx schedule on/off <id> ──\nfor (const [verb, enabled] of [[\"on\", true], [\"off\", false]] as const) {\n schedule\n .command(`${verb} <id>`)\n .description(`${enabled ? \"enable\" : \"disable\"} a scheduled job`)\n .action(async (id: string) => {\n const result = await applyConfigMutation((cfg) => {\n if (!getAtPath(cfg, `crons.${id}`)) {\n throw new Error(`cron \"${id}\" not found`)\n }\n setAtPath(cfg, `crons.${id}.enabled`, enabled)\n })\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n console.log(chalk.green(` ✓ ${id} ${enabled ? \"enabled\" : \"disabled\"}`))\n if (result.reloaded) console.log(chalk.dim(\" Daemon hot-reloaded.\"))\n })\n}\n\n// ── agentx schedule remove <id> ──\nschedule\n .command(\"remove <id>\")\n .alias(\"rm\")\n .description(\"remove a scheduled job\")\n .action(async (id: string) => {\n const result = await applyConfigMutation((cfg) => {\n if (!getAtPath(cfg, `crons.${id}`)) {\n throw new Error(`cron \"${id}\" not found`)\n }\n unsetAtPath(cfg, `crons.${id}`)\n })\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n console.log(chalk.green(` ✓ ${id} removed`))\n if (result.reloaded) console.log(chalk.dim(\" Daemon hot-reloaded.\"))\n })\n\n// ── agentx schedule parse \"<english>\" — preview a parse without writing ──\nschedule\n .command(\"parse <when...>\")\n .description(\"preview a natural-language parse without writing anything\")\n .action((words: string[]) => {\n const when = words.join(\" \")\n const r = parseEnglishToCron(when)\n if (!r) {\n console.log(chalk.red(` ✗ could not parse: \"${when}\"`))\n process.exit(1)\n }\n console.log(chalk.green(` \"${when}\"`))\n console.log(chalk.dim(` → ${r.cron}`))\n console.log(chalk.dim(` → ${r.human}`))\n })\n","import cronstrue from \"cronstrue\"\n\n// --- Natural-language → cron ---\n//\n// Hand-coded pattern matcher for the dozen English phrasings people actually\n// type. Covers every morning/evening, weekdays/weekends, every N minutes,\n// every Monday, daily at X, first of every month, etc.\n//\n// Returns `null` for anything unrecognized rather than guessing — the caller\n// should surface the error to the user with a list of supported phrasings.\n\nexport interface NlCronResult {\n /** Standard 5-field cron expression. */\n cron: string\n /** Human-readable rendering from cronstrue. */\n human: string\n /** The bit of input that matched (useful for error messages + id generation). */\n matched: string\n}\n\ninterface Time { h: number; m: number }\n\nconst DAY_OF_WEEK: Record<string, number> = {\n sun: 0, sunday: 0,\n mon: 1, monday: 1,\n tue: 2, tuesday: 2, tues: 2,\n wed: 3, wednesday: 3,\n thu: 4, thursday: 4, thurs: 4,\n fri: 5, friday: 5,\n sat: 6, saturday: 6,\n}\n\nconst DEFAULT_TIMES: Record<string, Time> = {\n morning: { h: 9, m: 0 },\n afternoon: { h: 14, m: 0 },\n evening: { h: 18, m: 0 },\n night: { h: 22, m: 0 },\n noon: { h: 12, m: 0 },\n midnight: { h: 0, m: 0 },\n}\n\nfunction humanize(cron: string): string {\n try {\n return cronstrue.toString(cron, { use24HourTimeFormat: false })\n } catch {\n return cron\n }\n}\n\n/**\n * Pull out the first \"at HH(:MM)?(am|pm)?\" clause. Also accepts bare\n * \"noon\" / \"midnight\". Returns null if nothing time-like is present.\n */\nfunction extractTime(text: string): Time | null {\n // \"at noon\" / \"at midnight\" / standalone \"noon\" / \"midnight\"\n if (/\\b(noon|midday)\\b/.test(text)) return DEFAULT_TIMES.noon\n if (/\\bmidnight\\b/.test(text)) return DEFAULT_TIMES.midnight\n\n // \"at 9\" / \"at 9am\" / \"at 9:30am\" / \"at 14:30\" / \"by 9am\"\n const m = text.match(/\\b(?:at|by|@)\\s*(\\d{1,2})(?::(\\d{2}))?\\s*(am|pm)?\\b/)\n if (m) {\n let h = parseInt(m[1], 10)\n const min = m[2] ? parseInt(m[2], 10) : 0\n const ampm = m[3]\n if (ampm === \"pm\" && h < 12) h += 12\n if (ampm === \"am\" && h === 12) h = 0\n if (h > 23 || min > 59) return null\n return { h, m: min }\n }\n\n return null\n}\n\n/**\n * Main entry. Returns `null` if we don't recognize the phrasing.\n */\nexport function parseEnglishToCron(raw: string): NlCronResult | null {\n const text = raw.trim().toLowerCase()\n if (!text) return null\n\n // ── every N minutes / every minute ─────────────────────────────────\n let m: RegExpMatchArray | null\n if ((m = text.match(/\\bevery\\s+(\\d+)\\s*(minutes|mins|m)\\b/))) {\n const n = parseInt(m[1], 10)\n if (n < 1 || n > 59) return null\n return { cron: `*/${n} * * * *`, human: humanize(`*/${n} * * * *`), matched: m[0] }\n }\n if (/\\bevery\\s+minute\\b/.test(text)) {\n return { cron: `* * * * *`, human: humanize(`* * * * *`), matched: \"every minute\" }\n }\n\n // ── every hour / hourly / every N hours ────────────────────────────\n if ((m = text.match(/\\bevery\\s+(\\d+)\\s*(hours|hrs|h)\\b/))) {\n const n = parseInt(m[1], 10)\n if (n < 1 || n > 23) return null\n return { cron: `0 */${n} * * *`, human: humanize(`0 */${n} * * *`), matched: m[0] }\n }\n if (/\\b(every hour|hourly)\\b/.test(text)) {\n return { cron: `0 * * * *`, human: humanize(`0 * * * *`), matched: \"every hour\" }\n }\n\n const time = extractTime(text)\n\n // ── keyword-default times (every morning/evening/…) ────────────────\n let dayKeywordTime: Time | null = null\n for (const [kw, t] of Object.entries(DEFAULT_TIMES)) {\n if (kw === \"noon\" || kw === \"midnight\") continue\n if (new RegExp(`\\\\b(every\\\\s+)?${kw}s?\\\\b`).test(text)) {\n dayKeywordTime = t\n break\n }\n }\n const resolvedTime = time || dayKeywordTime\n // If we have no time at all, we can't build a cron for most patterns.\n\n // ── first / nth day of every month ─────────────────────────────────\n const domMatch = text.match(/\\b(first|1st|2nd|3rd|last|(\\d+)(?:st|nd|rd|th)?)\\s+(day\\s+)?of\\s+(every|each|the)\\s+month\\b/)\n if (domMatch) {\n const tok = domMatch[1]\n let dom = 1\n if (tok === \"last\") return null // cron doesn't cleanly support L; punt\n else if (/^\\d+(st|nd|rd|th)?$/.test(tok)) dom = parseInt(tok, 10)\n else if (tok === \"first\" || tok === \"1st\") dom = 1\n else if (tok === \"2nd\") dom = 2\n else if (tok === \"3rd\") dom = 3\n if (dom < 1 || dom > 31) return null\n const t = resolvedTime || { h: 9, m: 0 }\n const cron = `${t.m} ${t.h} ${dom} * *`\n return { cron, human: humanize(cron), matched: domMatch[0] }\n }\n\n // ── named days of the week (mon, tue…) ─────────────────────────────\n // \"every monday at 9\" / \"on mondays\" / \"every monday and friday at 10\"\n //\n // We require a structural anchor (\"every\"/\"on\"/\"each\") before the first day\n // to avoid false positives like \"sun aligns with mars\".\n const dayTokens: number[] = []\n const dayWordsAlt = Object.keys(DAY_OF_WEEK).join(\"|\")\n const anchorRe = new RegExp(`\\\\b(?:every|on|each|by)\\\\s+((?:${dayWordsAlt})s?(?:\\\\s*(?:,|and|&)\\\\s*(?:${dayWordsAlt})s?)*)\\\\b`)\n const anchor = text.match(anchorRe)\n if (anchor) {\n const list = anchor[1]\n for (const w of Object.keys(DAY_OF_WEEK)) {\n if (new RegExp(`\\\\b${w}s?\\\\b`).test(list)) {\n const n = DAY_OF_WEEK[w]\n if (!dayTokens.includes(n)) dayTokens.push(n)\n }\n }\n }\n if (dayTokens.length) {\n const t = resolvedTime || { h: 9, m: 0 }\n dayTokens.sort((a, b) => a - b)\n const dow = dayTokens.join(\",\")\n const cron = `${t.m} ${t.h} * * ${dow}`\n return { cron, human: humanize(cron), matched: `on ${dow}` }\n }\n\n // ── weekdays / weekends ────────────────────────────────────────────\n if (/\\b(weekday|workday|business day)s?\\b/.test(text)) {\n const t = resolvedTime || { h: 9, m: 0 }\n const cron = `${t.m} ${t.h} * * 1-5`\n return { cron, human: humanize(cron), matched: \"weekdays\" }\n }\n if (/\\bweekends?\\b/.test(text)) {\n const t = resolvedTime || { h: 9, m: 0 }\n const cron = `${t.m} ${t.h} * * 0,6`\n return { cron, human: humanize(cron), matched: \"weekends\" }\n }\n\n // ── daily / every day ──────────────────────────────────────────────\n if (/\\b(every day|daily|each day)\\b/.test(text) || dayKeywordTime) {\n const t = resolvedTime || { h: 9, m: 0 }\n const cron = `${t.m} ${t.h} * * *`\n return { cron, human: humanize(cron), matched: dayKeywordTime ? (Object.entries(DEFAULT_TIMES).find(([, v]) => v === dayKeywordTime)?.[0] || \"daily\") : \"daily\" }\n }\n\n // ── bare \"at 9am\" → assume daily ───────────────────────────────────\n if (time) {\n const cron = `${time.m} ${time.h} * * *`\n return { cron, human: humanize(cron), matched: `at ${time.h}:${String(time.m).padStart(2, \"0\")}` }\n }\n\n return null\n}\n\n/** Build a stable slug for cron id from the matched phrase + agent. */\nexport function slugifyScheduleId(phrase: string, agent: string): string {\n const slug = phrase\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 40)\n return `${slug || \"job\"}-${agent}`\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { connectTelegram } from \"@/connect/telegram\"\nimport { connectWhatsApp } from \"@/connect/whatsapp\"\nimport { invite as meshInvite, join as meshJoin } from \"@/connect/mesh\"\n\n// --- agentx connect <channel> ---\n//\n// Unified browser-cooperating pairing flow. Replaces manual \"paste token\n// into .env, edit agentx.json, restart daemon\" onboarding.\n//\n// Only offer channels backed by a live adapter.\n\nexport const connect = new Command()\n .name(\"connect\")\n .description(\"connect a channel or mesh peer — no manual file editing required\")\n\nconnect\n .command(\"telegram\")\n .description(\"pair a Telegram bot — persists token in .env, binds to an agent, auto-detects default chat\")\n .option(\"--agent <id>\", \"agent to bind the bot to (skips the prompt)\")\n .option(\"--account <name>\", \"account label in channels.telegram.accounts (defaults to agent id)\")\n .option(\"--skip-chat-capture\", \"don't listen for the first message after pairing\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .action(async (opts) => {\n await connectTelegram({\n agent: opts.agent,\n account: opts.account,\n configPath: opts.config,\n skipChatCapture: !!opts.skipChatCapture,\n })\n })\n\nconnect\n .command(\"whatsapp\")\n .description(\"pair WhatsApp via QR (prints in terminal), then writes channels.whatsapp config\")\n .option(\"--agent <id>\", \"default agent for inbound messages\")\n .option(\"--session-dir <path>\", \"session directory (default: .agentx/whatsapp-sessions)\")\n .option(\"--skip-pair\", \"skip QR pairing (use when session already exists)\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .action(async (opts) => {\n await connectWhatsApp({\n agent: opts.agent,\n sessionDir: opts.sessionDir,\n skipPair: !!opts.skipPair,\n configPath: opts.config,\n })\n })\n\nconst mesh = connect\n .command(\"mesh\")\n .description(\"mesh invite + join — replaces manual MESH_TOKEN copy-paste\")\n\nmesh\n .command(\"invite\")\n .description(\"emit a single-use join link for another AgentX node\")\n .option(\"--url <url>\", \"this node's URL as peers should reach it (Tailscale IP etc.)\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .action(async (opts) => {\n await meshInvite({ url: opts.url, configPath: opts.config })\n })\n\nmesh\n .command(\"join <link>\")\n .description(\"accept an invite link from another AgentX node\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .action(async (link: string, opts) => {\n await meshJoin(link, { configPath: opts.config })\n })\n\n// Default help: when the user types `agentx connect` with no subcommand, nudge.\nconnect.action(() => {\n console.log()\n console.log(chalk.bold(\" agentx connect — which channel?\"))\n console.log()\n console.log(` ${chalk.cyan(\"agentx connect telegram\")} — pair a Telegram bot`)\n console.log(` ${chalk.cyan(\"agentx connect whatsapp\")} — pair WhatsApp via QR`)\n console.log(` ${chalk.cyan(\"agentx connect mesh invite\")} — emit a mesh join link for another node`)\n console.log(` ${chalk.cyan(\"agentx connect mesh join <link>\")} — accept a mesh invite`)\n console.log()\n console.log(chalk.dim(\" GitLab connect is the next slice.\"))\n console.log()\n})\n","import chalk from \"chalk\"\nimport prompts from \"prompts\"\nimport { applyConfigMutation, setAtPath, getAtPath } from \"@/daemon/config-mutator\"\nimport { setDotEnv } from \"@/utils/dotenv-mutator\"\n\n// --- agentx connect telegram ---\n//\n// Replaces the channel-add path for Telegram. The improvements over the old\n// prompt-for-everything flow:\n// 1. Token is persisted to .env under TG_<ACCOUNT>_BOT_TOKEN, never inline\n// in agentx.json. The config holds only `${TG_<ACCOUNT>_BOT_TOKEN}`.\n// 2. After pairing, the CLI polls getUpdates until the user sends a message\n// from the chat they want to be \"me\". The first inbound message's chatId\n// is captured and written to notifications.destination so `--notify me`\n// just works.\n// 3. A quick getMe verifies the token before anything is written. Invalid\n// tokens never reach the config.\n\nconst BOTFATHER_URL = \"https://t.me/BotFather\"\n\nasync function getMe(token: string): Promise<{ username: string; first_name: string; id: number } | null> {\n try {\n const res = await fetch(`https://api.telegram.org/bot${token}/getMe`, { signal: AbortSignal.timeout(8000) })\n if (!res.ok) return null\n const j: any = await res.json()\n return j?.ok ? j.result : null\n } catch { return null }\n}\n\nasync function pollFirstMessage(token: string, timeoutMs: number): Promise<{ chatId: number; chatTitle?: string; from: string } | null> {\n const deadline = Date.now() + timeoutMs\n let offset = 0\n // Learn the current offset so we only catch fresh messages.\n try {\n const r = await fetch(`https://api.telegram.org/bot${token}/getUpdates?offset=-1&timeout=0`, { signal: AbortSignal.timeout(5000) })\n const j: any = await r.json()\n if (j?.result?.length) offset = j.result[0].update_id + 1\n } catch { /* start from 0 */ }\n\n while (Date.now() < deadline) {\n try {\n const res = await fetch(\n `https://api.telegram.org/bot${token}/getUpdates?offset=${offset}&timeout=10`,\n { signal: AbortSignal.timeout(15000) },\n )\n const j: any = await res.json()\n for (const u of j?.result || []) {\n offset = Math.max(offset, u.update_id + 1)\n const msg = u.message || u.edited_message || u.channel_post\n if (msg?.chat?.id) {\n return {\n chatId: msg.chat.id,\n chatTitle: msg.chat.title || msg.chat.username || msg.chat.first_name,\n from: msg.from?.first_name || msg.from?.username || \"unknown\",\n }\n }\n }\n } catch { /* transient; retry */ }\n }\n return null\n}\n\nexport interface ConnectTelegramOpts {\n agent?: string\n account?: string\n configPath?: string\n skipChatCapture?: boolean\n}\n\nexport async function connectTelegram(opts: ConnectTelegramOpts = {}): Promise<void> {\n console.log()\n console.log(chalk.bold(\" Connect Telegram\"))\n console.log()\n console.log(chalk.dim(` 1. Open ${BOTFATHER_URL}`))\n console.log(chalk.dim(` /newbot (or /mybots → pick existing → API Token)`))\n console.log(chalk.dim(` 2. Copy the HTTP API token — looks like 123456789:ABCdef...`))\n console.log()\n\n const { openBrowser } = await prompts({\n type: \"confirm\",\n name: \"openBrowser\",\n message: \"Open BotFather in your browser?\",\n initial: true,\n })\n if (openBrowser) {\n try {\n const { spawn } = await import(\"child_process\")\n const opener = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\"\n spawn(opener, [BOTFATHER_URL], { stdio: \"ignore\", detached: true }).unref()\n } catch { /* non-fatal */ }\n }\n\n const { token } = await prompts({\n type: \"password\",\n name: \"token\",\n message: \"Paste the bot token from BotFather:\",\n validate: (t: string) => /^\\d+:[A-Za-z0-9_-]{20,}$/.test(t.trim()) || \"That doesn't look like a Telegram token\",\n })\n if (!token) { console.log(chalk.red(\" Aborted\")); process.exit(1) }\n\n // --- Verify token ---\n process.stdout.write(\" Verifying token... \")\n const me = await getMe(token.trim())\n if (!me) {\n console.log(chalk.red(\"✗ invalid or revoked\"))\n process.exit(1)\n }\n console.log(chalk.green(`✓ ${me.first_name} (@${me.username})`))\n\n // --- Existing config ---\n const { readFileSync, existsSync } = await import(\"fs\")\n const { resolve } = await import(\"path\")\n const cfgPath = opts.configPath || resolve(process.cwd(), \"agentx.json\")\n if (!existsSync(cfgPath)) {\n console.log(chalk.red(` No agentx.json at ${cfgPath}. Run: agentx init`))\n process.exit(1)\n }\n const raw = JSON.parse(readFileSync(cfgPath, \"utf-8\"))\n\n const agents = Object.keys(raw.agents || {})\n if (agents.length === 0) {\n console.log(chalk.red(` No agents configured. Run: agentx agent add`))\n process.exit(1)\n }\n\n let agent = opts.agent\n if (!agent) {\n const r = await prompts({\n type: \"select\",\n name: \"agent\",\n message: \"Bind this bot to which agent?\",\n choices: agents.map((id) => ({ title: id, value: id })),\n initial: 0,\n })\n agent = r.agent\n }\n if (!agent) { console.log(chalk.red(\" Aborted\")); process.exit(1) }\n\n // Account name — default to the agent id (one bot per agent is the common case).\n // If that collides with an existing account, prompt.\n const accounts = raw.channels?.telegram?.accounts || {}\n let account = opts.account || agent\n if (accounts[account] && accounts[account].agentBinding !== agent) {\n const r = await prompts({\n type: \"text\",\n name: \"account\",\n message: `Account \"${account}\" is already in use. Pick a different label:`,\n initial: `${agent}-2`,\n validate: (s: string) => /^[a-z0-9-]+$/i.test(s) || \"lowercase letters, digits, hyphens only\",\n })\n account = r.account\n }\n if (!account) { console.log(chalk.red(\" Aborted\")); process.exit(1) }\n\n // --- Persist token to .env, reference it from config ---\n const envVar = `TG_${account.toUpperCase().replace(/-/g, \"_\")}_BOT_TOKEN`\n setDotEnv(envVar, token.trim())\n process.env[envVar] = token.trim() // so validation downstream sees it\n\n const result = await applyConfigMutation((cfg) => {\n setAtPath(cfg, \"channels.telegram.enabled\", true)\n setAtPath(cfg, `channels.telegram.accounts.${account}`, {\n token: `\\${${envVar}}`,\n agentBinding: agent,\n })\n // Nudge agent.mentions to include the bot handle, if not already there.\n const mentions: string[] = getAtPath(cfg, `agents.${agent}.mentions`) as any || []\n const handle = `@${me.username}`\n if (!mentions.includes(handle)) {\n mentions.push(handle)\n setAtPath(cfg, `agents.${agent}.mentions`, mentions)\n }\n }, { configPath: opts.configPath })\n\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n\n console.log()\n console.log(chalk.green(` ✓ Bot @${me.username} bound to agent \"${agent}\"`))\n console.log(chalk.dim(` Token stored in .env as ${envVar}`))\n console.log(chalk.dim(` Mentions updated to include @${me.username}`))\n if (result.reloaded) console.log(chalk.dim(\" Daemon hot-reloaded.\"))\n else console.log(chalk.dim(\" Start the daemon to begin polling (agentx daemon start)\"))\n\n // --- Auto-detect chatId for notifications.destination ---\n if (opts.skipChatCapture) return\n\n console.log()\n const { capture } = await prompts({\n type: \"confirm\",\n name: \"capture\",\n message: `Listen for a message so we can set this as your default --notify target?`,\n initial: true,\n })\n if (!capture) return\n\n console.log()\n console.log(chalk.dim(` Send any message to @${me.username} from the chat you want to use.`))\n console.log(chalk.dim(` Waiting up to 90s...`))\n const first = await pollFirstMessage(token.trim(), 90_000)\n if (!first) {\n console.log(chalk.yellow(` No message received — skipping. You can set it later with:`))\n console.log(chalk.dim(` agentx config set notifications.destination.channel telegram`))\n console.log(chalk.dim(` agentx config set notifications.destination.chatId <chatId>`))\n console.log(chalk.dim(` agentx config set notifications.destination.accountId ${account}`))\n return\n }\n\n const destResult = await applyConfigMutation((cfg) => {\n setAtPath(cfg, \"notifications.destination\", {\n channel: \"telegram\",\n chatId: String(first.chatId),\n accountId: account,\n })\n }, { configPath: opts.configPath })\n\n if (!destResult.success) {\n console.log(chalk.red(` ✗ failed to save destination: ${destResult.error}`))\n return\n }\n\n console.log(chalk.green(` ✓ Default --notify target set`))\n console.log(chalk.dim(` Chat: ${first.chatTitle || first.chatId} (from ${first.from})`))\n console.log(chalk.dim(` From now on, --notify me resolves to this chat.`))\n if (destResult.reloaded) console.log(chalk.dim(\" Daemon hot-reloaded.\"))\n}\n","import { readFileSync, writeFileSync, existsSync } from \"fs\"\nimport { resolve } from \"path\"\n\n// --- .env mutator ---\n//\n// Line-preserving read/write for .env files. Comments, blank lines, and\n// original key order are kept intact. Used by `agentx connect <channel>`\n// (and anything else that needs to persist secrets) so we never hand the\n// user a file-editor instruction.\n\nexport type DotEnvLine =\n | { kind: \"kv\"; key: string; value: string; raw: string }\n | { kind: \"comment\"; raw: string }\n | { kind: \"blank\"; raw: string }\n\nconst KV_RE = /^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*(.*)$/\n\nfunction parseValue(raw: string): string {\n // Strip matching surrounding quotes — write path re-adds them as needed.\n const s = raw.trim()\n if ((s.startsWith('\"') && s.endsWith('\"')) || (s.startsWith(\"'\") && s.endsWith(\"'\"))) {\n return s.slice(1, -1)\n }\n return s\n}\n\nfunction quoteIfNeeded(value: string): string {\n if (/[\\s#\"'\\\\]/.test(value) || value === \"\") return JSON.stringify(value)\n return value\n}\n\nexport function readDotEnv(path: string = \".env\"): DotEnvLine[] {\n const abs = resolve(path)\n if (!existsSync(abs)) return []\n const content = readFileSync(abs, \"utf-8\")\n const lines: DotEnvLine[] = []\n for (const raw of content.split(/\\r?\\n/)) {\n if (raw.trim() === \"\") {\n lines.push({ kind: \"blank\", raw })\n continue\n }\n if (raw.trim().startsWith(\"#\")) {\n lines.push({ kind: \"comment\", raw })\n continue\n }\n const m = raw.match(KV_RE)\n if (m) {\n lines.push({ kind: \"kv\", key: m[1], value: parseValue(m[2]), raw })\n } else {\n // Unparseable line — preserve verbatim as \"comment\" so we don't trample it\n lines.push({ kind: \"comment\", raw })\n }\n }\n // Strip a single trailing blank line (every file ends with \\n → one empty split)\n if (lines.length && lines[lines.length - 1].kind === \"blank\") lines.pop()\n return lines\n}\n\nexport function serializeDotEnv(lines: DotEnvLine[]): string {\n return lines.map((l) => {\n if (l.kind === \"kv\") return `${l.key}=${quoteIfNeeded(l.value)}`\n return l.raw\n }).join(\"\\n\") + \"\\n\"\n}\n\n/**\n * Set a key to a value, preserving ordering & comments.\n * - If the key exists, the line is rewritten in place.\n * - If it doesn't, the key is appended (with a blank separator if the file\n * doesn't already end in one).\n */\nexport function setDotEnv(key: string, value: string, path: string = \".env\"): void {\n const abs = resolve(path)\n const lines = readDotEnv(abs)\n\n const idx = lines.findIndex((l) => l.kind === \"kv\" && l.key === key)\n if (idx >= 0) {\n lines[idx] = { kind: \"kv\", key, value, raw: `${key}=${quoteIfNeeded(value)}` }\n } else {\n if (lines.length && lines[lines.length - 1].kind !== \"blank\") {\n lines.push({ kind: \"blank\", raw: \"\" })\n }\n lines.push({ kind: \"kv\", key, value, raw: `${key}=${quoteIfNeeded(value)}` })\n }\n\n writeFileSync(abs, serializeDotEnv(lines))\n}\n\n/**\n * Append a key only if it isn't already present. Use this when you don't want\n * to clobber an existing value (e.g. a MESH_TOKEN the user already rotated).\n */\nexport function appendDotEnv(key: string, value: string, path: string = \".env\"): boolean {\n const lines = readDotEnv(path)\n if (lines.some((l) => l.kind === \"kv\" && l.key === key)) return false\n setDotEnv(key, value, path)\n return true\n}\n\nexport function getDotEnv(key: string, path: string = \".env\"): string | undefined {\n const lines = readDotEnv(path)\n const hit = lines.find((l): l is Extract<DotEnvLine, { kind: \"kv\" }> => l.kind === \"kv\" && l.key === key)\n return hit?.value\n}\n\nexport function unsetDotEnv(key: string, path: string = \".env\"): boolean {\n const abs = resolve(path)\n const lines = readDotEnv(abs)\n const idx = lines.findIndex((l) => l.kind === \"kv\" && l.key === key)\n if (idx < 0) return false\n lines.splice(idx, 1)\n // Collapse double-blank that may result\n if (idx > 0 && idx < lines.length && lines[idx - 1].kind === \"blank\" && lines[idx].kind === \"blank\") {\n lines.splice(idx, 1)\n }\n writeFileSync(abs, serializeDotEnv(lines))\n return true\n}\n","import chalk from \"chalk\"\nimport prompts from \"prompts\"\nimport { existsSync, mkdirSync, readdirSync, readFileSync } from \"fs\"\nimport { resolve } from \"path\"\nimport { applyConfigMutation, setAtPath } from \"@/daemon/config-mutator\"\n\n// --- agentx connect whatsapp ---\n//\n// Runs a pairing-only Baileys session inside the CLI, prints the QR, waits\n// for the scan, and persists the session files. After that the daemon picks\n// the session up automatically on start. This removes the \"run daemon, find\n// the QR in logs, scan\" two-step from the legacy channel add flow.\n\nconst DEFAULT_SESSION_DIR = \".agentx/whatsapp-sessions\"\n\nfunction daemonRunning(): boolean {\n const pidFile = resolve(process.cwd(), \".agentx/daemon.pid\")\n if (!existsSync(pidFile)) return false\n try {\n const pid = parseInt(readFileSync(pidFile, \"utf-8\").trim(), 10)\n if (!pid) return false\n // process.kill with signal 0 only probes existence, doesn't actually signal.\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n\nfunction sessionExists(dir: string): boolean {\n if (!existsSync(dir)) return false\n try { return readdirSync(dir).some((f) => f.includes(\"creds\") || f.endsWith(\".json\")) } catch { return false }\n}\n\nexport interface ConnectWhatsAppOpts {\n agent?: string\n sessionDir?: string\n configPath?: string\n skipPair?: boolean\n}\n\nasync function pairSession(sessionDir: string, log: (s: string) => void): Promise<boolean> {\n let baileys: any\n try {\n // @ts-ignore optional dep\n baileys = await import(\"@whiskeysockets/baileys\")\n } catch {\n log(chalk.red(\" WhatsApp pairing needs @whiskeysockets/baileys.\"))\n log(chalk.red(\" Install with: pnpm add @whiskeysockets/baileys (or npm install)\"))\n return false\n }\n\n const { makeWASocket, useMultiFileAuthState } = baileys.default || baileys\n mkdirSync(sessionDir, { recursive: true })\n const { state, saveCreds } = await useMultiFileAuthState(sessionDir)\n\n let version: [number, number, number] | undefined\n try { version = (await baileys.fetchLatestBaileysVersion()).version } catch { /* fallback */ }\n\n const silentLogger = {\n level: \"silent\",\n trace: () => {}, debug: () => {}, info: () => {},\n warn: () => {}, fatal: () => {}, error: () => {},\n child: () => silentLogger,\n } as any\n\n const sock = makeWASocket({\n auth: {\n creds: state.creds,\n keys: baileys.makeCacheableSignalKeyStore\n ? baileys.makeCacheableSignalKeyStore(state.keys, silentLogger)\n : state.keys,\n },\n ...(version ? { version } : {}),\n logger: silentLogger,\n printQRInTerminal: false,\n browser: [\"agentx-connect\", \"pairing\", \"1.0\"],\n syncFullHistory: false,\n markOnlineOnConnect: false,\n })\n\n sock.ev.on(\"creds.update\", saveCreds)\n\n return await new Promise<boolean>((resolveP) => {\n const timeoutMs = 120_000\n const deadline = setTimeout(() => {\n log(chalk.yellow(\" Timed out waiting for scan (2min).\"))\n try { sock.end(undefined) } catch { /* ignore */ }\n resolveP(false)\n }, timeoutMs)\n\n sock.ev.on(\"connection.update\", async (u: any) => {\n if (u.qr) {\n log(chalk.dim(\" Scan this QR with WhatsApp → Linked devices → Link a device:\"))\n log(\"\")\n try {\n const { default: qrcode } = await import(\"qrcode-terminal\") as any\n qrcode.generate(u.qr, { small: true })\n } catch {\n log(` QR: ${u.qr}`)\n }\n log(\"\")\n }\n if (u.connection === \"open\") {\n clearTimeout(deadline)\n log(chalk.green(\" ✓ Paired\"))\n try { sock.end(undefined) } catch { /* ignore */ }\n resolveP(true)\n }\n if (u.connection === \"close\" && !u.qr) {\n // If we haven't opened yet and close is final, abort.\n const reason = u.lastDisconnect?.error?.output?.statusCode\n // 401 = \"Unauthorized\" / kicked. 515 = reset. Otherwise just let it retry via new QR.\n if (reason === 401) {\n clearTimeout(deadline)\n log(chalk.red(\" ✗ Authorization failed — rescan required\"))\n resolveP(false)\n }\n }\n })\n })\n}\n\nexport async function connectWhatsApp(opts: ConnectWhatsAppOpts = {}): Promise<void> {\n console.log()\n console.log(chalk.bold(\" Connect WhatsApp\"))\n console.log()\n\n if (daemonRunning()) {\n console.log(chalk.yellow(\" ⚠ The daemon is running. Stop it first so pairing can open a fresh Baileys session:\"))\n console.log(chalk.dim(\" agentx daemon stop\"))\n console.log()\n const { cont } = await prompts({ type: \"confirm\", name: \"cont\", message: \"Continue anyway? (expect errors)\", initial: false })\n if (!cont) { console.log(chalk.red(\" Aborted\")); process.exit(1) }\n }\n\n const cfgPath = opts.configPath || resolve(process.cwd(), \"agentx.json\")\n if (!existsSync(cfgPath)) {\n console.log(chalk.red(` No agentx.json at ${cfgPath}. Run: agentx init`))\n process.exit(1)\n }\n const raw = JSON.parse(readFileSync(cfgPath, \"utf-8\"))\n\n const sessionDir = opts.sessionDir || raw.channels?.whatsapp?.sessionDir || DEFAULT_SESSION_DIR\n const absSession = resolve(process.cwd(), sessionDir)\n\n // --- Agent binding ---\n const agents = Object.keys(raw.agents || {})\n if (agents.length === 0) {\n console.log(chalk.red(\" No agents configured. Run: agentx agent add\"))\n process.exit(1)\n }\n\n let agent = opts.agent\n if (!agent) {\n const r = await prompts({\n type: \"select\",\n name: \"agent\",\n message: \"Default agent for incoming messages:\",\n choices: agents.map((id) => ({ title: id, value: id })),\n initial: 0,\n })\n agent = r.agent\n }\n if (!agent) { console.log(chalk.red(\" Aborted\")); process.exit(1) }\n\n // --- Decide whether to re-pair ---\n let shouldPair = !opts.skipPair\n if (sessionExists(absSession) && shouldPair) {\n const { keep } = await prompts({\n type: \"confirm\",\n name: \"keep\",\n message: `An existing session was found at ${sessionDir}. Keep it (recommended), or pair again?`,\n initial: true,\n })\n shouldPair = !keep\n if (keep) console.log(chalk.dim(\" Keeping existing session — skipping QR pair.\"))\n }\n\n // --- Pair ---\n if (shouldPair) {\n const ok = await pairSession(absSession, (s) => console.log(s))\n if (!ok) {\n console.log(chalk.red(\" Pairing failed. You can retry with `agentx connect whatsapp`.\"))\n process.exit(1)\n }\n }\n\n // --- Persist config ---\n const result = await applyConfigMutation((cfg) => {\n setAtPath(cfg, \"channels.whatsapp.enabled\", true)\n setAtPath(cfg, \"channels.whatsapp.sessionDir\", sessionDir)\n setAtPath(cfg, \"channels.whatsapp.defaultAgent\", agent)\n }, { configPath: opts.configPath })\n\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n\n console.log()\n console.log(chalk.green(` ✓ WhatsApp bound to agent \"${agent}\"`))\n console.log(chalk.dim(` Session: ${sessionDir}`))\n console.log(chalk.dim(\" Start the daemon to begin receiving:\"))\n console.log(chalk.dim(\" agentx daemon start\"))\n console.log(chalk.dim(\" Add routes later with:\"))\n console.log(chalk.dim(` agentx config set channels.whatsapp.routes '[{\"contact\":\"+1234567890\",\"agent\":\"${agent}\"}]'`))\n console.log()\n}\n","import { randomBytes } from \"crypto\"\nimport chalk from \"chalk\"\nimport prompts from \"prompts\"\nimport { applyConfigMutation, getAtPath, setAtPath } from \"@/daemon/config-mutator\"\nimport { getDotEnv, setDotEnv } from \"@/utils/dotenv-mutator\"\n\n// --- agentx connect mesh ---\n//\n// One-command mesh pairing for two AgentX nodes on the same private network\n// (Tailscale / WireGuard / VPN). Replaces the manual \"generate a MESH_TOKEN,\n// copy it to both .env files, add peer to each agentx.json\" sequence.\n//\n// Node A: agentx connect mesh invite\n// → prints agentx-mesh://join/<base64({url, token, name})>\n// Node B: agentx connect mesh join <link>\n// → persists the shared token + adds A as a peer\n\nconst PROTOCOL = \"agentx-mesh:\"\nconst PATH_PREFIX = \"//join/\"\n\nexport interface MeshInvitePayload {\n url: string\n token: string\n name: string\n version: 1\n}\n\nfunction b64urlEncode(input: string): string {\n return Buffer.from(input, \"utf-8\").toString(\"base64url\")\n}\n\nfunction b64urlDecode(input: string): string {\n return Buffer.from(input, \"base64url\").toString(\"utf-8\")\n}\n\nexport function encodeInvite(payload: MeshInvitePayload): string {\n return `${PROTOCOL}${PATH_PREFIX}${b64urlEncode(JSON.stringify(payload))}`\n}\n\nexport function decodeInvite(link: string): MeshInvitePayload {\n if (!link.startsWith(`${PROTOCOL}${PATH_PREFIX}`)) {\n throw new Error(`Not a mesh invite link — expected ${PROTOCOL}${PATH_PREFIX}…`)\n }\n const raw = link.slice(PROTOCOL.length + PATH_PREFIX.length)\n const parsed = JSON.parse(b64urlDecode(raw))\n if (parsed.version !== 1) throw new Error(`Unsupported invite version: ${parsed.version}`)\n if (typeof parsed.url !== \"string\" || typeof parsed.token !== \"string\" || typeof parsed.name !== \"string\") {\n throw new Error(\"Invite payload missing required fields (url, token, name)\")\n }\n return parsed\n}\n\nfunction generateToken(): string {\n // 32 bytes → 64-char hex; plenty of entropy and stays readable in a URL.\n return randomBytes(32).toString(\"hex\")\n}\n\nfunction resolveBindUrl(raw: any): string {\n const bind: string = raw?.node?.bind || \"127.0.0.1:18800\"\n const [host, port] = bind.split(\":\")\n // Invites need a routable address, not 0.0.0.0. We don't know the Tailscale IP,\n // so we let the user confirm before sending.\n return `http://${host}:${port}`\n}\n\nfunction nodeName(raw: any): string {\n return raw?.node?.name || raw?.node?.id || \"node\"\n}\n\n/**\n * invite() — produce a join link for the OTHER node to consume.\n * Creates a MESH_TOKEN in .env if one doesn't exist yet.\n */\nexport async function invite(opts: { url?: string; configPath?: string }): Promise<void> {\n // Read the raw config to get node info + existing token ref\n const { readFileSync, existsSync } = await import(\"fs\")\n const { resolve } = await import(\"path\")\n const cfgPath = opts.configPath || resolve(process.cwd(), \"agentx.json\")\n if (!existsSync(cfgPath)) {\n console.log(chalk.red(` No agentx.json at ${cfgPath}. Run: agentx init`))\n process.exit(1)\n }\n const raw = JSON.parse(readFileSync(cfgPath, \"utf-8\"))\n\n // 1. Ensure a token exists\n let token = getDotEnv(\"MESH_TOKEN\")\n if (!token) {\n token = generateToken()\n setDotEnv(\"MESH_TOKEN\", token)\n console.log(chalk.dim(` Generated new MESH_TOKEN (32 bytes) and saved to .env`))\n }\n\n // 2. Resolve the URL — default from node.bind, but confirm because 0.0.0.0 isn't routable.\n let url = opts.url || resolveBindUrl(raw)\n const needsHint = url.includes(\"0.0.0.0\") || url.includes(\"127.0.0.1\") || url.includes(\"localhost\")\n if (needsHint && !opts.url) {\n const { url: entered } = await prompts({\n type: \"text\",\n name: \"url\",\n message: \"This node's URL as peers should reach it (e.g. http://100.x.x.x:18800):\",\n initial: url,\n validate: (v: string) => /^https?:\\/\\//.test(v) || \"must start with http:// or https://\",\n })\n if (!entered) { console.log(chalk.red(\" Aborted\")); process.exit(1) }\n url = entered\n }\n\n // 3. Make sure mesh is enabled\n const result = await applyConfigMutation((cfg) => {\n setAtPath(cfg, \"mesh.enabled\", true)\n }, { configPath: opts.configPath })\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n\n const link = encodeInvite({ url, token, name: nodeName(raw), version: 1 })\n\n console.log()\n console.log(chalk.bold(\" Mesh invite\"))\n console.log()\n console.log(` ${chalk.cyan(link)}`)\n console.log()\n console.log(chalk.dim(` Run on the other node:`))\n console.log(chalk.dim(` agentx connect mesh join \"${link}\"`))\n console.log()\n console.log(chalk.yellow(` Share over a trusted channel only — whoever holds this link can join your mesh.`))\n console.log()\n}\n\n/**\n * join(link) — consume a join link on the OTHER node. Adds the sender as a\n * peer and stores the shared token in .env.\n */\nexport async function join(link: string, opts: { configPath?: string } = {}): Promise<void> {\n let payload: MeshInvitePayload\n try {\n payload = decodeInvite(link)\n } catch (e: any) {\n console.log(chalk.red(` ✗ ${e.message}`))\n process.exit(1)\n }\n\n // Store the shared token (or confirm overwrite if MESH_TOKEN already exists but differs)\n const existing = getDotEnv(\"MESH_TOKEN\")\n if (existing && existing !== payload.token) {\n const { overwrite } = await prompts({\n type: \"confirm\",\n name: \"overwrite\",\n message: \"A different MESH_TOKEN already exists in .env. Overwrite with the invite's token?\",\n initial: false,\n })\n if (!overwrite) { console.log(chalk.red(\" Aborted (keeping existing .env)\")); process.exit(1) }\n }\n setDotEnv(\"MESH_TOKEN\", payload.token)\n\n // Add the peer (idempotent on name)\n const result = await applyConfigMutation((cfg) => {\n setAtPath(cfg, \"mesh.enabled\", true)\n const peers: any[] = getAtPath(cfg, \"mesh.peers\") as any || []\n const idx = peers.findIndex((p) => p.name === payload.name)\n const peer = { name: payload.name, url: payload.url, token: \"${MESH_TOKEN}\" }\n if (idx >= 0) peers[idx] = peer\n else peers.push(peer)\n setAtPath(cfg, \"mesh.peers\", peers)\n }, { configPath: opts.configPath })\n\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n\n console.log(chalk.green(` ✓ Joined mesh`))\n console.log(chalk.dim(` Peer: ${payload.name} @ ${payload.url}`))\n console.log(chalk.dim(` Shared token stored in .env as MESH_TOKEN`))\n if (result.reloaded) console.log(chalk.dim(\" Daemon hot-reloaded.\"))\n else console.log(chalk.dim(\" Restart the daemon to start the mesh (agentx daemon start).\"))\n console.log()\n\n // Health check against the peer — advisory only\n try {\n const res = await fetch(`${payload.url.replace(/\\/$/, \"\")}/.well-known/agent-card.json`, {\n signal: AbortSignal.timeout(5000),\n })\n if (res.ok) {\n const card: any = await res.json()\n const agents = Array.isArray(card.agents) ? card.agents.length : \"?\"\n console.log(chalk.dim(` Reachable — ${payload.name} exposes ${agents} agents`))\n } else {\n console.log(chalk.yellow(` Peer returned HTTP ${res.status} — double-check the URL`))\n }\n } catch (e: any) {\n console.log(chalk.yellow(` Could not reach ${payload.url} right now (${e?.cause?.code || e.message}) — verify VPN / Tailscale when the peer daemon is up`))\n }\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\nexport const usage = new Command()\n .name(\"usage\")\n .description(\"token usage analysis and reporting\")\n\n// agentx usage — quick today summary\nusage\n .command(\"today\", { isDefault: true })\n .description(\"show today's token usage\")\n .action(async () => {\n try {\n const config = loadDaemonConfig()\n const [host, port] = config.node.bind.split(\":\")\n const res = await fetch(`http://${host || \"127.0.0.1\"}:${port}/usage`, { signal: AbortSignal.timeout(3000) })\n const data = await res.json() as any\n\n console.log()\n console.log(chalk.bold(` Token Usage (last 7 days)`))\n console.log()\n\n if (data.totalTasks === 0) {\n console.log(chalk.dim(\" No tasks recorded yet\"))\n console.log()\n return\n }\n\n const fmt = (n: number) => n.toLocaleString()\n\n console.log(` Total: ${chalk.bold(fmt(data.totalTokens))} tokens across ${data.totalTasks} tasks`)\n console.log(` Input: ${fmt(data.totalInput)}`)\n console.log(` Output: ${fmt(data.totalOutput)}`)\n console.log(` Cache read: ${fmt(data.totalCacheRead)}`)\n console.log(` Cache create: ${fmt(data.totalCacheCreate)}`)\n if (data.cacheHitRatio > 0) {\n console.log(` Cache hit: ${(data.cacheHitRatio * 100).toFixed(1)}%`)\n }\n if (data.totalErrors > 0) {\n console.log(` Errors: ${chalk.red(String(data.totalErrors))}`)\n }\n\n console.log()\n console.log(chalk.bold(\" By Agent:\"))\n const agents = Object.entries(data.byAgent || {}) as Array<[string, any]>\n agents.sort((a, b) => b[1].total - a[1].total)\n\n for (const [id, ag] of agents) {\n const total = fmt(ag.total || (ag.input + ag.output + ag.cacheRead + ag.cacheCreate))\n const avgMs = ag.avgDuration ? `${(ag.avgDuration / 1000).toFixed(1)}s avg` : \"\"\n console.log(` ${chalk.cyan(id)}: ${total} tokens (${ag.tasks} tasks) ${chalk.dim(avgMs)}`)\n }\n console.log()\n } catch (e: any) {\n if (e.cause?.code === \"ECONNREFUSED\") {\n console.log(chalk.red(\" Daemon not running. Start with: agentx daemon start\"))\n } else {\n console.log(chalk.red(` ${e.message}`))\n }\n }\n })\n\n// `agentx usage serve` was removed — the same data now lives at\n// /admin/cost on the dashboard, so there's no second port to keep\n// running. Anyone with a stale `usage serve` bookmark gets a redirect\n// from the dashboard root pointing to /admin/cost.\n\n// agentx usage report — run Python analyzer\nusage\n .command(\"report\")\n .description(\"run full session analysis (parses Claude Code JSONL files)\")\n .option(\"--days <n>\", \"analyze last N days\", \"7\")\n .action(async (opts) => {\n const { execSync } = await import(\"child_process\")\n const { existsSync } = await import(\"fs\")\n const { resolve } = await import(\"path\")\n\n const scriptPath = resolve(process.cwd(), \"scripts/token-report.py\")\n if (!existsSync(scriptPath)) {\n console.log(chalk.red(` Script not found: ${scriptPath}`))\n console.log(chalk.dim(\" The token analyzer script should be at scripts/token-report.py\"))\n return\n }\n\n console.log(chalk.dim(\" Analyzing Claude Code sessions...\"))\n try {\n execSync(`SINCE_DAYS=${opts.days} python3 \"${scriptPath}\"`, { stdio: \"inherit\" })\n } catch {\n console.log(chalk.red(\" Analysis failed. Is Python 3 installed?\"))\n }\n })\n\n// ---------------------------------------------------------------------------\n// agentx usage surfaces — which CLI commands and dashboard pages get used\n// ---------------------------------------------------------------------------\n//\n// The evidence side of the surface-reduction work. `usage today` answers\n// \"what did the agents cost\"; this answers \"which of the 46 commands and 16\n// pages does anyone actually open\". Reads straight from SQLite — no daemon\n// needed, and it works on a node whose daemon is stopped.\n//\n// See docs/architecture/surface-reduction.md for the bar a surface must clear.\nusage\n .command(\"surfaces\")\n .description(\"which CLI commands and dashboard pages are actually used\")\n .option(\"--days <n>\", \"window in days\", \"30\")\n .option(\"--kind <kind>\", \"cli | page (default: both)\")\n .option(\"--unused\", \"list registered surfaces with ZERO recorded use instead\")\n .option(\"--json\", \"raw JSON output\")\n .action(async (opts) => {\n const { listSurfaceUse } = await import(\"@/observability/surface-usage\")\n const kind = opts.kind === \"cli\" || opts.kind === \"page\" ? opts.kind : undefined\n const rows = listSurfaceUse({ kind, sinceDays: Number(opts.days) || 30 })\n\n if (opts.unused) {\n const { buildProgram } = await import(\"@/program\")\n const program = await buildProgram()\n const seen = new Set(rows.filter((r) => r.kind === \"cli\").map((r) => r.name))\n const registered: string[] = []\n const walk = (cmd: any, prefix: string) => {\n for (const sub of cmd.commands ?? []) {\n const name = prefix ? `${prefix} ${sub.name()}` : sub.name()\n registered.push(name)\n walk(sub, name)\n }\n }\n walk(program, \"\")\n const unused = registered.filter((c) => !seen.has(c)).sort()\n\n if (opts.json) {\n console.log(JSON.stringify({ windowDays: Number(opts.days) || 30, unused }, null, 2))\n return\n }\n console.log()\n console.log(chalk.bold(` Never used in the last ${opts.days} days (${unused.length}/${registered.length})`))\n console.log()\n for (const c of unused) console.log(` ${chalk.dim(\"·\")} ${c}`)\n console.log()\n console.log(chalk.dim(\" Zero use is necessary but not sufficient to remove a surface —\"))\n console.log(chalk.dim(\" it must also fail the impact test. See docs/architecture/surface-reduction.md\"))\n console.log()\n return\n }\n\n if (opts.json) {\n console.log(JSON.stringify(rows, null, 2))\n return\n }\n\n if (rows.length === 0) {\n console.log()\n console.log(chalk.dim(` No surface usage recorded in the last ${opts.days} days.`))\n console.log(chalk.dim(\" Counting starts once this build has been running for a while.\"))\n console.log()\n return\n }\n\n console.log()\n console.log(chalk.bold(` Surface usage — last ${opts.days} days`))\n console.log()\n let lastKind = \"\"\n for (const r of rows) {\n if (r.kind !== lastKind) {\n console.log(chalk.dim(` ${r.kind === \"cli\" ? \"CLI commands\" : \"Dashboard pages\"}`))\n lastKind = r.kind\n }\n const count = String(r.count).padStart(6)\n const days = chalk.dim(`${r.days}d`)\n console.log(` ${chalk.cyan(count)} ${r.name.padEnd(28)} ${days}`)\n }\n console.log()\n console.log(chalk.dim(` ${rows.length} surface(s) with recorded use. See --unused for the rest.`))\n console.log()\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { resolve } from \"path\"\nimport { loadEnvFileIntoProcess } from \"@/utils/workspace-env\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\nimport { mutateAgentxConfig } from \"@/daemon/config-mutate\"\n\nexport const board = new Command()\n .name(\"board\")\n .description(\"kanban board dashboard — visual work view over configured sources\")\n\n// agentx board serve — start the dashboard HTTP server\nboard\n .command(\"serve\", { isDefault: true })\n .description(\"start the dashboard server (live view always; boards if configured)\")\n .option(\"--port <n>\", \"override dashboard.port\")\n .option(\"--bind <host>\", \"override dashboard.bind (e.g. 0.0.0.0)\")\n .action(async (opts) => {\n try {\n // Must precede loadDaemonConfig(): agentx.json expands ${VAR} at load\n // time, so without .env the dashboard's peer tokens resolve to \"\" and\n // every proxied mesh call is rejected 401. Same load the daemon does.\n try { loadEnvFileIntoProcess(resolve(process.cwd(), \".env\")) } catch { /* best effort */ }\n const config = resolveServerConfig(opts.port, opts.bind)\n const { startBoardDashboard } = await import(\"@/daemon/board-dashboard\")\n startBoardDashboard(config)\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n if (process.env.DEBUG && e.stack) console.log(chalk.dim(e.stack))\n process.exit(1)\n }\n })\n\n/**\n * Load agentx.json if it exists; otherwise fabricate a minimal config so the\n * dashboard can serve the setup wizard. Without this, `agentx setup` on a\n * fresh machine would crash with \"No config found\" before the user has a\n * chance to create one.\n */\nfunction resolveServerConfig(portOpt?: string, bindOpt?: string): any {\n try {\n const cfg = loadDaemonConfig()\n if (portOpt) cfg.dashboard.port = parseInt(portOpt, 10)\n if (bindOpt) cfg.dashboard.bind = bindOpt\n return cfg\n } catch (e: any) {\n console.log(chalk.yellow(\" No agentx.json found — starting dashboard in setup-only mode.\"))\n console.log(chalk.dim(\" Visit http://127.0.0.1:\" + (portOpt || \"4202\") + \" to run the wizard.\\n\"))\n return {\n node: { id: \"setup\", name: \"Setup\", bind: \"127.0.0.1:18800\" },\n providers: {},\n agents: {},\n channels: {},\n crons: {},\n mesh: { enabled: false, peers: [], discovery: \"static\", healthCheck: { interval: 60, timeout: 10 } },\n boards: [],\n dashboard: {\n enabled: true,\n port: portOpt ? parseInt(portOpt, 10) : 4202,\n bind: bindOpt || \"127.0.0.1\",\n daemonUrl: \"http://localhost:18800\",\n daemons: [],\n },\n business: undefined,\n session: { staleMinutes: 120 },\n }\n }\n}\n\n// agentx board list — show configured boards (quick sanity check)\nboard\n .command(\"list\")\n .description(\"list configured boards\")\n .action(() => {\n try {\n const config = loadDaemonConfig()\n if (!config.boards?.length) {\n console.log(chalk.dim(\"\\n No boards configured.\\n\"))\n return\n }\n console.log()\n for (const b of config.boards) {\n console.log(` ${chalk.cyan(b.id)} — ${b.name}`)\n const src = b.source as any\n console.log(chalk.dim(` source: ${src.type}${src.projects ? \" (\" + src.projects.join(\", \") + \")\" : \"\"}`))\n if (b.primaryToolLabel) console.log(chalk.dim(` primary label: ${b.primaryToolLabel}`))\n console.log(chalk.dim(` window: ${b.timeRangeDays} days`))\n }\n console.log()\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\n// agentx board add — append a board to agentx.json\nboard\n .command(\"add <id>\")\n .description(\"add a GitLab board to agentx.json\")\n .requiredOption(\"--name <name>\", \"human-readable board name\")\n .requiredOption(\"--projects <paths>\", \"comma-separated GitLab project paths (e.g. 'globex/system,globex/website')\")\n .option(\"--label <label>\", \"primary tool label ANDed into every query (e.g. 'Tool::Claude')\")\n .option(\"--days <n>\", \"open-window time range in days\", \"30\")\n .option(\"--closed-days <n>\", \"closed-window in days\", \"30\")\n .action((id: string, opts) => {\n try {\n mutateConfig((cfg) => {\n if (!Array.isArray(cfg.boards)) cfg.boards = []\n if (cfg.boards.find((b: any) => b.id === id)) {\n throw new Error(`board \"${id}\" already exists`)\n }\n const projects = String(opts.projects).split(\",\").map((s) => s.trim()).filter(Boolean)\n if (projects.length === 0) throw new Error(\"--projects must include at least one path\")\n const board: any = {\n id,\n name: opts.name,\n source: { type: \"gitlab\", projects },\n timeRangeDays: parseInt(opts.days, 10) || 30,\n closedWindowDays: parseInt(opts.closedDays, 10) || 30,\n }\n if (opts.label) board.primaryToolLabel = opts.label\n cfg.boards.push(board)\n return `added board \"${id}\" (${projects.join(\", \")})`\n })\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\n// agentx board edit — update a board in place\nboard\n .command(\"edit <id>\")\n .description(\"edit board fields without re-creating it\")\n .option(\"--name <name>\", \"rename\")\n .option(\"--projects <paths>\", \"comma-separated GitLab project paths (replaces the list)\")\n .option(\"--label <label>\", \"primary tool label (set to '-' to clear)\")\n .option(\"--days <n>\", \"open-window time range in days\")\n .option(\"--closed-days <n>\", \"closed-window in days\")\n .action((id: string, opts) => {\n try {\n mutateConfig((cfg) => {\n const list = Array.isArray(cfg.boards) ? cfg.boards : []\n const b = list.find((x: any) => x.id === id)\n if (!b) throw new Error(`board \"${id}\" not found`)\n const changes: string[] = []\n if (opts.name) { b.name = opts.name; changes.push(`name=\"${opts.name}\"`) }\n if (opts.projects) {\n const projects = String(opts.projects).split(\",\").map((s) => s.trim()).filter(Boolean)\n if (projects.length === 0) throw new Error(\"--projects must include at least one path\")\n b.source = { ...(b.source || { type: \"gitlab\" }), type: \"gitlab\", projects }\n changes.push(`projects=${projects.length}`)\n }\n if (opts.label !== undefined) {\n if (opts.label === \"-\") { delete b.primaryToolLabel; changes.push(\"label cleared\") }\n else { b.primaryToolLabel = opts.label; changes.push(`label=\"${opts.label}\"`) }\n }\n if (opts.days) { b.timeRangeDays = parseInt(opts.days, 10) || b.timeRangeDays; changes.push(`days=${b.timeRangeDays}`) }\n if (opts.closedDays) { b.closedWindowDays = parseInt(opts.closedDays, 10) || b.closedWindowDays; changes.push(`closed-days=${b.closedWindowDays}`) }\n if (changes.length === 0) throw new Error(\"no changes — pass at least one option\")\n return `board \"${id}\" updated (${changes.join(\", \")})`\n })\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\n// agentx board column ... — manage a board's column flow\nconst column = board\n .command(\"column\")\n .description(\"manage a board's columns (add / remove / edit / list)\")\n\ncolumn\n .command(\"list <boardId>\")\n .description(\"list columns on a board, in order\")\n .action((boardId: string) => {\n try {\n const cfg = JSON.parse(require(\"fs\").readFileSync(\"agentx.json\", \"utf-8\"))\n const b = (cfg.boards || []).find((x: any) => x.id === boardId)\n if (!b) throw new Error(`board \"${boardId}\" not found`)\n const cols = b.columns || []\n if (cols.length === 0) { console.log(chalk.dim(` no columns (board falls back to GitLab default flow)`)); return }\n for (const c of cols) {\n const map = c.kind === \"scoped-label\" ? `scoped=\"${c.scopedLabel}\"` :\n c.kind === \"label\" ? `label=\"${c.mapsToLabel || \"\"}\"` :\n c.kind === \"open-backlog\" ? `prefix=\"${c.scopedPrefix}\"` :\n c.kind\n console.log(` ${chalk.cyan(c.id.padEnd(12))} ${c.title.padEnd(14)} ${chalk.dim(map)}`)\n }\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\ncolumn\n .command(\"add <boardId> <columnId>\")\n .description(\"add a column to a board\")\n .requiredOption(\"--title <title>\", \"column title\")\n .option(\"--kind <kind>\", \"open-backlog | scoped-label | closed | label\", \"scoped-label\")\n .option(\"--scoped <label>\", \"for kind=scoped-label, the full label (e.g. 'Status::Doing')\")\n .option(\"--label <label>\", \"for kind=label, the label name to add/remove\")\n .option(\"--scoped-prefix <prefix>\", \"for kind=open-backlog/scoped-label\", \"Status\")\n .option(\"--accent <color>\", \"hex/CSS color for the column accent bar\")\n .action((boardId: string, columnId: string, opts) => {\n try {\n mutateConfig((cfg) => {\n const list = Array.isArray(cfg.boards) ? cfg.boards : []\n const b = list.find((x: any) => x.id === boardId)\n if (!b) throw new Error(`board \"${boardId}\" not found`)\n b.columns = b.columns || []\n if (b.columns.find((c: any) => c.id === columnId)) {\n throw new Error(`column \"${columnId}\" already exists on board \"${boardId}\"`)\n }\n const col: any = { id: columnId, title: opts.title, kind: opts.kind, scopedPrefix: opts.scopedPrefix }\n if (opts.kind === \"scoped-label\") {\n if (!opts.scoped) throw new Error(\"--scoped required for kind=scoped-label\")\n col.scopedLabel = opts.scoped\n }\n if (opts.kind === \"label\") {\n if (!opts.label) throw new Error(\"--label required for kind=label\")\n col.mapsToLabel = opts.label\n }\n if (opts.accent) col.accent = opts.accent\n b.columns.push(col)\n return `column \"${columnId}\" added to board \"${boardId}\"`\n })\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\ncolumn\n .command(\"remove <boardId> <columnId>\")\n .alias(\"rm\")\n .description(\"remove a column from a board\")\n .action((boardId: string, columnId: string) => {\n try {\n mutateConfig((cfg) => {\n const list = Array.isArray(cfg.boards) ? cfg.boards : []\n const b = list.find((x: any) => x.id === boardId)\n if (!b) throw new Error(`board \"${boardId}\" not found`)\n const before = (b.columns || []).length\n b.columns = (b.columns || []).filter((c: any) => c.id !== columnId)\n if (b.columns.length === before) throw new Error(`column \"${columnId}\" not found`)\n return `column \"${columnId}\" removed from board \"${boardId}\"`\n })\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\n// agentx board remove — drop a board by id\nboard\n .command(\"remove <id>\")\n .alias(\"rm\")\n .description(\"remove a board from agentx.json\")\n .action((id: string) => {\n try {\n mutateConfig((cfg) => {\n if (!Array.isArray(cfg.boards) || cfg.boards.length === 0) throw new Error(\"no boards configured\")\n const before = cfg.boards.length\n cfg.boards = cfg.boards.filter((b: any) => b.id !== id)\n if (cfg.boards.length === before) throw new Error(`board \"${id}\" not found`)\n return `removed board \"${id}\"`\n })\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\n/**\n * CLI-friendly wrapper around the shared mutateAgentxConfig helper — prints\n * colourized success + backup hint so `agentx board add/remove` feels the same\n * as it did before the refactor.\n */\nfunction mutateConfig(mutator: (cfg: any) => string): void {\n const { summary, backupPath } = mutateAgentxConfig((cfg) => mutator(cfg))\n console.log(chalk.green(`\\n ✓ ${summary}\\n`))\n if (backupPath) console.log(chalk.dim(` Backup: ${backupPath}`))\n console.log(chalk.dim(` Restart the dashboard to pick up the change if not auto-reloading.\\n`))\n}\n","import { Command } from \"commander\"\nimport { stripAnthropicApiKey } from \"@/utils/workspace-env\"\nimport chalk from \"chalk\"\nimport { WikiHub } from \"@/wiki\"\nimport type { WikiMode } from \"@/wiki/hub\"\nimport { startWikiServer } from \"@/wiki/serve\"\nimport { buildAbsorbPrompt } from \"@/wiki/prompts\"\nimport { runPromotion } from \"@/wiki/promote\"\nimport { GraphStore } from \"@/graph\"\nimport { resolve, relative, dirname } from \"path\"\nimport { execSync } from \"child_process\"\nimport { writeFileSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, existsSync } from \"fs\"\n\nfunction getHub(dir?: string, mode?: WikiMode): WikiHub {\n return new WikiHub(wikiDir(dir), undefined, mode || \"graph\")\n}\n\n/** The wiki root, resolved the same way everywhere that needs it. */\nfunction wikiDir(dir?: string): string {\n return dir || resolve(process.cwd(), \".agentx/wiki\")\n}\n\nfunction modeLabel(mode: WikiMode): string {\n if (mode === \"graph\") return \"Knowledge Graph\"\n if (mode === \"flat\") return \"Karpathy Flat\"\n return \"Unified\"\n}\n\nexport const wiki = new Command()\n .name(\"wiki\")\n .description(\"wiki knowledge base management\")\n\n// agentx wiki status\nwiki\n .command(\"status\")\n .description(\"show wiki status per agent\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--mode <mode>\", \"graph (default, canonical) | unified | flat (legacy, back-compat)\", \"graph\")\n .action((opts) => {\n const mode = opts.mode as WikiMode\n const hub = getHub(opts.dir, mode)\n const agents = hub.summary()\n const shared = hub.getSharedStore()\n const totalEntries = shared.listEntries().length\n\n console.log()\n console.log(chalk.bold(` Wiki Hub Status [${modeLabel(mode)}]`))\n console.log()\n console.log(` Total raw entries: ${totalEntries}`)\n console.log(` Agents: ${agents.length}`)\n console.log()\n\n for (const agent of agents) {\n const status = agent.unabsorbed > 0\n ? chalk.yellow(`${agent.unabsorbed} unabsorbed`)\n : chalk.green(\"up to date\")\n\n console.log(` ${chalk.cyan(agent.agentId)}`)\n console.log(` Entries: ${agent.totalEntries} Articles: ${agent.totalArticles} ${status}`)\n\n if (agent.articles.length > 0) {\n for (const a of agent.articles.slice(0, 3)) {\n console.log(chalk.dim(` - ${a.title} [${(a.tags || []).slice(0, 3).join(\", \")}]`))\n }\n if (agent.articles.length > 3) {\n console.log(chalk.dim(` ... and ${agent.articles.length - 3} more`))\n }\n }\n console.log()\n }\n\n const totalUnabsorbed = agents.reduce((s, a) => s + a.unabsorbed, 0)\n if (totalUnabsorbed > 0) {\n console.log(chalk.dim(` ${totalUnabsorbed} raw entries on disk. Absorb is deprecated — see 'agentx wiki absorb --help'.`))\n console.log()\n }\n })\n\n// agentx wiki lint\nwiki\n .command(\"lint\")\n .description(\"check wiki for issues per agent\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--mode <mode>\", \"graph (default, canonical) | unified | flat (legacy, back-compat)\", \"graph\")\n .option(\"--agent <id>\", \"lint a specific agent's wiki\")\n .action((opts) => {\n const hub = getHub(opts.dir, opts.mode as WikiMode)\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n let totalIssues = 0\n\n console.log()\n for (const agentId of agents) {\n const store = hub.getAgentWiki(agentId)\n const issues = store.lint()\n totalIssues += issues.length\n\n if (issues.length === 0) {\n console.log(` ${chalk.cyan(agentId)}: ${chalk.green(\"healthy\")}`)\n } else {\n console.log(` ${chalk.cyan(agentId)}: ${chalk.yellow(`${issues.length} issues`)}`)\n for (const issue of issues) {\n const icon = issue.type === \"broken-link\" ? \"x\" : issue.type === \"orphan\" ? \"?\" : \"!\"\n console.log(` [${icon}] ${chalk.dim(issue.type)} ${issue.article}: ${issue.message}`)\n }\n }\n }\n\n console.log()\n if (totalIssues === 0) {\n console.log(chalk.green(\" All agent wikis are healthy\"))\n }\n console.log()\n })\n\n// agentx wiki absorb — Farzapedia-faithful compilation.\n// Reads unabsorbed raw entries, classifies by type, writes articles with\n// wikilinked `related`, updates the catalog. Phase 4 un-gated this after\n// the query + prune layers landed; see docs/blog/wiki-karpathy-review.\nwiki\n .command(\"absorb\")\n .description(\"compile unabsorbed entries into typed per-agent wiki articles (Farzapedia-faithful)\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--mode <mode>\", \"graph (default, canonical) | unified | flat (legacy, back-compat)\", \"graph\")\n .option(\"--agent <id>\", \"absorb only this agent\")\n .option(\"--dry-run\", \"preview without running\")\n .option(\"--no-facts\", \"skip the system-of-record lookups\")\n .option(\"--max <n>\", \"max entries per agent\", \"10\")\n .option(\"--since <date>\", \"only entries dated on or after YYYY-MM-DD\")\n .action(async (opts) => {\n const mode = opts.mode as WikiMode\n const hub = getHub(opts.dir, mode)\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n const maxEntries = parseInt(opts.max)\n\n // Build a lookup so each absorbed article can carry the intent path\n // its source entries were classified into. Without this, graphPath stays\n // empty and the wiki retrieval scorer multiplies the graph weight by 0.\n // Best-effort: graph may be disabled, store may be empty — we just fall\n // through to legacy behaviour (graphPath undefined) in those cases.\n const graphStore = (() => {\n try {\n const baseDir = resolve(process.cwd(), \".agentx/graph\")\n if (!existsSync(baseDir)) return null\n return new GraphStore({ baseDir })\n } catch { return null }\n })()\n const fpToPath = new Map<string, string[]>()\n if (graphStore) {\n try {\n const idx = graphStore.loadIndex()\n for (const [fp, e] of Object.entries(idx.entries)) {\n fpToPath.set(fp, (e as any).path)\n }\n } catch { /* leave map empty */ }\n }\n // Built once for the whole absorb, not per agent: it reads every\n // article on the fleet.\n let knownPeople: string[] | undefined\n const lookupPath = (entry: { content: string; source?: string; meta?: Record<string, unknown> }): string[] | undefined => {\n // Preferred: entry was stamped with the classifier's path at creation\n // time (registry.ts addEntry call). Free, exact, no fingerprint dance.\n const stamped = (entry.meta as any)?.intentPath\n if (Array.isArray(stamped) && stamped.every((s: unknown) => typeof s === \"string\") && stamped.length > 0) {\n return stamped\n }\n // Fallback for legacy entries: try the fingerprint cache. Often misses\n // because entry.content has a \"User: \" prefix and entry.source can\n // include @<node>; surfaced here for completeness, not as a guarantee.\n if (!graphStore || fpToPath.size === 0) return undefined\n const sender = String((entry.meta as any)?.sender ?? \"\")\n const fp = graphStore.fingerprint({\n text: entry.content,\n channel: entry.source,\n sender,\n })\n return fpToPath.get(fp)\n }\n const pickGraphPath = (sources: string[], entries: Array<{ id: string; content: string; source: string; meta?: Record<string, unknown> }>): string[] | undefined => {\n const counts = new Map<string, { path: string[]; n: number }>()\n for (const sid of sources) {\n const entry = entries.find((e) => e.id === sid)\n if (!entry) continue\n const path = lookupPath(entry)\n if (!path?.length) continue\n const key = path.join(\"/\")\n const cur = counts.get(key)\n if (cur) cur.n++\n else counts.set(key, { path, n: 1 })\n }\n if (counts.size === 0) return undefined\n let best: { path: string[]; n: number } | undefined\n for (const v of counts.values()) if (!best || v.n > best.n) best = v\n return best?.path\n }\n\n let totalAbsorbed = 0\n let totalWithPath = 0\n\n for (const agentId of agents) {\n // Oldest-first, so without a floor absorb spends every run on the\n // earliest entries. Those predate intent-path stamping — devops-agent\n // has 367 entries from April with no intentPath and 1,728 from May\n // onward with one — so an unfiltered run compiles articles that can\n // never carry graphPath, zeroing 0.6 of their retrieval score.\n const sinceDate = typeof opts.since === \"string\" ? opts.since.trim() : \"\"\n const unabsorbed = hub\n .getUnabsorbedEntries(agentId)\n .filter((e) => !sinceDate || (e.date ?? \"\") >= sinceDate)\n .slice(0, maxEntries)\n\n if (unabsorbed.length === 0) {\n console.log(` ${chalk.cyan(agentId)}: ${chalk.green(\"all absorbed\")}`)\n continue\n }\n\n console.log()\n console.log(chalk.bold(` ${chalk.cyan(agentId)}: ${unabsorbed.length} entries to absorb`))\n for (const e of unabsorbed.slice(0, 3)) {\n console.log(chalk.dim(` [${e.date} via ${e.source}] ${e.content.slice(0, 80)}...`))\n }\n if (unabsorbed.length > 3) console.log(chalk.dim(` ... and ${unabsorbed.length - 3} more`))\n\n if (opts.dryRun) continue\n\n // Get this agent's wiki store\n const agentWiki = hub.getAgentWiki(agentId)\n\n // Build prompt using mode-specific template\n const existingIndex = agentWiki.rebuildIndex()\n const worldview = agentWiki.getWorldview() || hub.getSharedStore().getWorldview() || \"\"\n const entryTexts = unabsorbed.map(e =>\n `--- ENTRY ${e.id} [${e.date} ${e.agentId} via ${e.source}] ---\\n${e.content}\\n--- END ENTRY ---`\n ).join(\"\\n\\n\")\n\n // Look up the people this batch names in the systems that actually\n // hold their identifiers. Absorb cannot write down a contact value\n // that nobody typed into a chat, and nobody types their own.\n let factsBlock = \"\"\n if (opts.facts !== false) {\n const { extractHints, resolveFacts, mergeRecords, renderFactsBlock, installPrompts, defaultSources, recordsFromEntries } =\n await import(\"@/wiki/facts\")\n // The dictionary is fleet-wide, not per-agent. The wiki is one\n // shared source of truth, so a person another agent has an\n // article for is still a person here — and scoping it to the\n // current agent's six person articles found nobody. Across a\n // month of entries the fleet dictionary raised hints from 4 to\n // 10, and the six it added were all body-only mentions.\n if (!knownPeople) {\n const names = new Set<string>()\n for (const a of hub.listAgents()) {\n for (const art of hub.getAgentWiki(a).listArticles(a)) {\n if (art.meta.type === \"person\") names.add(art.meta.title)\n }\n }\n knownPeople = [...names]\n }\n const hints = extractHints(\n unabsorbed.map((e) => ({\n context: e.sourceContext,\n content: e.content,\n sender: typeof e.meta?.sender === \"string\" ? e.meta.sender : undefined,\n })),\n { known: knownPeople },\n )\n // The entries' own stamped identifiers come first: they are the\n // platform's record of who sent this message, so unlike a\n // directory lookup there is no name to resolve and nothing to\n // mismatch. Directory results fill in around them.\n const fromEntries = recordsFromEntries(unabsorbed)\n if (hints.length > 0 || fromEntries.length > 0) {\n const sources = defaultSources()\n const { records, results } = hints.length > 0\n ? await resolveFacts(hints, { sources })\n : { records: [], results: [] }\n const merged = mergeRecords([...fromEntries, ...records])\n factsBlock = renderFactsBlock(merged)\n const got = [\n ...(fromEntries.length > 0 ? [`entries:${fromEntries.length}`] : []),\n ...results.filter((r) => r.records.length > 0).map((r) => `${r.source}:${r.records.length}`),\n ]\n console.log(chalk.dim(` Facts: ${hints.length} entities → ${merged.length} resolved${got.length ? ` (${got.join(\" \")})` : \"\"}`))\n for (const p of installPrompts(results, sources)) {\n // A source nobody knows is missing becomes a permanent hole\n // in the corpus shaped like the tool that was never installed.\n console.log(chalk.yellow(` ! ${p.source} ${p.kind} — would supply ${p.provides.join(\", \")}`))\n console.log(chalk.dim(` ${p.hint}`))\n }\n }\n }\n\n const prompt = buildAbsorbPrompt(mode, agentId, worldview, existingIndex.articles, entryTexts, unabsorbed.length, factsBlock)\n console.log(chalk.dim(` Mode: ${modeLabel(mode)}`))\n\n // Write prompt and run Claude\n const tmpDir = resolve(agentWiki[\"baseDir\"], \"_tmp\")\n mkdirSync(tmpDir, { recursive: true })\n const promptPath = resolve(tmpDir, \"absorb-prompt.txt\")\n writeFileSync(promptPath, prompt)\n\n console.log(chalk.dim(` Compiling with Claude...`))\n\n try {\n let rawOutput: string\n try {\n rawOutput = execSync(\n `cat '${promptPath}' | claude -p - --output-format json --max-turns 3 --model sonnet --disallowedTools \"Bash Read Write Edit Glob Grep Agent WebSearch WebFetch NotebookEdit\"`,\n { env: stripAnthropicApiKey({ ...process.env }), encoding: \"utf-8\", timeout: 900_000, maxBuffer: 10 * 1024 * 1024 },\n )\n } catch (execErr: any) {\n rawOutput = execErr.stdout || \"\"\n if (!rawOutput) throw execErr\n }\n\n // Parse Claude's response — may be JSON envelope or raw text\n let responseText = rawOutput\n\n // Try to extract \"result\" from Claude's JSON envelope\n try {\n const envelope = JSON.parse(rawOutput)\n responseText = envelope.result || envelope.content || \"\"\n if (!responseText) {\n console.log(chalk.dim(` Claude envelope keys: ${Object.keys(envelope).join(\", \")}`))\n console.log(chalk.dim(` is_error: ${envelope.is_error}, stop_reason: ${envelope.stop_reason}`))\n }\n } catch {\n // Not a JSON envelope — use as-is\n }\n\n // Parse response — could be { articles: [...], gaps: [...] } or bare [...]\n let articles: Array<{ path: string; title: string; tags: string[]; content: string; sources: string[]; type?: string; related?: string[] }>\n let gaps: string[] = []\n\n // Find outermost JSON object or array. New prompt emits { articles, gaps };\n // legacy arrays are tolerated for back-compat during migration.\n const objStart = responseText.indexOf(\"{\")\n const arrStart = responseText.indexOf(\"[\")\n const jsonStart = (objStart >= 0 && (arrStart < 0 || objStart < arrStart)) ? objStart : arrStart\n\n if (jsonStart === -1) {\n console.log(chalk.red(` No JSON found in response`))\n console.log(chalk.dim(responseText.slice(0, 500)))\n continue\n }\n\n const openChar = responseText[jsonStart]\n const closeChar = openChar === \"{\" ? \"}\" : \"]\"\n let depth = 0\n let jsonEnd = -1\n for (let i = jsonStart; i < responseText.length; i++) {\n if (responseText[i] === openChar) depth++\n else if (responseText[i] === closeChar) { depth--; if (depth === 0) { jsonEnd = i + 1; break } }\n }\n\n if (jsonEnd === -1) { console.log(chalk.red(` Unbalanced JSON`)); continue }\n\n const jsonStr = responseText.slice(jsonStart, jsonEnd)\n try {\n const parsed = JSON.parse(jsonStr)\n if (Array.isArray(parsed)) {\n articles = parsed\n } else {\n articles = parsed.articles || []\n gaps = parsed.gaps || []\n }\n } catch (parseErr: any) {\n console.log(chalk.red(` JSON parse error: ${parseErr.message}`))\n console.log(chalk.dim(` First 300 chars: ${jsonStr.slice(0, 300)}`))\n continue\n }\n\n for (const article of articles) {\n const now = new Date().toISOString().slice(0, 10)\n const graphPath = pickGraphPath(article.sources || [], unabsorbed)\n agentWiki.writeArticle(article.path, {\n title: article.title,\n type: article.type as any,\n related: Array.isArray(article.related) ? article.related : undefined,\n tags: article.tags || [],\n owner: agentId,\n access: \"public\",\n created: now,\n lastUpdated: now,\n sources: article.sources || [],\n graphPath,\n }, article.content, agentId)\n\n const typeTag = article.type ? chalk.magenta(`[${article.type}]`) + \" \" : \"\"\n const relStr = Array.isArray(article.related) && article.related.length\n ? ` → ${article.related.slice(0, 3).join(\", \")}${article.related.length > 3 ? \", …\" : \"\"}`\n : \"\"\n console.log(` ${chalk.green(\"+\")} ${typeTag}${article.path}: ${article.title}${chalk.dim(relStr)}`)\n const tagStr = (article.tags || []).slice(0, 4).join(\", \")\n if (tagStr) console.log(chalk.dim(` tags: ${tagStr}`))\n if (graphPath?.length) {\n console.log(chalk.dim(` graphPath: ${graphPath.join(\" › \")}`))\n totalWithPath++\n }\n totalAbsorbed++\n }\n\n // Gaps: entities absorb referenced but has no article for.\n //\n // These were printed and dropped. Absorb runs on a cron, so the\n // one signal the wiki produces about its own holes was landing\n // in a log nobody reads. They go on the same queue as the field\n // gaps a lookup cannot close — one list of things needing a\n // person, not two.\n if (gaps.length > 0) {\n console.log()\n console.log(chalk.yellow(` Gaps detected (${gaps.length} missing pieces):`))\n for (const gap of gaps) {\n console.log(chalk.yellow(` ? ${gap}`))\n }\n try {\n const { QuestionStore } = await import(\"@/wiki/questions\")\n const q = new QuestionStore(wikiDir(opts.dir)).add(\n gaps.map((gap) => ({\n kind: \"article\" as const,\n agentId,\n path: \"\",\n subject: String(gap).slice(0, 120),\n question: `No article yet for: ${String(gap).slice(0, 160)}`,\n })),\n )\n if (q.added > 0) console.log(chalk.dim(` queued ${q.added} for follow-up (agentx wiki questions)`))\n } catch {\n // Queueing is best-effort; never fail an absorb over it.\n }\n }\n\n agentWiki.rebuildIndex()\n } catch (e: any) {\n console.log(chalk.red(` Absorb failed: ${e.message?.slice(0, 200)}`))\n if (e.stderr) console.log(chalk.dim(String(e.stderr).slice(0, 300)))\n if (e.stdout) console.log(chalk.dim(\"stdout: \" + String(e.stdout).slice(0, 300)))\n }\n }\n\n console.log()\n if (opts.dryRun) {\n console.log(chalk.dim(\" Dry run — no changes made\"))\n } else if (totalAbsorbed > 0) {\n console.log(chalk.green(` ${totalAbsorbed} articles compiled across ${agents.length} agent(s)`))\n if (graphStore) {\n const pct = totalAbsorbed > 0 ? Math.round((totalWithPath / totalAbsorbed) * 100) : 0\n console.log(chalk.dim(` ${totalWithPath}/${totalAbsorbed} carry graphPath (${pct}%) — wiki retrieval graph weight is now non-zero for those`))\n }\n }\n console.log()\n })\n\n// agentx wiki promote — memory→wiki promotion. Reads per-agent memories\n// (.agentx/agent-memory/), has an LLM judge which are durable and\n// cross-agent relevant, and writes them as [[wikilinked]] articles in the\n// SHARED store under owner \"memory-promoter\". Idempotent via stamps in\n// article sources[] + the _memory-promotions.json skip ledger — the\n// planned follow-up documented in agents/agent-memory.ts.\nwiki\n .command(\"promote\")\n .description(\"promote per-agent memories into shared, authoritative wiki articles\")\n .option(\"--dir <path>\", \"wiki directory (default .agentx/wiki)\")\n .option(\"--memory-dir <path>\", \"the .agentx dir holding agent-memory/ (default .agentx)\")\n .option(\"--since <duration>\", \"memory window, e.g. 24h, 7d\", \"7d\")\n .option(\"--agent <id>\", \"only this agent's memories\")\n .option(\"--types <list>\", \"comma-separated memory types\", \"project,reference,feedback\")\n .option(\"--max <n>\", \"max candidate memories per run\", \"20\")\n .option(\"--via <agentId>\", \"route the LLM call through an agent — uses the agent's own session, no API key\")\n .option(\"--model <model>\", \"direct Anthropic API — needs ANTHROPIC_API_KEY\")\n .option(\"--daemon <url>\", \"daemon API base URL for --via\", \"http://127.0.0.1:18800\")\n .option(\"--reviews\", \"also promote findings from session-monitor reviews\")\n .option(\"--review-kinds <list>\", \"which review kinds\", \"decisions,warnings,friction,context\")\n .option(\"--commit\", \"write articles and ledger (default: dry-run)\", false)\n .action(async (opts) => {\n const sinceMs = parsePromoteSince(opts.since)\n const types = String(opts.types).split(\",\").map((t: string) => t.trim()).filter(Boolean)\n const validTypes = [\"user\", \"feedback\", \"project\", \"reference\"]\n const badType = types.find((t: string) => !validTypes.includes(t))\n if (badType) {\n console.log(chalk.red(` Invalid memory type \"${badType}\". Valid: ${validTypes.join(\", \")}`))\n process.exit(1)\n }\n if (opts.commit && !opts.via && !opts.model) {\n console.log(chalk.red(\" --commit needs an LLM: pass --via <agentId> or --model <model>\"))\n process.exit(1)\n }\n\n console.log()\n console.log(chalk.bold(\" Memory → Wiki Promotion\"))\n console.log()\n\n // The monitor has been producing structured findings all along and\n // none of them ever reached the wiki. They are not conversation, so\n // absorb was never going to see them; they are already-formed\n // claims, which is exactly what promotion is for.\n let extraCandidates: import(\"@/wiki/promote\").MemoryCandidate[] = []\n if (opts.reviews) {\n const { reviewsToCandidates } = await import(\"@/wiki/review-candidates\")\n const { default: Database } = await import(\"better-sqlite3\")\n const dbPath = resolve(process.cwd(), \".agentx/db.sqlite\")\n if (!existsSync(dbPath)) {\n console.log(chalk.yellow(` --reviews: no ${dbPath}`))\n } else {\n const db = new Database(dbPath, { readonly: true })\n try {\n const rows = db.prepare(\n \"SELECT id, session_id, agent, source, updated_at, result FROM session_reviews WHERE status='ready' AND result IS NOT NULL AND updated_at >= ? ORDER BY updated_at DESC\",\n ).all(Date.now() - (sinceMs ?? 7 * 864e5)) as never[]\n extraCandidates = reviewsToCandidates(rows, {\n kinds: String(opts.reviewKinds).split(\",\").map((k: string) => k.trim()).filter(Boolean),\n })\n const recurring = (extraCandidates as Array<{ occurrences?: number }>).filter((c) => (c.occurrences ?? 1) > 1).length\n console.log(chalk.dim(` ${rows.length} review(s) in window → ${extraCandidates.length} candidate finding(s), ${recurring} seen in more than one session`))\n const top = (extraCandidates as Array<{ occurrences?: number; memory: { description: string } }>)[0]\n if (top && (top.occurrences ?? 1) > 1) {\n console.log(chalk.dim(` most recurrent (${top.occurrences} sessions): ${top.memory.description.slice(0, 84)}`))\n }\n } finally {\n db.close()\n }\n }\n }\n\n const report = await runPromotion({\n extraCandidates,\n wikiDir: opts.dir ? resolve(opts.dir) : undefined,\n memoryRoot: opts.memoryDir ? resolve(opts.memoryDir) : undefined,\n sinceMs,\n agentFilter: opts.agent,\n types: types as import(\"@/agents/agent-memory\").MemoryType[],\n max: Number(opts.max) || 20,\n viaAgent: opts.via,\n model: opts.model,\n daemonUrl: opts.daemon,\n commit: opts.commit,\n log: (msg) => console.log(chalk.dim(` ${msg}`)),\n })\n\n if (report.candidates.length === 0) {\n console.log(chalk.dim(\" Nothing unpromoted in window\"))\n console.log()\n return\n }\n\n console.log(` ${report.candidates.length} candidate(s) in ${report.clusters.length} cluster(s):`)\n for (const cluster of report.clusters) {\n const c = cluster.candidates[0]\n const corr = cluster.corroboratingAgents.length > 1\n ? chalk.green(` ×${cluster.corroboratingAgents.length} agents`)\n : \"\"\n console.log(` ${chalk.cyan(`[${c.memory.type}]`)} ${c.memory.name}${corr} ${chalk.dim(`(${cluster.corroboratingAgents.join(\", \")}, conf ${cluster.confidence.toFixed(2)})`)}`)\n console.log(chalk.dim(` ${c.memory.description}`))\n }\n console.log()\n\n if (report.dryRun) {\n console.log(chalk.dim(\" Dry run — pass --commit to promote\"))\n console.log()\n return\n }\n\n for (const w of report.written) {\n const typeTag = w.type ? chalk.magenta(`[${w.type}]`) + \" \" : \"\"\n const relStr = w.related?.length\n ? ` → ${w.related.slice(0, 3).join(\", \")}${w.related.length > 3 ? \", …\" : \"\"}`\n : \"\"\n console.log(` ${chalk.green(\"+\")} ${typeTag}${w.path}: ${w.title}${chalk.dim(relStr)}`)\n console.log(chalk.dim(` from: ${w.stamps.join(\", \")}`))\n }\n for (const s of report.skipped) {\n console.log(` ${chalk.yellow(\"-\")} ${s.stamp} ${chalk.dim(`— ${s.reason}`)}`)\n }\n if (report.gaps.length) {\n console.log()\n console.log(chalk.yellow(` Gaps (${report.gaps.length}):`))\n for (const gap of report.gaps) console.log(chalk.yellow(` ? ${gap}`))\n }\n for (const wmsg of report.warnings) console.log(chalk.dim(` ! ${wmsg}`))\n for (const err of report.errors) console.log(chalk.red(` x ${err}`))\n console.log()\n console.log(\n report.errors.length\n ? chalk.red(` ${report.written.length} promoted, ${report.errors.length} error(s)`)\n : chalk.green(` ${report.written.length} promoted, ${report.skipped.length} skipped`),\n )\n console.log()\n if (report.errors.length) process.exit(1)\n })\n\n/** \"24h\" / \"7d\" / \"30m\" → window in ms. (Same grammar as workflow absorb's\n * parseSince, but returns the window size — runPromotion applies the clock.) */\nfunction parsePromoteSince(input: string | undefined): number | undefined {\n if (!input) return undefined\n const m = /^(\\d+)\\s*([smhd])$/.exec(input.trim())\n if (!m) {\n console.log(chalk.red(` Invalid --since \"${input}\". Use \"30m\", \"24h\", or \"7d\".`))\n process.exit(1)\n }\n const n = Number(m[1])\n const unit = m[2]\n return n * (unit === \"s\" ? 1000 : unit === \"m\" ? 60_000 : unit === \"h\" ? 3600_000 : 86_400_000)\n}\n\n// agentx wiki ab-test — compare old BM25 preload vs new agentic query on\n// real messages pulled from .agentx/task-history. Emits a markdown report\n// with both retrieval paths side-by-side so the operator can rate.\nwiki\n .command(\"ab-test\")\n .description(\"side-by-side comparison: BM25 preload (old) vs agentic query (new) on real task-history messages\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--agent <id>\", \"which agent to test against (required)\")\n .option(\"--history <path>\", \"task-history root\", resolve(process.cwd(), \".agentx/task-history\"))\n .option(\"--n <n>\", \"number of messages to sample (newest first)\", \"10\")\n .option(\"--out <path>\", \"markdown output file (default: stdout)\")\n .option(\"--selector-model <m>\", \"agentic selector model\", \"haiku\")\n .option(\"--synth-model <m>\", \"agentic synthesis model\", \"sonnet\")\n .action(async (opts) => {\n const { agenticQuery } = await import(\"@/wiki/query\")\n const { readdirSync: rd, readFileSync: rf, existsSync: ex } = await import(\"fs\")\n const { resolve: rv, join: jn } = await import(\"path\")\n\n const hub = getHub(opts.dir)\n const agentId = opts.agent\n if (!agentId) {\n console.log(chalk.red(\" --agent <id> is required\"))\n return\n }\n const store = hub.getAgentWiki(agentId)\n const n = parseInt(opts.n)\n\n // Gather recent task messages from .agentx/task-history/<agent>/<YYYY-MM-DD>/*.json\n const agentHistDir = rv(opts.history, agentId)\n if (!ex(agentHistDir)) {\n console.log(chalk.yellow(` no task-history at ${agentHistDir}`))\n return\n }\n type Task = { id: string; message: string; ts: string }\n const tasks: Task[] = []\n const days = rd(agentHistDir).sort().reverse() // newest day first\n for (const day of days) {\n const dayDir = jn(agentHistDir, day)\n let files: string[] = []\n try { files = rd(dayDir).filter(f => f.endsWith(\".json\")).sort().reverse() } catch { continue }\n for (const f of files) {\n if (tasks.length >= n) break\n try {\n const rec = JSON.parse(rf(jn(dayDir, f), \"utf-8\"))\n const msg = rec.message || rec.task?.message\n if (typeof msg === \"string\" && msg.trim().length > 10) {\n tasks.push({ id: rec.id || f.replace(\".json\", \"\"), message: msg.trim(), ts: rec.at || rec.timestamp || day })\n }\n } catch {}\n }\n if (tasks.length >= n) break\n }\n\n if (tasks.length === 0) {\n console.log(chalk.yellow(` no task messages found under ${agentHistDir}`))\n return\n }\n\n console.log()\n console.log(chalk.bold(` A/B harness — ${tasks.length} messages from ${agentId}`))\n console.log(chalk.dim(` OLD: findRelevant() BM25 over title+tags+content, top 3 truncated`))\n console.log(chalk.dim(` NEW: agenticQuery() catalog+wikilink walk (selector=${opts.selectorModel}, synth=${opts.synthModel})`))\n console.log()\n\n const lines: string[] = [\n `# Wiki A/B: ${agentId}`,\n \"\",\n `_Generated ${new Date().toISOString()} · ${tasks.length} messages sampled_`,\n \"\",\n \"For each message, the OLD BM25 retrieval (what Layer 10 used to preload) is shown alongside the NEW agentic query's selected articles + synthesized answer. Rate each pair on relevance 0–2 in the notes column.\",\n \"\",\n ]\n\n for (let i = 0; i < tasks.length; i++) {\n const t = tasks[i]\n process.stdout.write(chalk.dim(` [${i + 1}/${tasks.length}] querying... `))\n\n // OLD\n const old = store.findRelevant(t.message, agentId, 3)\n const oldTitles = old.map(a => `- **${a.meta.title}** [${a.meta.type || \"?\"}] (${a.path})`).join(\"\\n\") || \"_(none returned)_\"\n\n // NEW\n let newBlock: string\n try {\n const q = await agenticQuery(t.message, store, agentId, {\n selectorModel: opts.selectorModel,\n synthModel: opts.synthModel,\n })\n if (q.status !== \"ok\") {\n newBlock = `_(status: ${q.status}${q.error ? \" — \" + q.error : \"\"})_`\n } else {\n const cites = q.citations.map(c => `\\`${c.title}\\` [${c.type || \"?\"}]`).join(\", \")\n newBlock = `**Answer:**\\n\\n${q.answer}\\n\\n**Citations:** ${cites}`\n }\n } catch (e: any) {\n newBlock = `_(error: ${e.message})_`\n }\n console.log(chalk.dim(\"done\"))\n\n lines.push(\n `## ${i + 1}. ${t.id}`,\n \"\",\n `> ${t.message.replace(/\\n/g, \" \").slice(0, 400)}${t.message.length > 400 ? \"…\" : \"\"}`,\n \"\",\n \"### OLD — BM25 preload (top 3)\",\n \"\",\n oldTitles,\n \"\",\n \"### NEW — agentic query\",\n \"\",\n newBlock,\n \"\",\n \"| Path | Rating 0–2 | Notes |\",\n \"|---|---|---|\",\n \"| OLD | | |\",\n \"| NEW | | |\",\n \"\",\n )\n }\n\n const out = lines.join(\"\\n\")\n if (opts.out) {\n (await import(\"fs\")).writeFileSync(opts.out, out)\n console.log()\n console.log(chalk.green(` Wrote ${out.length} bytes to ${opts.out}`))\n } else {\n console.log()\n console.log(out)\n }\n })\n\n// agentx wiki interview — interactive write-side for the wiki.\n// Operator answers a short question bank per article type; an LLM\n// synthesizes a Farzapedia-shape article from the transcript. Accounts\n// for the \"absorb only captures what's already been said in channels\"\n// gap — this is where knowledge lives in your head.\nwiki\n .command(\"interview\")\n .description(\"interactive interview session — Q&A with an LLM synthesizer, produces one typed wiki article\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--agent <id>\", \"which agent's wiki to write to (required)\")\n .option(\"--topic <text>\", \"what to interview about (e.g. 'Globex deployment procedure')\")\n .option(\"--type <t>\", \"article type hint (person|project|place|concept|event|decision|pattern)\")\n .option(\"--model <m>\", \"synthesis model\", \"sonnet\")\n .option(\"--no-commit\", \"show the draft but don't write\")\n .option(\"--answers <path>\", \"non-interactive: one answer per line (same order as questions); last line = save|edit|scrap\")\n .action(async (opts) => {\n const readline = await import(\"node:readline/promises\")\n const { randomUUID } = await import(\"node:crypto\")\n const { WIKI_ARTICLE_TYPES } = await import(\"@/wiki/types\")\n\n // --answers: read all lines up front; feed them to each `ask()`.\n // Avoids readline/stdin interaction entirely for scripted runs.\n const scripted = opts.answers\n ? (readFileSync(opts.answers, \"utf-8\").split(/\\r?\\n/).filter(l => l.length > 0))\n : null\n let scriptCursor = 0\n\n if (!opts.agent) {\n console.log(chalk.red(\" --agent <id> is required. The article will be owned by this agent.\"))\n return\n }\n const hub = getHub(opts.dir)\n let store\n try { store = hub.getAgentWiki(opts.agent) } catch (e: any) {\n console.log(chalk.red(` can't open wiki for agent \"${opts.agent}\": ${e.message}`))\n return\n }\n\n const rl = scripted\n ? null\n : readline.createInterface({ input: process.stdin, output: process.stdout })\n const ask = async (prompt: string): Promise<string> => {\n if (scripted) {\n const answer = scripted[scriptCursor++] ?? \"\"\n process.stdout.write(prompt + chalk.dim(`[scripted] ${answer.slice(0, 80)}${answer.length > 80 ? \"…\" : \"\"}`) + \"\\n\")\n return answer.trim()\n }\n return (await rl!.question(prompt)).trim()\n }\n\n console.log()\n console.log(chalk.bold(\" Wiki Interview\"))\n console.log(chalk.dim(\" One article per session. Empty answer = skip field. /done = stop & synthesize. /abort = quit.\"))\n console.log()\n\n // Topic\n let topic = opts.topic || \"\"\n if (!topic) {\n topic = await ask(chalk.cyan(\" Topic? \") + chalk.dim(\"(a person, a procedure, a past event, …) \"))\n if (!topic || topic === \"/abort\") { rl?.close(); return }\n }\n\n // Type\n let type = (opts.type || \"\").toLowerCase()\n const validTypes = new Set(WIKI_ARTICLE_TYPES as readonly string[])\n if (!validTypes.has(type)) {\n console.log(chalk.dim(` Types: ${WIKI_ARTICLE_TYPES.join(\" | \")}`))\n const picked = await ask(chalk.cyan(\" Type? \"))\n if (picked === \"/abort\") { rl?.close(); return }\n if (!validTypes.has(picked)) {\n console.log(chalk.yellow(` \"${picked}\" isn't a valid type. Falling back to \"concept\".`))\n type = \"concept\"\n } else {\n type = picked\n }\n }\n\n // Question bank per type\n const QUESTIONS: Record<string, string[]> = {\n person: [\n \"Full name (and any aliases / Telegram handle / GitLab username)?\",\n \"Role or title?\",\n \"Which org or team are they part of (use the article title if you have one)?\",\n \"Key responsibilities in OUR work?\",\n \"Preferred channel to reach them (Telegram, email, in-person, …)?\",\n \"Who do they report to? (skip if none)\",\n \"Notable decisions, events, or patterns they're involved in?\",\n \"Anything quirky we should remember (timezone, working hours, style)?\",\n ],\n project: [\n \"One-line description — what is this project?\",\n \"Who owns it? (person article title)\",\n \"Tech stack or key tools involved?\",\n \"Current status (active / paused / archived)?\",\n \"Repo / URL / path on disk?\",\n \"Two or three key decisions made so far?\",\n \"Any open blockers, risks, or known issues?\",\n \"Related projects or patterns?\",\n ],\n place: [\n \"Kind — office / server / environment / domain / URL?\",\n \"Address — URL, IP, hostname, or physical location?\",\n \"Owner (person or team)?\",\n \"How to access it (SSH host, login, VPN, …)?\",\n \"What lives there (services, people, data)?\",\n \"Known quirks (timezone, uptime, access restrictions)?\",\n ],\n concept: [\n \"Define it in one sentence — what does this term mean in OUR work?\",\n \"Where did we first adopt it (origin story, date)?\",\n \"Two or three concrete examples from our team?\",\n \"What does it replace or extend (older concept, related concept)?\",\n \"Common misunderstandings to avoid?\",\n ],\n event: [\n \"Date (YYYY-MM-DD)?\",\n \"One-line summary — what happened?\",\n \"Who was involved?\",\n \"Timeline — key moments (start → resolution)?\",\n \"Impact — what broke, what got delivered, who was affected?\",\n \"Resolution / outcome?\",\n \"Follow-ups or lessons captured?\",\n ],\n decision: [\n \"Context — what was the situation forcing a choice?\",\n \"Options that were considered?\",\n \"Chosen option — and one-sentence why?\",\n \"Alternatives rejected — and one-sentence why not?\",\n \"Who decided, and when (date)?\",\n \"Is this reversible, and what would trigger a revisit?\",\n ],\n pattern: [\n \"Trigger — when should someone follow this pattern?\",\n \"Inputs required (what do you need before starting)?\",\n \"Steps in order — keep it tight, one line per step?\",\n \"Expected output — how do you know it worked?\",\n \"Common failure modes?\",\n \"Related patterns, decisions, or runbooks?\",\n ],\n }\n const questions = QUESTIONS[type] || QUESTIONS.concept\n\n // Ask each question\n console.log()\n console.log(chalk.bold(` Topic: ${chalk.cyan(topic)} · Type: ${chalk.magenta(type)}`))\n console.log(chalk.dim(` ${questions.length} questions. Skip with empty answer. /done to stop early.`))\n console.log()\n\n type QA = { q: string; a: string }\n const qas: QA[] = []\n let aborted = false\n for (let i = 0; i < questions.length; i++) {\n const q = questions[i]\n const a = await ask(` ${chalk.dim(`[${i + 1}/${questions.length}]`)} ${q}\\n ${chalk.green(\">\")} `)\n if (a === \"/abort\") { aborted = true; break }\n if (a === \"/done\") break\n if (a === \"/skip\") continue\n if (a) qas.push({ q, a })\n }\n\n // Always ask for anything extra\n if (!aborted) {\n const extra = await ask(`\\n ${chalk.dim(\"Anything else worth capturing?\")}\\n ${chalk.green(\">\")} `)\n if (extra && extra !== \"/abort\" && extra !== \"/done\") qas.push({ q: \"Anything else worth capturing?\", a: extra })\n }\n\n if (aborted || qas.length === 0) {\n console.log(chalk.yellow(\"\\n Nothing captured. Exiting.\"))\n rl?.close()\n return\n }\n\n // Build the catalog slice for wikilink grounding (first 40 titles max)\n const existingArticles = store.listArticles(opts.agent).slice(0, 40)\n const catalogLines = existingArticles\n .map(a => `- ${a.meta.title} [${a.meta.type || \"?\"}]`)\n .join(\"\\n\")\n\n const synthesisPrompt = [\n `You are compiling one Farzapedia-style wiki article from an operator interview transcript.`,\n ``,\n `**Topic:** ${topic}`,\n `**Type:** ${type}`,\n `**Owning agent:** ${opts.agent}`,\n ``,\n `## Transcript`,\n ...qas.map(x => `\\nQ: ${x.q}\\nA: ${x.a}`),\n ``,\n `## Existing articles (use [[Title]] wikilinks when referencing these)`,\n catalogLines || \"(none yet)\",\n ``,\n `## Output rules`,\n `- Output EXACTLY one markdown file: frontmatter (---) + body. No code fences, no preamble.`,\n `- Frontmatter fields in this exact order: title, type, related, tags, owner, access, created, last_updated, sources.`,\n ` - \\`title\\`: \"…\"`,\n ` - \\`type\\`: ${type}`,\n ` - \\`related\\`: [\"Article Title\", …] (titles that exist in the catalog above; drop if none)`,\n ` - \\`tags\\`: 2-4 specific tags, lowercase-kebab — no dates unless type=event`,\n ` - \\`owner\\`: ${opts.agent}`,\n ` - \\`access\\`: public (unless the content is sensitive)`,\n ` - \\`created\\`: ${new Date().toISOString().slice(0, 10)}`,\n ` - \\`last_updated\\`: ${new Date().toISOString().slice(0, 10)}`,\n ` - \\`sources\\`: [\"interview-${new Date().toISOString().slice(0, 10)}\"]`,\n `- Body: 20-80 lines, Wikipedia-style, organized by theme (not by question), synthesized (not verbatim Q&A).`,\n `- Use [[Title]] inline every time you reference something that has an article in the catalog.`,\n `- Do NOT invent facts. If the transcript didn't cover something, skip that sub-topic.`,\n ].join(\"\\n\")\n\n // Write prompt to tmp, run claude -p\n const tmpDir = resolve(store.baseDir, \"_tmp\")\n mkdirSync(tmpDir, { recursive: true })\n const promptPath = resolve(tmpDir, `interview-${randomUUID().slice(0, 8)}.txt`)\n writeFileSync(promptPath, synthesisPrompt)\n\n console.log()\n console.log(chalk.dim(` Synthesizing draft with ${opts.model}...`))\n\n let draft = \"\"\n try {\n const cmd = `cat '${promptPath}' | claude -p - --output-format json --max-turns 1 --model ${opts.model} --disallowedTools \"Bash Read Write Edit Glob Grep Agent WebSearch WebFetch NotebookEdit\"`\n const raw = execSync(cmd, { env: stripAnthropicApiKey({ ...process.env }), encoding: \"utf-8\", timeout: 180_000, maxBuffer: 4 * 1024 * 1024 })\n try {\n const envelope = JSON.parse(raw)\n draft = String(envelope.result || envelope.content || \"\")\n } catch {\n draft = raw\n }\n } catch (e: any) {\n console.log(chalk.red(` synthesis failed: ${e.message?.slice(0, 200)}`))\n rl?.close()\n return\n }\n\n // Strip any wrapping code fences / preamble\n draft = draft.trim()\n const fence = draft.match(/```(?:markdown|md)?\\s*\\n([\\s\\S]*?)\\n```\\s*$/)\n if (fence) draft = fence[1].trim()\n // If there's a preamble before the `---`, drop it\n const fmStart = draft.indexOf(\"---\")\n if (fmStart > 0) draft = draft.slice(fmStart)\n\n // Parse frontmatter to extract title + type\n const fmMatch = draft.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/)\n if (!fmMatch) {\n console.log(chalk.red(\" LLM output is not a valid frontmatter+body article:\"))\n console.log(draft.slice(0, 600))\n rl?.close()\n return\n }\n const fm: Record<string, string> = {}\n for (const line of fmMatch[1].split(\"\\n\")) {\n const m = line.match(/^(\\w+):\\s*(.+)$/)\n if (m) fm[m[1]] = m[2].trim().replace(/^\"(.*)\"$/, \"$1\")\n }\n const body = fmMatch[2]\n const title = fm.title || topic\n const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\").slice(0, 60)\n // Use canonical per-type directory names. Most types pluralise with +s,\n // but \"person\" goes in \"people/\" (English irregular plural — and matches\n // what Farzapedia / our catalog groupings use everywhere else).\n const TYPE_DIR: Record<string, string> = {\n person: \"people\", project: \"projects\", place: \"places\",\n concept: \"concepts\", event: \"events\", decision: \"decisions\", pattern: \"patterns\",\n }\n const articlePath = `${TYPE_DIR[type] || type + \"s\"}/${slug}.md`\n\n console.log()\n console.log(chalk.bold(\" === Draft preview ===\"))\n console.log(chalk.dim(` Path: ${articlePath}`))\n console.log()\n console.log(draft)\n console.log()\n\n const choice = await ask(` ${chalk.green(\"save\")} / ${chalk.yellow(\"edit (opens $EDITOR)\")} / ${chalk.red(\"scrap\")} ? `)\n rl?.close()\n\n if (choice === \"scrap\" || choice === \"/abort\") {\n console.log(chalk.dim(\" Discarded.\"))\n return\n }\n if (!opts.commit) {\n console.log(chalk.dim(\" --no-commit: not writing.\"))\n console.log(chalk.dim(` Draft kept at ${promptPath} (prompt only; no article file)`))\n return\n }\n\n // Optional editor pass\n let finalContent = body\n let finalMeta: Record<string, any> = {\n title,\n type: fm.type || type,\n related: fm.related\n ? fm.related.replace(/^\\[|\\]$/g, \"\").split(\",\").map(s => s.trim().replace(/^\"(.*)\"$/, \"$1\")).filter(Boolean)\n : undefined,\n tags: fm.tags\n ? fm.tags.replace(/^\\[|\\]$/g, \"\").split(\",\").map(s => s.trim().replace(/^\"(.*)\"$/, \"$1\")).filter(Boolean)\n : [],\n owner: opts.agent,\n access: fm.access || \"public\",\n created: fm.created || new Date().toISOString().slice(0, 10),\n lastUpdated: fm.last_updated || new Date().toISOString().slice(0, 10),\n sources: [`interview-${new Date().toISOString().slice(0, 10)}`],\n }\n\n if (choice === \"edit\") {\n const editor = process.env.EDITOR || \"vi\"\n const editPath = resolve(tmpDir, `draft-${randomUUID().slice(0, 8)}.md`)\n writeFileSync(editPath, draft)\n try {\n execSync(`${editor} '${editPath}'`, { stdio: \"inherit\" })\n const edited = readFileSync(editPath, \"utf-8\")\n const m = edited.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/)\n if (m) {\n const ef: Record<string, string> = {}\n for (const line of m[1].split(\"\\n\")) {\n const mm = line.match(/^(\\w+):\\s*(.+)$/)\n if (mm) ef[mm[1]] = mm[2].trim().replace(/^\"(.*)\"$/, \"$1\")\n }\n finalContent = m[2]\n finalMeta = {\n ...finalMeta,\n title: ef.title || finalMeta.title,\n type: ef.type || finalMeta.type,\n access: ef.access || finalMeta.access,\n related: ef.related\n ? ef.related.replace(/^\\[|\\]$/g, \"\").split(\",\").map(s => s.trim().replace(/^\"(.*)\"$/, \"$1\")).filter(Boolean)\n : finalMeta.related,\n tags: ef.tags\n ? ef.tags.replace(/^\\[|\\]$/g, \"\").split(\",\").map(s => s.trim().replace(/^\"(.*)\"$/, \"$1\")).filter(Boolean)\n : finalMeta.tags,\n }\n }\n } catch (e: any) {\n console.log(chalk.red(` editor failed: ${e.message}`))\n return\n }\n }\n\n // Write via the store — type validation kicks in\n const written = store.writeArticle(articlePath, finalMeta as any, finalContent, opts.agent)\n if (!written) {\n console.log(chalk.red(\" write failed (permission?)\"))\n return\n }\n store.rebuildIndex()\n console.log(chalk.green(` ✓ ${articlePath} saved.`))\n\n // Suggest next topics from wikilinks in the body that don't yet exist\n const referenced = store.extractWikilinks(finalContent)\n const titleIdx = new Map<string, boolean>()\n for (const a of store.listArticles(opts.agent)) titleIdx.set(a.meta.title.toLowerCase(), true)\n const gaps = referenced.filter(r => !titleIdx.has(r.toLowerCase()))\n if (gaps.length) {\n console.log()\n console.log(chalk.bold(\" Gaps referenced but not yet covered:\"))\n for (const g of gaps.slice(0, 8)) {\n console.log(chalk.dim(` - ${g}`))\n }\n console.log(chalk.dim(` Run \\`agentx wiki interview --agent ${opts.agent} --topic \"<title>\"\\` for any of these.`))\n }\n })\n\n// agentx wiki quiz — reverse interview: operator asks, agent answers\n// via agenticQuery, operator grades with /ok /correct /add /link and the\n// cited article gets patched. Grows the wiki through dialogue instead\n// of structured extraction.\nwiki\n .command(\"quiz\")\n .description(\"reverse interview — ask the wiki questions and patch cited articles with corrections, additions, or links\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--agent <id>\", \"which agent's wiki to quiz (required)\")\n .option(\"--selector-model <m>\", \"candidate-selection model\", \"haiku\")\n .option(\"--synth-model <m>\", \"answer synthesis model\", \"sonnet\")\n .option(\"--patch-model <m>\", \"article patch model\", \"sonnet\")\n .option(\"--rounds <n>\", \"stop after N rounds\", \"20\")\n .option(\"--script <path>\", \"non-interactive: question line + /verdict line per entry, entries separated by blank lines\")\n .option(\"--no-commit\", \"show proposed patches but don't write\")\n .option(\"--out <path>\", \"write a session transcript as markdown\")\n .action(async (opts) => {\n const readline = await import(\"node:readline/promises\")\n const { randomUUID } = await import(\"node:crypto\")\n const { agenticQuery } = await import(\"@/wiki/query\")\n\n if (!opts.agent) {\n console.log(chalk.red(\" --agent <id> is required.\"))\n return\n }\n const hub = getHub(opts.dir)\n let store\n try { store = hub.getAgentWiki(opts.agent) } catch (e: any) {\n console.log(chalk.red(` can't open wiki for agent \"${opts.agent}\": ${e.message}`))\n return\n }\n\n type Script = { q: string; verdict: string }[]\n let script: Script | null = null\n if (opts.script) {\n const raw = readFileSync(opts.script, \"utf-8\")\n const entries = raw.split(/\\n\\s*\\n/).map(e => e.trim()).filter(Boolean)\n script = []\n for (const entry of entries) {\n const lines = entry.split(/\\r?\\n/).filter(l => l.trim())\n if (lines.length < 2) continue\n const q = lines[0].replace(/^Q:\\s*/i, \"\").trim()\n const verdict = lines.slice(1).join(\" \").trim()\n if (q && verdict) script.push({ q, verdict })\n }\n }\n\n const rl = script\n ? null\n : readline.createInterface({ input: process.stdin, output: process.stdout })\n const ask = async (prompt: string): Promise<string> => {\n if (rl) return (await rl.question(prompt)).trim()\n return \"\"\n }\n\n const rounds = Math.min(parseInt(opts.rounds) || 20, script?.length ?? 999)\n const commit = opts.commit !== false\n\n console.log()\n console.log(chalk.bold(\" Wiki Quiz\"))\n console.log(chalk.dim(` Agent: ${opts.agent} · Rounds: ${rounds} · ${commit ? \"commit\" : \"dry-run\"} · ${script ? `scripted (${script.length})` : \"interactive\"}`))\n console.log(chalk.dim(\" Verdicts: /ok /correct <note> /add <note> /link <url> /skip /done\"))\n console.log()\n\n type Entry = { q: string; answer: string; citations: Array<{ title: string; path: string; type?: string }>; verdict: string; patched?: string }\n const transcript: Entry[] = []\n let applied = 0\n\n for (let i = 0; i < rounds; i++) {\n let q: string\n let verdict: string\n if (script) {\n const entry = script[i]\n if (!entry) break\n q = entry.q\n verdict = entry.verdict\n console.log(chalk.cyan(` [${i + 1}] Q: `) + q)\n } else {\n q = await ask(chalk.cyan(` [${i + 1}] Q: `))\n if (!q || q === \"/done\" || q === \"/abort\") break\n verdict = \"\"\n }\n\n process.stdout.write(chalk.dim(\" querying... \"))\n let result\n try {\n result = await agenticQuery(q, store, opts.agent, {\n selectorModel: opts.selectorModel,\n synthModel: opts.synthModel,\n })\n } catch (e: any) {\n console.log(chalk.red(`failed: ${e.message?.slice(0, 120)}`))\n continue\n }\n console.log(chalk.dim(\"done\"))\n\n if (result.status !== \"ok\") {\n console.log(chalk.yellow(` (status: ${result.status}${result.error ? \" — \" + result.error : \"\"})`))\n } else {\n const cites = result.citations.map(c => `${c.title} [${c.type || \"?\"}]`).join(\" · \")\n console.log()\n console.log(chalk.dim(\" A: \") + result.answer.replace(/\\n/g, \"\\n \"))\n console.log(chalk.dim(\" citations: \" + cites))\n }\n\n if (!script) {\n verdict = await ask(chalk.cyan(\" verdict > \"))\n }\n console.log(chalk.dim(\" verdict: \") + verdict)\n\n const entry: Entry = { q, answer: result.answer, citations: result.citations, verdict }\n\n const m = verdict.match(/^(\\/ok|\\/correct|\\/add|\\/link|\\/skip)(?:\\s+(.+))?$/i)\n if (!m) {\n console.log(chalk.yellow(\" (verdict not recognised — treating as /skip)\"))\n transcript.push(entry)\n continue\n }\n const action = m[1].toLowerCase()\n const note = (m[2] || \"\").trim()\n transcript.push(entry)\n\n if (action === \"/ok\" || action === \"/skip\") continue\n if (!note) {\n console.log(chalk.yellow(` ${action} without note — skipping.`))\n continue\n }\n\n const primary = result.citations[0]\n if (!primary) {\n console.log(chalk.yellow(\" no cited article to patch.\"))\n continue\n }\n\n const article = store.readArticle(primary.path)\n if (!article) {\n console.log(chalk.red(` can't read ${primary.path} to patch.`))\n continue\n }\n\n console.log(chalk.dim(` patching ${primary.title} (${primary.path})...`))\n const patchPrompt = buildQuizPatchPrompt(article.content, action, note, article.meta.title, article.meta.type)\n const tmpDir = resolve(store.baseDir, \"_tmp\")\n mkdirSync(tmpDir, { recursive: true })\n const promptPath = resolve(tmpDir, `quiz-patch-${randomUUID().slice(0, 8)}.txt`)\n writeFileSync(promptPath, patchPrompt)\n\n let patched = \"\"\n try {\n const cmd = `cat '${promptPath}' | claude -p - --output-format json --max-turns 1 --model ${opts.patchModel} --disallowedTools \"Bash Read Write Edit Glob Grep Agent WebSearch WebFetch NotebookEdit\"`\n const raw = execSync(cmd, { env: stripAnthropicApiKey({ ...process.env }), encoding: \"utf-8\", timeout: 120_000, maxBuffer: 4 * 1024 * 1024 })\n try {\n const envelope = JSON.parse(raw)\n patched = String(envelope.result || envelope.content || \"\")\n } catch { patched = raw }\n const fence = patched.trim().match(/```(?:markdown|md)?\\s*\\n([\\s\\S]*?)\\n```\\s*$/)\n if (fence) patched = fence[1].trim()\n patched = patched.trim()\n } catch (e: any) {\n console.log(chalk.red(` patch failed: ${e.message?.slice(0, 120)}`))\n continue\n }\n\n if (!patched || patched.length < 20) {\n console.log(chalk.yellow(\" patch returned nothing usable.\"))\n continue\n }\n\n const before = article.content.split(\"\\n\").length\n const after = patched.split(\"\\n\").length\n console.log(chalk.dim(` diff: ${before} → ${after} lines (${after - before >= 0 ? \"+\" : \"\"}${after - before})`))\n\n if (!commit) {\n console.log(chalk.dim(\" (--no-commit: patch not written)\"))\n entry.patched = primary.path + \" (dry)\"\n continue\n }\n\n const ok = store.writeArticle(primary.path, { ...article.meta, lastUpdated: new Date().toISOString().slice(0, 10) }, patched, opts.agent)\n if (!ok) {\n console.log(chalk.red(\" write failed (permission?)\"))\n continue\n }\n applied++\n entry.patched = primary.path\n console.log(chalk.green(` ✓ patched ${primary.path}`))\n }\n\n if (rl) rl.close()\n if (applied > 0 && commit) store.rebuildIndex()\n\n console.log()\n console.log(chalk.bold(` Session done: ${transcript.length} rounds, ${applied} patches applied.`))\n\n if (opts.out) {\n const lines: string[] = [\n `# Wiki Quiz — ${opts.agent}`,\n \"\",\n `_Generated ${new Date().toISOString()} · ${transcript.length} rounds · ${applied} patches_`,\n \"\",\n ]\n for (let i = 0; i < transcript.length; i++) {\n const e = transcript[i]\n lines.push(\n `## ${i + 1}. Q: ${e.q}`, \"\",\n `**A:** ${e.answer}`, \"\",\n `**Citations:** ${e.citations.map(c => `\\`${c.title}\\``).join(\", \") || \"_(none)_\"}`, \"\",\n `**Verdict:** \\`${e.verdict}\\`` + (e.patched ? ` → patched \\`${e.patched}\\`` : \"\"), \"\",\n )\n }\n writeFileSync(opts.out, lines.join(\"\\n\"))\n console.log(chalk.dim(` Transcript written to ${opts.out}`))\n }\n })\n\n// agentx wiki edit — direct $EDITOR on a known article.\n// Resolves <title-or-path> against the catalog, opens the file in\n// $EDITOR, rebuilds the catalog on exit. No LLM, no confirm step,\n// just the fastest path from \"I see a typo\" to \"it's fixed\".\nwiki\n .command(\"edit <agent> <titleOrPath>\")\n .description(\"open an article in $EDITOR (resolves by title or path), rebuild catalog on exit\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--editor <cmd>\", \"override $EDITOR for this run\")\n .action((agentId, titleOrPath, opts) => {\n const hub = getHub(opts.dir)\n let store\n try { store = hub.getAgentWiki(agentId) } catch (e: any) {\n console.log(chalk.red(` can't open wiki for agent \"${agentId}\": ${e.message}`))\n return\n }\n\n const relPath = resolveArticlePath(store, titleOrPath, agentId)\n if (!relPath) {\n console.log(chalk.yellow(` no article matches \"${titleOrPath}\" in ${agentId}'s wiki.`))\n console.log(chalk.dim(` Tip: ${chalk.green(\"agentx wiki status\")} lists agents; ${chalk.green(`agentx wiki search \"term\" --agent ${agentId}`)} finds by content.`))\n return\n }\n\n const absPath = resolve(store.baseDir, relPath)\n const editor = opts.editor || process.env.EDITOR || \"vi\"\n console.log(chalk.dim(` opening ${relPath} in ${editor}...`))\n try {\n execSync(`${editor} '${absPath}'`, { stdio: \"inherit\" })\n } catch (e: any) {\n console.log(chalk.red(` editor exited with error: ${e.message?.slice(0, 150)}`))\n return\n }\n\n // Sync `related` from body wikilinks if the user added/removed any.\n // Read back the article, compare wikilinks, rewrite frontmatter if drift.\n const after = store.readArticle(relPath)\n if (after) {\n const seenLinks = new Set<string>()\n const bodyLinks = store.extractWikilinks(after.content).filter((w: string) => {\n if (seenLinks.has(w)) return false\n seenLinks.add(w); return true\n })\n const currentRelated = after.meta.related || []\n const drift = bodyLinks.some(b => !currentRelated.includes(b)) ||\n currentRelated.some(r => !bodyLinks.includes(r))\n if (drift) {\n store.writeArticle(relPath, {\n ...after.meta,\n related: bodyLinks.length ? bodyLinks : undefined,\n lastUpdated: new Date().toISOString().slice(0, 10),\n }, after.content, agentId)\n console.log(chalk.dim(` (synced frontmatter.related from body: ${bodyLinks.length} wikilink${bodyLinks.length === 1 ? \"\" : \"s\"})`))\n }\n }\n\n // Rebuild catalog so related/title changes propagate\n try {\n store.rebuildIndex()\n console.log(chalk.green(` ✓ ${relPath} saved. Catalog rebuilt.`))\n } catch (e: any) {\n console.log(chalk.yellow(` saved, but catalog rebuild failed: ${e.message?.slice(0, 100)}`))\n }\n })\n\n// agentx wiki patch — LLM-driven minimal edit from a free-form\n// instruction. \"quiz without the question\" — when you already know\n// what's wrong and just want the patch applied without hunting for\n// the specific line to change.\nwiki\n .command(\"patch <agent> <titleOrPath> <instruction>\")\n .description(\"LLM-patch an article from a free-form instruction; shows diff + confirms before writing\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--patch-model <m>\", \"patch model\", \"sonnet\")\n .option(\"--yes\", \"skip confirmation and write immediately\")\n .option(\"--no-commit\", \"show the patched body but don't write\")\n .action(async (agentId, titleOrPath, instruction, opts) => {\n const readline = await import(\"node:readline/promises\")\n const { randomUUID } = await import(\"node:crypto\")\n const hub = getHub(opts.dir)\n let store\n try { store = hub.getAgentWiki(agentId) } catch (e: any) {\n console.log(chalk.red(` can't open wiki for agent \"${agentId}\": ${e.message}`))\n return\n }\n\n const relPath = resolveArticlePath(store, titleOrPath, agentId)\n if (!relPath) {\n console.log(chalk.yellow(` no article matches \"${titleOrPath}\" in ${agentId}'s wiki.`))\n return\n }\n const article = store.readArticle(relPath)\n if (!article) {\n console.log(chalk.red(` can't read ${relPath}.`))\n return\n }\n\n const prompt = buildWikiPatchPrompt(article.content, article.meta.title, article.meta.type, instruction)\n const tmpDir = resolve(store.baseDir, \"_tmp\")\n mkdirSync(tmpDir, { recursive: true })\n const promptPath = resolve(tmpDir, `patch-${randomUUID().slice(0, 8)}.txt`)\n writeFileSync(promptPath, prompt)\n\n console.log()\n console.log(chalk.dim(` Target: ${article.meta.title} (${relPath})`))\n console.log(chalk.dim(` Patching with ${opts.patchModel}...`))\n\n let patched = \"\"\n try {\n const cmd = `cat '${promptPath}' | claude -p - --output-format json --max-turns 1 --model ${opts.patchModel} --disallowedTools \"Bash Read Write Edit Glob Grep Agent WebSearch WebFetch NotebookEdit\"`\n const raw = execSync(cmd, { env: stripAnthropicApiKey({ ...process.env }), encoding: \"utf-8\", timeout: 120_000, maxBuffer: 4 * 1024 * 1024 })\n try {\n const envelope = JSON.parse(raw)\n patched = String(envelope.result || envelope.content || \"\")\n } catch { patched = raw }\n const fence = patched.trim().match(/```(?:markdown|md)?\\s*\\n([\\s\\S]*?)\\n```\\s*$/)\n if (fence) patched = fence[1].trim()\n patched = patched.trim()\n } catch (e: any) {\n console.log(chalk.red(` patch failed: ${e.message?.slice(0, 150)}`))\n return\n }\n\n if (!patched || patched.length < 20) {\n console.log(chalk.yellow(\" patch returned nothing usable.\"))\n return\n }\n\n const before = article.content.split(\"\\n\").length\n const after = patched.split(\"\\n\").length\n console.log()\n console.log(chalk.bold(\" === Patched preview ===\"))\n console.log(chalk.dim(` diff: ${before} → ${after} lines (${after - before >= 0 ? \"+\" : \"\"}${after - before})`))\n console.log()\n console.log(patched)\n console.log()\n\n if (!opts.commit) {\n console.log(chalk.dim(\" --no-commit: preview only, not written.\"))\n return\n }\n\n let go = !!opts.yes\n if (!go) {\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n const ans = (await rl.question(chalk.cyan(\" apply? [y/N] \"))).trim().toLowerCase()\n rl.close()\n go = ans === \"y\" || ans === \"yes\"\n }\n if (!go) {\n console.log(chalk.dim(\" aborted.\"))\n return\n }\n\n // Auto-sync `related` from body wikilinks — after an edit the body's\n // wikilinks are the source of truth, frontmatter.related should follow.\n // Dedupe preserving first-occurrence order.\n const seen = new Set<string>()\n const syncedRelated = store.extractWikilinks(patched).filter((w: string) => {\n if (seen.has(w)) return false\n seen.add(w); return true\n })\n const ok = store.writeArticle(relPath, {\n ...article.meta,\n related: syncedRelated.length ? syncedRelated : undefined,\n lastUpdated: new Date().toISOString().slice(0, 10),\n }, patched, agentId)\n if (!ok) {\n console.log(chalk.red(\" write failed (permission?)\"))\n return\n }\n store.rebuildIndex()\n const relDrift = (article.meta.related || []).filter(r => !syncedRelated.includes(r))\n if (relDrift.length) {\n console.log(chalk.dim(` (pruned stale related: ${relDrift.slice(0, 3).join(\", \")}${relDrift.length > 3 ? \", …\" : \"\"})`))\n }\n console.log(chalk.green(` ✓ ${relPath} patched.`))\n })\n\n/**\n * Resolve a user-provided \"title or path\" to a valid article path within\n * the given store. Matches by:\n * 1. Exact case-insensitive title\n * 2. If the arg looks like a path (has '/' or ends in '.md'), tries that\n * path against the store directly\n * 3. Slug-of-title match (case-insensitive)\n * Returns the relative path on success, null on no match.\n */\nfunction resolveArticlePath(store: any, titleOrPath: string, agentId: string): string | null {\n const arg = titleOrPath.trim()\n const articles = store.listArticles(agentId)\n\n // 1. Exact title match (case-insensitive)\n const lower = arg.toLowerCase()\n const byTitle = articles.find((a: any) => a.meta.title.toLowerCase() === lower)\n if (byTitle) return byTitle.path\n\n // 2. Path-like: try direct lookup\n if (arg.includes(\"/\") || arg.endsWith(\".md\")) {\n const normPath = arg.endsWith(\".md\") ? arg : `${arg}.md`\n const byPath = articles.find((a: any) => a.path === normPath || a.path === arg)\n if (byPath) return byPath.path\n }\n\n // 3. Slug match — both sides slugified, prefix or equality\n const argSlug = arg.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\")\n const bySlug = articles.find((a: any) => {\n const titleSlug = a.meta.title.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\")\n return titleSlug === argSlug || titleSlug.includes(argSlug) || a.path.toLowerCase().includes(argSlug)\n })\n if (bySlug) return bySlug.path\n\n return null\n}\n\nfunction buildWikiPatchPrompt(content: string, title: string, type: string | undefined, instruction: string): string {\n return [\n `You are editing a single wiki article to incorporate an operator instruction.`,\n ``,\n `## Article: \"${title}\" (type: ${type || \"untyped\"})`,\n ``,\n `<article-body>`,\n content,\n `</article-body>`,\n ``,\n `## Operator instruction`,\n instruction,\n ``,\n `## Rules`,\n `- Output ONLY the modified article body (content between the --- frontmatter markers).`,\n `- Do NOT output frontmatter (title, type, tags, etc.) — the serializer handles that.`,\n `- Do NOT wrap the output in code fences.`,\n `- Do NOT prepend any preamble like \"Here's the updated article:\".`,\n `- Preserve existing wikilinks, markdown formatting, and section structure unless the instruction requires changing them.`,\n `- Make the MINIMUM edit that satisfies the instruction — don't rewrite untouched sections.`,\n `- If the instruction is ambiguous or can't be applied, return the original body unchanged.`,\n ].join(\"\\n\")\n}\n\nfunction buildQuizPatchPrompt(content: string, action: string, note: string, title: string, type?: string): string {\n const instructions: Record<string, string> = {\n \"/correct\": `The operator says the article contains an error:\\n\\n ${note}\\n\\nEdit the article to correct ONLY this mistake. Do not rewrite untouched sections. Keep the existing prose style. If the correction invalidates a larger passage, revise the minimum that must change.`,\n \"/add\": `The operator wants to add this detail:\\n\\n ${note}\\n\\nIncorporate it into the most relevant existing section, or create a short new section if nothing fits. Keep the prose encyclopedic and under 100 additional words.`,\n \"/link\": `The operator wants to add this resource:\\n\\n ${note}\\n\\nAdd it as a Markdown link in the most relevant section, or append a \"## References\" section at the end if none exists. If it looks like a URL, use it as-is; otherwise treat it as a wikilink target and use [[${note}]].`,\n }\n\n return [\n `You are editing a single wiki article to incorporate operator feedback.`,\n ``,\n `## Article: \"${title}\" (type: ${type || \"untyped\"})`,\n ``,\n `<article-body>`,\n content,\n `</article-body>`,\n ``,\n `## Edit instruction`,\n instructions[action] || `Make a minimal edit per: ${note}`,\n ``,\n `## Rules`,\n `- Output ONLY the modified article body (content between the --- frontmatter markers).`,\n `- Do NOT output frontmatter (title, type, tags, etc.) — the serializer handles that.`,\n `- Do NOT wrap the output in code fences.`,\n `- Do NOT prepend any preamble like \"Here's the updated article:\".`,\n `- Preserve existing wikilinks, markdown formatting, and section structure unless the edit requires changing them.`,\n `- If no meaningful edit can be made from the operator's feedback, return the original body unchanged.`,\n ].join(\"\\n\")\n}\n\n// agentx wiki prune — Phase 3 cleanup before un-gating absorb.\n// Collapses legacy per-mode dirs (flat/, unified/) into canonical graph/.\n// Title-level dedup: for each title, the best copy wins (prefer typed,\n// then newer `last_updated`); losers are archived to `_versions/`.\nwiki\n .command(\"prune\")\n .description(\"collapse legacy flat/unified mode dirs into graph/ (dedup by title; losers archived)\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--agent <id>\", \"prune only this agent's wiki\")\n .option(\"--commit\", \"execute moves + archives (default: dry-run)\")\n .action(async (opts) => {\n const hub = getHub(opts.dir)\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n const commit = !!opts.commit\n const wikiRoot = opts.dir ? resolve(opts.dir) : resolve(process.cwd(), \".agentx/wiki\")\n const CANONICAL = \"graph\"\n const LEGACY_MODES = [\"flat\", \"unified\"]\n\n console.log()\n console.log(chalk.bold(commit ? \" Pruning (commit)\" : \" Pruning (dry-run)\"))\n console.log(chalk.dim(` Canonical: ${CANONICAL}/ · Legacy to collapse: ${LEGACY_MODES.join(\"/, \")}/`))\n\n let totalLegacy = 0\n let totalPromote = 0\n let totalUpgrade = 0\n let totalArchive = 0\n\n for (const agentId of agents) {\n const agentRoot = resolve(wikiRoot, \"agents\", agentId)\n if (!existsSync(agentRoot)) continue\n\n const canonicalDir = resolve(agentRoot, CANONICAL)\n const legacyEntries = LEGACY_MODES\n .map(m => ({ mode: m, dir: resolve(agentRoot, m) }))\n .filter(e => existsSync(e.dir))\n\n if (legacyEntries.length === 0) continue\n\n // Build a title → {relPath, type, lastUpdated} index of the canonical dir.\n const canonIdx = new Map<string, { relPath: string; type?: string; lastUpdated: string }>()\n walkMd(canonicalDir, (abs) => {\n const rel = relative(canonicalDir, abs)\n if (rel.startsWith(\"_\") || rel.startsWith(\"raw/\") || rel.includes(\"_tmp/\")) return\n const parsed = parseWikiFrontmatter(readFileSync(abs, \"utf-8\"))\n if (!parsed?.meta.title) return\n canonIdx.set(parsed.meta.title.trim().toLowerCase(), {\n relPath: rel,\n type: parsed.meta.type,\n lastUpdated: parsed.meta.lastUpdated || \"\",\n })\n })\n\n // Enumerate legacy articles.\n type Legacy = {\n mode: string\n relPath: string\n absPath: string\n title: string\n type?: string\n lastUpdated: string\n }\n const legacy: Legacy[] = []\n for (const e of legacyEntries) {\n walkMd(e.dir, (abs) => {\n const rel = relative(e.dir, abs)\n if (rel.startsWith(\"_\") || rel.startsWith(\"raw/\") || rel.includes(\"_tmp/\")) return\n const parsed = parseWikiFrontmatter(readFileSync(abs, \"utf-8\"))\n if (!parsed?.meta.title) return\n legacy.push({\n mode: e.mode,\n relPath: rel,\n absPath: abs,\n title: parsed.meta.title.trim(),\n type: parsed.meta.type,\n lastUpdated: parsed.meta.lastUpdated || \"\",\n })\n })\n }\n totalLegacy += legacy.length\n\n if (legacy.length === 0) continue\n\n console.log()\n const modeStr = legacyEntries.map(e => e.mode).join(\"+\")\n console.log(chalk.bold(` ${chalk.cyan(agentId)}: ${legacy.length} legacy article(s) across ${modeStr}`))\n\n for (const la of legacy) {\n const key = la.title.toLowerCase()\n const existing = canonIdx.get(key)\n\n // Decide: promote (new), upgrade (beat canonical), or archive (lose to canonical)\n let action: \"promote\" | \"upgrade\" | \"archive\"\n if (!existing) action = \"promote\"\n else if (!existing.type && la.type) action = \"upgrade\"\n else if (!!existing.type === !!la.type && la.lastUpdated && existing.lastUpdated &&\n la.lastUpdated > existing.lastUpdated) action = \"upgrade\"\n else action = \"archive\"\n\n const typeTag = la.type ? chalk.magenta(`[${la.type}]`) : chalk.yellow(\"[untyped]\")\n const arrow = action === \"promote\" ? chalk.green(\"→ promote \")\n : action === \"upgrade\" ? chalk.cyan(\"⟳ upgrade \")\n : chalk.dim(\"✗ archive \")\n const where = la.relPath.length > 46 ? la.relPath.slice(0, 43) + \"...\" : la.relPath.padEnd(46)\n console.log(` ${arrow} ${typeTag} ${chalk.dim(la.mode + \"/\")}${where}`)\n if (action === \"upgrade\") console.log(chalk.dim(` (replaces ${existing!.relPath}, old version kept under _versions/)`))\n\n if (!commit) {\n if (action === \"promote\") totalPromote++\n else if (action === \"upgrade\") totalUpgrade++\n else totalArchive++\n continue\n }\n\n try {\n if (action === \"promote\") {\n const target = resolve(canonicalDir, la.relPath)\n if (existsSync(target)) {\n console.log(chalk.yellow(` ! target path already exists, archiving instead: ${la.relPath}`))\n archiveLegacy(agentRoot, la)\n totalArchive++\n } else {\n mkdirSync(dirname(target), { recursive: true })\n renameSync(la.absPath, target)\n canonIdx.set(key, { relPath: la.relPath, type: la.type, lastUpdated: la.lastUpdated })\n totalPromote++\n }\n } else if (action === \"upgrade\") {\n const target = resolve(canonicalDir, existing!.relPath)\n if (existsSync(target)) {\n const verDir = resolve(agentRoot, \"_versions\", existing!.relPath.replace(/\\.md$/, \"\"))\n mkdirSync(verDir, { recursive: true })\n const ts = new Date().toISOString().replace(/[:.]/g, \"-\")\n renameSync(target, resolve(verDir, `${ts}.md`))\n }\n mkdirSync(dirname(target), { recursive: true })\n renameSync(la.absPath, target)\n canonIdx.set(key, { relPath: existing!.relPath, type: la.type, lastUpdated: la.lastUpdated })\n totalUpgrade++\n } else {\n archiveLegacy(agentRoot, la)\n totalArchive++\n }\n } catch (e: any) {\n console.log(chalk.red(` ! ${action} failed: ${e.message?.slice(0, 120)}`))\n }\n }\n\n if (commit) {\n // Delete the now-empty legacy mode dirs (they will also contain obsolete\n // _index.md, _schema.md, log.md etc.; rmSync -f nukes the whole subtree).\n for (const e of legacyEntries) {\n try { rmSync(e.dir, { recursive: true, force: true }) } catch {}\n }\n // Rebuild the canonical catalog so _index.md reflects the merged corpus.\n try {\n hub.getAgentWiki(agentId).rebuildIndex()\n } catch (e: any) {\n console.log(chalk.dim(` (catalog rebuild skipped: ${e.message?.slice(0, 80)})`))\n }\n }\n }\n\n console.log()\n console.log(chalk.dim(` Legacy scanned: ${totalLegacy}`))\n if (commit) {\n console.log(chalk.green(` Promoted: ${totalPromote} · Upgraded canonical: ${totalUpgrade} · Archived: ${totalArchive}`))\n console.log(chalk.dim(\" Archived losers preserved under <agent>/_versions/. Legacy mode dirs deleted.\"))\n } else {\n console.log(chalk.dim(` Would: promote ${totalPromote} · upgrade ${totalUpgrade} · archive ${totalArchive}`))\n console.log(chalk.dim(\" Dry-run — add --commit to execute\"))\n }\n console.log()\n })\n\nfunction walkMd(dir: string, cb: (absPath: string) => void): void {\n if (!existsSync(dir)) return\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const abs = resolve(dir, entry.name)\n if (entry.isDirectory()) walkMd(abs, cb)\n else if (entry.isFile() && entry.name.endsWith(\".md\")) cb(abs)\n }\n}\n\nfunction parseWikiFrontmatter(raw: string): { meta: Record<string, any> } | null {\n const fm = raw.match(/^---\\n([\\s\\S]*?)\\n---/)\n if (!fm) return null\n const meta: Record<string, any> = {}\n for (const line of fm[1].split(\"\\n\")) {\n const m = line.match(/^(\\w+):\\s*(.+)$/)\n if (!m) continue\n const key = m[1] === \"last_updated\" ? \"lastUpdated\" : m[1]\n meta[key] = m[2].trim().replace(/^\"(.*)\"$/, \"$1\")\n }\n return { meta }\n}\n\nfunction archiveLegacy(\n agentRoot: string,\n la: { mode: string; relPath: string; absPath: string },\n): void {\n const verDir = resolve(agentRoot, \"_versions\", `legacy-${la.mode}`, la.relPath.replace(/\\.md$/, \"\"))\n mkdirSync(verDir, { recursive: true })\n const ts = new Date().toISOString().replace(/[:.]/g, \"-\")\n renameSync(la.absPath, resolve(verDir, `${ts}.md`))\n}\n\n// agentx wiki migrate — Phase 2 of the Karpathy-alignment plan.\n// Backfills `type` + `related` on legacy articles so Phase 3's agentic\n// query has a corpus with a usable `_index.md` + wikilink graph.\nwiki\n .command(\"migrate\")\n .description(\"backfill type + related on legacy articles (one-shot)\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--agent <id>\", \"migrate only this agent's articles\")\n .option(\"--commit\", \"write changes (default: dry-run, reports what would change)\")\n .option(\"--batch <n>\", \"articles per LLM call\", \"10\")\n .option(\"--max <n>\", \"cap articles this run (for spot-checks)\")\n .option(\"--model <m>\", \"classifier model\", \"sonnet\")\n .action(async (opts) => {\n const hub = getHub(opts.dir)\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n const batchSize = Math.max(1, parseInt(opts.batch) || 10)\n const maxArticles = opts.max ? parseInt(opts.max) : Infinity\n const commit = !!opts.commit\n\n console.log()\n console.log(chalk.bold(commit ? \" Migrating (commit)\" : \" Migrating (dry-run)\"))\n console.log(chalk.dim(` Batch size: ${batchSize} · Model: ${opts.model}`))\n console.log()\n\n let totalScanned = 0\n let totalNeeds = 0\n let totalApplied = 0\n\n for (const agentId of agents) {\n const agentWiki = hub.getAgentWiki(agentId)\n const articles = agentWiki.listArticles(agentId)\n const needs = articles.filter(a => !a.meta.type)\n totalScanned += articles.length\n totalNeeds += needs.length\n\n if (needs.length === 0) {\n console.log(` ${chalk.cyan(agentId)}: ${chalk.green(\"all typed\")} (${articles.length} articles)`)\n continue\n }\n\n const remaining = Math.max(0, maxArticles - totalApplied)\n const limit = Math.min(needs.length, remaining)\n if (limit === 0) {\n console.log(chalk.dim(` ${agentId}: skipped (--max reached)`))\n continue\n }\n\n console.log()\n console.log(chalk.bold(` ${chalk.cyan(agentId)}: ${limit}/${needs.length} untyped articles`))\n\n const baseDir = agentWiki[\"baseDir\"]\n const tmpDir = resolve(baseDir, \"_tmp\")\n mkdirSync(tmpDir, { recursive: true })\n\n for (let i = 0; i < limit; i += batchSize) {\n const batch = needs.slice(i, Math.min(i + batchSize, limit))\n const prompt = buildMigratePrompt(batch)\n const promptPath = resolve(tmpDir, \"migrate-prompt.txt\")\n writeFileSync(promptPath, prompt)\n\n let classifications: Array<{ path: string; type: string }>\n try {\n const cmd = `cat '${promptPath}' | claude -p - --output-format json --max-turns 1 --model ${opts.model} --disallowedTools \"Bash Read Write Edit Glob Grep Agent WebSearch WebFetch NotebookEdit\"`\n const rawOutput = execSync(cmd, { env: stripAnthropicApiKey({ ...process.env }), encoding: \"utf-8\", timeout: 120_000, maxBuffer: 4 * 1024 * 1024 })\n const envelope = JSON.parse(rawOutput)\n const responseText = String(envelope.result || envelope.content || \"\")\n const arrMatch = responseText.match(/\\[[\\s\\S]*\\]/)\n if (!arrMatch) throw new Error(\"no JSON array in classifier response\")\n classifications = JSON.parse(arrMatch[0])\n } catch (e: any) {\n console.log(chalk.red(` LLM classify failed: ${e.message?.slice(0, 150)}`))\n continue\n }\n\n for (const article of batch) {\n const c = classifications.find((x) => x.path === article.path)\n const norm = normalizeWikiType(c?.type)\n if (!c || !norm) {\n console.log(chalk.yellow(` ? ${article.path}: unclassified${c ? ` (got \"${c.type}\")` : \"\"}`))\n continue\n }\n const related = agentWiki.extractWikilinks(article.content)\n const newMeta = {\n ...article.meta,\n type: norm.type as any,\n related: related.length ? related : undefined,\n lastUpdated: new Date().toISOString().slice(0, 10),\n }\n const relStr = related.length ? chalk.dim(` → ${related.slice(0, 3).join(\", \")}${related.length > 3 ? \", …\" : \"\"}`) : \"\"\n const aliasNote = norm.alias ? chalk.dim(` (from \"${norm.alias}\")`) : \"\"\n console.log(` ${chalk.green(\"+\")} ${chalk.magenta(\"[\" + norm.type + \"]\")}${aliasNote} ${article.path}${relStr}`)\n\n if (commit) {\n agentWiki.writeArticle(article.path, newMeta, article.content, agentId)\n totalApplied++\n }\n }\n }\n\n if (commit) agentWiki.rebuildIndex()\n }\n\n console.log()\n console.log(chalk.dim(` Scanned ${totalScanned} articles; ${totalNeeds} needed migration`))\n if (commit) {\n console.log(chalk.green(` Applied ${totalApplied} patches.`))\n } else {\n console.log(chalk.dim(\" Dry-run — add --commit to write changes.\"))\n }\n console.log()\n })\n\n/**\n * Map the classifier's output to the 7-type enum. The LLM often volunteers\n * domain-specific types (issue, MR, runbook, agent…). Rather than reject\n * and re-run, map them to the nearest valid enum value. Caller gets back\n * {type, alias?} — alias is the raw LLM output when it wasn't an exact\n * match, for logging.\n */\nfunction normalizeWikiType(raw: string | undefined): { type: string; alias?: string } | null {\n if (!raw) return null\n const key = String(raw).trim().toLowerCase().replace(/^[\\s\"'`]+|[\\s\"'`]+$/g, \"\")\n if (!key) return null\n const ALIASES: Record<string, string> = {\n // Exact enum values\n person: \"person\", project: \"project\", place: \"place\", concept: \"concept\",\n event: \"event\", decision: \"decision\", pattern: \"pattern\",\n // Plurals\n people: \"person\", projects: \"project\", places: \"place\", concepts: \"concept\",\n events: \"event\", decisions: \"decision\", patterns: \"pattern\",\n // Domain variants → enum equivalents\n agent: \"project\", bot: \"project\", service: \"project\", product: \"project\",\n tool: \"project\", repo: \"project\", repository: \"project\", app: \"project\",\n application: \"project\", team: \"project\", organization: \"project\", company: \"project\",\n issue: \"event\", mr: \"event\", \"merge-request\": \"event\", \"merge_request\": \"event\",\n ticket: \"event\", incident: \"event\", deploy: \"event\", deployment: \"event\",\n launch: \"event\", release: \"event\",\n process: \"pattern\", procedure: \"pattern\", workflow: \"pattern\",\n runbook: \"pattern\", recipe: \"pattern\", template: \"pattern\", sop: \"pattern\",\n infrastructure: \"place\", infra: \"place\", server: \"place\", environment: \"place\",\n env: \"place\", location: \"place\", host: \"place\",\n decisionrecord: \"decision\", adr: \"decision\", \"decision-record\": \"decision\",\n }\n const mapped = ALIASES[key]\n if (!mapped) return null\n return mapped === key ? { type: mapped } : { type: mapped, alias: key }\n}\n\nfunction buildMigratePrompt(articles: Array<{ path: string; meta: { title: string; tags?: string[] }; content: string }>): string {\n const items = articles.map((a, i) => {\n const body = a.content.replace(/\\s+/g, \" \").slice(0, 400)\n const tags = (a.meta.tags || []).slice(0, 8).join(\", \")\n return `${i + 1}. path: \"${a.path}\"\\n title: \"${a.meta.title}\"\\n tags: [${tags}]\\n body: ${body}${a.content.length > 400 ? \"…\" : \"\"}`\n }).join(\"\\n\\n\")\n\n return `Classify each of these ${articles.length} wiki articles into EXACTLY ONE type from this closed set (no synonyms, no plurals, no new values):\n\n person | project | place | concept | event | decision | pattern\n\nWhat each type means:\n- person: an individual human (team member, stakeholder, contact)\n- project: a named initiative, repo, product, service, bot, agent, team, or org\n- place: a physical or logical location (office, server, environment, infrastructure)\n- concept: a recurring idea, philosophy, methodology, or thinking pattern\n- event: a specific dated thing that happened (incident, deploy, launch, GitLab issue, MR)\n- decision: a specific choice made and why (architecture decision, policy, ADR)\n- pattern: a reusable workflow, template, recipe, procedure, runbook, or SOP\n\nExplicit mappings (you WILL be tempted to volunteer these — don't; use the right-hand value):\n- \"agent\" / \"bot\" / \"service\" / \"repo\" / \"team\" → project\n- \"issue\" / \"MR\" / \"ticket\" / \"incident\" / \"deploy\" → event\n- \"process\" / \"procedure\" / \"runbook\" / \"workflow\" → pattern\n- \"infrastructure\" / \"server\" / \"environment\" → place\n- \"ADR\" / \"decision record\" → decision\n\nRules:\n- Return EXACTLY one type per article, by path, from the 7 allowed values above.\n- Do not invent new types. Do not return plurals. Do not return synonyms.\n- If the title is a person's name, it's person. If it's a repo/product/bot name, it's project. If it's dated + past tense, it's event.\n- If you genuinely cannot decide, pick \"concept\" as the fallback.\n- Output ONLY valid JSON, no markdown fencing, no prose.\n\nArticles:\n\n${items}\n\nOutput (JSON array, one entry per input article, same order):\n[\n {\"path\": \"path/to/article.md\", \"type\": \"project\"},\n ...\n]`\n}\n\n// agentx wiki entries\nwiki\n .command(\"entries\")\n .description(\"list raw entries\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--agent <id>\", \"filter by agent\")\n .action((opts) => {\n const hub = getHub(opts.dir)\n const shared = hub.getSharedStore()\n let entries = shared.listEntries()\n\n if (opts.agent) {\n entries = entries.filter(e => e.agentId === opts.agent)\n }\n\n console.log()\n console.log(chalk.bold(` ${entries.length} raw entries`))\n console.log()\n\n for (const e of entries.slice(-20)) {\n console.log(` ${chalk.dim(e.date)} ${chalk.cyan(e.agentId)} via ${e.source}: ${e.content.slice(0, 80)}...`)\n }\n\n if (entries.length > 20) {\n console.log(chalk.dim(` ... showing last 20 of ${entries.length}`))\n }\n console.log()\n })\n\n// agentx wiki serve\nwiki\n .command(\"serve\")\n .description(\"start a local web server to browse agent wikis (local + mesh)\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--mode <mode>\", \"graph (default, canonical) | unified | flat (legacy, back-compat)\", \"graph\")\n .option(\"--agent <id>\", \"serve only this agent's wiki\")\n .option(\"--port <n>\", \"port number\", \"4200\")\n .option(\"--peer <urls...>\", \"mesh peer URLs to federate\")\n .action(async (opts) => {\n const dir = opts.dir || resolve(process.cwd(), \".agentx/wiki\")\n const port = parseInt(opts.port)\n\n // Auto-discover peers from daemon config if not specified\n let peerUrls: string[] = opts.peer || []\n if (peerUrls.length === 0) {\n try {\n const { loadDaemonConfig } = await import(\"@/daemon/config\")\n const config = loadDaemonConfig()\n peerUrls = (config.mesh?.peers || []).map((p: any) => p.url)\n } catch { /* no config */ }\n }\n\n console.log()\n console.log(chalk.bold(\" AgentX Wiki Server\"))\n console.log()\n console.log(` ${chalk.green(\">\")} http://localhost:${port}`)\n if (opts.agent) {\n console.log(` Agent: ${chalk.cyan(opts.agent)}`)\n } else {\n console.log(` Mode: ${chalk.cyan(\"Hub\")} (all agents)`)\n }\n if (peerUrls.length > 0) {\n console.log(` Mesh: ${chalk.cyan(peerUrls.length + \" peer(s)\")} — ${peerUrls.join(\", \")}`)\n }\n console.log(chalk.dim(` Wiki: ${dir}`))\n console.log(chalk.dim(\" Press Ctrl+C to stop\"))\n console.log()\n\n startWikiServer(dir, port, opts.agent, peerUrls, opts.mode as WikiMode)\n })\n\n// agentx wiki query <question> — Phase 3 agentic query.\n// Walks _index.md → picks candidate articles → walks `related` wikilinks\n// → synthesizes an answer with citations. This is the Farzapedia-faithful\n// retrieval path; `wiki search` stays as the raw BM25 escape hatch.\nwiki\n .command(\"grade\")\n .description(\"grade absorbed articles with the article-quality seat\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--mode <mode>\", \"graph | unified | flat\", \"graph\")\n .option(\"--agent <id>\", \"grade only this agent's wiki\")\n .option(\"--limit <n>\", \"articles to grade\", \"20\")\n .option(\"--min <n>\", \"only show articles scoring below this\", \"3\")\n .option(\"--fields\", \"also check the required fields for each article's type\")\n .option(\"--type <t>\", \"grade only articles of this type (person, place, project, …)\")\n .option(\"--json\")\n .action(async (opts) => {\n const { articleQualityQuestionsFor, articleQualityState, gradeArticle, ARTICLE_QUALITY_SEAT } =\n await import(\"@/decisions/seats/article-quality\")\n const { fieldQuestions, reportFields } = await import(\"@/decisions/seats/article-fields\")\n const { askSeat } = await import(\"@/decisions/seat\")\n const hub = getHub(opts.dir, opts.mode as WikiMode)\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n const limit = parseInt(opts.limit)\n const min = parseFloat(opts.min)\n\n const rows: any[] = []\n outer: for (const agentId of agents) {\n const store = hub.getAgentWiki(agentId)\n for (const meta of store.listArticles(agentId)) {\n if (rows.length >= limit) break outer\n const article = store.readArticle(meta.path)\n if (!article) continue\n if (opts.type && article.meta.type !== opts.type) continue\n // One state, every question. The rubric and the per-type field\n // checklist ride in the same call — a Jev fan-out costs the same\n // whether it answers four questions or seventeen.\n const questions = {\n ...articleQualityQuestionsFor(article.meta.type),\n ...(opts.fields ? fieldQuestions(article.meta.type) : {}),\n }\n const res = await askSeat(\n ARTICLE_QUALITY_SEAT,\n articleQualityState({\n path: meta.path, title: article.meta.title,\n type: article.meta.type, tags: article.meta.tags, body: article.content,\n }),\n questions,\n { links: [{ kind: \"article\", id: meta.path }], features: { agent: agentId, type: article.meta.type ?? \"?\" } },\n )\n if (!res) {\n console.log(chalk.yellow(\" seat is off or unavailable — set decisions.seats.article-quality.mode\"))\n return\n }\n const v = gradeArticle(res.answers as never)\n const fr = opts.fields ? reportFields(article.meta.type, res.answers as never) : null\n // A missing critical field is a finding regardless of the score:\n // an article can read well, score 2.8, and still lack the one\n // fact it exists to carry.\n if (v.completeness >= min && !(fr && !fr.fit)) continue\n rows.push({\n agent: agentId, type: article.meta.type ?? \"?\",\n score: v.completeness.toFixed(2),\n standsAlone: v.standsAlone.toFixed(2),\n gap: v.biggestGap,\n ...(fr ? { missing: fr.missingCritical.join(\",\") || \"-\", cov: `${Math.round(fr.coverage * 100)}%` } : {}),\n title: article.meta.title.slice(0, 44),\n })\n }\n }\n if (opts.json) { console.log(JSON.stringify(rows, null, 2)); return }\n if (rows.length === 0) { console.log(chalk.green(\" no articles below the threshold\")); return }\n rows.sort((a, b) => parseFloat(a.score) - parseFloat(b.score))\n const cols = opts.fields\n ? [\"score\", \"cov\", \"missing\", \"type\", \"gap\", \"agent\", \"title\"]\n : [\"score\", \"standsAlone\", \"type\", \"gap\", \"agent\", \"title\"]\n const w = cols.map((c) => Math.max(c.length, ...rows.map((r) => String(r[c]).length)))\n const fmt = (cells: any[]) => cells.map((v, i) => String(v).padEnd(w[i])).join(\" \")\n console.log()\n console.log(chalk.bold(fmt(cols)))\n for (const r of rows) console.log(fmt(cols.map((c) => r[c])))\n if (opts.fields) {\n const unfit = rows.filter((r) => r.missing !== \"-\").length\n console.log(chalk.dim(`\\n ${rows.length} article(s) flagged; ${unfit} missing a required field.`))\n console.log(chalk.dim(\" 'missing' is the actionable column — a named field beats a score.\"))\n } else {\n console.log(chalk.dim(`\\n ${rows.length} article(s) below ${min}. standsAlone is the one that matters:`))\n console.log(chalk.dim(\" an article can open with a tidy identity line and still send the reader back to the source.\"))\n }\n })\n\nwiki\n .command(\"query <question>\")\n .description(\"agentic wiki query — walks the catalog + wikilink graph, synthesizes an answer\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--agent <id>\", \"which agent's wiki to query (default: first one with a catalog)\")\n .option(\"--selector-model <m>\", \"candidate-selection model\", \"haiku\")\n .option(\"--synth-model <m>\", \"synthesis model\", \"sonnet\")\n .option(\"--max-candidates <n>\", \"candidates from selector\", \"3\")\n .option(\"--max-hops <n>\", \"wikilink hops from candidates\", \"2\")\n .option(\"--max-articles <n>\", \"cap on total articles walked\", \"8\")\n .option(\"--json\", \"emit full result as JSON (for A/B harnesses)\")\n .option(\"--trace\", \"print selector + walk trace\")\n .action(async (question, opts) => {\n const { agenticQuery } = await import(\"@/wiki/query\")\n const hub = getHub(opts.dir)\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n\n // Find the first agent that actually has a catalog.\n let chosen: string | null = null\n for (const id of agents) {\n const s = hub.getAgentWiki(id)\n const cat = resolve(s.baseDir, \"_index.md\")\n try {\n if ((await import(\"fs\")).existsSync(cat)) { chosen = id; break }\n } catch {}\n }\n if (!chosen) {\n console.log(chalk.yellow(\" No agent has a catalog yet. Run `agentx wiki status` or migrate first.\"))\n return\n }\n\n const store = hub.getAgentWiki(chosen)\n const result = await agenticQuery(question, store, chosen, {\n selectorModel: opts.selectorModel,\n synthModel: opts.synthModel,\n maxCandidates: parseInt(opts.maxCandidates),\n maxHops: parseInt(opts.maxHops),\n maxArticles: parseInt(opts.maxArticles),\n })\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2))\n return\n }\n\n console.log()\n console.log(chalk.bold(` Q: ${question}`))\n console.log(chalk.dim(` agent: ${chosen} · status: ${result.status} · walked: ${result.walked.length}`))\n console.log()\n\n if (result.status !== \"ok\") {\n console.log(chalk.yellow(` (no answer) ${result.error || result.status}`))\n return\n }\n\n console.log(result.answer)\n console.log()\n if (result.citations.length) {\n console.log(chalk.dim(\" Citations:\"))\n for (const c of result.citations) {\n const type = c.type ? chalk.magenta(` [${c.type}]`) : \"\"\n console.log(chalk.dim(` - ${c.title}${type} (${c.path})`))\n }\n console.log()\n }\n\n if (opts.trace && result.trace) {\n console.log(chalk.dim(` selector: ${result.trace.selectorMs}ms synthesis: ${result.trace.synthesisMs}ms`))\n console.log(chalk.dim(` candidates: ${result.candidates.map(c => c.title).join(\" | \") || \"(none)\"}`))\n if (result.walked.length > result.candidates.length) {\n const follow = result.walked.filter(w => !result.candidates.some(c => c.path === w.path))\n console.log(chalk.dim(` followed: ${follow.map(w => `${w.title}@h${w.hop}`).join(\" | \")}`))\n }\n console.log()\n }\n })\n\n// agentx wiki search <query>\nwiki\n .command(\"search <query>\")\n .description(\"search wiki articles\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--mode <mode>\", \"graph (default, canonical) | unified | flat (legacy, back-compat)\", \"graph\")\n .option(\"--agent <id>\", \"search specific agent's wiki\")\n .action(async (query, opts) => {\n const hub = getHub(opts.dir, opts.mode as WikiMode)\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n\n console.log()\n let found = 0\n\n for (const agentId of agents) {\n const store = hub.getAgentWiki(agentId)\n const results = await store.findRelevantReranked(query, undefined, 10)\n\n if (results.length > 0) {\n console.log(chalk.bold(` ${chalk.cyan(agentId)}:`))\n for (const r of results) {\n console.log(` ${r.meta.title} [${(r.meta.tags || []).slice(0, 3).join(\", \")}]`)\n console.log(chalk.dim(` ${r.path} — ${r.content.slice(0, 100)}...`))\n }\n found += results.length\n }\n }\n\n if (found === 0) console.log(chalk.dim(\" No matching articles\"))\n console.log()\n })\n\n// agentx wiki backfill-graphpath — populate graphPath on existing articles\n//\n// Reads each article's `sources[]`, looks the source entries up by id, computes\n// the graph fingerprint from each entry's (content, channel, sender), and if\n// the cache hits, picks the most-common path among the article's sources and\n// writes it as `graph_path:` in frontmatter. Without this, the wiki retrieval\n// score function multiplies the graph weight (0.6 by default) by 0 for every\n// pre-existing article — the graph half of the hybrid score is dead weight.\nwiki\n .command(\"backfill-graphpath\")\n .description(\"populate graphPath on existing articles by looking up source-entry classifications\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--agent <id>\", \"backfill only this agent\")\n .option(\"--dry-run\", \"preview without writing\", false)\n .action((opts) => {\n const hub = getHub(opts.dir)\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n\n const baseDir = resolve(process.cwd(), \".agentx/graph\")\n if (!existsSync(baseDir)) {\n console.log(chalk.red(` No graph store at ${baseDir} — nothing to backfill against.`))\n return\n }\n const graphStore = new GraphStore({ baseDir })\n const idx = graphStore.loadIndex()\n const fpToPath = new Map<string, string[]>()\n for (const [fp, e] of Object.entries(idx.entries)) {\n fpToPath.set(fp, (e as any).path)\n }\n if (fpToPath.size === 0) {\n console.log(chalk.yellow(` Graph index is empty — nothing to look up.`))\n return\n }\n console.log(chalk.dim(` Loaded ${fpToPath.size} fingerprint -> path entries from .agentx/graph/index.json`))\n\n let totalArticles = 0\n let totalEligible = 0 // articles with empty graphPath that COULD be looked up\n let totalMatched = 0 // articles where at least one source matched\n let totalWritten = 0\n\n for (const agentId of agents) {\n const store = hub.getAgentWiki(agentId)\n const articles = store.listArticles(agentId)\n const sharedEntries = hub.getSharedStore().listEntries()\n const entriesById = new Map(sharedEntries.map((e) => [e.id, e]))\n\n let agentEligible = 0\n let agentMatched = 0\n let agentWritten = 0\n\n for (const article of articles) {\n totalArticles++\n if (article.meta.graphPath?.length) continue\n if (!article.meta.sources?.length) continue\n agentEligible++\n totalEligible++\n\n const counts = new Map<string, { path: string[]; n: number }>()\n for (const sid of article.meta.sources) {\n const entry = entriesById.get(sid)\n if (!entry) continue\n const sender = String((entry.meta as any)?.sender ?? \"\")\n const fp = graphStore.fingerprint({\n text: entry.content,\n channel: entry.source,\n sender,\n })\n const path = fpToPath.get(fp)\n if (!path?.length) continue\n const key = path.join(\"/\")\n const cur = counts.get(key)\n if (cur) cur.n++\n else counts.set(key, { path, n: 1 })\n }\n if (counts.size === 0) continue\n agentMatched++\n totalMatched++\n\n let best: { path: string[]; n: number } | undefined\n for (const v of counts.values()) if (!best || v.n > best.n) best = v\n if (!best) continue\n\n if (opts.dryRun) {\n continue\n }\n // Write through writeArticle so frontmatter renders consistently.\n store.writeArticle(article.path, {\n ...article.meta,\n graphPath: best.path,\n }, article.content, agentId)\n agentWritten++\n totalWritten++\n }\n\n console.log(` ${chalk.cyan(agentId)}: ${chalk.bold(articles.length)} articles · ${agentEligible} eligible · ${agentMatched} matched · ${chalk.green(agentWritten)} written`)\n }\n\n console.log()\n console.log(chalk.bold(` Total: ${totalArticles} articles, ${totalEligible} missing graphPath, ${totalMatched} matched (${Math.round((totalMatched / Math.max(1, totalEligible)) * 100)}%), ${totalWritten} written`))\n if (opts.dryRun) console.log(chalk.dim(` Dry-run — re-run without --dry-run to commit.`))\n console.log()\n })\n\n// agentx wiki sync — pull entries from mesh peers\nwiki\n .command(\"sync\")\n .description(\"pull raw entries from mesh peers into local wiki\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--peer <url>\", \"sync from a specific peer URL (e.g., http://100.64.0.11:19900)\")\n .option(\"--dry-run\", \"show what would be synced without writing\")\n .action(async (opts) => {\n const hub = getHub(opts.dir)\n const shared = hub.getSharedStore()\n\n // Discover peers: from --peer flag, or from local daemon config\n let peerUrls: string[] = []\n\n if (opts.peer) {\n peerUrls = [opts.peer]\n } else {\n // Try to read mesh peers from local daemon\n try {\n const { loadDaemonConfig } = await import(\"@/daemon/config\")\n const config = loadDaemonConfig()\n peerUrls = (config.mesh?.peers || []).map((p: any) => p.url)\n } catch {\n console.log(chalk.red(\" No --peer specified and no daemon config found\"))\n console.log(chalk.dim(\" Usage: agentx wiki sync --peer http://100.64.0.11:19900\"))\n return\n }\n }\n\n if (peerUrls.length === 0) {\n console.log(chalk.dim(\" No mesh peers configured\"))\n return\n }\n\n // Get existing entry IDs to avoid duplicates\n const existingIds = new Set(shared.listEntries().map(e => e.id))\n\n let totalSynced = 0\n\n for (const peerUrl of peerUrls) {\n console.log()\n console.log(chalk.bold(` Syncing from ${peerUrl}...`))\n\n try {\n // Fetch entries from peer\n const res = await fetch(`${peerUrl}/wiki/entries`, { signal: AbortSignal.timeout(120000) })\n if (!res.ok) {\n console.log(chalk.red(` HTTP ${res.status}`))\n continue\n }\n\n const data = await res.json() as any\n const entries = data.entries || []\n const nodeId = data.nodeId || \"unknown\"\n\n console.log(chalk.dim(` Node: ${nodeId} — ${entries.length} entries`))\n\n let newCount = 0\n for (const entry of entries) {\n if (existingIds.has(entry.id)) continue\n\n if (!opts.dryRun) {\n shared.addEntry({\n id: entry.id,\n date: entry.date,\n agentId: entry.agentId,\n source: `${entry.source}@${nodeId}`, // Tag source with node\n sourceContext: entry.sourceContext,\n content: entry.content,\n })\n existingIds.add(entry.id)\n }\n newCount++\n }\n\n if (newCount > 0) {\n console.log(chalk.green(` ${newCount} new entries${opts.dryRun ? \" (dry run)\" : \" synced\"}`))\n } else {\n console.log(chalk.dim(\" Already up to date\"))\n }\n\n totalSynced += newCount\n\n // Also show remote agents summary\n try {\n const agentsRes = await fetch(`${peerUrl}/wiki/agents`, { signal: AbortSignal.timeout(5000) })\n if (agentsRes.ok) {\n const agentsData = await agentsRes.json() as any\n for (const agent of (agentsData.agents || [])) {\n if (agent.totalEntries > 0) {\n console.log(chalk.dim(` ${agent.agentId}: ${agent.totalEntries} entries, ${agent.totalArticles} articles`))\n }\n }\n }\n } catch { /* optional */ }\n\n } catch (e: any) {\n if (e.cause?.code === \"ECONNREFUSED\") {\n console.log(chalk.red(` Connection refused`))\n } else {\n console.log(chalk.red(` ${e.message}`))\n }\n }\n }\n\n console.log()\n if (totalSynced > 0 && !opts.dryRun) {\n console.log(chalk.green(` ${totalSynced} entries synced.`))\n } else if (totalSynced > 0) {\n console.log(chalk.dim(` ${totalSynced} entries would be synced (dry run)`))\n } else {\n console.log(chalk.dim(\" All peers up to date\"))\n }\n console.log()\n })\n\n// agentx wiki compare — deterministic comparison of all three modes\nwiki\n .command(\"compare\")\n .description(\"compare all wiki compilation modes for an agent\")\n .option(\"--dir <path>\", \"wiki directory\")\n .requiredOption(\"--agent <id>\", \"agent to compare\")\n .action((opts) => {\n const dir = opts.dir || resolve(process.cwd(), \".agentx/wiki\")\n const agentId = opts.agent\n const modes: WikiMode[] = [\"flat\", \"graph\", \"unified\"]\n\n // Collect stats per mode\n const stats = modes.map(mode => {\n const hub = new WikiHub(dir, undefined, mode)\n const wiki = hub.getAgentWiki(agentId)\n const index = wiki.rebuildIndex()\n const entries = hub.getAgentEntries(agentId)\n const unabsorbed = hub.getUnabsorbedEntries(agentId)\n\n const tags = new Set<string>()\n let totalTags = 0\n const sources = new Set<string>()\n for (const a of index.articles) {\n for (const t of (a.tags || [])) tags.add(t)\n totalTags += (a.tags?.length || 0)\n for (const s of (a.sources || [])) sources.add(s)\n }\n const dirs = new Set(index.articles.map(a => a.path.includes(\"/\") ? a.path.split(\"/\")[0] : \"/\"))\n\n return {\n mode,\n label: modeLabel(mode),\n articles: index.articles.length,\n entries: entries.length,\n unabsorbed: unabsorbed.length,\n uniqueTags: tags.size,\n avgTags: index.articles.length > 0 ? (totalTags / index.articles.length).toFixed(1) : \"0\",\n dirs: dirs.size,\n coverage: sources.size,\n articleList: index.articles,\n }\n })\n\n console.log()\n console.log(chalk.bold(` Wiki Compare: ${agentId}`))\n console.log(` Raw entries: ${stats[0].entries}`)\n console.log()\n\n // Table header\n const w = 22\n console.log(` ${\"\".padEnd(20)} ${stats.map(s => s.label.padEnd(w)).join(\" \")}`)\n console.log(` ${\"─\".repeat(20)} ${stats.map(() => \"─\".repeat(w)).join(\" \")}`)\n\n const rows: Array<[string, (s: typeof stats[0]) => string]> = [\n [\"Articles\", s => String(s.articles)],\n [\"Unabsorbed\", s => String(s.unabsorbed)],\n [\"Unique tags\", s => String(s.uniqueTags)],\n [\"Avg tags/article\", s => s.avgTags],\n [\"Directories\", s => String(s.dirs)],\n [\"Entry coverage\", s => `${s.coverage}/${s.entries}`],\n ]\n\n for (const [label, fn] of rows) {\n const vals = stats.map(s => fn(s).padEnd(w))\n console.log(` ${label.padEnd(20)} ${vals.join(\" \")}`)\n }\n\n console.log()\n\n // Best in each category\n const best = (key: \"uniqueTags\" | \"articles\" | \"coverage\", label: string) => {\n const max = Math.max(...stats.map(s => s[key] as number))\n const winners = stats.filter(s => (s[key] as number) === max).map(s => s.label)\n if (max > 0) console.log(chalk.dim(` Best ${label}: ${winners.join(\", \")} (${max})`))\n }\n best(\"uniqueTags\", \"tag richness\")\n best(\"articles\", \"article count\")\n best(\"coverage\", \"entry coverage\")\n\n console.log()\n })\n\n// ---------------------------------------------------------------------------\n// agentx wiki export / import — bulk tarball backup of .agentx/wiki/\n//\n// Closes the audit gap: no operator-facing way to back up wiki content\n// before a risky migration or move it between installs. Tarball is the\n// safest portable shape; we don't ship a sync tool yet (see `wiki migrate`\n// for in-place schema changes).\n\nwiki\n .command(\"export [output]\")\n .description(\"export the entire wiki tree to a .tar.gz\")\n .option(\"--dir <path>\", \"wiki directory to archive (default: .agentx/wiki)\")\n .option(\"--include-raw\", \"also include raw entries (.agentx/wiki/raw/) — bigger archive\")\n .action(async (output, opts) => {\n const wikiDir = opts.dir ? resolve(process.cwd(), opts.dir) : resolve(process.cwd(), \".agentx/wiki\")\n if (!existsSync(wikiDir)) {\n console.log(chalk.red(` Wiki dir not found: ${wikiDir}`))\n process.exit(1)\n }\n const date = new Date().toISOString().slice(0, 10)\n const out = output ? resolve(process.cwd(), output) : resolve(process.cwd(), `agentx-wiki-${date}.tar.gz`)\n const parent = resolve(wikiDir, \"..\")\n const base = wikiDir.split(\"/\").pop() || \"wiki\"\n const args = [\"-C\", parent, \"-czf\", out]\n if (!opts.includeRaw) args.push(\"--exclude=\" + base + \"/raw\")\n args.push(base)\n console.log(chalk.dim(` tar ${args.join(\" \")}`))\n const { spawnSync } = await import(\"child_process\")\n const r = spawnSync(\"tar\", args, { stdio: \"inherit\" })\n if (r.status !== 0) {\n console.log(chalk.red(` tar exited with ${r.status}`))\n process.exit(r.status || 1)\n }\n const { statSync } = await import(\"fs\")\n const size = existsSync(out) ? statSync(out).size : 0\n console.log()\n console.log(chalk.green(` ✓ wrote ${out} (${formatWikiBytes(size)})`))\n console.log(chalk.dim(` Restore on another node: agentx wiki import ${out}`))\n console.log()\n })\n\n// The post-absorb work list.\n//\n// Absorb writes an article once and never looks at it again, which\n// assumes one pass over a batch of conversation can see everything worth\n// keeping. It cannot: much of what an article needs was never in the\n// conversation. This turns the grader's per-field verdict into the next\n// pass's input, ordered by how much of the article rests on each gap, so\n// the corpus gets built up in layers instead of being declared finished\n// at the first draft.\nwiki\n .command(\"gaps\")\n .description(\"what each article still needs, most load-bearing first\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--mode <mode>\", \"graph | unified | flat\", \"graph\")\n .option(\"--agent <id>\", \"only this agent's wiki\")\n .option(\"--type <t>\", \"only articles of this type\")\n .option(\"--max-tier <tier>\", \"stop at this layer: foundation|pillar|walls|openings|furniture\", \"pillar\")\n .option(\"--limit <n>\", \"articles to check\", \"40\")\n .option(\"--auto\", \"only gaps a system of record can close without asking anyone\")\n .option(\"--ask\", \"queue the gaps that need a person onto the questions list\")\n .option(\"--notify\", \"push the load-bearing ones to notifications.destination\")\n .option(\"--notify-tier <tier>\", \"tier at or above which to push\", \"pillar\")\n .option(\"--unclear\", \"include fields the grader was unsure about\")\n .option(\"--json\")\n .action(async (opts) => {\n // Its own seat, not article-quality's. Both ask about the same\n // articles, but a per-field yes/no and a 0-3 rubric calibrate\n // differently, and pooling them would average two unrelated error\n // profiles into one meaningless reliability curve.\n const { fieldQuestions, reportFields, articleFieldsState, nextActions, TIER_MEANING, ARTICLE_FIELDS_SEAT } =\n await import(\"@/decisions/seats/article-fields\")\n const { askSeat } = await import(\"@/decisions/seat\")\n const { QuestionStore } = await import(\"@/wiki/questions\")\n const hub = getHub(opts.dir, opts.mode as WikiMode)\n const pending: Array<Parameters<InstanceType<typeof QuestionStore>[\"add\"]>[0][number]> = []\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n const limit = parseInt(opts.limit)\n\n let checked = 0\n const rows: any[] = []\n outer: for (const agentId of agents) {\n const store = hub.getAgentWiki(agentId)\n for (const meta of store.listArticles(agentId)) {\n if (checked >= limit) break outer\n const article = store.readArticle(meta.path)\n if (!article) continue\n if (opts.type && article.meta.type !== opts.type) continue\n checked++\n const res = await askSeat(\n ARTICLE_FIELDS_SEAT,\n articleFieldsState({ title: article.meta.title, type: article.meta.type, body: article.content }),\n fieldQuestions(article.meta.type),\n { links: [{ kind: \"article\", id: meta.path }], features: { agent: agentId, type: article.meta.type ?? \"?\" } },\n )\n if (!res) {\n console.log(chalk.yellow(\" seat is off or unavailable — set decisions.seats.article-fields.mode\"))\n return\n }\n const report = reportFields(article.meta.type, res.answers as never)\n for (const a of nextActions(report, { maxTier: opts.maxTier, includeUnclear: Boolean(opts.unclear) })) {\n if (opts.auto && a.needsHuman) continue\n if (opts.ask && a.needsHuman) {\n pending.push({\n kind: \"field\", agentId, path: meta.path, subject: article.meta.title,\n field: a.field, tier: a.tier,\n question: `${article.meta.title} (${article.meta.type ?? \"?\"}) — ${a.label}?`,\n })\n }\n rows.push({\n tier: a.tier,\n need: a.field,\n how: a.needsHuman ? chalk.yellow(\"ask\") : a.sources.join(\"/\"),\n uncertain: a.uncertain ? \"?\" : \"\",\n agent: agentId,\n article: article.meta.title.slice(0, 40),\n })\n }\n }\n }\n\n let queued = { added: 0, skipped: 0 }\n if (opts.ask && pending.length > 0) {\n queued = new QuestionStore(wikiDir(opts.dir)).add(pending)\n }\n\n if (opts.json) { console.log(JSON.stringify(rows, null, 2)); return }\n if (rows.length === 0) {\n console.log(chalk.green(` ${checked} article(s) checked — nothing missing at or above ${opts.maxTier}`))\n return\n }\n const cols = [\"tier\", \"need\", \"how\", \"uncertain\", \"agent\", \"article\"]\n const plain = (v: any) => String(v).replace(/\\u001b\\[[0-9;]*m/g, \"\")\n const w = cols.map((c) => Math.max(c.length, ...rows.map((r) => plain(r[c]).length)))\n const pad = (v: any, i: number) => String(v) + \" \".repeat(Math.max(0, w[i] - plain(v).length))\n console.log()\n console.log(chalk.bold(cols.map((c, i) => pad(c, i)).join(\" \")))\n for (const r of rows) console.log(cols.map((c, i) => pad(r[c], i)).join(\" \"))\n\n const auto = rows.filter((r) => r.how !== chalk.yellow(\"ask\")).length\n console.log()\n console.log(chalk.dim(` ${rows.length} gap(s) across ${checked} article(s).`))\n console.log(chalk.dim(` ${auto} can be closed by a lookup; ${rows.length - auto} need a person.`))\n const worst = rows[0]?.tier\n if (worst) console.log(chalk.dim(` Start at ${worst} — ${TIER_MEANING[worst as keyof typeof TIER_MEANING]}.`))\n if (opts.ask) {\n console.log(chalk.cyan(` Queued ${queued.added} question(s) for a person (${queued.skipped} already asked).`))\n console.log(chalk.dim(\" agentx wiki questions · agentx wiki answer <id> \\\"<value>\\\"\"))\n }\n\n // Interrupting someone is itself a decision, and until now the only\n // one agentx made on that was \"did the task run for 30 seconds\".\n // Tier is a better basis: a missing foundation fact makes an article\n // describe nothing, and a missing piece of furniture can wait for\n // whenever somebody opens the queue.\n if (opts.ask && opts.notify && queued.added > 0) {\n const { TIER_RANK } = await import(\"@/decisions/seats/article-fields\")\n const floor = TIER_RANK[opts.notifyTier as keyof typeof TIER_RANK] ?? TIER_RANK.pillar\n const worth = pending.filter((q) => (TIER_RANK[(q.tier ?? \"furniture\") as keyof typeof TIER_RANK] ?? 9) <= floor)\n if (worth.length === 0) {\n console.log(chalk.dim(` Nothing at or above ${opts.notifyTier} — not interrupting anyone.`))\n } else {\n const { loadDaemonConfig } = await import(\"@/daemon/config\")\n const cfg: any = loadDaemonConfig()\n const dest = cfg?.notifications?.destination\n if (!dest?.channel || !dest?.chatId) {\n console.log(chalk.yellow(\" --notify: no notifications.destination configured — questions are queued but nobody was told.\"))\n } else {\n const lines = worth.slice(0, 10).map((q) => `• ${q.question}`).join(\"\\n\")\n const more = worth.length > 10 ? `\\n…and ${worth.length - 10} more` : \"\"\n const text = `${worth.length} wiki gap(s) need you (${opts.notifyTier}+):\\n${lines}${more}\\n\\nagentx wiki questions`\n const port = cfg?.daemon?.port ?? cfg?.port ?? 18800\n try {\n const r = await fetch(`http://127.0.0.1:${port}/channel/send`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ channel: dest.channel, chatId: dest.chatId, accountId: dest.accountId, text }),\n })\n console.log(r.ok\n ? chalk.cyan(` Pushed ${worth.length} question(s) to ${dest.channel}.`)\n : chalk.yellow(` Push failed (${r.status}) — questions are still queued.`))\n } catch (e: any) {\n // The queue is the durable thing; the push is a courtesy.\n console.log(chalk.yellow(` Push failed (${String(e?.message ?? e).slice(0, 80)}) — questions are still queued.`))\n }\n }\n }\n }\n })\n\n// Closing the gaps that need no judgement.\n//\n// `wiki gaps` reports that an article has no contact value and that a\n// system of record can supply one. This writes it. Only identity fields\n// are eligible — verbatim strings a directory handed us — because\n// copying those involves no reading of the world. Status, reasoning and\n// ownership stay on the report where a person can answer them.\n//\n// Dry-run by default. Every applied edit versions the prior article\n// into _versions/ first, so a bad run is one `git`-less restore away.\nwiki\n .command(\"backfill\")\n .description(\"write resolved identifiers into articles that are missing them\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--mode <mode>\", \"graph | unified | flat\", \"graph\")\n .option(\"--agent <id>\", \"only this agent's wiki\")\n .option(\"--limit <n>\", \"articles to consider\", \"40\")\n .option(\"--apply\", \"write the changes (default: show them only)\")\n .option(\"--json\")\n .action(async (opts) => {\n const { fieldQuestions, reportFields, articleFieldsState, ARTICLE_FIELDS_SEAT, BACKFILL_ORDER } =\n await import(\"@/decisions/seats/article-fields\")\n const { askSeat } = await import(\"@/decisions/seat\")\n const { resolveFacts, mergeRecords, installPrompts, defaultSources, recordsFromEntries } =\n await import(\"@/wiki/facts\")\n const { backfillArticle } = await import(\"@/wiki/backfill\")\n\n const hub = getHub(opts.dir, opts.mode as WikiMode)\n const agents = opts.agent ? [opts.agent] : hub.listAgents()\n const limit = parseInt(opts.limit)\n const sources = defaultSources()\n\n // Identifiers already stamped on captured entries. These need no\n // tool and no token, so on a node with neither wacli nor a GitLab\n // token this is the only source there is — and it is the most\n // reliable one, because the platform recorded who sent the message\n // rather than us matching a name against a directory.\n const stamped = mergeRecords(recordsFromEntries((hub.getSharedStore() as never as {\n listEntries: () => Array<{ source?: string; meta?: Record<string, unknown> }>\n }).listEntries()))\n const stampedByName = new Map(stamped.map((e) => [e.name.toLowerCase().trim(), e]))\n\n let considered = 0\n let written = 0\n const rows: any[] = []\n let promptedInstall = false\n\n outer: for (const agentId of agents) {\n const store = hub.getAgentWiki(agentId)\n for (const meta of store.listArticles(agentId)) {\n if (considered >= limit) break outer\n // Only people. The backfillable fields are all person fields,\n // and grading a project article to discover that is a wasted call.\n if (meta.meta.type !== \"person\") continue\n const article = store.readArticle(meta.path)\n if (!article) continue\n considered++\n\n const res = await askSeat(\n ARTICLE_FIELDS_SEAT,\n articleFieldsState({ title: article.meta.title, type: article.meta.type, body: article.content }),\n fieldQuestions(article.meta.type),\n { links: [{ kind: \"article\", id: meta.path }], features: { agent: agentId, op: \"backfill\" } },\n )\n if (!res) {\n console.log(chalk.yellow(\" seat is off or unavailable — set decisions.seats.article-fields.mode\"))\n return\n }\n const report = reportFields(article.meta.type, res.answers as never)\n const wanted = report.missing.filter((f) => (BACKFILL_ORDER as readonly string[]).includes(f))\n if (wanted.length === 0) continue\n\n const { records, results } = await resolveFacts([{ name: article.meta.title, type: \"person\" }], { sources })\n const own = stampedByName.get(article.meta.title.toLowerCase().trim())\n if (!promptedInstall) {\n for (const p of installPrompts(results, sources)) {\n console.log(chalk.yellow(` ! ${p.source} ${p.kind} — would supply ${p.provides.join(\", \")}`))\n console.log(chalk.dim(` ${p.hint}`))\n }\n promptedInstall = true\n }\n // Stamped identifiers win over directory hits: same reasoning as\n // absorb, there is no name resolution step to get wrong.\n const merged = mergeRecords([\n ...(own ? [{ name: own.name, source: \"entries\", fields: Object.fromEntries(Object.entries(own.fields).map(([k, v]) => [k, v.value])) }] : []),\n ...records,\n ])\n if (merged.length === 0) continue\n\n const { content, edits } = backfillArticle(article.content, merged[0], wanted)\n if (edits.length === 0) continue\n\n for (const e of edits) {\n rows.push({\n agent: agentId,\n article: article.meta.title.slice(0, 32),\n field: e.field,\n action: e.replaced ? \"replace\" : \"add\",\n // Values are identifiers; show that one was found, not what it is.\n got: `${e.value.split(\";\").length} value(s)`,\n })\n }\n if (opts.apply) {\n const ok = store.writeArticle(meta.path, article.meta, content, agentId)\n if (ok) written++\n else console.log(chalk.red(` could not write ${meta.path}`))\n }\n }\n }\n\n if (opts.json) { console.log(JSON.stringify(rows, null, 2)); return }\n if (rows.length === 0) {\n console.log(chalk.green(` ${considered} person article(s) considered — nothing to backfill`))\n return\n }\n const cols = [\"agent\", \"article\", \"field\", \"action\", \"got\"]\n const w = cols.map((c) => Math.max(c.length, ...rows.map((r) => String(r[c]).length)))\n const fmt = (cells: any[]) => cells.map((v, i) => String(v).padEnd(w[i])).join(\" \")\n console.log()\n console.log(chalk.bold(fmt(cols)))\n for (const r of rows) console.log(fmt(cols.map((c) => r[c])))\n console.log()\n if (opts.apply) {\n console.log(chalk.green(` ${rows.length} field(s) written across ${written} article(s).`))\n console.log(chalk.dim(\" Prior versions are in _versions/ if any of this is wrong.\"))\n } else {\n console.log(chalk.dim(` ${rows.length} field(s) would be written across ${considered} article(s) considered.`))\n console.log(chalk.dim(\" Re-run with --apply to write them.\"))\n }\n })\n\n// The questions only a person can answer, and the way back in.\n//\n// Everything a lookup could close is closed by `wiki backfill`. What is\n// left is judgement — a preferred language, who owns a relationship,\n// why a decision was made — and no amount of machinery produces it.\n// These two commands are the whole human path: see what is being\n// asked, answer it, and have the answer land in the source of truth\n// rather than in a chat log.\nwiki\n .command(\"questions\")\n .alias(\"ask\")\n .description(\"gaps waiting on a person\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--status <s>\", \"open | answered | dismissed\", \"open\")\n .option(\"--json\")\n .action(async (opts) => {\n const { QuestionStore } = await import(\"@/wiki/questions\")\n const { TIER_RANK } = await import(\"@/decisions/seats/article-fields\")\n const qs = new QuestionStore(wikiDir(opts.dir)).list(opts.status as never)\n if (opts.json) { console.log(JSON.stringify(qs, null, 2)); return }\n if (qs.length === 0) { console.log(chalk.green(` no ${opts.status} questions`)); return }\n\n // Most load-bearing first, same order the articles should be built in.\n qs.sort((a, b) =>\n (TIER_RANK[(a.tier ?? \"furniture\") as keyof typeof TIER_RANK] ?? 9) -\n (TIER_RANK[(b.tier ?? \"furniture\") as keyof typeof TIER_RANK] ?? 9))\n\n console.log()\n for (const q of qs) {\n const tier = q.tier ? chalk.dim(`[${q.tier}]`) : \"\"\n console.log(` ${chalk.cyan(q.id)} ${tier} ${q.question}`)\n if (q.answer) console.log(chalk.dim(` → ${q.answer}`))\n }\n console.log()\n console.log(chalk.dim(` ${qs.length} ${opts.status}. agentx wiki answer <id> \"<value>\" · --dismiss to drop one`))\n })\n\nwiki\n .command(\"answer <id> [value]\")\n .description(\"answer a queued question; writes it into the article\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--mode <mode>\", \"graph | unified | flat\", \"graph\")\n .option(\"--dismiss\", \"close the question without answering it\")\n .action(async (id, value, opts) => {\n const { QuestionStore } = await import(\"@/wiki/questions\")\n const { patchIdentityField } = await import(\"@/wiki/backfill\")\n const { IDENTITY_SLOTS } = await import(\"@/decisions/seats/article-fields\")\n const store = new QuestionStore(wikiDir(opts.dir))\n\n if (opts.dismiss) {\n const q = store.resolve(id, \"dismissed\")\n console.log(q ? chalk.dim(` dismissed: ${q.question}`) : chalk.red(` no question matching \"${id}\"`))\n return\n }\n if (!value) { console.log(chalk.red(\" give a value, or pass --dismiss\")); return }\n\n const q = store.resolve(id, \"answered\", value)\n if (!q) { console.log(chalk.red(` no question matching \"${id}\"`)); return }\n console.log(chalk.green(` answered: ${q.question}`))\n\n // An answer to a missing-article question is a note, not a patch —\n // there is no article yet to write it into. Absorb will create one\n // when the entries justify it.\n if (q.kind !== \"field\" || !q.field || !q.path) {\n console.log(chalk.dim(\" recorded. No article to patch yet.\"))\n return\n }\n // Only the identity fields have a defined place in the article. For\n // anything else the answer is recorded and a person decides where\n // it belongs — guessing a location in the source of truth is worse\n // than leaving the answer on the queue.\n if (!IDENTITY_SLOTS[q.field]) {\n console.log(chalk.dim(` recorded against ${q.path}. \"${q.field}\" has no fixed slot, so nothing was rewritten.`))\n return\n }\n\n const hub = getHub(opts.dir, opts.mode as WikiMode)\n const store2 = hub.getAgentWiki(q.agentId)\n const article = store2.readArticle(q.path)\n if (!article) { console.log(chalk.yellow(` article gone: ${q.path}`)); return }\n\n const patched = patchIdentityField(article.content, q.field, `${value} (answered by operator)`)\n if (!patched) { console.log(chalk.dim(\" already present — nothing to write.\")); return }\n const ok = store2.writeArticle(q.path, article.meta, patched.content, q.agentId)\n console.log(ok\n ? chalk.green(` wrote ${q.field} into ${q.path} (prior version kept)`)\n : chalk.red(` could not write ${q.path}`))\n })\n\n// Does the triage gate actually work? Measured, not assumed.\n//\n// The seat has existed unwired for a while because nothing could say\n// whether it was right. The corpus answers that: absorb has already\n// judged 5,626 entries, so the gate can be run against its verdicts\n// before it is allowed to drop anything.\nwiki\n .command(\"triage-backtest\")\n .description(\"grade the entry-triage gate against what absorb actually kept\")\n .option(\"--dir <path>\", \"wiki directory\")\n .option(\"--n <n>\", \"entries to sample (half positive, half negative)\", \"200\")\n .option(\"--min-worth <n>\", \"P(useful in six months) required to keep\")\n .option(\"--min-durability <n>\", \"expected durability required to keep\")\n .option(\"--min-type <n>\", \"type confidence required to keep\")\n .option(\"--sweep\", \"search thresholds for the most filtering that still keeps ~all positives\")\n .option(\"--min-recall <n>\", \"recall floor for --sweep\", \"0.95\")\n .option(\"--save <file>\", \"write the graded outcomes so sweeps can be re-run for free\")\n .option(\"--load <file>\", \"re-sweep saved outcomes without paying for the calls again\")\n .option(\"--json\")\n .action(async (opts) => {\n const { ENTRY_TRIAGE_SEAT, entryTriageQuestions, triageState, triage } =\n await import(\"@/decisions/seats/entry-triage\")\n const { askSeat } = await import(\"@/decisions/seat\")\n const { labelEntries, sample, scoreBacktest, toGradedRows, sweepPolicies } = await import(\"@/wiki/triage-backtest\")\n const { calibrationReport } = await import(\"@/decisions/calibration\")\n\n const hub = getHub(opts.dir, \"graph\")\n const shared = hub.getSharedStore() as never as {\n listEntries: () => Array<{ id: string; date?: string; source?: string; sourceContext?: string; content: string }>\n getUnabsorbedEntries: () => Array<{ id: string }>\n }\n const all = shared.listEntries()\n const unabsorbed = new Set(shared.getUnabsorbedEntries().map((e) => e.id))\n const { labeled, backlog } = labelEntries(all, unabsorbed)\n const picked = sample(labeled, (e) => e.absorbed, parseInt(opts.n))\n\n const policy = {\n minWorth: opts.minWorth ? parseFloat(opts.minWorth) : undefined,\n minDurability: opts.minDurability ? parseFloat(opts.minDurability) : undefined,\n minTypeConfidence: opts.minType ? parseFloat(opts.minType) : undefined,\n }\n\n const outcomes: Array<{ entry: typeof picked[number]; verdict: ReturnType<typeof triage>; citeWorthy?: number }> = []\n let failures = 0\n const t0 = Date.now()\n\n // Model calls are the expensive part; thresholds are free to vary\n // afterwards. Caching them turns a 74-second sweep into an instant one.\n if (opts.load) {\n const { readFileSync } = await import(\"fs\")\n outcomes.push(...JSON.parse(readFileSync(opts.load, \"utf-8\")))\n console.log(chalk.dim(` re-sweeping ${outcomes.length} saved outcome(s) — no calls made`))\n } else {\n console.log(chalk.dim(` ${labeled.length} labelled (${backlog} in backlog) — grading ${picked.length}`))\n }\n\n for (const entry of opts.load ? [] : picked) {\n const res = await askSeat(ENTRY_TRIAGE_SEAT, triageState(entry), entryTriageQuestions, {\n features: { source: entry.source ?? \"\", absorbed: entry.absorbed },\n })\n if (!res) { failures++; continue }\n const a = res.answers as never as { citeWorthy?: { noul: number } }\n outcomes.push({\n entry,\n verdict: triage(res.answers as never, policy),\n citeWorthy: a.citeWorthy?.noul,\n })\n }\n\n if (outcomes.length === 0) {\n console.log(chalk.yellow(\" seat is off or unavailable — set decisions.seats.entry-triage.mode\"))\n return\n }\n\n if (opts.save) {\n const { writeFileSync } = await import(\"fs\")\n writeFileSync(opts.save, JSON.stringify(outcomes))\n console.log(chalk.dim(` saved ${outcomes.length} outcome(s) to ${opts.save}`))\n }\n\n const report = scoreBacktest(outcomes, {\n minType: policy.minTypeConfidence, minWorth: policy.minWorth, minDurability: policy.minDurability,\n })\n // The seat records backend and model per call in its own store; the\n // backtest only needs the rows to carry a consistent tag.\n const rows = toGradedRows(outcomes, \"seat\", \"seat\")\n const cal = calibrationReport(rows, { minN: 50 })\n const elapsed = ((Date.now() - t0) / 1000).toFixed(1)\n\n if (opts.json) {\n console.log(JSON.stringify({ report, calibration: cal, failures, elapsed }, null, 2))\n return\n }\n\n const pct = (x: number) => `${(x * 100).toFixed(1)}%`\n console.log()\n console.log(chalk.bold(\" entry-triage vs absorb's own verdicts\"))\n console.log(` graded ${report.n} (${report.positives} kept by absorb, ${report.negatives} passed over)`)\n console.log(` recall ${pct(report.recall)} ${chalk.dim(\"of what absorb kept, the gate would keep\")}`)\n console.log(` precision ${pct(report.precision)} ${chalk.dim(\"of what the gate keeps, absorb agreed\")}`)\n console.log(` filtered ${pct(report.filtered)} ${chalk.dim(\"never reaches the writing model\")}`)\n console.log(` ${report.lostPositives > 0 ? chalk.yellow(`lost ${report.lostPositives} article(s) absorb would have written`) : chalk.green(\"lost 0 — nothing absorb kept was dropped\")}`)\n if (!(\"insufficient\" in cal) || !cal.insufficient) {\n console.log(` ECE ${(cal as { ece: number }).ece?.toFixed(3) ?? \"n/a\"} ${chalk.dim(\"on P(worth keeping)\")}`)\n }\n if (report.lostPositives > 0) {\n const d = report.droppedBy\n console.log(chalk.dim(` dropped by: type ${d.type} · worth ${d.worth} · durability ${d.durability} (a positive can fail several)`))\n }\n const m = report.positiveMeans\n console.log(chalk.dim(` positives avg: worth ${m.worth.toFixed(2)} · durability ${m.durability.toFixed(2)} · typeConf ${m.typeConfidence.toFixed(2)}`))\n console.log(chalk.dim(` ${elapsed}s, ${failures} seat failure(s)`))\n console.log()\n console.log(chalk.dim(\" Recall is the number that decides this: a dropped positive is\"))\n console.log(chalk.dim(\" knowledge destroyed silently. Filtered is only the prize.\"))\n\n if (opts.sweep) {\n // Free: the calls are already paid for, only the thresholds vary.\n const floor = parseFloat(opts.minRecall)\n const { best, points } = sweepPolicies(outcomes, { minRecall: floor })\n console.log()\n console.log(chalk.bold(` threshold sweep (${points.length} policies, recall floor ${pct(floor)})`))\n if (!best) {\n console.log(chalk.red(` No policy reaches ${pct(floor)} recall — not even keeping everything typed.`))\n const loosest = points.slice().sort((a, b) => b.recall - a.recall)[0]\n if (loosest) {\n console.log(chalk.dim(` Best recall available: ${pct(loosest.recall)} at ${loosest.requireTyped ? `type>=${loosest.minType}` : \"type gate OFF\"} worth>=${loosest.minWorth} dur>=${loosest.minDurability}, filtering ${pct(loosest.filtered)}`))\n }\n console.log(chalk.yellow(\" The gate is not safe to run in active mode on this evidence.\"))\n } else {\n console.log(` best: ${best.requireTyped ? `typed & type>=${best.minType}` : \"type gate OFF\"} worth>=${best.minWorth} durability>=${best.minDurability}`)\n console.log(` recall ${pct(best.recall)} · filtered ${pct(best.filtered)} · precision ${pct(best.precision)} · lost ${best.lostPositives}`)\n console.log(chalk.dim(\" Filtering here is the real saving; anything above it costs articles.\"))\n }\n }\n })\n\nwiki\n .command(\"import <archive>\")\n .description(\"restore a wiki archive (created with `agentx wiki export`)\")\n .option(\"--dir <path>\", \"where to restore (default: .agentx/wiki)\")\n .option(\"--force\", \"overwrite existing wiki without prompting\")\n .action(async (archive, opts) => {\n const archivePath = resolve(process.cwd(), archive)\n if (!existsSync(archivePath)) {\n console.log(chalk.red(` archive not found: ${archivePath}`))\n process.exit(1)\n }\n const target = opts.dir ? resolve(process.cwd(), opts.dir) : resolve(process.cwd(), \".agentx/wiki\")\n if (existsSync(target) && !opts.force) {\n console.log(chalk.yellow(` ${target} already exists.`))\n console.log(chalk.yellow(` Re-run with --force to overwrite (existing files where the archive has them; others stay).`))\n process.exit(1)\n }\n const parent = resolve(target, \"..\")\n const { mkdirSync } = await import(\"fs\")\n mkdirSync(parent, { recursive: true })\n const args = [\"-C\", parent, \"-xzf\", archivePath]\n console.log(chalk.dim(` tar ${args.join(\" \")}`))\n const { spawnSync } = await import(\"child_process\")\n const r = spawnSync(\"tar\", args, { stdio: \"inherit\" })\n if (r.status !== 0) {\n console.log(chalk.red(` tar exited with ${r.status}`))\n process.exit(r.status || 1)\n }\n console.log()\n console.log(chalk.green(` ✓ restored to ${target}`))\n console.log(chalk.dim(` Restart the daemon (or POST /reload) for the wiki hub to pick up the new content.`))\n console.log()\n })\n\nfunction formatWikiBytes(b: number): string {\n if (b < 1024) return b + \"B\"\n if (b < 1024 * 1024) return (b / 1024).toFixed(1) + \"K\"\n if (b < 1024 * 1024 * 1024) return (b / 1024 / 1024).toFixed(1) + \"M\"\n return (b / 1024 / 1024 / 1024).toFixed(2) + \"G\"\n}\n","import { Command } from \"commander\"\nimport { extractJson } from \"@/utils/extract-json\"\nimport chalk from \"chalk\"\nimport { resolve } from \"path\"\nimport { existsSync } from \"fs\"\nimport { GraphStore } from \"@/graph/store\"\nimport { hashPath, pathLabel } from \"@/graph/classifier\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx graph — intent knowledge graph operations ---\n//\n// v1 scope: just the review loop. Future: `graph status`, `graph nodes`,\n// `graph show <msgHash>`, `graph schema edit`. The admin panel surfaces\n// pending classifications; this CLI lets an operator (or a cron) invoke\n// the reviewer agent to triage them in batch.\n\nexport const graph = new Command()\n .name(\"graph\")\n .description(\"intent knowledge graph — review, inspect, manage\")\n\ngraph\n .command(\"review\")\n .description(\"triage pending classifications via the configured review agent (the agent uses `wiki query` for context before deciding)\")\n .option(\"--agent <id>\", \"override the review agent (defaults to graph.reviewAgent or graph.draftAgent)\")\n .option(\"--max <n>\", \"cap reviews this run\", \"20\")\n .option(\"--dry-run\", \"show the agent's decision but don't apply approvals/rejections\")\n .option(\"--daemon-url <url>\", \"daemon URL (default: http://localhost:18800)\")\n .action(async (opts) => {\n const config = loadDaemonConfig()\n if (!config.graph?.enabled) {\n console.log(chalk.yellow(\" graph.enabled is false — nothing to review\"))\n return\n }\n\n const agentId = opts.agent || config.graph.reviewAgent || config.graph.draftAgent\n if (!agentId) {\n console.log(chalk.red(\" no review agent. Set graph.reviewAgent in agentx.json or pass --agent <id>.\"))\n return\n }\n if (!config.agents?.[agentId]) {\n console.log(chalk.red(` agent \"${agentId}\" not in config`))\n return\n }\n const daemonUrl = (opts.daemonUrl || config.dashboard?.daemonUrl || \"http://localhost:18800\").replace(/\\/+$/, \"\")\n const cap = Math.max(1, parseInt(opts.max) || 20)\n\n const store = new GraphStore({ baseDir: resolve(process.cwd(), config.graph.baseDir) })\n const pending = store.listPendingClassifications(cap)\n if (pending.length === 0) {\n console.log(chalk.dim(\" no pending classifications — nothing to review\"))\n return\n }\n\n const schema = store.loadSchema()\n const nodes = store.loadNodes().nodes\n console.log()\n console.log(chalk.bold(` Graph review — ${pending.length} pending`))\n console.log(chalk.dim(` Reviewer: ${agentId} · daemon: ${daemonUrl} · ${opts.dryRun ? \"dry-run\" : \"commit\"}`))\n console.log()\n\n let approvedN = 0, rejectedN = 0, skippedN = 0, errorN = 0\n for (let i = 0; i < pending.length; i++) {\n const c = pending[i]\n const label = pathLabel(c.path, nodes) || c.path.join(\" › \")\n process.stdout.write(` [${i + 1}/${pending.length}] ${chalk.cyan(c.msgHash.slice(0, 8))} ${chalk.dim(label)} ... `)\n\n const prompt = buildReviewPrompt(c, schema, nodes)\n let decision: { decision?: string; reason?: string } | null = null\n try {\n decision = await askAgent(daemonUrl, agentId, prompt, config.dashboard?.token)\n } catch (e: any) {\n errorN++\n console.log(chalk.red(`ERR ${e.message?.slice(0, 80)}`))\n continue\n }\n if (!decision || !decision.decision) {\n errorN++\n console.log(chalk.red(\"ERR no decision\"))\n continue\n }\n const verdict = String(decision.decision).toLowerCase().trim()\n const reason = (decision.reason || \"\").toString().slice(0, 180)\n\n if (verdict === \"approve\") {\n console.log(chalk.green(`APPROVE`) + \" \" + chalk.dim(reason))\n if (!opts.dryRun) {\n try {\n commitApproved(store, c, schema, nodes, agentId)\n store.updateClassificationStatus(c.msgHash, {\n status: \"approved\",\n reviewer: agentId,\n reviewReason: reason,\n })\n approvedN++\n } catch (e: any) {\n console.log(chalk.yellow(` (commit failed, staying pending: ${e.message?.slice(0, 100)})`))\n errorN++\n }\n } else {\n approvedN++\n }\n } else if (verdict === \"reject\") {\n console.log(chalk.red(`REJECT`) + \" \" + chalk.dim(reason))\n if (!opts.dryRun) {\n store.updateClassificationStatus(c.msgHash, {\n status: \"rejected\",\n reviewer: agentId,\n reviewReason: reason,\n })\n }\n rejectedN++\n } else {\n console.log(chalk.yellow(`SKIP`) + \" \" + chalk.dim(reason || verdict))\n skippedN++\n }\n }\n\n console.log()\n const verb = opts.dryRun ? \"would\" : \"did\"\n console.log(chalk.dim(\n ` Summary: ${verb} approve ${approvedN}, ${verb} reject ${rejectedN}, ${skippedN} skipped, ${errorN} errors.`\n ))\n if (opts.dryRun && (approvedN > 0 || rejectedN > 0)) {\n console.log(chalk.dim(` Dry-run — omit --dry-run to apply.`))\n }\n console.log()\n })\n\n// --- graph migrate (Phase 2 of classifier-retire) ---\n// Bulk remap classifications.jsonl + index.json from v1 (scope/location/...)\n// to v2 (category/verb) via keyword heuristics. Idempotent. No LLM calls.\n\ngraph\n .command(\"migrate\")\n .description(\"remap past classifications from v1 (scope/location/org/unit/activity) to v2 (category/verb) via keyword heuristics. No LLM calls. Idempotent.\")\n .option(\"--dry-run\", \"report what would change, don't write\")\n .action(async (opts) => {\n const config = loadDaemonConfig()\n if (!config.graph) {\n console.log(chalk.yellow(\" graph block missing from agentx.json — nothing to migrate\"))\n return\n }\n const baseDir = resolve(process.cwd(), config.graph.baseDir)\n if (!existsSync(baseDir)) {\n console.log(chalk.yellow(` ${baseDir} does not exist — nothing to migrate`))\n return\n }\n const { migrateV2 } = await import(\"@/graph/migrate-v2\")\n const store = new GraphStore({ baseDir, log: () => undefined })\n const result = migrateV2(store, { dryRun: !!opts.dryRun, log: (...a) => console.log(chalk.dim(\" \"), ...a) })\n console.log()\n console.log(chalk.bold(\" Pattern hits:\"))\n const hits = Object.entries(result.patternHits).sort((a, b) => b[1] - a[1])\n if (hits.length === 0) console.log(chalk.dim(\" (none)\"))\n for (const [verb, count] of hits) console.log(` ${verb.padEnd(28)} ${count}`)\n console.log()\n if (opts.dryRun) {\n console.log(chalk.dim(` Dry-run — omit --dry-run to apply.`))\n } else {\n console.log(chalk.green(` Done. Backups: ${result.backups.length} file(s).`))\n }\n console.log()\n })\n\n// --- graph pull (cross-mesh sync) ---\n// v1: leader-follower — pull schema + nodes + approved classifications from\n// a peer's daemon. Conflicts skip silently; local always wins. Only approved\n// classifications come across — pending/rejected stay peer-local. Schema\n// divergence is reported but not reconciled (that's a harder design).\n\ngraph\n .command(\"pull\")\n .description(\"pull schema + nodes + approved classifications from a peer's graph\")\n .requiredOption(\"--from <url>\", \"peer daemon URL (e.g. http://peer.example.com:19900)\")\n .option(\"--token <t>\", \"bearer token for the peer (if it requires auth)\")\n .option(\"--limit <n>\", \"max approved classifications to pull\", \"500\")\n .option(\"--dry-run\", \"show what would change, don't write\")\n .action(async (opts) => {\n const config = loadDaemonConfig()\n if (!config.graph?.enabled) {\n console.log(chalk.yellow(\" graph.enabled is false on this node — nothing to sync INTO.\"))\n return\n }\n const peer = String(opts.from).replace(/\\/+$/, \"\")\n const limit = Math.max(1, parseInt(opts.limit) || 500)\n const headers: Record<string, string> = { Accept: \"application/json\" }\n if (opts.token) headers[\"Authorization\"] = `Bearer ${opts.token}`\n\n const store = new GraphStore({ baseDir: resolve(process.cwd(), config.graph.baseDir) })\n const localSchema = store.loadSchema()\n const localNodes = store.loadNodes().nodes\n const localIds = new Set(localNodes.map(n => n.id))\n\n // 1. Schema — warn on divergence. If local is fresh (no nodes committed),\n // adopt peer schema. Otherwise keep local + warn about axis drift.\n console.log()\n console.log(chalk.bold(` graph pull ← ${peer}`))\n let peerSchema: any, peerNodes: any[], peerClassifications: any[]\n try {\n const schemaRes = await fetch(`${peer}/graph/schema`, { headers })\n if (!schemaRes.ok) throw new Error(`schema HTTP ${schemaRes.status}`)\n const schemaData = await schemaRes.json() as any\n peerSchema = schemaData.schema\n\n const nodesRes = await fetch(`${peer}/graph/nodes`, { headers })\n if (!nodesRes.ok) throw new Error(`nodes HTTP ${nodesRes.status}`)\n peerNodes = ((await nodesRes.json() as any).nodes) || []\n\n const clRes = await fetch(`${peer}/graph/classifications?status=approved&limit=${limit}`, { headers })\n if (!clRes.ok) throw new Error(`classifications HTTP ${clRes.status}`)\n peerClassifications = ((await clRes.json() as any).classifications) || []\n } catch (e: any) {\n console.log(chalk.red(` fetch failed: ${e.message}`))\n return\n }\n\n const localLevels = localSchema.levels.map((l: any) => l.id).join(\",\")\n const peerLevels = peerSchema?.levels?.map((l: any) => l.id).join(\",\")\n const schemaMatches = localLevels === peerLevels\n if (!schemaMatches) {\n console.log(chalk.yellow(` ⚠ schema levels differ:`))\n console.log(chalk.dim(` local: ${localLevels}`))\n console.log(chalk.dim(` peer: ${peerLevels}`))\n if (localNodes.length === 0 && !opts.dryRun) {\n console.log(chalk.dim(` local is empty — adopting peer schema`))\n store.saveSchema(peerSchema)\n } else {\n console.log(chalk.yellow(` keeping local schema; node import may fail if levels disagree`))\n }\n } else {\n console.log(chalk.dim(` schema matches (${localSchema.levels.length} levels)`))\n }\n\n // 2. Nodes — import in topological order (level ascending) so parents\n // exist before children. Skip any id already present locally.\n const schemaForImport = schemaMatches ? localSchema : peerSchema\n const levelOrder = new Map<string, number>()\n schemaForImport.levels.forEach((l: any, i: number) => levelOrder.set(l.id, i))\n const sortedPeerNodes = [...peerNodes].sort(\n (a, b) => (levelOrder.get(a.level) ?? 99) - (levelOrder.get(b.level) ?? 99),\n )\n\n let nodesAdded = 0, nodesSkipped = 0, nodesFailed = 0\n for (const n of sortedPeerNodes) {\n if (localIds.has(n.id)) { nodesSkipped++; continue }\n if (opts.dryRun) { nodesAdded++; localIds.add(n.id); continue }\n try {\n store.addNode({\n ...n,\n createdBy: n.createdBy ? `${n.createdBy} (sync)` : `sync:${peer}`,\n })\n localIds.add(n.id)\n nodesAdded++\n } catch (e: any) {\n nodesFailed++\n console.log(chalk.yellow(` skip node ${n.id}: ${e.message?.slice(0, 100)}`))\n }\n }\n console.log(chalk.dim(` nodes: +${nodesAdded} added · ${nodesSkipped} already-present · ${nodesFailed} failed`))\n\n // 3. Approved classifications — populate fingerprint cache so recurring\n // similar messages here snap to the peer's approved path without\n // another LLM call. Skip any fingerprint already cached locally.\n let fpAdded = 0, fpSkipped = 0\n for (const c of peerClassifications) {\n if (!c.msgHash || !Array.isArray(c.path)) continue\n if (store.getFingerprint(c.msgHash)) { fpSkipped++; continue }\n if (opts.dryRun) { fpAdded++; continue }\n store.setFingerprint(c.msgHash, { path: c.path, leaf: c.leaf || {} })\n fpAdded++\n }\n console.log(chalk.dim(` fingerprints: +${fpAdded} cached · ${fpSkipped} already-present`))\n\n console.log()\n if (opts.dryRun) {\n console.log(chalk.dim(` Dry-run — omit --dry-run to apply.`))\n } else {\n console.log(chalk.green(` ✓ pulled from ${peer}`))\n }\n console.log()\n })\n\n// --- helpers ---\n\n/**\n * Build the review prompt for the agent. The agent sees the original message,\n * the proposed path + axes, a slice of the current catalog so it can sanity-\n * check names, and explicit instructions to use `wiki query` for institutional\n * context before deciding.\n */\nfunction buildReviewPrompt(\n c: any,\n schema: any,\n nodes: any[],\n): string {\n const existingByLevel: Record<string, string[]> = {}\n for (const n of nodes) {\n (existingByLevel[n.level] ||= []).push(`${n.id}${n.axes?.name ? ` (${n.axes.name})` : \"\"}`)\n }\n const levelsSummary = schema.levels\n .map((l: any) => ` ${l.id}: [${(existingByLevel[l.id] || []).slice(0, 10).join(\", \") || \"(none yet)\"}]`)\n .join(\"\\n\")\n\n const axesJson = JSON.stringify(c.proposedAxes || {}, null, 2)\n return [\n `You are reviewing a pending intent classification. Decide whether it is reasonable.`,\n ``,\n `--- MESSAGE (first 500 chars) ---`,\n (c.preview || \"\").slice(0, 500),\n `channel: ${c.channel || \"?\"} · sender: ${c.sender || \"?\"}`,\n ``,\n `--- PROPOSED PATH ---`,\n c.path.join(\" › \"),\n ``,\n `--- PROPOSED AXES (per new node) ---`,\n axesJson,\n ``,\n `--- CURRENT NODES BY LEVEL (first 10 per level) ---`,\n levelsSummary,\n ``,\n `--- YOUR JOB ---`,\n `Decide one of:`,\n ` approve — the path is right and the axes make sense for the message`,\n ` reject — the path is wrong (e.g. the message is NOT about the proposed org/topic, or the axes are bogus)`,\n ` skip — you can't confidently decide; leave it for a human`,\n ``,\n `BEFORE you decide, you MAY call \\`agentx wiki query\\` (via Bash) to check institutional context — e.g. \"is there an article for this project\" or \"who is this person\". This is optional; don't call it for obvious cases.`,\n ``,\n `Bias toward reject over approve when uncertain. A wrong approval pollutes the graph; a wrong rejection just keeps the entry pending.`,\n ``,\n `Return EXACTLY one JSON object on one line, no prose, no fences:`,\n ` {\"decision\":\"approve\"|\"reject\"|\"skip\",\"reason\":\"one sentence\"}`,\n ].join(\"\\n\")\n}\n\nasync function askAgent(\n daemonUrl: string,\n agentId: string,\n message: string,\n token?: string,\n): Promise<any> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" }\n if (token) headers[\"Authorization\"] = `Bearer ${token}`\n const ac = new AbortController()\n const timer = setTimeout(() => ac.abort(), 120_000) // 2 min — reviewer may call wiki query\n try {\n const r = await fetch(`${daemonUrl}/task`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n agent: agentId,\n message,\n context: { channel: \"a2a\", sender: \"graph-review\" },\n }),\n signal: ac.signal,\n })\n if (!r.ok) throw new Error(`daemon /task HTTP ${r.status}`)\n const data: any = await r.json()\n if (data?.error) throw new Error(String(data.error))\n return extractJson((data?.content || \"\").toString())\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** Commit any new nodes along the path + populate the fingerprint cache.\n * Delegates to store.commitNodesAlongPath which handles level inference\n * from axes (so paths that skip levels, like business→acme when location\n * is absent, land at the right level) and refreshes nodes between adds. */\nfunction commitApproved(\n store: GraphStore,\n c: any,\n schema: any,\n _existing: any[], // unused — helper re-reads fresh each time\n createdBy: string,\n): void {\n store.commitNodesAlongPath(c.path, c.proposedAxes || {}, schema, createdBy)\n store.setFingerprint(c.msgHash, { path: c.path, leaf: c.leaf || {} })\n}\n\n\n// Suppress unused-import warning — hashPath is exported via the types; we don't\n// need it in this file but keep the dependency explicit in case future\n// --- Human labels for the classifier ---\n//\n// `graph review` above hands pending rows to an AGENT. That is triage,\n// not ground truth: it produces more model output, and only 32 of 8,903\n// rows are pending anyway. The 8,871 marked \"approved\" were approved by\n// schema validation, not by a person, so the largest classification\n// site in agentx has no labels at all — and a decision seat there would\n// produce a better-formed number against nothing to check it with.\n//\n// These commands are the label supply. They are deliberately\n// non-interactive: a queue you can pipe, and a verdict you can record\n// from a script or the dashboard later.\n\nfunction graphStoreFrom(): { store: GraphStore; baseDir: string } | null {\n const config = loadDaemonConfig()\n if (!config.graph?.baseDir) {\n console.log(chalk.red(\" graph.baseDir is not configured\"))\n return null\n }\n const baseDir = resolve(process.cwd(), config.graph.baseDir)\n return { store: new GraphStore({ baseDir }), baseDir }\n}\n\nconst label = graph\n .command(\"label\")\n .description(\"human verdicts on classifications — the labels calibration needs\")\n\nlabel\n .command(\"next\")\n .alias(\"list\")\n .description(\"what to check next, spread across the confidence range\")\n .option(\"--n <n>\", \"how many\", \"10\")\n .option(\"--strategy <s>\", \"stratified | uncertain\", \"stratified\")\n .option(\"--json\")\n .action(async (opts) => {\n const g = graphStoreFrom()\n if (!g) return\n const { ReviewStore, buildQueue } = await import(\"@/graph/review-store\")\n const rows = g.store.listAllClassifications()\n const reviews = new ReviewStore(g.baseDir).load()\n const queue = buildQueue(rows as never, new Set(reviews.keys()), {\n n: parseInt(opts.n), strategy: opts.strategy as never,\n })\n\n if (opts.json) { console.log(JSON.stringify(queue, null, 2)); return }\n if (queue.length === 0) { console.log(chalk.green(\" nothing left unreviewed\")); return }\n\n const nodes = g.store.loadNodes().nodes\n console.log()\n for (const c of queue) {\n const conf = typeof c.confidence === \"number\" ? c.confidence.toFixed(2) : chalk.dim(\"cache\")\n console.log(` ${chalk.cyan(c.msgHash.slice(0, 8))} ${conf.padStart(5)} ${chalk.bold(pathLabel(c.path, nodes) || c.path.join(\" › \"))}`)\n if (c.preview) console.log(chalk.dim(` ${String(c.preview).replace(/\\s+/g, \" \").slice(0, 96)}`))\n }\n console.log()\n console.log(chalk.dim(` ${queue.length} to check (${opts.strategy}).`))\n console.log(chalk.dim(` agentx graph label mark <hash> correct|wrong|unsure [--path a/b/c]`))\n })\n\nlabel\n .command(\"mark <hash> <verdict>\")\n .description(\"record a verdict: correct | wrong | unsure\")\n .option(\"--path <p>\", \"for `wrong`: the path it should have been, slash-separated\")\n .option(\"--note <t>\", \"why, when it is worth remembering\")\n .option(\"--by <who>\", \"reviewer\", \"operator\")\n .action(async (hash, verdict, opts) => {\n if (![\"correct\", \"wrong\", \"unsure\"].includes(verdict)) {\n console.log(chalk.red(` verdict must be correct | wrong | unsure`))\n return\n }\n const g = graphStoreFrom()\n if (!g) return\n const { ReviewStore } = await import(\"@/graph/review-store\")\n const rows = g.store.listAllClassifications()\n const match = rows.filter((c) => c.msgHash === hash || c.msgHash.startsWith(hash))\n if (match.length === 0) { console.log(chalk.red(` no classification matching \"${hash}\"`)); return }\n if (match.length > 1) { console.log(chalk.red(` \"${hash}\" matches ${match.length} rows — use more characters`)); return }\n\n const store = new ReviewStore(g.baseDir)\n store.record({\n msgHash: match[0].msgHash,\n verdict: verdict as never,\n correctPath: opts.path ? String(opts.path).split(\"/\").filter(Boolean) : undefined,\n note: opts.note,\n reviewer: opts.by,\n })\n const nodes = g.store.loadNodes().nodes\n console.log(chalk.green(` ${verdict}: ${pathLabel(match[0].path, nodes) || match[0].path.join(\" › \")}`))\n if (opts.path) console.log(chalk.dim(` should have been: ${opts.path}`))\n })\n\nlabel\n .command(\"stats\")\n .description(\"how many labels so far, and what they say\")\n .option(\"--json\")\n .action(async (opts) => {\n const g = graphStoreFrom()\n if (!g) return\n const { ReviewStore, labelStats } = await import(\"@/graph/review-store\")\n const rows = g.store.listAllClassifications()\n const reviews = new ReviewStore(g.baseDir).load()\n const st = labelStats(rows as never, reviews)\n\n if (opts.json) { console.log(JSON.stringify(st, null, 2)); return }\n const pct = (x: number) => `${(x * 100).toFixed(1)}%`\n console.log()\n console.log(` classifications ${st.classifications}`)\n console.log(` reviewed ${st.reviewed} (${st.correct} correct · ${st.wrong} wrong · ${st.unsure} unsure)`)\n if (st.correct + st.wrong > 0) console.log(` accuracy ${pct(st.accuracy)}`)\n console.log(` calibratable ${st.calibratable} ${chalk.dim(\"reviewed rows that carry a confidence\")}`)\n\n if (st.byBin.length > 0) {\n console.log()\n console.log(chalk.bold(\" reliability — confidence vs how often it was right\"))\n for (const b of st.byBin) {\n const gap = Math.abs((parseFloat(b.bin.split(\"-\")[0]) + 0.05) - b.accuracy)\n const flag = b.n >= 5 && gap > 0.15 ? chalk.yellow(\" ← miscalibrated\") : \"\"\n console.log(` ${b.bin} n=${String(b.n).padStart(3)} right ${pct(b.accuracy).padStart(6)}${flag}`)\n }\n }\n console.log()\n if (st.calibratable < 100) {\n // The harness refuses to report an ECE below this for good reason:\n // at n=30 the number is noise dressed as a measurement.\n console.log(chalk.dim(` ${100 - st.calibratable} more labelled rows before a calibration report means anything.`))\n } else {\n console.log(chalk.green(\" enough labels for a calibration report — a seat here can now be graded.\"))\n }\n })\n\n// subcommands want to regenerate pathId for display.\nvoid hashPath\nvoid existsSync\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { ProcedureStore } from \"@/procedures\"\nimport { matchProcedures } from \"@/procedures/match\"\nimport { extractCommand, watchCommand } from \"./procedure-extract\"\n\n// --- agentx procedure — user-perspective SOPs, the front door to automation ---\n//\n// A procedure describes a recurring activity from the USER's point of view\n// (trigger, inputs, steps, expected outcome) — the system executing it is a\n// black box. Drafts come from `extract` (mined from real activity) or `add`\n// (hand-written); review with promote/reject; agents consume matches as\n// guidance. Executable DAG workflows are an optional later promotion.\n\nexport const procedure = new Command()\n .name(\"procedure\")\n .description(\"procedures (SOPs) — extract from activity, review drafts, match, schedule\")\n\nprocedure.addCommand(extractCommand)\nprocedure.addCommand(watchCommand)\n\nprocedure\n .command(\"list\")\n .description(\"list procedures with their trigger line\")\n .option(\"--drafts\", \"list unreviewed drafts instead\", false)\n .option(\"--all\", \"list active procedures and drafts\", false)\n .action((opts) => {\n const store = new ProcedureStore()\n const items = [\n ...(opts.drafts ? [] : store.list()),\n ...(opts.drafts || opts.all ? store.listDrafts() : []),\n ]\n if (!items.length) {\n console.log(chalk.dim(\n opts.drafts\n ? \" no procedure drafts. Mine some with: agentx procedure extract\"\n : \" no procedures yet. Try: agentx procedure extract · or: agentx procedure add\",\n ))\n return\n }\n console.log()\n for (const p of items) {\n const status = p.meta.status === \"active\" ? chalk.green(p.meta.status) : p.meta.status === \"draft\" ? chalk.yellow(p.meta.status) : chalk.dim(p.meta.status)\n console.log(` ${chalk.cyan(p.meta.id)} ${chalk.bold(p.meta.title)} ${status}`)\n console.log(` ${chalk.dim(\"trigger:\")} ${p.meta.trigger}`)\n if (p.meta.source) console.log(` ${chalk.dim(\"source:\")} ${chalk.dim(p.meta.source)}`)\n if (p.meta.kpis?.length) console.log(` ${chalk.dim(\"kpis:\")} ${p.meta.kpis.join(\", \")}`)\n }\n console.log()\n console.log(chalk.dim(` ${items.length} procedure${items.length === 1 ? \"\" : \"s\"}.`))\n })\n\nprocedure\n .command(\"add\")\n .description(\"add a new procedure (non-interactive; pass all fields as flags)\")\n .requiredOption(\"--id <id>\", \"procedure id (lower-kebab, e.g. deploy-peer)\")\n .requiredOption(\"--title <t>\", \"human-readable title\")\n .requiredOption(\"--trigger <t>\", \"when this procedure applies (one sentence)\")\n .option(\"--input <i...>\", \"required input (repeatable)\", (v: string, prev: string[] = []) => [...prev, v])\n .option(\"--expected <t>\", \"expected output / success criterion\")\n .option(\"--kpi <k...>\", \"KPI (repeatable)\", (v: string, prev: string[] = []) => [...prev, v])\n .option(\"--owner <id>\", \"owning agent or person\")\n .option(\"--tag <t...>\", \"tag (repeatable)\", (v: string, prev: string[] = []) => [...prev, v])\n .option(\"--related <r...>\", \"related procedure id or wiki article title (repeatable)\", (v: string, prev: string[] = []) => [...prev, v])\n .option(\"--steps <md>\", \"markdown body — usually numbered steps\")\n .action((opts) => {\n const store = new ProcedureStore()\n const body = opts.steps\n ? String(opts.steps)\n : `## Steps\\n\\n1. (fill in)\\n\\n## Notes\\n\\n`\n try {\n const p = store.add({\n id: opts.id,\n title: opts.title,\n trigger: opts.trigger,\n inputs: opts.input || [],\n expected: opts.expected,\n kpis: opts.kpi || [],\n owner: opts.owner,\n tags: opts.tag || [],\n related: opts.related || [],\n } as any, body)\n console.log(chalk.green(` ✓ procedure added: ${p.meta.id}`))\n console.log(chalk.dim(` ${store.baseDir}/${p.path}`))\n } catch (e: any) {\n console.log(chalk.red(` add failed: ${e.message}`))\n process.exit(1)\n }\n })\n\nprocedure\n .command(\"show <id>\")\n .description(\"show a single procedure (active or draft)\")\n .action((id: string) => {\n const store = new ProcedureStore()\n const p = store.get(id) ?? store.getDraft(id)\n if (!p) {\n console.log(chalk.yellow(` no procedure matches \"${id}\". Try: agentx procedure list --all`))\n process.exit(1)\n }\n console.log()\n console.log(chalk.bold(` ${p!.meta.title}`) + chalk.dim(` (${p!.meta.id}, ${p!.meta.status})`))\n console.log(chalk.dim(` trigger: ${p!.meta.trigger}`))\n if (p!.meta.inputs?.length) console.log(chalk.dim(` inputs: ${p!.meta.inputs.join(\", \")}`))\n if (p!.meta.expected) console.log(chalk.dim(` expected: ${p!.meta.expected}`))\n if (p!.meta.kpis?.length) console.log(chalk.dim(` kpis: ${p!.meta.kpis.join(\", \")}`))\n if (p!.meta.owner) console.log(chalk.dim(` owner: ${p!.meta.owner}`))\n if (p!.meta.source) console.log(chalk.dim(` source: ${p!.meta.source}`))\n if (p!.meta.related?.length) console.log(chalk.dim(` related: ${p!.meta.related.join(\", \")}`))\n console.log()\n console.log(p!.body)\n console.log()\n })\n\nprocedure\n .command(\"promote <id>\")\n .description(\"promote a draft into the active procedure set\")\n .action((id: string) => {\n const store = new ProcedureStore()\n try {\n const p = store.promoteDraft(id)\n console.log(chalk.green(` ✓ promoted: ${p.meta.id}`))\n console.log(chalk.dim(` agents will now follow it when a task matches: \"${p.meta.trigger}\"`))\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\nprocedure\n .command(\"reject <id>\")\n .description(\"reject a draft (kept under _drafts/_rejected/ so it is never re-mined)\")\n .action((id: string) => {\n const store = new ProcedureStore()\n try {\n store.rejectDraft(id)\n console.log(chalk.green(` ✓ rejected: ${id}`))\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\nprocedure\n .command(\"deprecate <id>\")\n .description(\"retire an active procedure (kept, but never surfaced to agents)\")\n .action((id: string) => {\n const store = new ProcedureStore()\n try {\n store.deprecate(id)\n console.log(chalk.green(` ✓ deprecated: ${id}`))\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\nprocedure\n .command(\"match <text>\")\n .description(\"find active procedures matching a task description\")\n .option(\"--limit <n>\", \"max matches\", \"3\")\n .option(\"--min-score <s>\", \"minimum score 0..1\", \"0.2\")\n .action((text: string, opts) => {\n const store = new ProcedureStore()\n const matches = matchProcedures(text, store.list(), {\n limit: Number(opts.limit) || 3,\n minScore: Number(opts.minScore) || 0.2,\n })\n if (!matches.length) {\n console.log(chalk.dim(\" no matching procedures\"))\n return\n }\n for (const m of matches) {\n console.log(` ${chalk.cyan(m.procedure.meta.id)} ${chalk.bold(m.score.toFixed(2))} ${chalk.dim(m.reasons.join(\", \"))}`)\n console.log(chalk.dim(` ${m.procedure.meta.trigger}`))\n }\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { existsSync } from \"fs\"\nimport { resolve } from \"path\"\nimport Database from \"better-sqlite3\"\nimport { SessionStore } from \"@/agents/sessions\"\nimport { runExtraction, DEFAULT_MIN_OCCURRENCES, DEFAULT_MAX_CLUSTERS } from \"@/procedures/mine\"\nimport { applyConfigMutation, setAtPath } from \"@/daemon/config-mutator\"\n\n// --- agentx procedure extract / watch ---\n// extract: one mining pass (dry-run by default, like `wiki promote`).\n// watch: persist the cadence — a `crons.procedure-extract` entry that\n// shells this exact CLI, plus the `procedures.extraction` config\n// block the daemon's on-task watcher reads.\n\nfunction parseSince(input: string | undefined): number | undefined {\n if (!input) return undefined\n const m = /^(\\d+)\\s*([smhd])$/.exec(input.trim())\n if (m) {\n const n = Number(m[1])\n const unit = m[2]\n return Date.now() - n * (unit === \"s\" ? 1000 : unit === \"m\" ? 60_000 : unit === \"h\" ? 3600_000 : 86_400_000)\n }\n const n = Number(input)\n if (Number.isFinite(n) && n > 0) return n\n console.log(chalk.red(` Invalid --since \"${input}\". Use \"1h\", \"30m\", \"7d\", or an ms epoch.`))\n process.exit(1)\n}\n\nfunction openTraceDb(path: string): Database.Database {\n const dbPath = resolve(process.cwd(), path)\n if (!existsSync(dbPath)) {\n console.log(chalk.red(` No db at ${dbPath}`))\n process.exit(1)\n }\n return new Database(dbPath, { readonly: true })\n}\n\nexport const extractCommand = new Command()\n .name(\"extract\")\n .description(\"mine recurring user activity into procedure drafts (dry-run by default)\")\n .option(\"--path <path>\", \"SQLite db path\", \".agentx/db.sqlite\")\n .option(\"--since <duration>\", \"activity window, e.g. 24h, 7d, or ms epoch\", \"7d\")\n .option(\"--agent <id>\", \"only mine one agent's activity\")\n .option(\"--min-occurrences <n>\", \"recurrences before a pattern becomes a draft\", String(DEFAULT_MIN_OCCURRENCES))\n .option(\"--max <n>\", \"max clusters distilled per run\", String(DEFAULT_MAX_CLUSTERS))\n .option(\"--via <agentId>\", \"route the LLM call through a running agent — uses the agent's own session\")\n .option(\"--model <model>\", \"direct Anthropic API model — needs ANTHROPIC_API_KEY\")\n .option(\"--daemon <url>\", \"daemon API base URL for --via\", \"http://127.0.0.1:18800\")\n .option(\"--commit\", \"write drafts and persist recurrence counts\", false)\n .action(async (opts) => {\n if (opts.commit && !opts.via && !opts.model) {\n console.log(chalk.red(\" --commit needs an LLM: pass --via <agentId> or --model <model>\"))\n process.exit(1)\n }\n const db = openTraceDb(opts.path)\n const report = await runExtraction(db, {\n since: parseSince(opts.since),\n agentId: opts.agent,\n sessions: new SessionStore(process.cwd()),\n minOccurrences: Number(opts.minOccurrences) || DEFAULT_MIN_OCCURRENCES,\n max: Number(opts.max) || DEFAULT_MAX_CLUSTERS,\n commit: !!opts.commit,\n llm: { viaAgent: opts.via, model: opts.model, daemonUrl: opts.daemon, chatId: \"procedure-miner\" },\n log: (m) => console.log(chalk.dim(` ${m}`)),\n })\n\n console.log()\n console.log(` ${report.episodes} episode(s) → ${report.clusters} cluster(s), ${report.ready.length} at threshold`)\n for (const c of report.ready) {\n console.log(` ${chalk.cyan(c.key)} ${chalk.bold(`×${c.count}`)} ${chalk.dim(c.status)}`)\n if (c.sampleMessage) console.log(chalk.dim(` \"${c.sampleMessage.slice(0, 100)}\"`))\n }\n if (report.nearMisses.length) {\n console.log(chalk.dim(`\\n near-misses (same intent, different activity shape — tuning signal):`))\n for (const nm of report.nearMisses.slice(0, 5)) {\n console.log(chalk.dim(` ${nm.intent} → ${nm.keys.length} variants`))\n }\n }\n for (const d of report.drafted) {\n console.log(chalk.green(` ✓ draft written: ${d.id}`) + chalk.dim(` (${d.count} occurrences)`))\n }\n for (const s of report.skipped) {\n console.log(chalk.yellow(` skipped ${s.cluster}: ${s.reason}`))\n }\n for (const w of report.warnings) console.log(chalk.yellow(` ⚠ ${w}`))\n if (report.dryRun) {\n console.log(chalk.dim(\"\\n dry run only; pass --commit --via <agentId> to write drafts\"))\n } else if (report.drafted.length) {\n console.log(chalk.dim(\"\\n review with: agentx procedure list --drafts · then promote/reject <id>\"))\n }\n })\n\nconst CADENCE = {\n hourly: \"0 * * * *\",\n // 03:00 — after workflow-absorb (02:00) and memory-promote (02:30).\n daily: \"0 3 * * *\",\n} as const\n\nexport const watchCommand = new Command()\n .name(\"watch\")\n .description(\"set the extraction cadence: registers the cron + config the daemon runs on\")\n .option(\"--hourly\", \"extract every hour\")\n .option(\"--daily\", \"extract daily at 03:00\")\n .option(\"--cron <expr>\", \"custom 5-field cron expression\")\n .option(\"--on-task\", \"also count patterns live after each completed task\")\n .option(\"--off\", \"disable scheduled extraction\")\n .option(\"--via <agentId>\", \"agent that runs the extraction (LLM distillation goes through its session)\")\n .option(\"--min-occurrences <n>\", \"recurrences before a pattern becomes a draft\", String(DEFAULT_MIN_OCCURRENCES))\n .option(\"--timezone <tz>\", \"IANA timezone\", \"Africa/Tunis\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .option(\"--dry-run\", \"print what would be written without writing\")\n .action(async (opts) => {\n const schedule: string | undefined = opts.off\n ? undefined\n : opts.cron ?? (opts.hourly ? CADENCE.hourly : opts.daily ? CADENCE.daily : undefined)\n if (!opts.off && !schedule && !opts.onTask) {\n console.log(chalk.red(\" pick a cadence: --hourly, --daily, --cron <expr>, and/or --on-task (or --off)\"))\n process.exit(1)\n }\n if (!opts.off && !opts.via) {\n console.log(chalk.red(\" --via <agentId> is required: drafts are distilled through that agent's session\"))\n process.exit(1)\n }\n\n const minOccurrences = Number(opts.minOccurrences) || DEFAULT_MIN_OCCURRENCES\n const extraction = {\n enabled: !opts.off,\n onTaskCompletion: !opts.off && !!opts.onTask,\n minOccurrences,\n via: opts.off ? undefined : opts.via,\n }\n const prompt = [\n \"Run this shell command EXACTLY as written. Do NOT substitute, rewrite, shorten, or fall back to alternative commands. If it exits non-zero, report the verbatim exit code and stderr and STOP.\",\n \"\",\n `1) cd ${process.cwd()} && node dist/cli.js procedure extract --since 7d --max ${DEFAULT_MAX_CLUSTERS} --min-occurrences ${minOccurrences} --via ${opts.via} --commit`,\n \"\",\n \"Report a one-line summary of drafted/skipped counts.\",\n ].join(\"\\n\")\n\n const result = await applyConfigMutation(\n (c) => {\n setAtPath(c, \"procedures.extraction\", extraction)\n if (opts.off) {\n if ((c as any).crons?.[\"procedure-extract\"]) {\n setAtPath(c, \"crons.procedure-extract.enabled\", false)\n }\n } else if (schedule) {\n setAtPath(c, \"crons.procedure-extract\", {\n enabled: true,\n schedule,\n timezone: opts.timezone,\n agent: opts.via,\n prompt,\n timeout: 900,\n onError: \"log\",\n })\n }\n },\n { configPath: opts.config, dryRun: !!opts.dryRun },\n )\n if (!result.success) {\n console.log(chalk.red(` ✗ ${result.error}`))\n process.exit(1)\n }\n\n const verb = opts.dryRun ? \"would set\" : \"Set\"\n if (opts.off) {\n console.log(chalk.green(` ✓ ${verb} procedure extraction: off`))\n } else {\n console.log(chalk.green(` ✓ ${verb} procedure extraction cadence`))\n if (schedule) console.log(chalk.dim(` cron: ${schedule} (${opts.timezone}) via ${opts.via}`))\n if (opts.onTask) console.log(chalk.dim(` on-task counting: enabled`))\n console.log(chalk.dim(` threshold: ${minOccurrences} occurrences`))\n }\n console.log(chalk.yellow(\" ⚠ restart the daemon to activate — hot-reload does not pick up new config blocks\"))\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { resolve, basename } from \"path\"\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\"\nimport Database from \"better-sqlite3\"\nimport { RunStore, WorkflowStore, lintWorkflow, workflowSchema, parseYamlWorkflow, renderWorkflowYaml, WorkflowYamlError } from \"@/workflows\"\nimport { TEMPLATES, readTemplate, type TemplateName } from \"@/workflows/templates\"\nimport { getTrace } from \"@/storage/traces\"\n\n// --- agentx workflow — declarative state machines for channel events ---\n//\n// v1: list / show / validate / run-manual / runs / pause / resume / cancel\n// The engine itself runs inside the daemon; this CLI is the author tooling\n// (inspect YAML, validate, poke manual triggers, read run history).\n\nexport const workflow = new Command()\n .name(\"workflow\")\n .description(\"workflow definitions — list, show, validate, manage runs\")\n\nfunction durationToMs(input: string): number | null {\n const m = /^(\\d+)\\s*([smhd])$/.exec(input.trim())\n if (!m) return null\n const n = Number(m[1])\n const unit = m[2]\n return n * (unit === \"s\" ? 1000 : unit === \"m\" ? 60_000 : unit === \"h\" ? 3600_000 : 86_400_000)\n}\n\nfunction parseSince(input: string | undefined): number | undefined {\n if (!input) return undefined\n const ms = durationToMs(input)\n if (ms === null) {\n const n = Number(input)\n if (Number.isFinite(n) && n > 0) return n\n console.log(chalk.red(` Invalid --since \"${input}\". Use \"1h\", \"30m\", \"7d\", or an ms epoch.`))\n process.exit(1)\n }\n return Date.now() - ms\n}\n\nfunction openTraceDb(path = \".agentx/db.sqlite\"): Database.Database {\n const dbPath = resolve(process.cwd(), path)\n if (!existsSync(dbPath)) {\n console.log(chalk.red(` No db at ${dbPath}`))\n process.exit(1)\n }\n return new Database(dbPath, { readonly: true })\n}\n\n\nfunction traceSummary(records: any[]): { durationMs: number; totalTokens: number; models: string[]; status: string; result: string } {\n const models = Array.from(new Set(records.map((r) => r.model).filter(Boolean).map(String)))\n const durationMs = records.reduce((sum, r) => sum + (Number(r.durationMs) || 0), 0)\n const totalTokens = records.reduce((sum, r) => sum + (Number(r.totalTokens) || 0), 0)\n const last = records.at(-1)\n return {\n durationMs,\n totalTokens,\n models,\n status: records.some((r) => r.status === \"error\") ? \"error\" : (last?.status || \"ok\"),\n result: String(last?.outputSummary || last?.error || \"\").slice(0, 160),\n }\n}\n\nfunction printReplayComparison(original: ReturnType<typeof traceSummary>, replay: ReturnType<typeof traceSummary>): void {\n const deltaMs = replay.durationMs - original.durationMs\n const deltaTokens = replay.totalTokens - original.totalTokens\n console.log()\n console.log(chalk.bold(\" replay comparison\"))\n console.log(` original: ${original.status} ${original.totalTokens || 0}t ${original.durationMs || 0}ms model=${original.models.join(\",\") || \"—\"}`)\n console.log(` replay: ${replay.status} ${replay.totalTokens || 0}t ${replay.durationMs || 0}ms model=${replay.models.join(\",\") || \"—\"}`)\n console.log(` delta: ${deltaTokens >= 0 ? \"+\" : \"\"}${deltaTokens}t ${deltaMs >= 0 ? \"+\" : \"\"}${deltaMs}ms`)\n if (replay.result) console.log(` result: ${replay.result}`)\n}\n\nworkflow\n .command(\"list\")\n .description(\"list all workflows with their trigger + state count\")\n .action(() => {\n const store = new WorkflowStore()\n const items = store.list()\n if (!items.length) {\n console.log(chalk.dim(\" no workflows yet. Add one by writing .agentx/workflows/<id>.json\"))\n return\n }\n console.log()\n for (const wf of items) {\n const trigger = wf.nodes.find((n) => n.type.startsWith(\"trigger.\"))\n const cfg = (trigger?.config ?? {}) as { source?: string; filter?: { project?: string; repo?: string; chat?: string } }\n const filterParts = [cfg.filter?.project, cfg.filter?.repo, cfg.filter?.chat].filter(Boolean).join(\" / \")\n // `state` is the dispatch gate; `status` is review metadata (see\n // workflowSchema). Rendered unambiguously because the bare pair\n // \"state=… status=…\" kept getting misread as one lifecycle.\n const dispatch = wf.state === \"active\" ? chalk.green(\"dispatch: active\") : chalk.yellow(`dispatch: ${wf.state}`)\n console.log(` ${chalk.cyan(wf.id)} ${chalk.bold(wf.title)} ${chalk.dim(`v${wf.version} ·`)} ${dispatch} ${chalk.dim(`· review: ${wf.status}`)}`)\n console.log(` ${chalk.dim(\"trigger:\")} ${cfg.source ?? \"?\"}${filterParts ? ` ${chalk.dim(filterParts)}` : \"\"}`)\n console.log(` ${chalk.dim(\"nodes: \")} ${wf.nodes.length} (${wf.nodes.map((n) => n.type).join(\", \")})`)\n }\n console.log()\n console.log(chalk.dim(` ${items.length} workflow${items.length === 1 ? \"\" : \"s\"}.`))\n })\n\nworkflow\n .command(\"show <id>\")\n .description(\"show a single workflow's full definition\")\n .option(\"--format <fmt>\", \"output format: json (default) or yaml\", \"json\")\n .action((id: string, opts: { format: string }) => {\n const store = new WorkflowStore()\n const wf = store.get(id)\n if (!wf) {\n console.log(chalk.yellow(` no workflow matches \"${id}\". Try: agentx workflow list`))\n process.exit(1)\n }\n const fmt = opts.format.toLowerCase()\n if (fmt === \"yaml\" || fmt === \"yml\") {\n // Render the canonical (post-desugar) shape, not the original\n // YAML source — `flow:` sugar is a one-way authoring affordance,\n // not a round-trip format. The output validates clean when\n // copied back to a new file.\n console.log(renderWorkflowYaml(wf))\n } else if (fmt === \"json\") {\n console.log(JSON.stringify(wf, null, 2))\n } else {\n console.log(chalk.red(` unknown format \"${opts.format}\" — use json or yaml`))\n process.exit(1)\n }\n })\n\nworkflow\n .command(\"validate [file]\")\n .description(\"validate all workflows in .agentx/workflows (or a single file)\")\n .action((file?: string) => {\n if (file) {\n const path = resolve(process.cwd(), file)\n if (!existsSync(path)) {\n console.log(chalk.red(` file not found: ${path}`))\n process.exit(1)\n }\n try {\n const text = readFileSync(path, \"utf-8\")\n const isYaml = /\\.(ya?ml)$/i.test(file)\n // YAML files run through the desugar pass before Zod sees them.\n // JSON keeps its existing JSON.parse path.\n const raw = isYaml ? parseYamlWorkflow(text, { filePath: file }) : JSON.parse(text)\n const parsed = workflowSchema.safeParse(raw)\n if (!parsed.success) {\n console.log(chalk.red(` ✗ ${path}`))\n for (const i of parsed.error.issues) console.log(` ${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n process.exit(1)\n }\n const lintIssues = lintWorkflow(parsed.data)\n if (lintIssues.length) {\n console.log(chalk.yellow(` ! ${path} (lint)`))\n for (const l of lintIssues) console.log(` ${l}`)\n process.exit(1)\n }\n console.log(chalk.green(` ✓ ${parsed.data.id} — valid`))\n } catch (e: any) {\n // WorkflowYamlError already carries a friendly message with the\n // file path + line/col when js-yaml provided it; print as-is.\n const msg = e instanceof WorkflowYamlError ? e.message : `parse error: ${e?.message ?? e}`\n console.log(chalk.red(` ${msg}`))\n process.exit(1)\n }\n return\n }\n const store = new WorkflowStore()\n const results = store.validateAll()\n let ok = 0\n let bad = 0\n for (const r of results) {\n if (r.isValid) {\n console.log(chalk.green(` ✓ ${(r as any).workflow.id}`))\n ok++\n } else {\n const id = (r as any).workflow?.id || (r as any).id\n console.log(chalk.red(` ✗ ${id}`))\n for (const issue of r.issues) console.log(` ${issue}`)\n bad++\n }\n }\n console.log()\n console.log(chalk.dim(` ${ok} valid, ${bad} invalid.`))\n if (bad > 0) process.exit(1)\n })\n\nworkflow\n .command(\"init <id>\")\n .description(\"scaffold a new workflow YAML from a template (linear by default)\")\n .option(\"--template <name>\", `which template to use (${TEMPLATES.map((t) => t.name).join(\" | \")})`, \"linear\")\n .option(\"--agent <id>\", \"fill the agent placeholder with this agent id\", \"default\")\n .option(\"--reviewer <id>\", \"fill the reviewer placeholder for human-in-the-loop templates\", \"alice\")\n .option(\"--title <text>\", \"workflow title\", \"\")\n .option(\"--json\", \"scaffold as .json instead of .yaml\", false)\n .option(\"--force\", \"overwrite an existing workflow with the same id\", false)\n .action((id: string, opts) => {\n const tmplName = String(opts.template || \"linear\") as TemplateName\n if (!TEMPLATES.some((t) => t.name === tmplName)) {\n console.log(chalk.red(` unknown template \"${opts.template}\"`))\n console.log(chalk.dim(` available: ${TEMPLATES.map((t) => t.name).join(\", \")}`))\n process.exit(1)\n }\n if (!/^[a-z0-9][a-z0-9_-]*$/.test(id)) {\n console.log(chalk.red(` workflow id must be lower-kebab (got \"${id}\")`))\n process.exit(1)\n }\n const store = new WorkflowStore()\n if (!opts.force && store.get(id)) {\n console.log(chalk.red(` workflow \"${id}\" already exists. Use --force to overwrite or pick a new id.`))\n process.exit(1)\n }\n\n let body = readTemplate(tmplName)\n body = body\n .replace(/__ID__/g, id)\n .replace(/__TITLE__/g, opts.title ? String(opts.title) : `${tmplName} workflow ${id}`)\n .replace(/__AGENT__/g, String(opts.agent))\n .replace(/__REVIEWER__/g, String(opts.reviewer))\n\n // Validate the substituted text before writing — catches placeholder\n // typos and template drift before the operator opens it. Note: the\n // template may reference an agent that doesn't exist on this\n // install; lint flags unreachable nodes etc., not agent-existence,\n // so a \"valid\" workflow can still need editing before it runs.\n try {\n const raw = parseYamlWorkflow(body, { filePath: `${id}.yaml` })\n const parsed = workflowSchema.safeParse(raw)\n if (!parsed.success) {\n console.log(chalk.red(` template \"${tmplName}\" failed schema validation after substitution:`))\n for (const i of parsed.error.issues) console.log(` ${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n process.exit(1)\n }\n } catch (e: any) {\n console.log(chalk.red(` template parse failed: ${e?.message ?? e}`))\n process.exit(1)\n }\n\n const ext = opts.json ? \"json\" : \"yaml\"\n const dest = resolve(process.cwd(), \".agentx/workflows\", `${id}.${ext}`)\n if (opts.json) {\n // Round-trip through Zod so the JSON is canonical (sorted keys\n // become deterministic; stripped sugar; defaults filled).\n const raw = parseYamlWorkflow(body, { filePath: `${id}.yaml` })\n const parsed = workflowSchema.parse(raw)\n writeFileSync(dest, JSON.stringify(parsed, null, 2) + \"\\n\")\n } else {\n writeFileSync(dest, body)\n }\n\n console.log()\n console.log(chalk.green(` ✓ scaffolded ${dest}`))\n console.log(chalk.dim(` template: ${tmplName}`))\n console.log()\n console.log(chalk.dim(\" Next:\"))\n console.log(chalk.dim(` 1. edit ${dest}`))\n console.log(chalk.dim(` 2. agentx workflow validate ${dest}`))\n console.log(chalk.dim(` 3. agentx workflow run ${id} --watch`))\n console.log()\n })\n\nworkflow\n .command(\"templates\")\n .description(\"list the available workflow templates for `init`\")\n .action(() => {\n console.log()\n for (const t of TEMPLATES) {\n console.log(` ${chalk.cyan(t.name.padEnd(20))} ${chalk.bold(t.title)}`)\n console.log(` ${\" \".repeat(20)} ${chalk.dim(t.description)}`)\n }\n console.log()\n console.log(chalk.dim(` Use: agentx workflow init <id> --template <name>`))\n console.log()\n })\n\nworkflow\n .command(\"add <file>\")\n .description(\"import a YAML/JSON workflow file into .agentx/workflows and hot-reload\")\n .option(\"--daemon <url>\", \"daemon API base URL\", \"http://127.0.0.1:18800\")\n .option(\"--no-reload\", \"skip the POST /reload after writing\")\n .action(async (file: string, opts) => {\n const path = resolve(process.cwd(), file)\n if (!existsSync(path)) {\n console.log(chalk.red(` file not found: ${path}`))\n process.exit(1)\n }\n const text = readFileSync(path, \"utf-8\")\n const isYaml = /\\.(ya?ml)$/i.test(file)\n let raw: unknown\n try {\n raw = isYaml ? parseYamlWorkflow(text, { filePath: file }) : JSON.parse(text)\n } catch (e: any) {\n const msg = e instanceof WorkflowYamlError ? e.message : `parse error: ${e?.message ?? e}`\n console.log(chalk.red(` ${msg}`))\n process.exit(1)\n }\n const parsed = workflowSchema.safeParse(raw)\n if (!parsed.success) {\n console.log(chalk.red(` ✗ schema:`))\n for (const i of parsed.error.issues) console.log(` ${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n process.exit(1)\n }\n const lintIssues = lintWorkflow(parsed.data)\n if (lintIssues.length) {\n console.log(chalk.red(` ✗ lint:`))\n for (const l of lintIssues) console.log(` ${l}`)\n process.exit(1)\n }\n\n const store = new WorkflowStore()\n const ext = isYaml ? (basename(file).match(/\\.yml$/i) ? \"yml\" : \"yaml\") : \"json\"\n const dest = resolve(store.baseDir, `${parsed.data.id}.${ext}`)\n writeFileSync(dest, isYaml ? text : JSON.stringify(parsed.data, null, 2) + \"\\n\")\n console.log(chalk.green(` ✓ ${parsed.data.id} → ${dest}`))\n\n if (opts.reload === false) {\n console.log(chalk.dim(` --no-reload: skipped daemon hot-reload; restart manually if running.`))\n return\n }\n const url = `${String(opts.daemon).replace(/\\/$/, \"\")}/reload`\n try {\n const res = await fetch(url, { method: \"POST\" })\n if (res.ok) {\n console.log(chalk.dim(` ✓ daemon reloaded`))\n } else {\n console.log(chalk.dim(` daemon /reload returned ${res.status} — restart manually if needed`))\n }\n } catch {\n console.log(chalk.dim(` daemon not reachable at ${opts.daemon} — start it or restart to pick up the new workflow`))\n }\n })\n\nworkflow\n .command(\"runs [id]\")\n .description(\"list recent runs (optionally filtered to a single workflow)\")\n .option(\"--limit <n>\", \"max runs to show\", \"20\")\n .option(\"--node <id>\", \"home-node id for this daemon (defaults to WF_NODE_ID env or \\\"local\\\")\")\n .action((id: string | undefined, opts) => {\n const nodeId = opts.node || process.env.WF_NODE_ID || \"local\"\n const runs = new RunStore({ nodeId }).list({ workflowId: id, limit: Number(opts.limit) })\n if (!runs.length) {\n console.log(chalk.dim(` no runs yet${id ? ` for \"${id}\"` : \"\"}.`))\n return\n }\n console.log()\n for (const r of runs) {\n const last = r.history.at(-1)\n const nextLabel = r.pending[0] ?? (r.status === \"completed\" ? \"∅\" : \"—\")\n const stateColor = r.status === \"running\" ? chalk.cyan : r.status === \"failed\" ? chalk.red : chalk.green\n console.log(` ${chalk.dim(r.id.slice(0, 8))} ${chalk.bold(r.workflowId)} ${stateColor(nextLabel)} ${chalk.dim(r.status)}`)\n console.log(` ${chalk.dim(\"entity: \")} ${r.entityRef.backend}:${r.entityRef.id}`)\n console.log(` ${chalk.dim(\"home: \")} ${r.homeNode}`)\n console.log(` ${chalk.dim(\"updated: \")} ${r.updatedAt}`)\n if (last) console.log(` ${chalk.dim(\"last: \")} ${last.nodeId} (${last.status})`)\n }\n console.log()\n console.log(chalk.dim(` ${runs.length} run${runs.length === 1 ? \"\" : \"s\"}.`))\n })\n\nworkflow\n .command(\"run <id-or-file>\")\n .description(\"manually trigger a workflow by id, or load + register + run a YAML/JSON file\")\n .option(\"--input <json>\", \"JSON object merged into the trigger event payload\")\n .option(\"--force\", \"fire even if the trigger isn't `trigger.manual` (uses a synthesized event)\", false)\n .option(\"--watch\", \"tail per-step traces while the run executes\", false)\n .option(\"--daemon <url>\", \"daemon API base URL\", \"http://127.0.0.1:18800\")\n .action(async (idOrFile: string, opts) => {\n let payload: unknown = {}\n if (opts.input) {\n try { payload = JSON.parse(opts.input) } catch { console.log(chalk.red(` --input must be valid JSON`)); process.exit(1) }\n }\n\n // Two paths:\n // (1) `idOrFile` resolves to a real file → register-then-run it as a\n // one-shot. Useful for iterating on an unsaved YAML without\n // committing to .agentx/workflows/. The synthesized id collides\n // guard: prefix `_adhoc-` so we don't shadow stored workflows\n // unless the file's id already starts with that prefix.\n // (2) `idOrFile` is a workflow id → fire by id (existing behavior).\n let id = idOrFile\n const path = resolve(process.cwd(), idOrFile)\n const isFile = (idOrFile.includes(\"/\") || /\\.(ya?ml|json)$/i.test(idOrFile)) && existsSync(path)\n if (isFile) {\n const text = readFileSync(path, \"utf-8\")\n const isYaml = /\\.(ya?ml)$/i.test(idOrFile)\n let raw: unknown\n try {\n raw = isYaml ? parseYamlWorkflow(text, { filePath: idOrFile }) : JSON.parse(text)\n } catch (e: any) {\n const msg = e instanceof WorkflowYamlError ? e.message : `parse error: ${e?.message ?? e}`\n console.log(chalk.red(` ${msg}`))\n process.exit(1)\n }\n const parsed = workflowSchema.safeParse(raw)\n if (!parsed.success) {\n console.log(chalk.red(` ✗ schema:`))\n for (const i of parsed.error.issues) console.log(` ${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n process.exit(1)\n }\n const lintIssues = lintWorkflow(parsed.data)\n if (lintIssues.length) {\n console.log(chalk.red(` ✗ lint:`))\n for (const l of lintIssues) console.log(` ${l}`)\n process.exit(1)\n }\n // Write to the store under an _adhoc-prefixed id so the daemon's\n // fs.watch picks it up. We re-use the existing id when it already\n // starts with `_adhoc-` so repeated runs against the same file\n // don't accumulate copies.\n const store = new WorkflowStore()\n const adhocId = parsed.data.id.startsWith(\"_adhoc-\")\n ? parsed.data.id\n : `_adhoc-${parsed.data.id}-${Date.now().toString(36)}`\n const ext = isYaml ? \"yaml\" : \"json\"\n const dest = resolve(store.baseDir, `${adhocId}.${ext}`)\n const written = isYaml\n ? text.replace(new RegExp(`^id:\\\\s*${parsed.data.id}\\\\b`, \"m\"), `id: ${adhocId}`)\n : JSON.stringify({ ...parsed.data, id: adhocId }, null, 2) + \"\\n\"\n writeFileSync(dest, written)\n id = adhocId\n console.log(chalk.dim(` ad-hoc registered as \"${adhocId}\" → ${dest}`))\n // Hot-reload so the dispatcher knows about it before we POST.\n try { await fetch(`${String(opts.daemon).replace(/\\/$/, \"\")}/reload`, { method: \"POST\" }) } catch { /* daemon may not be running yet */ }\n }\n\n const url = `${String(opts.daemon).replace(/\\/$/, \"\")}/workflows/${encodeURIComponent(id)}/run`\n let runId: string | undefined\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ payload, force: !!opts.force }),\n })\n if (!res.ok) {\n const text = await res.text()\n console.log(chalk.red(` run failed (${res.status}): ${text.slice(0, 300)}`))\n if (res.status === 409) console.log(chalk.dim(` hint: pass --force to fire non-manual workflows for testing`))\n process.exit(1)\n }\n const body = await res.json() as { runId?: string; source?: string; force?: boolean }\n runId = body.runId\n console.log(chalk.green(` ✓ run started: ${runId || \"(unknown id)\"}${body.force ? chalk.dim(` (forced, source=${body.source})`) : \"\"}`))\n } catch (e: any) {\n console.log(chalk.red(` request to daemon failed: ${e.message}`))\n process.exit(1)\n }\n\n if (opts.watch && runId) {\n await tailTraces({ daemonUrl: String(opts.daemon).replace(/\\/$/, \"\"), runId })\n }\n })\n\n/** Poll /traces?workflowRunId=<id> every 500ms until the run is no\n * longer \"running\", printing each new step row as it appears. The\n * trace store keys per node, so we only need to track which nodeIds\n * we've already printed. */\nasync function tailTraces(args: { daemonUrl: string; runId: string; quiet?: boolean }): Promise<any[]> {\n const seen = new Set<string>()\n const collected = new Map<string, any>()\n const startedAt = Date.now()\n // Hard cap so a stuck run doesn't pin the terminal forever.\n const maxMs = 15 * 60 * 1000\n\n while (Date.now() - startedAt < maxMs) {\n let traces: any[] = []\n try {\n const r = await fetch(`${args.daemonUrl}/traces?workflowRunId=${encodeURIComponent(args.runId)}&limit=200`)\n if (r.ok) {\n const body = await r.json() as { traces?: any[] }\n traces = body.traces || []\n }\n } catch { /* transient — try again next tick */ }\n\n for (const t of traces) {\n if (!t.taskId || seen.has(t.taskId)) continue\n seen.add(t.taskId)\n collected.set(t.taskId, t)\n if (args.quiet) continue\n const status = t.status || \"running\"\n const color = status === \"ok\" ? chalk.green : status === \"error\" ? chalk.red : chalk.cyan\n const tokens = t.totalTokens != null ? chalk.dim(`${t.totalTokens}t`) : \"\"\n const dur = t.durationMs != null ? chalk.dim(`${t.durationMs}ms`) : \"\"\n console.log(` ${color(status.padEnd(5))} ${chalk.bold(t.nodeId || t.label || \"(node)\")} ${tokens} ${dur}`)\n if (t.error) console.log(` ${chalk.red(String(t.error).slice(0, 200))}`)\n }\n\n // Look up the run's status to know when to stop. The run isn't in\n // /traces, so we read it from the run-store's HTTP surface.\n try {\n const r = await fetch(`${args.daemonUrl}/api/workflows/runs/${encodeURIComponent(args.runId)}`)\n if (r.ok) {\n const body = await r.json() as { run?: { status?: string } }\n const run = body.run\n if (run && run.status && run.status !== \"running\") {\n if (!args.quiet) {\n console.log()\n console.log(` ${chalk.dim(\"run finished:\")} ${run.status}`)\n console.log(chalk.dim(` full traces: ${args.daemonUrl}/traces?workflowRunId=${args.runId}`))\n }\n return Array.from(collected.values())\n }\n }\n } catch { /* try again next tick */ }\n\n await new Promise((r) => setTimeout(r, 500))\n }\n if (!args.quiet) console.log(chalk.yellow(` watch timed out after 15min. Run is still active — check /traces`))\n return Array.from(collected.values())\n}\n\nworkflow\n .command(\"trace <id>\")\n .description(\"pretty-print a task's execution trace (taskId or runId)\")\n .option(\"--daemon <url>\", \"daemon API base URL\", \"http://127.0.0.1:18800\")\n .option(\"--json\", \"raw JSON output\", false)\n .action(async (id: string, opts) => {\n const base = String(opts.daemon).replace(/\\/$/, \"\")\n\n // Try as a taskId first (single-step trace), then fall back to\n // workflowRunId (multi-step listing).\n try {\n const single = await fetch(`${base}/traces/${encodeURIComponent(id)}`)\n if (single.ok) {\n const rec = await single.json() as any\n if (opts.json) { console.log(JSON.stringify(rec, null, 2)); return }\n printTrace(rec)\n return\n }\n } catch { /* fall through to runId */ }\n\n let body: { traces?: any[] }\n try {\n const r = await fetch(`${base}/traces?workflowRunId=${encodeURIComponent(id)}&limit=200`)\n if (!r.ok) {\n console.log(chalk.red(` /traces returned ${r.status}`))\n process.exit(1)\n }\n body = await r.json() as { traces?: any[] }\n } catch (e: any) {\n console.log(chalk.red(` daemon request failed: ${e.message}`))\n process.exit(1)\n }\n const traces = body.traces || []\n if (traces.length === 0) {\n console.log(chalk.yellow(` no traces for \"${id}\"`))\n console.log(chalk.dim(` (sqlite must be opened — check 'agentx doctor' if the daemon logged 'sqlite: not opened')`))\n return\n }\n if (opts.json) { console.log(JSON.stringify(traces, null, 2)); return }\n console.log()\n console.log(chalk.bold(` ${traces.length} step${traces.length === 1 ? \"\" : \"s\"} for run ${id}:`))\n console.log()\n for (const t of traces) printTrace(t)\n })\n\nfunction printTrace(t: any): void {\n const status = t.status || \"ok\"\n const color = status === \"ok\" ? chalk.green : status === \"error\" ? chalk.red : chalk.cyan\n const tokens = t.totalTokens != null ? `${t.totalTokens}t` : \"—\"\n const dur = t.durationMs != null ? `${t.durationMs}ms` : \"—\"\n const model = t.model || \"—\"\n console.log(` ${color(status.padEnd(5))} ${chalk.bold(String(t.nodeId || t.label || \"(node)\"))}`)\n console.log(` ${chalk.dim(\"taskId:\")} ${t.taskId || \"—\"}`)\n console.log(` ${chalk.dim(\"model:\")} ${model}`)\n console.log(` ${chalk.dim(\"tokens:\")} ${tokens} ${chalk.dim(\"duration:\")} ${dur}`)\n if (t.error) console.log(` ${chalk.dim(\"error:\")} ${chalk.red(String(t.error).slice(0, 300))}`)\n console.log()\n}\n\nworkflow\n .command(\"pause <runId>\")\n .description(\"pause an active run\")\n .option(\"--node <id>\", \"home-node id\", )\n .action((runId: string, opts) => {\n const nodeId = opts.node || process.env.WF_NODE_ID || \"local\"\n const runs = new RunStore({ nodeId })\n const updated = runs.setStatus(runId, \"paused\")\n if (!updated) { console.log(chalk.yellow(` no such run: ${runId}`)); process.exit(1) }\n console.log(chalk.green(` ✓ paused ${runId}`))\n })\n\nworkflow\n .command(\"resume <runId>\")\n .description(\"resume a paused run\")\n .option(\"--node <id>\", \"home-node id\")\n .action((runId: string, opts) => {\n const nodeId = opts.node || process.env.WF_NODE_ID || \"local\"\n const runs = new RunStore({ nodeId })\n const updated = runs.setStatus(runId, \"running\")\n if (!updated) { console.log(chalk.yellow(` no such run: ${runId}`)); process.exit(1) }\n console.log(chalk.green(` ✓ resumed ${runId}`))\n })\n\nworkflow\n .command(\"cancel <runId>\")\n .description(\"cancel an active run\")\n .option(\"--node <id>\", \"home-node id\")\n .action((runId: string, opts) => {\n const nodeId = opts.node || process.env.WF_NODE_ID || \"local\"\n const runs = new RunStore({ nodeId })\n const updated = runs.setStatus(runId, \"canceled\")\n if (!updated) { console.log(chalk.yellow(` no such run: ${runId}`)); process.exit(1) }\n console.log(chalk.green(` ✓ canceled ${runId}`))\n })\n","// Workflow templates — bundled as string exports so they survive\n// tsup's tree-shaking. Each template is the raw YAML; the CLI loads\n// it, substitutes the placeholders (__ID__, __TITLE__, __AGENT__,\n// __REVIEWER__), and writes the result into .agentx/workflows/.\n//\n// Why inline as a TS module instead of copying the .yaml files into\n// dist/? Two reasons: (1) tsup doesn't copy non-code assets, and\n// adding a custom copy step risks drift between dev and prod; (2) the\n// templates are small enough that inlining costs ~5KB in the bundle\n// — well below the threshold worth a separate file pipeline.\n//\n// To edit: change the .yaml file in this directory, then re-run\n// `pnpm tsx scripts/sync-templates.ts` (or just paste the new\n// content into the matching export below). The .yaml files are the\n// source of truth; this index.ts is a hand-mirror.\n\nimport { readFileSync } from \"fs\"\nimport { resolve, dirname } from \"path\"\nimport { fileURLToPath } from \"url\"\n\nexport type TemplateName =\n | \"linear\"\n | \"branching\"\n | \"extract\"\n | \"retry\"\n\nexport interface TemplateMeta {\n name: TemplateName\n title: string\n description: string\n}\n\nexport const TEMPLATES: TemplateMeta[] = [\n { name: \"linear\", title: \"Linear\", description: \"Trigger → Agent → End. Smallest workflow that runs.\" },\n { name: \"branching\", title: \"Branching\", description: \"Classify, then route on the result via a branch node.\" },\n { name: \"extract\", title: \"Structured extraction\", description: \"Pull typed fields from free-form text via extract.structured.\" },\n { name: \"retry\", title: \"Retry + fallback\", description: \"Per-node retry policy with a branch fallback path.\" },\n]\n\n/** Read a template's raw YAML. Tries a small set of candidate paths\n * so the same code works in (a) dev, where templates sit next to\n * this .ts file, and (b) the bundled CLI, where tsup's onSuccess\n * hook copies them to `dist/workflows/templates/`. After bundling\n * the calling chunk may not live at dist/cli.js, so we fall back\n * to argv[1]-relative + a couple of common parent layouts before\n * giving up. */\nexport function readTemplate(name: TemplateName): string {\n const here = dirname(fileURLToPath(import.meta.url))\n const cliDir = process.argv[1] ? dirname(process.argv[1]) : \"\"\n const candidates = [\n resolve(here, `${name}.yaml`),\n resolve(here, \"workflows/templates\", `${name}.yaml`),\n resolve(here, \"..\", \"workflows/templates\", `${name}.yaml`),\n resolve(here, \"../..\", \"workflows/templates\", `${name}.yaml`),\n cliDir ? resolve(cliDir, \"workflows/templates\", `${name}.yaml`) : \"\",\n cliDir ? resolve(cliDir, \"..\", \"workflows/templates\", `${name}.yaml`) : \"\",\n ].filter(Boolean) as string[]\n for (const path of candidates) {\n try { return readFileSync(path, \"utf-8\") } catch { /* try next */ }\n }\n throw new Error(`workflow template \"${name}\" not found in any of:\\n ${candidates.join(\"\\n \")}`)\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport prompts from \"prompts\"\nimport { readFileSync, existsSync } from \"fs\"\nimport { resolve } from \"path\"\nimport { applyConfigMutation } from \"@/daemon/config-mutator\"\n\n// --- agentx webhook — manage webhook entries from the CLI ---\n//\n// CLI parity with the dashboard's /admin → Webhooks tab. Mutates agentx.json\n// directly through applyConfigMutation, which validates with Zod and signals\n// the running daemon to hot-reload (no restart required).\n//\n// Subcommands:\n// list — print all webhook entries\n// add [id] — interactive add (or use flags)\n// remove <id> — delete a webhook entry\n// enable <id> — enable a webhook\n// disable <id> — disable a webhook\n// triggers set <id> <event> <workflow> — map event-type to workflow id\n// triggers remove <id> <event> — remove a trigger map entry\n// triggers default <id> <workflow> — set default workflow (no event match)\n\nconst VALID_SOURCES = [\"gitlab\", \"github\", \"sentry\", \"stripe\", \"vercel\", \"odoo\", \"hubspot\", \"discord\", \"slack\", \"custom\"] as const\ntype WebhookSource = (typeof VALID_SOURCES)[number]\n\nconst WIRED_SOURCES = new Set<WebhookSource>([\"gitlab\", \"github\", \"sentry\", \"stripe\", \"vercel\", \"odoo\", \"hubspot\"])\n\nconst SOURCE_HINTS: Record<WebhookSource, string> = {\n gitlab: \"GitLab → Settings → Webhooks (tick Push/Issue/Pipeline events)\",\n github: \"GitHub → Repo Settings → Webhooks\",\n sentry: \"Sentry → Project Settings → Alerts → Webhooks\",\n stripe: \"Stripe Dashboard → Developers → Webhooks\",\n vercel: \"Vercel → Project Settings → Webhooks\",\n odoo: \"Odoo → Settings → Technical → Automation → Webhooks (or your installed `webhook` module)\",\n hubspot: \"HubSpot → Settings → Integrations → Private Apps → Webhooks subscription\",\n discord: \"Discord channel → Integrations → Webhooks (inbound-only, no on:* events)\",\n slack: \"Slack Outgoing Webhooks / Events API (inbound-only, no on:* events)\",\n custom: \"Any service that POSTs JSON — Linear, Calendly, Notion, etc. (inbound-only)\",\n}\n\nfunction loadConfig(): any {\n const p = resolve(process.cwd(), \"agentx.json\")\n if (!existsSync(p)) throw new Error(\"No agentx.json found. Run: agentx init\")\n return JSON.parse(readFileSync(p, \"utf-8\"))\n}\n\nfunction statusBadge(w: any): string {\n if (!w.enabled) return chalk.dim(\"disabled\")\n const missingSecret = w.source !== \"custom\" && !w.secretEnv\n if (missingSecret) return chalk.yellow(\"⚠ no signing secret\")\n return chalk.green(\"✓ active\")\n}\n\nfunction printOneJson(w: any): void {\n console.log(JSON.stringify(w, null, 2))\n}\n\nfunction printOneHuman(w: any, daemonUrl?: string): void {\n const url = daemonUrl\n ? `${daemonUrl.replace(/\\/+$/, \"\")}/webhook/${encodeURIComponent(w.agentId)}/${encodeURIComponent(w.source)}`\n : `/webhook/${encodeURIComponent(w.agentId)}/${encodeURIComponent(w.source)}`\n const wired = WIRED_SOURCES.has(w.source) ? chalk.dim(\" · emits on:\" + w.source + \"-* hook events\") : \"\"\n console.log(` ${chalk.cyan(w.id)} ${statusBadge(w)}`)\n console.log(` ${chalk.dim(w.source)} → ${chalk.bold(w.agentId)}${wired}`)\n console.log(` POST ${chalk.dim(url)}`)\n if (w.secretEnv) console.log(` secret: ${chalk.dim(\"$\" + w.secretEnv)}`)\n if (w.description) console.log(` ${chalk.dim(w.description)}`)\n const triggers = w.triggers && typeof w.triggers === \"object\" ? w.triggers : {}\n const triggerKeys = Object.keys(triggers)\n if (triggerKeys.length) {\n console.log(` ${chalk.dim(\"triggers:\")}`)\n for (const k of triggerKeys) console.log(` ${k} → ${triggers[k]}`)\n }\n if (w.defaultWorkflow) {\n console.log(` ${chalk.dim(\"default workflow:\")} ${w.defaultWorkflow}`)\n }\n console.log()\n}\n\nexport const webhook = new Command()\n .name(\"webhook\")\n .description(\"manage webhook entries (gitlab, github, sentry, stripe, vercel, custom)\")\n\n// agentx webhook list\nwebhook\n .command(\"list\")\n .alias(\"ls\")\n .description(\"list webhook entries\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const cfg = loadConfig()\n const entries = Array.isArray(cfg.webhooks) ? cfg.webhooks : []\n if (opts.json) {\n console.log(JSON.stringify(entries, null, 2))\n return\n }\n if (!entries.length) {\n console.log(chalk.dim(\"\\n No webhooks registered. Add one with: agentx webhook add\\n\"))\n return\n }\n console.log()\n for (const w of entries) printOneHuman(w)\n })\n\n// agentx webhook add [id]\nwebhook\n .command(\"add [id]\")\n .description(\"register a new webhook entry\")\n .option(\"--source <source>\", `one of: ${VALID_SOURCES.join(\", \")}`)\n .option(\"--agent <agentId>\", \"agent that receives the webhook\")\n .option(\"--secret-env <name>\", \"env var holding the signing secret (recommended)\")\n .option(\"--description <text>\", \"free-text description\")\n .option(\"--node <peer>\", \"forward to a mesh peer (skips local agent check; validates against mesh.peers)\")\n .option(\"--no-prompt\", \"fail instead of prompting for missing values\")\n .action(async (idArg, opts) => {\n const cfg = loadConfig()\n const knownAgents = Object.keys(cfg.agents || {})\n const meshPeers: string[] = (cfg.mesh?.peers || []).map((p: any) => p.name).filter(Boolean)\n const node = String(opts.node || \"\").trim()\n if (!knownAgents.length && !node) throw new Error(\"No local agents configured. Add one with: agentx agent add — or use --node <peer> to forward to a mesh peer.\")\n\n let id = (idArg || \"\").trim()\n let source = String(opts.source || \"\").trim() as WebhookSource\n let agentId = String(opts.agent || \"\").trim()\n let secretEnv = String(opts.secretEnv || \"\").trim()\n let description = String(opts.description || \"\").trim()\n\n const interactive = opts.prompt !== false\n\n if (!id && interactive) {\n const r = await prompts({\n type: \"text\",\n name: \"id\",\n message: \"Webhook id (lowercase, e.g. globex-gitlab)\",\n validate: (v: string) => /^[a-z0-9][a-z0-9_-]*$/.test(v) || \"Use lowercase letters, digits, -, _\",\n })\n id = (r.id || \"\").trim()\n }\n if (!id) throw new Error(\"Webhook id is required.\")\n if (!/^[a-z0-9][a-z0-9_-]*$/.test(id)) throw new Error(\"Webhook id must be lowercase (letters, digits, -, _).\")\n\n if (!source && interactive) {\n const r = await prompts({\n type: \"select\",\n name: \"source\",\n message: \"Source\",\n choices: VALID_SOURCES.map((s) => ({\n title: `${s}${WIRED_SOURCES.has(s) ? \" ✓ wired\" : \"\"}`,\n value: s,\n description: SOURCE_HINTS[s],\n })),\n })\n source = r.source\n }\n if (!VALID_SOURCES.includes(source)) {\n throw new Error(`Source must be one of: ${VALID_SOURCES.join(\", \")}`)\n }\n\n if (!agentId && interactive) {\n // When --node is set, ask for a free-text agent id (the agent lives\n // on the remote peer; we don't have its definition locally).\n if (node) {\n const r = await prompts({\n type: \"text\",\n name: \"agentId\",\n message: `Agent on remote peer \"${node}\"`,\n })\n agentId = (r.agentId || \"\").trim()\n } else {\n const r = await prompts({\n type: \"select\",\n name: \"agentId\",\n message: \"Agent\",\n choices: knownAgents.map((a) => ({ title: a, value: a })),\n })\n agentId = r.agentId\n }\n }\n if (!agentId) throw new Error(\"Agent is required.\")\n if (node) {\n if (!meshPeers.includes(node)) {\n throw new Error(`Mesh peer \"${node}\" not found in mesh.peers. Add the peer first or omit --node.`)\n }\n } else if (!cfg.agents?.[agentId]) {\n throw new Error(`Unknown agent \"${agentId}\". Add it locally, or use --node <peer> to forward to a mesh peer.`)\n }\n\n if (!secretEnv && interactive && source !== \"custom\") {\n const r = await prompts({\n type: \"text\",\n name: \"secretEnv\",\n message: `Signing secret env-var (recommended for ${source})`,\n initial: `${source.toUpperCase()}_WEBHOOK_SECRET`,\n })\n secretEnv = (r.secretEnv || \"\").trim()\n }\n\n if (!description && interactive) {\n const r = await prompts({ type: \"text\", name: \"description\", message: \"Description (optional)\" })\n description = (r.description || \"\").trim()\n }\n\n const result = await applyConfigMutation((c: any) => {\n c.webhooks = Array.isArray(c.webhooks) ? c.webhooks : []\n if (c.webhooks.find((w: any) => w.id === id)) {\n throw new Error(`Webhook \"${id}\" already exists.`)\n }\n const entry: any = { id, source, agentId, enabled: true }\n if (secretEnv) entry.secretEnv = secretEnv\n if (description) entry.description = description\n if (node) entry.node = node\n c.webhooks.push(entry)\n })\n if (!result.success) throw new Error(result.error)\n\n console.log(chalk.green(`✓ added webhook \"${id}\" (${source} → ${agentId}${node ? ` @ ${node}` : \"\"})`))\n if (result.reloaded) console.log(chalk.dim(\" daemon hot-reloaded\"))\n if (!secretEnv && source !== \"custom\") {\n console.log(chalk.yellow(` ⚠ no signing secret set — payloads will be accepted unsigned. Add one with --secret-env`))\n }\n })\n\n// agentx webhook remove <id>\nwebhook\n .command(\"remove <id>\")\n .alias(\"rm\")\n .description(\"delete a webhook entry\")\n .option(\"--yes\", \"skip confirmation\")\n .action(async (id, opts) => {\n if (!opts.yes) {\n const r = await prompts({ type: \"confirm\", name: \"ok\", message: `Delete webhook \"${id}\"?`, initial: false })\n if (!r.ok) return\n }\n const result = await applyConfigMutation((c: any) => {\n const before = (c.webhooks || []).length\n c.webhooks = (c.webhooks || []).filter((w: any) => w.id !== id)\n if (c.webhooks.length === before) throw new Error(`Webhook \"${id}\" not found.`)\n })\n if (!result.success) throw new Error(result.error)\n console.log(chalk.green(`✓ removed webhook \"${id}\"`))\n })\n\n// agentx webhook enable <id> / disable <id>\nfunction toggleEnabled(enabled: boolean) {\n return async (id: string) => {\n const result = await applyConfigMutation((c: any) => {\n const w = (c.webhooks || []).find((x: any) => x.id === id)\n if (!w) throw new Error(`Webhook \"${id}\" not found.`)\n w.enabled = enabled\n })\n if (!result.success) throw new Error(result.error)\n console.log(chalk.green(`✓ ${enabled ? \"enabled\" : \"disabled\"} webhook \"${id}\"`))\n }\n}\n\nwebhook.command(\"enable <id>\").description(\"enable a webhook entry\").action(toggleEnabled(true))\nwebhook.command(\"disable <id>\").description(\"disable a webhook entry\").action(toggleEnabled(false))\n\n// agentx webhook triggers ...\nconst triggers = new Command()\n .name(\"triggers\")\n .description(\"manage event-type → workflow mappings on a webhook\")\n\ntriggers\n .command(\"set <id> <eventType> <workflowId>\")\n .description(\"map an event-type to a workflow id\")\n .action(async (id: string, eventType: string, workflowId: string) => {\n const result = await applyConfigMutation((c: any) => {\n const w = (c.webhooks || []).find((x: any) => x.id === id)\n if (!w) throw new Error(`Webhook \"${id}\" not found.`)\n w.triggers = w.triggers && typeof w.triggers === \"object\" ? w.triggers : {}\n w.triggers[eventType] = workflowId\n })\n if (!result.success) throw new Error(result.error)\n console.log(chalk.green(`✓ ${id}: ${eventType} → ${workflowId}`))\n })\n\ntriggers\n .command(\"remove <id> <eventType>\")\n .alias(\"rm\")\n .description(\"remove an event-type → workflow mapping\")\n .action(async (id: string, eventType: string) => {\n const result = await applyConfigMutation((c: any) => {\n const w = (c.webhooks || []).find((x: any) => x.id === id)\n if (!w) throw new Error(`Webhook \"${id}\" not found.`)\n if (w.triggers && typeof w.triggers === \"object\") delete w.triggers[eventType]\n })\n if (!result.success) throw new Error(result.error)\n console.log(chalk.green(`✓ removed trigger ${eventType} from \"${id}\"`))\n })\n\ntriggers\n .command(\"default <id> <workflowId>\")\n .description(\"set the default workflow when no event-type matches (use '-' to clear)\")\n .action(async (id: string, workflowId: string) => {\n const clear = workflowId === \"-\" || workflowId === \"\"\n const result = await applyConfigMutation((c: any) => {\n const w = (c.webhooks || []).find((x: any) => x.id === id)\n if (!w) throw new Error(`Webhook \"${id}\" not found.`)\n if (clear) delete w.defaultWorkflow\n else w.defaultWorkflow = workflowId\n })\n if (!result.success) throw new Error(result.error)\n console.log(chalk.green(`✓ ${id}: defaultWorkflow ${clear ? \"cleared\" : `→ ${workflowId}`}`))\n })\n\nwebhook.addCommand(triggers)\n\n// agentx webhook sources — list known sources with hints\nwebhook\n .command(\"sources\")\n .description(\"list known webhook source types\")\n .option(\"--json\", \"emit JSON\")\n .action((opts) => {\n const list = VALID_SOURCES.map((s) => ({\n source: s,\n wired: WIRED_SOURCES.has(s),\n hint: SOURCE_HINTS[s],\n }))\n if (opts.json) {\n console.log(JSON.stringify(list, null, 2))\n return\n }\n console.log()\n for (const item of list) {\n const tag = item.wired ? chalk.green(\"✓ wired\") : chalk.dim(\"inbound-only\")\n console.log(` ${chalk.cyan(item.source.padEnd(8))} ${tag} ${chalk.dim(item.hint)}`)\n }\n console.log()\n console.log(chalk.dim(\" Wired sources emit on:<source>-* hook events that workflows can subscribe to via trigger.hook.\"))\n console.log(chalk.dim(\" Use 'custom' for any service not in the list (Odoo, HubSpot, Linear, Calendly, etc.).\"))\n console.log()\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { mutateAgentxConfig } from \"@/daemon/config-mutate\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx business — manage the business layer config ---\n//\n// Closes the second-pass parity gap: business.* in agentx.json had no\n// CLI surface and no dashboard UI, forcing operators to hand-edit\n// JSON for org-chart / project / contact-map changes — the same data\n// the activity-graph attribution and PM-gating rely on.\n//\n// Scope kept narrow on purpose:\n// show — read-only summary\n// orgchart — add / remove / list entries (agentId → { role, reportsTo, schedule })\n// project — add / remove / list (id, pm?, client?)\n// contact — add / remove / list (chatId/username → client/project)\n//\n// Out of scope for this round (use Advanced JSON tab in /admin or hand-\n// edit): workSource, roles, schedules beyond start/end, mainChannel.\n\nfunction mutate(mutator: (cfg: any) => string): void {\n const { summary, backupPath } = mutateAgentxConfig((cfg) => mutator(cfg))\n console.log(chalk.green(`\\n ✓ ${summary}`))\n if (backupPath) console.log(chalk.dim(` Backup: ${backupPath}`))\n console.log(chalk.dim(` Restart the daemon (or POST /reload) for the change to take effect.\\n`))\n}\n\nfunction readBusiness(): any {\n try {\n const cfg = loadDaemonConfig()\n return (cfg as any).business || {}\n } catch {\n return {}\n }\n}\n\nexport const business = new Command()\n .name(\"business\")\n .description(\"manage the business layer in agentx.json — orgChart, projects, contactMap\")\n\n// ---- show ----------------------------------------------------------------\n\nbusiness\n .command(\"show\")\n .description(\"print the current business config (orgChart, projects, contactMap)\")\n .option(\"--json\", \"machine-readable JSON\")\n .action((opts) => {\n const b = readBusiness()\n if (opts.json) { console.log(JSON.stringify(b, null, 2)); return }\n if (!b || !b.enabled) {\n console.log()\n console.log(chalk.yellow(\" business block not enabled (or missing).\"))\n console.log(chalk.dim(\" Add a `business` key to agentx.json to opt in.\"))\n console.log()\n return\n }\n const orgChart = b.orgChart || {}\n const projects = b.projects || []\n const contactMap = b.contactMap || []\n console.log()\n console.log(chalk.bold(\" Org chart\"))\n const orgEntries = Object.entries(orgChart) as Array<[string, any]>\n if (orgEntries.length === 0) console.log(chalk.dim(\" (empty)\"))\n else for (const [id, e] of orgEntries) {\n const reports = e.reportsTo ? chalk.dim(` → reports to ${e.reportsTo}`) : \"\"\n const sched = e.schedule ? chalk.dim(` · ${(e.schedule.days || []).join(\",\")} ${e.schedule.start}–${e.schedule.end}`) : \"\"\n console.log(` ${chalk.cyan(id)} ${e.role}${reports}${sched}`)\n }\n console.log()\n console.log(chalk.bold(` Projects (${projects.length})`))\n if (projects.length === 0) console.log(chalk.dim(\" (empty)\"))\n else for (const p of projects) {\n const pm = p.pm ? chalk.dim(` · pm=${p.pm}`) : \"\"\n const client = p.client ? chalk.dim(` · client=${p.client}`) : \"\"\n console.log(` ${chalk.cyan(p.id)}${pm}${client}`)\n }\n console.log()\n console.log(chalk.bold(` Contact map (${contactMap.length})`))\n if (contactMap.length === 0) console.log(chalk.dim(\" (empty)\"))\n else for (const c of contactMap) {\n const key = c.chatId ? `chatId=${c.chatId}` : c.username ? `username=${c.username}` : c.senderId ? `senderId=${c.senderId}` : \"?\"\n const ch = c.channel ? `${c.channel}/` : \"\"\n console.log(` ${chalk.cyan(ch + key)} → ${c.client}${c.project ? `/${c.project}` : \"\"}${c.displayName ? chalk.dim(` (${c.displayName})`) : \"\"}`)\n }\n console.log()\n })\n\n// ---- orgchart ------------------------------------------------------------\n\nconst orgchart = business\n .command(\"orgchart\")\n .description(\"manage business.orgChart — agentId → { role, reportsTo, schedule }\")\n\norgchart\n .command(\"list\")\n .description(\"list orgChart entries\")\n .option(\"--json\", \"JSON output\")\n .action((opts) => {\n const b = readBusiness()\n const entries = Object.entries(b.orgChart || {}) as Array<[string, any]>\n if (opts.json) { console.log(JSON.stringify(Object.fromEntries(entries), null, 2)); return }\n if (entries.length === 0) { console.log(chalk.dim(\" no entries\")); return }\n for (const [id, e] of entries) {\n console.log(` ${chalk.cyan(id)} ${e.role}${e.reportsTo ? chalk.dim(` → ${e.reportsTo}`) : \"\"}`)\n }\n })\n\norgchart\n .command(\"add <agentId>\")\n .description(\"add or update an orgChart entry for an agent\")\n .requiredOption(\"--role <role>\", \"role title (e.g. 'PM', 'Coder', 'DevOps')\")\n .option(\"--reports-to <agentId>\", \"manager's agentId\")\n .option(\"--start <hh:mm>\", \"schedule start\", \"09:00\")\n .option(\"--end <hh:mm>\", \"schedule end\", \"17:00\")\n .option(\"--days <csv>\", \"working days (mon,tue,wed,thu,fri)\", \"mon,tue,wed,thu,fri\")\n .option(\"--utilization <0..1>\", \"target utilization\", \"0.8\")\n .action((agentId: string, opts) => {\n const days = String(opts.days).split(\",\").map((s) => s.trim()).filter(Boolean) as Array<\"mon\" | \"tue\" | \"wed\" | \"thu\" | \"fri\" | \"sat\" | \"sun\">\n mutate((cfg) => {\n cfg.business = cfg.business || {}\n cfg.business.orgChart = cfg.business.orgChart || {}\n cfg.business.orgChart[agentId] = {\n role: opts.role,\n ...(opts.reportsTo ? { reportsTo: opts.reportsTo } : {}),\n schedule: { days, start: opts.start, end: opts.end },\n utilizationTarget: parseFloat(opts.utilization) || 0.8,\n }\n return `orgChart entry \"${agentId}\" upserted (role=${opts.role}${opts.reportsTo ? `, reports to ${opts.reportsTo}` : \"\"})`\n })\n })\n\norgchart\n .command(\"remove <agentId>\")\n .alias(\"rm\")\n .description(\"remove an orgChart entry\")\n .action((agentId: string) => {\n mutate((cfg) => {\n if (!cfg.business?.orgChart || !(agentId in cfg.business.orgChart)) {\n throw new Error(`no orgChart entry for \"${agentId}\"`)\n }\n delete cfg.business.orgChart[agentId]\n return `orgChart entry \"${agentId}\" removed`\n })\n })\n\n// ---- project -------------------------------------------------------------\n\nconst project = business\n .command(\"project\")\n .description(\"manage business.projects — id, pm, client\")\n\nproject\n .command(\"list\")\n .description(\"list projects\")\n .option(\"--json\", \"JSON output\")\n .action((opts) => {\n const b = readBusiness()\n const projects = b.projects || []\n if (opts.json) { console.log(JSON.stringify(projects, null, 2)); return }\n if (projects.length === 0) { console.log(chalk.dim(\" no projects\")); return }\n for (const p of projects) {\n console.log(` ${chalk.cyan(p.id)} ${p.pm ? `pm=${p.pm}` : \"\"} ${p.client ? `client=${p.client}` : \"\"}`.trimEnd())\n }\n })\n\nproject\n .command(\"add <id>\")\n .description(\"add or update a project entry\")\n .option(\"--pm <agentId>\", \"PM responsible for this project (drives PM gate)\")\n .option(\"--client <name>\", \"client this project belongs to (drives activity-graph attribution)\")\n .action((id: string, opts) => {\n mutate((cfg) => {\n cfg.business = cfg.business || {}\n cfg.business.projects = cfg.business.projects || []\n const idx = cfg.business.projects.findIndex((p: any) => p.id === id)\n const next = { id, ...(opts.pm ? { pm: opts.pm } : {}), ...(opts.client ? { client: opts.client } : {}) }\n if (idx >= 0) cfg.business.projects[idx] = { ...cfg.business.projects[idx], ...next }\n else cfg.business.projects.push(next)\n return idx >= 0 ? `project \"${id}\" updated` : `project \"${id}\" added`\n })\n })\n\nproject\n .command(\"remove <id>\")\n .alias(\"rm\")\n .description(\"remove a project entry\")\n .action((id: string) => {\n mutate((cfg) => {\n const list = cfg.business?.projects || []\n const before = list.length\n cfg.business.projects = list.filter((p: any) => p.id !== id)\n if (cfg.business.projects.length === before) throw new Error(`no project \"${id}\"`)\n return `project \"${id}\" removed`\n })\n })\n\n// ---- contact -------------------------------------------------------------\n\nconst contact = business\n .command(\"contact\")\n .description(\"manage business.contactMap — chatId/username/senderId → client/project\")\n\ncontact\n .command(\"list\")\n .description(\"list contact map entries\")\n .option(\"--json\", \"JSON output\")\n .action((opts) => {\n const b = readBusiness()\n const list = b.contactMap || []\n if (opts.json) { console.log(JSON.stringify(list, null, 2)); return }\n if (list.length === 0) { console.log(chalk.dim(\" no entries\")); return }\n for (const c of list) {\n const key = c.chatId ? `chatId=${c.chatId}` : c.username ? `username=${c.username}` : c.senderId ? `senderId=${c.senderId}` : \"?\"\n console.log(` ${c.channel ? c.channel + \"/\" : \"\"}${chalk.cyan(key)} → ${c.client}${c.project ? \"/\" + c.project : \"\"}`)\n }\n })\n\ncontact\n .command(\"add\")\n .description(\"add a contactMap entry\")\n .requiredOption(\"--client <name>\", \"client this contact belongs to\")\n .option(\"--channel <name>\", \"telegram | whatsapp | slack | discord\")\n .option(\"--chat-id <id>\", \"native chat id (e.g. -100…, JID)\")\n .option(\"--username <handle>\", \"sender username/handle\")\n .option(\"--sender-id <id>\", \"numeric sender id (when username is unstable)\")\n .option(\"--project <id>\", \"project this traffic should attribute to\")\n .option(\"--display-name <name>\", \"display-name override for the initiator pill\")\n .action((opts) => {\n if (!opts.chatId && !opts.username && !opts.senderId) {\n console.log(chalk.red(\" one of --chat-id / --username / --sender-id is required\"))\n process.exit(1)\n }\n mutate((cfg) => {\n cfg.business = cfg.business || {}\n cfg.business.contactMap = cfg.business.contactMap || []\n const entry: any = { client: opts.client }\n if (opts.channel) entry.channel = opts.channel\n if (opts.chatId) entry.chatId = opts.chatId\n if (opts.username) entry.username = opts.username\n if (opts.senderId) entry.senderId = opts.senderId\n if (opts.project) entry.project = opts.project\n if (opts.displayName) entry.displayName = opts.displayName\n cfg.business.contactMap.push(entry)\n const key = opts.chatId || opts.username || opts.senderId\n return `contact ${opts.channel ? opts.channel + \"/\" : \"\"}${key} → ${opts.client}${opts.project ? \"/\" + opts.project : \"\"} added`\n })\n })\n\ncontact\n .command(\"remove\")\n .alias(\"rm\")\n .description(\"remove a contactMap entry by matching field(s)\")\n .option(\"--channel <name>\")\n .option(\"--chat-id <id>\")\n .option(\"--username <handle>\")\n .option(\"--sender-id <id>\")\n .action((opts) => {\n mutate((cfg) => {\n const list = cfg.business?.contactMap || []\n const before = list.length\n cfg.business.contactMap = list.filter((c: any) => {\n if (opts.channel && c.channel !== opts.channel) return true\n if (opts.chatId && c.chatId !== opts.chatId) return true\n if (opts.username && c.username !== opts.username) return true\n if (opts.senderId && c.senderId !== opts.senderId) return true\n return false // matched all provided filters → drop\n })\n if (cfg.business.contactMap.length === before) throw new Error(\"no matching contact entry\")\n return `${before - cfg.business.contactMap.length} contact entry/entries removed`\n })\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { DayPlanStore, parsePriorities, type PlanTier } from \"@/business/day-plan\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx plan: human-driven daily / weekly / monthly priorities ---\n//\n// Replaces the old mechanical standup-tick. The day-cycle reads\n// .agentx/plans/<date>.md (day → week → month fallback) every morning;\n// without a plan, the cycle posts a notification and dispatches no agent.\n// This CLI is the fast path for operators who'd rather type than open the\n// admin form. Markdown files are also editable directly on disk and via\n// the admin Plans tab — three surfaces, one source of truth.\n\nconst TIER_ALIAS: Record<string, PlanTier> = {\n today: \"day\", day: \"day\",\n week: \"week\", \"this-week\": \"week\",\n month: \"month\", \"this-month\": \"month\",\n}\n\nfunction resolveTier(label: string): PlanTier {\n const t = TIER_ALIAS[label.toLowerCase()]\n if (!t) throw new Error(`Unknown plan tier \"${label}\". Use: today | week | month.`)\n return t\n}\n\nfunction resolveStore(): DayPlanStore {\n const cfg = loadDaemonConfig()\n const dir = cfg.business?.standup?.plansDir || \".agentx/plans\"\n return new DayPlanStore(dir)\n}\n\nexport const plan = new Command()\n .name(\"plan\")\n .description(\"set / read / list day-week-month plans that drive the standup-tick\")\n\nplan\n .command(\"set <tier>\")\n .description(\"write a plan for today | week | month (priorities-as-bullets)\")\n .option(\"-p, --priority <text...>\", \"bullet line — repeat for multiple priorities\")\n .option(\"-m, --markdown <md>\", \"raw markdown body (overrides --priority)\")\n .option(\"-f, --file <path>\", \"read markdown from a file\")\n .action(async (tier: string, opts) => {\n const t = resolveTier(tier)\n const store = resolveStore()\n let body: string\n if (opts.file) {\n const { readFileSync } = await import(\"fs\")\n body = readFileSync(opts.file, \"utf-8\")\n } else if (opts.markdown) {\n body = opts.markdown\n } else if (opts.priority?.length) {\n body = (opts.priority as string[]).map((p) => `- ${p}`).join(\"\\n\")\n } else {\n console.error(chalk.red(\" Provide --priority, --markdown, or --file.\"))\n process.exit(1)\n }\n const result = store.write(t, body)\n console.log(chalk.green(` ✓ ${t} plan saved → ${result.path}`))\n const items = parsePriorities(body)\n if (items.length) {\n console.log(chalk.dim(` ${items.length} bullet${items.length === 1 ? \"\" : \"s\"}:`))\n for (const it of items) console.log(chalk.dim(` • ${it}`))\n }\n })\n\nplan\n .command(\"show [tier]\")\n .description(\"print the plan that the next standup will use (default: resolve day→week→month)\")\n .action(async (tier: string | undefined) => {\n const store = resolveStore()\n if (tier) {\n const t = resolveTier(tier)\n const r = store.read(t)\n if (!r) { console.log(chalk.dim(` No ${t} plan set.`)); return }\n printPlan(r.tier, r.date, r.content)\n return\n }\n const r = store.resolve()\n if (!r) {\n console.log(chalk.yellow(\" No plan set at any tier.\"))\n console.log(chalk.dim(\" The next standup-tick will post a 'no plan today' notice and dispatch no agent.\"))\n console.log(chalk.dim(\" Set one with: agentx plan set today --priority \\\"…\\\"\"))\n return\n }\n printPlan(r.tier, r.date, r.content)\n })\n\nplan\n .command(\"list\")\n .description(\"recent plans across all tiers\")\n .option(\"-n, --limit <n>\", \"max rows\", \"20\")\n .action(async (opts) => {\n const store = resolveStore()\n const rows = store.list(parseInt(opts.limit, 10) || 20)\n if (!rows.length) { console.log(chalk.dim(\" No plans yet.\")); return }\n for (const r of rows) {\n console.log(` ${chalk.cyan(r.tier.padEnd(5))} ${chalk.bold(r.date.padEnd(11))} ${chalk.dim(r.path)}`)\n }\n })\n\nplan\n .command(\"clear <tier>\")\n .description(\"remove the plan for today | week | month\")\n .action(async (tier: string) => {\n const t = resolveTier(tier)\n const store = resolveStore()\n const existing = store.read(t)\n if (!existing) { console.log(chalk.dim(` No ${t} plan to clear.`)); return }\n const { unlinkSync } = await import(\"fs\")\n unlinkSync(existing.path)\n console.log(chalk.green(` ✓ ${t} plan cleared (${existing.path})`))\n })\n\nfunction printPlan(tier: PlanTier, date: string, content: string): void {\n console.log(chalk.cyan(` ${tier} plan — ${date}`))\n console.log()\n for (const line of content.split(\"\\n\")) console.log(` ${line}`)\n console.log()\n const items = parsePriorities(content)\n if (items.length) console.log(chalk.dim(` ${items.length} bullet${items.length === 1 ? \"\" : \"s\"} extracted as priorities.`))\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { mutateAgentxConfig } from \"@/daemon/config-mutate\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx notifications — manage where + when AgentX pings the operator ---\n//\n// Closes the audit gap: notifications.* in agentx.json had no CLI surface.\n// Operators tuning where task-error pings land or which event types are\n// surfaced were stuck hand-editing JSON.\n//\n// The whole notifications block is small: a destination (channel/chatId/\n// accountId), three event toggles (taskComplete / taskError / taskQueued),\n// and a longTaskThreshold.\n\nfunction readNotifications(): any {\n try { return (loadDaemonConfig() as any).notifications || {} } catch { return {} }\n}\n\nfunction mutate(mutator: (n: any) => string): void {\n const { summary, backupPath } = mutateAgentxConfig((cfg) => {\n cfg.notifications = cfg.notifications || {}\n return mutator(cfg.notifications)\n })\n console.log(chalk.green(`\\n ✓ ${summary}`))\n if (backupPath) console.log(chalk.dim(` Backup: ${backupPath}`))\n console.log(chalk.dim(` Restart the daemon (or POST /reload) for the change to take effect.\\n`))\n}\n\nexport const notifications = new Command()\n .name(\"notifications\")\n .description(\"manage notifications routing — destination, event toggles, long-task threshold\")\n\nnotifications\n .command(\"show\")\n .description(\"print current notifications config\")\n .option(\"--json\", \"JSON output\")\n .action((opts) => {\n const n = readNotifications()\n if (opts.json) { console.log(JSON.stringify(n, null, 2)); return }\n console.log()\n if (n.destination) {\n const acct = n.destination.accountId ? ` · account=${n.destination.accountId}` : \"\"\n console.log(` destination ${chalk.cyan(n.destination.channel + \":\" + n.destination.chatId)}${chalk.dim(acct)}`)\n } else {\n console.log(` destination ${chalk.dim(\"(unset — notifications go to the daemon log only)\")}`)\n }\n console.log(` longTaskThreshold ${n.longTaskThreshold ?? 30}s ${chalk.dim(\"(0 disables long-task pings)\")}`)\n const on = n.on || {}\n console.log(` on.taskComplete ${on.taskComplete === false ? chalk.dim(\"off\") : \"on\"}`)\n console.log(` on.taskError ${on.taskError === false ? chalk.dim(\"off\") : \"on\"}`)\n console.log(` on.taskQueued ${on.taskQueued ? \"on\" : chalk.dim(\"off\")}`)\n console.log()\n })\n\nnotifications\n .command(\"route\")\n .description(\"set the destination channel/chatId for notifications\")\n .requiredOption(\"--channel <name>\", \"telegram | whatsapp | slack | discord\")\n .requiredOption(\"--chat-id <id>\", \"native chat id (e.g. -100…, JID, channel id)\")\n .option(\"--account-id <id>\", \"channel account id when the channel is multi-account (telegram with multiple bots)\")\n .option(\"--clear\", \"clear the destination instead of setting it\")\n .action((opts) => {\n if (opts.clear) {\n mutate((n) => { delete n.destination; return \"notifications destination cleared\" })\n return\n }\n mutate((n) => {\n n.destination = {\n channel: opts.channel,\n chatId: opts.chatId,\n ...(opts.accountId ? { accountId: opts.accountId } : {}),\n }\n return `notifications destination → ${opts.channel}:${opts.chatId}${opts.accountId ? ` (account=${opts.accountId})` : \"\"}`\n })\n })\n\nnotifications\n .command(\"event <name> <state>\")\n .description(\"toggle an event: name in {taskComplete, taskError, taskQueued}; state in {on, off}\")\n .action((name: string, state: string) => {\n const known = [\"taskComplete\", \"taskError\", \"taskQueued\"]\n if (!known.includes(name)) {\n console.log(chalk.red(` unknown event \"${name}\". Pick from: ${known.join(\", \")}`))\n process.exit(1)\n }\n const onv = state.toLowerCase()\n if (![\"on\", \"off\", \"true\", \"false\", \"1\", \"0\"].includes(onv)) {\n console.log(chalk.red(` state must be on|off`))\n process.exit(1)\n }\n const enabled = onv === \"on\" || onv === \"true\" || onv === \"1\"\n mutate((n) => {\n n.on = n.on || {}\n n.on[name] = enabled\n return `notifications.on.${name} = ${enabled}`\n })\n })\n\nnotifications\n .command(\"threshold <seconds>\")\n .description(\"set the long-task threshold in seconds (0 disables long-task pings)\")\n .action((seconds: string) => {\n const n = parseInt(seconds, 10)\n if (!Number.isFinite(n) || n < 0) {\n console.log(chalk.red(\" threshold must be a non-negative integer\"))\n process.exit(1)\n }\n mutate((cfg) => {\n cfg.longTaskThreshold = n\n return `longTaskThreshold = ${n}s`\n })\n })\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { readdirSync, statSync, unlinkSync, rmSync, existsSync } from \"fs\"\nimport { resolve, join } from \"path\"\n\n// --- agentx retention — prune old session/drift files ---\n//\n// Closes the \"no operator-facing cleanup\" gap from the audit. Long-\n// lived daemons accumulate per-day session JSONs and drift snapshots;\n// neither gets pruned automatically. This subcommand walks each\n// allow-listed directory and removes files older than --days.\n\ninterface PruneTarget {\n /** Root path under .agentx/ to walk. */\n dir: string\n /** Description shown in the dry-run + summary output. */\n label: string\n /** When true, recurse into subdirs (sessions are flat; some workspaces nest). */\n recursive?: boolean\n}\n\nconst TARGETS: PruneTarget[] = [\n { dir: \".agentx/sessions\", label: \"Per-day session JSON\" },\n { dir: \".agentx/drift\", label: \"Drift snapshots\", recursive: true },\n { dir: \".agentx/router\", label: \"Router-decision logs\", recursive: true },\n { dir: \".agentx/patterns\", label: \"Self-improving pattern store\", recursive: true },\n]\n\nfunction walkFiles(dir: string, recursive: boolean): string[] {\n if (!existsSync(dir)) return []\n const out: string[] = []\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name)\n if (entry.isFile()) out.push(full)\n else if (entry.isDirectory() && recursive) out.push(...walkFiles(full, true))\n }\n return out\n}\n\nexport const retention = new Command()\n .name(\"retention\")\n .description(\"prune old workspace state (sessions, drift, router traces, pattern store)\")\n\nretention\n .command(\"show\", { isDefault: true })\n .description(\"show how much each retention target currently weighs\")\n .action(() => {\n console.log()\n let total = 0\n for (const t of TARGETS) {\n const root = resolve(process.cwd(), t.dir)\n const files = walkFiles(root, !!t.recursive)\n let bytes = 0\n let oldest: number | null = null\n for (const f of files) {\n try {\n const s = statSync(f)\n bytes += s.size\n if (oldest === null || s.mtimeMs < oldest) oldest = s.mtimeMs\n } catch { /* skip */ }\n }\n total += bytes\n const oldestAge = oldest !== null ? `${Math.round((Date.now() - oldest) / 86_400_000)}d` : \"—\"\n console.log(` ${chalk.cyan(t.dir.padEnd(22))} ${String(files.length).padStart(5)} files ${formatBytes(bytes).padStart(10)} oldest=${oldestAge}`)\n }\n console.log(chalk.dim(` ${\"\".padEnd(22)} ${\"\".padStart(5)} ${formatBytes(total).padStart(10)} total`))\n console.log()\n console.log(chalk.dim(\" Run `agentx retention prune --days 30` to delete files older than 30 days.\"))\n console.log()\n })\n\nretention\n .command(\"prune\")\n .description(\"delete files older than --days from each retention target\")\n .option(\"--days <n>\", \"max age in days; everything older is deleted\", \"30\")\n .option(\"--dry-run\", \"list candidates, don't delete\")\n .option(\"--target <name>\", \"limit to one target dir (e.g. .agentx/sessions)\")\n .action((opts) => {\n const days = parseInt(opts.days, 10)\n if (!Number.isFinite(days) || days < 1) {\n console.log(chalk.red(\" --days must be a positive integer\"))\n process.exit(1)\n }\n const cutoff = Date.now() - days * 86_400_000\n const filterTarget = opts.target as string | undefined\n let totalRemoved = 0\n let totalBytes = 0\n console.log()\n console.log(chalk.bold(` Pruning files older than ${days}d (${new Date(cutoff).toISOString().slice(0, 10)})${opts.dryRun ? chalk.yellow(\" — DRY RUN\") : \"\"}`))\n console.log()\n for (const t of TARGETS) {\n if (filterTarget && t.dir !== filterTarget) continue\n const root = resolve(process.cwd(), t.dir)\n const files = walkFiles(root, !!t.recursive)\n let removed = 0\n let bytes = 0\n for (const f of files) {\n try {\n const s = statSync(f)\n if (s.mtimeMs < cutoff) {\n bytes += s.size\n removed++\n if (!opts.dryRun) {\n try { unlinkSync(f) } catch { /* */ }\n }\n }\n } catch { /* skip */ }\n }\n // Best-effort cleanup of empty subdirs (recursive targets only).\n if (t.recursive && !opts.dryRun) {\n try { pruneEmptyDirs(root) } catch { /* */ }\n }\n const action = opts.dryRun ? \"would remove\" : \"removed\"\n console.log(` ${chalk.cyan(t.dir.padEnd(22))} ${action} ${String(removed).padStart(5)} files (${formatBytes(bytes)})`)\n totalRemoved += removed\n totalBytes += bytes\n }\n console.log()\n console.log(chalk.green(` ✓ ${opts.dryRun ? \"(dry-run)\" : \"\"} ${totalRemoved} files, ${formatBytes(totalBytes)} ${opts.dryRun ? \"would be reclaimed\" : \"reclaimed\"}`))\n console.log()\n })\n\nfunction pruneEmptyDirs(root: string): void {\n if (!existsSync(root)) return\n for (const entry of readdirSync(root, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue\n const full = join(root, entry.name)\n pruneEmptyDirs(full)\n try {\n const remaining = readdirSync(full)\n if (remaining.length === 0) rmSync(full, { recursive: false })\n } catch { /* skip */ }\n }\n}\n\nfunction formatBytes(b: number): string {\n if (b < 1024) return b + \"B\"\n if (b < 1024 * 1024) return (b / 1024).toFixed(1) + \"K\"\n if (b < 1024 * 1024 * 1024) return (b / 1024 / 1024).toFixed(1) + \"M\"\n return (b / 1024 / 1024 / 1024).toFixed(2) + \"G\"\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { ActionStore } from \"@/actions/store\"\nimport { runAction } from \"@/actions/runner\"\nimport { actionSchema, type Action } from \"@/actions/types\"\n\n// --- agentx actions — manage the action registry ---\n//\n// Closes the last outstanding parity audit gap: a registry of named,\n// parameterized invocations that workflows / CLI / dashboard can call\n// instead of hardcoding shell/http calls per use site.\n//\n// Two action kinds in v1:\n// shell — exec a command (cwd-aware, env-merge, template inputs)\n// http — fetch a URL with method/headers/body\n//\n// Storage: .agentx/actions/<id>.json (one file per action).\n\nexport const actions = new Command()\n .name(\"actions\")\n .description(\"manage the action registry — reusable shell/http invocations\")\n\nactions\n .command(\"list\")\n .description(\"list registered actions\")\n .option(\"--json\", \"JSON output\")\n .action((opts) => {\n const store = new ActionStore()\n const list = store.list()\n if (opts.json) { console.log(JSON.stringify(list, null, 2)); return }\n if (list.length === 0) {\n console.log()\n console.log(chalk.dim(\" No actions yet. Add one with `agentx actions add` or `agentx actions create`.\"))\n console.log()\n return\n }\n console.log()\n for (const a of list) {\n const inputs = a.inputs?.length ? chalk.dim(` (${a.inputs.length} input${a.inputs.length === 1 ? \"\" : \"s\"})`) : \"\"\n const target = a.kind === \"shell\" ? `shell: ${a.command.slice(0, 50)}` : `${a.method} ${a.url.slice(0, 50)}`\n console.log(` ${chalk.cyan(a.id.padEnd(24))} ${a.title}${inputs}`)\n console.log(` ${\" \".repeat(24)} ${chalk.dim(target)}`)\n }\n console.log()\n })\n\nactions\n .command(\"show <id>\")\n .description(\"show an action's full definition\")\n .option(\"--json\", \"JSON output\")\n .action((id: string, opts) => {\n const store = new ActionStore()\n const a = store.get(id)\n if (!a) { console.log(chalk.red(` no action \"${id}\"`)); process.exit(1) }\n if (opts.json) { console.log(JSON.stringify(a, null, 2)); return }\n console.log()\n console.log(chalk.bold(` ${a.title}`))\n if (a.description) console.log(chalk.dim(` ${a.description}`))\n console.log()\n console.log(` id ${a.id}`)\n console.log(` kind ${a.kind}`)\n console.log(` timeout ${a.timeoutMs}ms`)\n if (a.kind === \"shell\") {\n console.log(` command ${a.command}`)\n if (a.cwd) console.log(` cwd ${a.cwd}`)\n if (a.env) console.log(` env ${JSON.stringify(a.env)}`)\n } else {\n console.log(` ${a.method.padEnd(9)} ${a.url}`)\n if (a.headers) console.log(` headers ${JSON.stringify(a.headers)}`)\n if (a.body) console.log(` body ${a.body.slice(0, 200)}`)\n }\n if (a.inputs.length) {\n console.log()\n console.log(chalk.bold(\" Inputs:\"))\n for (const inp of a.inputs) {\n const req = inp.required ? chalk.red(\"*\") : \" \"\n const def = inp.defaultValue !== undefined ? chalk.dim(` default=${JSON.stringify(inp.defaultValue)}`) : \"\"\n const desc = inp.description ? chalk.dim(` — ${inp.description}`) : \"\"\n console.log(` ${req} ${chalk.cyan(inp.name)} (${inp.type})${def}${desc}`)\n }\n }\n console.log()\n })\n\nactions\n .command(\"add <id>\")\n .description(\"add (or replace) an action non-interactively\")\n .requiredOption(\"--title <text>\")\n .requiredOption(\"--kind <kind>\", \"shell | http\")\n .option(\"--description <text>\")\n .option(\"--command <text>\", \"[shell] templated shell command\")\n .option(\"--cwd <path>\", \"[shell] working directory\")\n .option(\"--url <url>\", \"[http] URL\")\n .option(\"--method <m>\", \"[http] GET|POST|PUT|PATCH|DELETE\", \"POST\")\n .option(\"--headers <json>\", \"[http] headers as JSON object\")\n .option(\"--body <text>\", \"[http] body template\")\n .option(\"--inputs <csv>\", \"comma-separated list of name:type[!] (e.g. amount:number!,note:string)\")\n .option(\"--timeout <ms>\", \"timeout in ms (default 30000)\", \"30000\")\n .action((id: string, opts) => {\n const inputs = parseInputsCsv(opts.inputs)\n const base: any = {\n id, title: opts.title, description: opts.description, inputs,\n timeoutMs: parseInt(opts.timeout, 10) || 30_000,\n kind: opts.kind,\n }\n if (opts.kind === \"shell\") {\n if (!opts.command) { console.log(chalk.red(\" --command required for kind=shell\")); process.exit(1) }\n base.command = opts.command\n if (opts.cwd) base.cwd = opts.cwd\n } else if (opts.kind === \"http\") {\n if (!opts.url) { console.log(chalk.red(\" --url required for kind=http\")); process.exit(1) }\n base.url = opts.url\n base.method = opts.method\n if (opts.headers) {\n try { base.headers = JSON.parse(opts.headers) }\n catch { console.log(chalk.red(\" --headers must be valid JSON\")); process.exit(1) }\n }\n if (opts.body) base.body = opts.body\n } else {\n console.log(chalk.red(\" --kind must be shell|http\"))\n process.exit(1)\n }\n const parsed = actionSchema.safeParse(base)\n if (!parsed.success) {\n console.log(chalk.red(\" validation failed:\"))\n for (const issue of parsed.error.issues) console.log(chalk.red(` ${issue.path.join(\".\")}: ${issue.message}`))\n process.exit(1)\n }\n const store = new ActionStore()\n const saved = store.save(parsed.data)\n console.log(chalk.green(`\\n ✓ action \"${saved.id}\" saved (${saved.kind}).`))\n console.log(chalk.dim(` Test: agentx actions run ${saved.id}\\n`))\n })\n\nactions\n .command(\"remove <id>\")\n .alias(\"rm\")\n .description(\"delete an action\")\n .action((id: string) => {\n const store = new ActionStore()\n if (!store.delete(id)) { console.log(chalk.red(` no action \"${id}\"`)); process.exit(1) }\n console.log(chalk.green(` ✓ action \"${id}\" removed`))\n })\n\nactions\n .command(\"run <id>\")\n .description(\"invoke an action and print its output\")\n .option(\"--input <kv...>\", \"input as key=value (repeat for each)\")\n .option(\"--json\", \"JSON output (full ActionRunResult)\")\n .action(async (id: string, opts) => {\n const store = new ActionStore()\n const action = store.get(id)\n if (!action) { console.log(chalk.red(` no action \"${id}\"`)); process.exit(1) }\n const inputs: Record<string, string> = {}\n for (const kv of (opts.input || []) as string[]) {\n const eq = kv.indexOf(\"=\")\n if (eq < 0) { console.log(chalk.red(` --input \"${kv}\" must be key=value`)); process.exit(1) }\n inputs[kv.slice(0, eq)] = kv.slice(eq + 1)\n }\n try {\n const result = await runAction(action as Action, inputs)\n if (opts.json) { console.log(JSON.stringify(result, null, 2)); return }\n console.log()\n console.log(` ${result.ok ? chalk.green(\"✓ ok\") : chalk.red(\"✗ failed\")} status=${result.status} ${result.durationMs}ms`)\n console.log()\n if (result.output) {\n console.log(chalk.dim(\" --- output ---\"))\n console.log(result.output)\n }\n if (result.errors) {\n console.log(chalk.dim(\" --- errors ---\"))\n console.log(chalk.red(result.errors))\n }\n console.log()\n if (!result.ok) process.exit(1)\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exit(1)\n }\n })\n\n// --- Typed built-in actions (separate registry from custom shell/http) ---\n//\n// Built-in actions are TypeScript modules under src/actions/builtin/ that\n// register at daemon boot. They expose strict input/output Zod schemas and\n// are the preferred way for agents to do typed work (HTTP, file I/O, RAG,\n// extract.structured, mesh.delegate). Operators don't author them — they\n// ship as part of the binary and appear at GET /api/actions/builtin.\n//\n// This subcommand exists so agents can invoke a built-in via Bash and\n// have the call land as a structured action step in /traces (vs an opaque\n// curl invocation). The CLI just POSTs to the daemon's existing endpoint.\n\nactions\n .command(\"builtin [name]\")\n .description(\"list registered built-in actions, or run one with --input\")\n .option(\"--input <json>\", \"JSON input matching the action's inputSchema\")\n .option(\"--daemon <url>\", \"daemon API base URL\", \"http://127.0.0.1:18800\")\n .option(\"--json\", \"raw JSON output (omit chrome)\")\n .option(\"--schema\", \"show the action's input/output schema instead of running it\")\n .action(async (name: string | undefined, opts) => {\n const base = String(opts.daemon).replace(/\\/+$/, \"\")\n\n // No name → list all built-ins.\n if (!name) {\n try {\n const res = await fetch(`${base}/api/actions/builtin`)\n if (!res.ok) {\n console.log(chalk.red(` list failed (${res.status}): ${(await res.text()).slice(0, 200)}`))\n process.exit(1)\n }\n const body = await res.json() as { actions?: Array<{ name: string; description?: string; timeoutMs?: number }> }\n const list = body.actions || []\n if (opts.json) { console.log(JSON.stringify(list, null, 2)); return }\n if (list.length === 0) {\n console.log(chalk.dim(\" No built-in actions registered. Daemon may not be running, or registerAllBuiltins() didn't fire at boot.\"))\n return\n }\n console.log()\n console.log(chalk.bold(\" Built-in typed actions\"))\n console.log(chalk.dim(\" Invoke: agentx actions builtin <name> --input '<json>'\"))\n console.log()\n for (const a of list) {\n const t = a.timeoutMs ? chalk.dim(` (timeout=${Math.round(a.timeoutMs / 1000)}s)`) : \"\"\n console.log(` ${chalk.cyan(a.name.padEnd(22))} ${a.description || \"\"}${t}`)\n }\n console.log()\n } catch (e: any) {\n console.log(chalk.red(` daemon unreachable: ${e.message || e}`))\n process.exit(1)\n }\n return\n }\n\n // --schema mode: print the input/output schema without running.\n if (opts.schema) {\n try {\n const res = await fetch(`${base}/api/actions/builtin`)\n const body = await res.json() as { actions?: Array<{ name: string; inputSchema?: unknown; outputSchema?: unknown; description?: string }> }\n const a = (body.actions || []).find((x) => x.name === name)\n if (!a) { console.log(chalk.red(` unknown action: ${name}`)); process.exit(1) }\n if (opts.json) { console.log(JSON.stringify(a, null, 2)); return }\n console.log()\n console.log(chalk.bold(` ${a.name}`))\n if (a.description) console.log(chalk.dim(` ${a.description}`))\n console.log()\n console.log(chalk.dim(\" --- input schema ---\"))\n console.log(JSON.stringify(a.inputSchema ?? {}, null, 2))\n if (a.outputSchema) {\n console.log()\n console.log(chalk.dim(\" --- output schema ---\"))\n console.log(JSON.stringify(a.outputSchema, null, 2))\n }\n console.log()\n } catch (e: any) {\n console.log(chalk.red(` schema fetch failed: ${e.message || e}`))\n process.exit(1)\n }\n return\n }\n\n // Run mode: POST to the daemon's typed-action endpoint with --input.\n let input: unknown = {}\n if (opts.input) {\n try { input = JSON.parse(opts.input) } catch (e: any) {\n console.log(chalk.red(` --input must be valid JSON: ${e.message}`))\n process.exit(1)\n }\n }\n try {\n const res = await fetch(`${base}/api/actions/builtin/${encodeURIComponent(name)}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(input),\n })\n const body = await res.json().catch(() => ({}))\n if (!res.ok) {\n if (opts.json) { console.log(JSON.stringify(body, null, 2)); process.exit(1) }\n console.log(chalk.red(` action failed (${res.status}): ${(body as any).error || JSON.stringify(body).slice(0, 300)}`))\n process.exit(1)\n }\n if (opts.json) { console.log(JSON.stringify(body, null, 2)); return }\n // Default human-friendly output: print the structured result.\n console.log(JSON.stringify(body, null, 2))\n } catch (e: any) {\n console.log(chalk.red(` daemon unreachable: ${e.message || e}`))\n process.exit(1)\n }\n })\n\n/** Parse the --inputs CSV: name:type[!],name:type. `!` marks required. */\nfunction parseInputsCsv(csv: string | undefined): Action[\"inputs\"] {\n if (!csv) return []\n const out: Action[\"inputs\"] = []\n for (const part of csv.split(\",\").map((s) => s.trim()).filter(Boolean)) {\n const required = part.endsWith(\"!\")\n const clean = required ? part.slice(0, -1) : part\n const colon = clean.indexOf(\":\")\n const name = colon >= 0 ? clean.slice(0, colon) : clean\n const type = (colon >= 0 ? clean.slice(colon + 1) : \"string\") as \"string\" | \"number\" | \"boolean\"\n out.push({ name, type, required })\n }\n return out\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx watch — one live operator console for the daemon ---\n//\n// Opens an SSE connection to the daemon's /events endpoint with optional\n// filters and prints one-line formatted entries. Meant for\n// agentx watch # everything\n// agentx watch --type run,task # just workflow runs + user tasks\n// agentx watch --workflow X # runs of a specific workflow\n// agentx watch --actor actor:alice\n//\n// Multi-daemon: pass --node <url> to point at a peer; otherwise uses the\n// local daemon URL from dashboard.daemonUrl or -c config.\n\nexport const watch = new Command()\n .name(\"watch\")\n .description(\"stream live daemon events — workflow runs, user tasks, signals, mesh health\")\n .option(\"-c, --config <path>\", \"daemon config file\")\n .option(\"-t, --type <kinds>\", \"comma-separated event kinds (run,task,signal,mesh,channel,status)\")\n .option(\"-w, --workflow <id>\", \"only events for this workflow id\")\n .option(\"-a, --actor <id>\", \"only task events involving this actor id\")\n .option(\"-r, --run <id>\", \"only events for this run id\")\n .option(\"--channel <name>\", \"only channel events on this channel (telegram/whatsapp/…)\")\n .option(\"--node <url>\", \"daemon URL (defaults to dashboard.daemonUrl from config)\")\n .option(\"--token <token>\", \"bearer token (defaults to dashboard.token from config)\")\n .action(async (opts) => {\n let baseUrl = typeof opts.node === \"string\" ? opts.node : \"\"\n let token = typeof opts.token === \"string\" ? opts.token : \"\"\n if (!baseUrl || !token) {\n try {\n const cfg = loadDaemonConfig(opts.config)\n if (!baseUrl) baseUrl = cfg.dashboard?.daemonUrl || \"\"\n if (!token) token = cfg.dashboard?.token || \"\"\n } catch {\n // No config — fall back to localhost:18800 and no auth.\n }\n }\n if (!baseUrl) baseUrl = \"http://localhost:18800\"\n\n const qs: string[] = []\n if (typeof opts.type === \"string\") qs.push(`type=${encodeURIComponent(opts.type)}`)\n if (typeof opts.workflow === \"string\") qs.push(`workflow=${encodeURIComponent(opts.workflow)}`)\n if (typeof opts.actor === \"string\") qs.push(`actor=${encodeURIComponent(opts.actor)}`)\n if (typeof opts.run === \"string\") qs.push(`run=${encodeURIComponent(opts.run)}`)\n if (typeof opts.channel === \"string\") qs.push(`channel=${encodeURIComponent(opts.channel)}`)\n const url = `${baseUrl.replace(/\\/+$/, \"\")}/events${qs.length ? `?${qs.join(\"&\")}` : \"\"}`\n\n console.log(chalk.dim(` connecting to ${url}`))\n\n const headers: Record<string, string> = { Accept: \"text/event-stream\" }\n if (token) headers[\"Authorization\"] = `Bearer ${token}`\n\n try {\n const res = await fetch(url, { headers })\n if (!res.ok || !res.body) {\n console.error(chalk.red(` connect failed: HTTP ${res.status}`))\n process.exit(1)\n }\n console.log(chalk.green(` connected — Ctrl-C to stop`))\n console.log(\"\")\n\n // Parse SSE frames: `event: <kind>\\ndata: <payload>\\n\\n`.\n const reader = res.body.getReader()\n const dec = new TextDecoder()\n let buf = \"\"\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n buf += dec.decode(value, { stream: true })\n let idx: number\n while ((idx = buf.indexOf(\"\\n\\n\")) >= 0) {\n const frame = buf.slice(0, idx)\n buf = buf.slice(idx + 2)\n printFrame(frame)\n }\n }\n } catch (e: any) {\n console.error(chalk.red(` disconnected: ${e.message || e}`))\n process.exit(1)\n }\n })\n\nfunction printFrame(frame: string): void {\n let event = \"message\"\n let data = \"\"\n for (const line of frame.split(\"\\n\")) {\n if (line.startsWith(\"event: \")) event = line.slice(7)\n else if (line.startsWith(\"data: \")) data = line.slice(6)\n }\n if (!data) return\n let payload: any = {}\n try { payload = JSON.parse(data) } catch { /* print raw */ console.log(`${event}: ${data}`); return }\n\n const ts = payload.at ? chalk.dim(new Date(payload.at).toLocaleTimeString()) : \"\"\n switch (event) {\n case \"run\": {\n const tag = chalk.cyan(payload.phase?.padEnd(9) ?? \"run\")\n const wf = chalk.bold(payload.workflowId ?? \"\")\n const runShort = chalk.dim((payload.runId ?? \"\").slice(0, 8))\n const node = payload.nodeId ? chalk.yellow(payload.nodeId) : \"\"\n const note = payload.note ? chalk.dim(`— ${payload.note}`) : \"\"\n console.log(`${ts} ${tag} ${wf} ${runShort} ${node} ${note}`)\n break\n }\n case \"task\": {\n const tag = chalk.magenta(`task.${payload.phase}`.padEnd(14))\n const wf = chalk.bold(payload.workflowId ?? \"\")\n const actors = Array.isArray(payload.assignedTo) ? payload.assignedTo.join(\",\") : \"\"\n const title = payload.title ? chalk.dim(`\"${payload.title}\"`) : \"\"\n console.log(`${ts} ${tag} ${wf} ${chalk.cyan(actors)} ${title}`)\n break\n }\n case \"signal\": {\n const tag = chalk.green(\"signal\".padEnd(9))\n const name = chalk.bold(payload.name)\n const scope = chalk.dim(`(${payload.scope})`)\n const wf = payload.workflowId ? chalk.dim(payload.workflowId) : \"\"\n console.log(`${ts} ${tag} ${name} ${scope} ${wf}`)\n break\n }\n case \"mesh\": {\n const tag = chalk.blue(\"mesh\".padEnd(9))\n const peer = chalk.bold(payload.peer)\n const health = payload.healthy ? chalk.green(\"✓ healthy\") : chalk.red(\"✗ lost\")\n console.log(`${ts} ${tag} ${peer} ${health} ${chalk.dim(payload.delta ?? \"\")}`)\n break\n }\n case \"channel\": {\n const tag = chalk.yellow(\"channel\".padEnd(9))\n const dir = payload.direction === \"in\" ? chalk.cyan(\"←\") : chalk.magenta(\"→\")\n const label = chalk.bold(`${payload.channel}:${payload.chatId ?? \"\"}`)\n const preview = payload.textPreview ? chalk.dim(payload.textPreview) : \"\"\n console.log(`${ts} ${tag} ${dir} ${label} ${preview}`)\n break\n }\n case \"status\": {\n console.log(chalk.dim(`${ts} status ${payload.node ?? \"\"} agents=${payload.agents ?? 0} active=${(payload.active ?? []).length} peers=${(payload.mesh ?? []).length}`))\n break\n }\n default:\n console.log(`${ts} ${event} ${JSON.stringify(payload)}`)\n }\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { spawn } from \"node:child_process\"\nimport { checkOpenCodeVersion } from \"@/tui/opencode-cli\"\n\n// OpenCode is the preferred terminal UI. The built-in Ink UI remains a\n// functional fallback when OpenCode v2 is unavailable.\n\nexport const tui = new Command()\n .name(\"tui\")\n .description(\"open the AgentX console in OpenCode\")\n .option(\"-c, --config <path>\", \"daemon config file\")\n .option(\"--node <url>\", \"daemon URL (defaults to dashboard.daemonUrl from config)\")\n .option(\"--token <token>\", \"daemon mesh bearer token for remote nodes\")\n .option(\"--agent <id>\", \"AgentX agent to use as the OpenCode model\")\n .option(\"--legacy\", \"open the built-in Ink terminal UI\")\n .option(\"--poll <ms>\", \"legacy UI snapshot poll interval in ms\", \"3000\")\n .action(async (opts) => {\n if (!process.stdout.isTTY) {\n console.error(chalk.red(\"agentx tui requires an interactive terminal\"))\n process.exit(1)\n }\n const { resolveConn } = await import(\"@/tui/client\")\n const conn = resolveConn({ node: opts.node, token: opts.token, config: opts.config })\n const openCode = opts.legacy ? null : checkOpenCodeVersion()\n if (openCode?.ok) {\n const { fetchAgents } = await import(\"@/tui/client\")\n const agents = await fetchAgents(conn)\n if (!agents.length) throw new Error(`No AgentX agents returned by ${conn.baseUrl}`)\n const agentId = opts.agent || agents[0].id\n if (!agents.some(agent => agent.id === agentId)) throw new Error(`Unknown AgentX agent: ${agentId}`)\n let inlineServerConfig: Record<string, any> = {}\n try { inlineServerConfig = JSON.parse(process.env.OPENCODE_CONFIG_CONTENT || \"{}\") } catch { /* ignore invalid override */ }\n const models = Object.fromEntries(agents.map(agent => [agent.id, { name: `AgentX ${agent.name || agent.id}` }]))\n const env = {\n ...process.env,\n OPENCODE_CONFIG_CONTENT: JSON.stringify({\n ...inlineServerConfig,\n model: `agentx/${agentId}`,\n providers: {\n ...inlineServerConfig.providers,\n agentx: {\n name: \"AgentX\",\n package: \"@opencode/ai/providers/openai-compatible\",\n settings: { baseURL: `${conn.baseUrl}/v1` },\n models,\n },\n },\n }),\n }\n console.error(chalk.dim(`Opening ${openCode.version} with AgentX model ${agentId}.`))\n const child = spawn(\"opencode\", [\"--standalone\"], { stdio: \"inherit\", env })\n await new Promise<void>((done, reject) => {\n child.once(\"error\", reject)\n child.once(\"exit\", code => code === 0 ? done() : reject(new Error(`OpenCode exited with code ${code ?? \"unknown\"}`)))\n })\n return\n }\n if (openCode && !openCode.ok) {\n console.error(chalk.yellow(openCode.reason))\n console.error(chalk.dim(\"Using the built-in AgentX TUI. Install OpenCode v2: https://opencode.ai/v2/docs\"))\n }\n // Defer-load Ink + the app so non-TUI commands don't pay the React/Ink import cost.\n const { App } = await import(\"@/tui/App\")\n const { render } = await import(\"ink\")\n const React = (await import(\"react\")).default\n\n const pollMs = Math.max(500, Number(opts.poll) || 3000)\n const instance = render(React.createElement(App, { conn, pollMs }))\n await instance.waitUntilExit()\n })\n","import { execFileSync } from \"node:child_process\"\n\nexport type OpenCodeCheck =\n | { ok: true; version: string }\n | { ok: false; reason: string }\n\n/** Check the executable before launching the TUI so v1 never receives v2 config. */\nexport function checkOpenCodeVersion(runVersion: () => string = () =>\n execFileSync(\"opencode\", [\"--version\"], { encoding: \"utf8\", timeout: 5_000 }).trim(),\n): OpenCodeCheck {\n let version: string\n try {\n version = runVersion().trim()\n } catch (error: any) {\n return {\n ok: false,\n reason: error?.code === \"ENOENT\"\n ? \"OpenCode is not installed or is not on PATH.\"\n : `Could not run opencode --version: ${error?.message || String(error)}`,\n }\n }\n const match = version.match(/^(?:opencode\\s+)?v?(\\d+)\\.\\d+\\.\\d+(?:\\s|$)/i)\n if (!match) return { ok: false, reason: `Could not recognize the OpenCode version: ${version || \"empty output\"}` }\n if (Number(match[1]) < 2) return { ok: false, reason: `OpenCode ${version} is too old; AgentX TUI requires OpenCode v2 or newer.` }\n return { ok: true, version }\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { randomUUID } from \"crypto\"\nimport { createInterface } from \"node:readline/promises\"\nimport ora from \"ora\"\nimport { resolveConn, streamTask, fetchAgents, type AgentRow } from \"@/tui/client\"\nimport { deprecationNotice, CHAT_SURFACE_DEPRECATION } from \"./deprecation\"\n\n// `agentx chat @agent` — daemon-mediated REPL.\n//\n// Multi-turn conversation with a daemon-registered agent over POST /task.\n// We synthesize a stable (channel, chatId) per session so the daemon's\n// process registry keeps the agent's claude process warm across turns —\n// no cold spawn per message, no provider config duplicated in the CLI.\n//\n// Special commands at the prompt:\n// /exit, /quit leave the REPL\n// /clear start a fresh chatId (drops warm process)\n// /agent <id> switch the target agent for the next turn\n// /who print current target + chatId\n// /agents list registered agents\n\nexport const chat = new Command()\n .name(\"chat\")\n .description(\"[deprecated — see agentx attach] interactive chat with a daemon-registered agent\")\n .argument(\"[agent]\", \"agent id to talk to (with or without leading @)\")\n .option(\"-c, --config <path>\", \"daemon config file\")\n .option(\"--node <url>\", \"daemon URL (defaults to dashboard.daemonUrl from config)\")\n .option(\"--token <token>\", \"bearer token (defaults to dashboard.token from config)\")\n .option(\"--channel <name>\", \"logical channel name passed in context\", \"chat-cli\")\n .option(\"--chat-id <id>\", \"resume an existing chatId (otherwise a fresh one is generated)\")\n .action(async (agentArg: string | undefined, opts) => {\n deprecationNotice({ what: \"agentx chat\", ...CHAT_SURFACE_DEPRECATION })\n const conn = resolveConn({ node: opts.node, token: opts.token, config: opts.config })\n let agentId = (agentArg ?? \"\").replace(/^@/, \"\").trim()\n const channel: string = opts.channel\n let chatId: string = opts.chatId || `chat-cli:${randomUUID().slice(0, 12)}`\n\n // Confirm the daemon is reachable and the requested agent exists. We\n // pull the registry up front to give a useful error before the first\n // turn — and to default to the first available agent if none was given.\n let agents: AgentRow[] = []\n try {\n agents = await fetchAgents(conn)\n } catch (e: any) {\n console.error(chalk.red(` cannot reach daemon at ${conn.baseUrl}: ${e?.message || e}`))\n console.error(chalk.dim(` is the daemon running? try: agentx daemon status`))\n process.exit(1)\n }\n if (agents.length === 0) {\n console.error(chalk.red(\" no agents registered with the daemon\"))\n process.exit(1)\n }\n if (!agentId) {\n agentId = agents[0].id\n console.log(chalk.dim(` no agent given — defaulting to @${agentId}`))\n } else if (!agents.find((a) => a.id === agentId)) {\n console.error(chalk.red(` unknown agent: @${agentId}`))\n console.error(chalk.dim(` registered: ${agents.map((a) => `@${a.id}`).join(\", \")}`))\n process.exit(1)\n }\n\n // Interactive terminal → rich Ink REPL (streaming, markdown, tool\n // badges, history). Non-TTY (piped/scripted) → the plain streaming\n // fallback below, which stays scriptable.\n if (process.stdout.isTTY && process.stdin.isTTY) {\n const { render } = await import(\"ink\")\n const { ChatApp } = await import(\"@/tui/ChatApp\")\n const React = (await import(\"react\")).default\n // The Ink app is a full-height layout (welcome/empty-state lives inside\n // it), so no pre-render banner — that would push the layout off-screen.\n const instance = render(React.createElement(ChatApp, { conn, agentId, channel, chatId, agents }))\n await instance.waitUntilExit()\n return\n }\n\n printBanner(conn.baseUrl, agentId, chatId, channel)\n\n const rl = createInterface({ input: process.stdin, output: process.stdout })\n // Don't hard-exit mid-turn: if stdin closes (Ctrl-D / piped EOF) while a\n // reply is streaming, let the in-flight turn finish, then quit.\n let busy = false\n let closeRequested = false\n rl.on(\"close\", () => {\n if (busy) { closeRequested = true; return }\n console.log(chalk.dim(\"\\n bye\"))\n process.exit(0)\n })\n\n while (true) {\n let line: string\n try {\n line = (await rl.question(chalk.cyan(`you › `))).trim()\n } catch {\n // SIGINT during input — readline rejects.\n rl.close()\n return\n }\n if (!line) continue\n\n if (line === \"/exit\" || line === \"/quit\") { rl.close(); return }\n if (line === \"/who\") {\n console.log(chalk.dim(` @${agentId} chatId=${chatId} channel=${channel}`))\n continue\n }\n if (line === \"/clear\") {\n chatId = `chat-cli:${randomUUID().slice(0, 12)}`\n console.log(chalk.dim(` fresh chatId=${chatId} (warm process dropped)`))\n continue\n }\n if (line === \"/agents\") {\n try {\n const fresh = await fetchAgents(conn)\n for (const a of fresh) {\n const marker = a.id === agentId ? chalk.green(\"●\") : chalk.dim(\"○\")\n console.log(` ${marker} @${a.id} ${chalk.dim(a.tier)} ${a.model ?? \"\"}`)\n }\n } catch (e: any) {\n console.error(chalk.red(` failed to list agents: ${e?.message || e}`))\n }\n continue\n }\n if (line.startsWith(\"/agent \")) {\n const next = line.slice(\"/agent \".length).replace(/^@/, \"\").trim()\n if (!next) { console.log(chalk.red(\" usage: /agent <id>\")); continue }\n // Re-fetch to validate against the live registry.\n try {\n const fresh = await fetchAgents(conn)\n if (!fresh.find((a) => a.id === next)) {\n console.log(chalk.red(` unknown agent: @${next}`))\n continue\n }\n agentId = next\n console.log(chalk.dim(` now talking to @${agentId}`))\n } catch (e: any) {\n console.error(chalk.red(` failed to switch agent: ${e?.message || e}`))\n }\n continue\n }\n if (line.startsWith(\"/\")) {\n console.log(chalk.red(` unknown command: ${line.split(/\\s+/)[0]}`))\n console.log(chalk.dim(` available: /exit /quit /clear /agent <id> /who /agents`))\n continue\n }\n\n busy = true\n const spinner = ora({ text: `@${agentId}…`, color: \"cyan\" }).start()\n const startedAt = Date.now()\n const render = createStreamRenderer(agentId)\n try {\n const r = await streamTask(conn, agentId, line, {\n channel,\n chatId,\n onText: (t) => { spinner.stop(); render.text(t) },\n onThinking: () => { /* reasoning lane — kept quiet in the MVP */ },\n onTool: (tool) => { spinner.stop(); render.tool(tool) },\n })\n spinner.stop()\n const elapsed = Math.round((Date.now() - startedAt) / 100) / 10\n if (r.error) {\n render.finishError(r.error)\n } else {\n render.finish(elapsed, r.usage)\n }\n } catch (e: any) {\n spinner.stop()\n render.finishError(e?.message || String(e))\n } finally {\n busy = false\n }\n if (closeRequested) { console.log(chalk.dim(\" bye\")); return }\n }\n })\n\n/** Stateful renderer for one streamed reply. Streams text deltas with a\n * hanging 2-space indent and prints Claude-Code-style `● tool` badges as\n * the agent works — interleaving cleanly by tracking line position. */\nfunction createStreamRenderer(agentId: string) {\n let headerShown = false\n let atLineStart = true\n let anyText = false\n const seenTools = new Set<string>()\n\n const header = () => {\n if (headerShown) return\n process.stdout.write(`${chalk.green(`@${agentId}`)}\\n`)\n headerShown = true\n }\n\n return {\n /** Write a streamed text delta, indenting each new line by two spaces. */\n text(delta: string) {\n if (!delta) return\n header()\n anyText = true\n for (const ch of delta) {\n if (atLineStart && ch !== \"\\n\") { process.stdout.write(\" \"); atLineStart = false }\n process.stdout.write(ch)\n if (ch === \"\\n\") atLineStart = true\n }\n },\n /** Print a tool-call badge (once per tool invocation id). */\n tool(t: { status: \"start\" | \"result\"; id?: string; name?: string; error?: boolean; arg?: string }) {\n header()\n if (t.status === \"start\" && t.name) {\n const key = t.id || `${t.name}:${seenTools.size}`\n if (seenTools.has(key)) return\n seenTools.add(key)\n if (!atLineStart) { process.stdout.write(\"\\n\"); atLineStart = true }\n const arg = t.arg ? chalk.dim(`(${t.arg})`) : \"\"\n process.stdout.write(` ${chalk.green(\"●\")} ${chalk.bold(t.name)}${arg}\\n`)\n } else if (t.status === \"result\" && t.error) {\n if (!atLineStart) { process.stdout.write(\"\\n\"); atLineStart = true }\n process.stdout.write(` ${chalk.red(\"●\")} ${chalk.dim(`${t.name ?? \"tool\"} failed`)}\\n`)\n }\n },\n /** Close the turn: ensure a trailing newline + a dim timing/usage footer. */\n finish(elapsedS: number, usage?: Record<string, number>) {\n if (!headerShown) { process.stdout.write(`${chalk.green(`@${agentId}`)} ${chalk.dim(\"· (empty reply)\")}\\n\\n`); return }\n if (!atLineStart) process.stdout.write(\"\\n\")\n const out = usage?.outputTokens != null ? `, ${usage.outputTokens} tok` : \"\"\n process.stdout.write(chalk.dim(` · ${elapsedS}s${out}\\n\\n`))\n void anyText\n },\n finishError(msg: string) {\n if (headerShown && !atLineStart) process.stdout.write(\"\\n\")\n process.stdout.write(chalk.red(` ✗ ${msg}\\n\\n`))\n },\n }\n}\n\nfunction printBanner(baseUrl: string, agentId: string, chatId: string, channel: string) {\n console.log()\n console.log(chalk.bold(` agentx chat`))\n console.log(chalk.dim(` daemon: ${baseUrl} · channel: ${channel} · chatId: ${chatId}`))\n console.log(chalk.dim(` agent: @${agentId} · /exit to quit · /agent <id> to switch`))\n console.log()\n}\n","import chalk from \"chalk\"\n\n// --- Deprecation notices ---\n//\n// A surface is deprecated when the evidence says nobody uses it AND something\n// better exists. Both halves matter: dropping a capability because it is\n// unpopular is how tools get worse. Replacing one because it lost to a better\n// host is how they get simpler.\n//\n// See docs/architecture/surface-reduction.md for the fleet usage data behind\n// each entry here.\n//\n// The notice is a warning, never a block. The command still runs — an operator\n// mid-incident should never be stopped by a message about roadmaps.\n\nexport interface Deprecation {\n /** What is going away. */\n what: string\n /** Why, in one line an operator can evaluate. Cite evidence, not opinion. */\n why: string\n /** What to do instead, as a runnable command where possible. */\n instead: string\n /** Extra context worth one more line. */\n note?: string\n}\n\nexport function deprecationNotice(d: Deprecation): void {\n console.error()\n console.error(chalk.yellow(` ⚠ ${d.what} is deprecated.`))\n console.error(chalk.dim(` ${d.why}`))\n console.error()\n console.error(` Use ${chalk.cyan(d.instead)} instead.`)\n if (d.note) console.error(chalk.dim(` ${d.note}`))\n console.error()\n}\n\n/** `agentx chat` and the legacy Ink TUI — the old terminal chat surfaces. Both went\n * unused on every node in the fleet after 2026-07-03. They lost to Claude\n * Code, and attach mode is the answer: rather than a third attempt at a chat\n * client, let the client people already prefer wear the agent identity. */\nexport const CHAT_SURFACE_DEPRECATION: Omit<Deprecation, \"what\"> = {\n why: \"No recorded use on any node since 2026-07-03.\",\n instead: \"agentx attach <agent>\",\n note: \"Wears the identity in the Claude Code session you already have open — see docs/reference/attach.md\",\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { readFileSync } from \"fs\"\nimport { AgentMemory, type MemoryType } from \"@/agents/agent-memory\"\n\n// --- agentx memory — audit + edit an agent's structured memory ---\n//\n// Structured memory is Claude-Code-style:\n// user: who the user is, their role, preferences\n// feedback: rules the user gave me; what to do / avoid\n// project: facts about current work the code can't reveal\n// reference: pointers to external systems (linear, grafana, …)\n//\n// Each entry is a small markdown file with frontmatter. MEMORY.md is\n// auto-generated as the index and inlined into every task's system\n// prompt, so agents see everything they've learned on every turn.\n\nconst VALID_TYPES: MemoryType[] = [\"user\", \"feedback\", \"project\", \"reference\"]\n\nexport const memory = new Command()\n .name(\"memory\")\n .description(\"audit + edit agent-memory (per-agent experiential notes)\")\n\nmemory\n .command(\"add\")\n .description(\"add a memory for an agent\")\n .requiredOption(\"--agent <id>\", \"agent id\")\n .requiredOption(\"--type <type>\", \"one of: user, feedback, project, reference\")\n .requiredOption(\"--name <slug>\", \"short slug, unique per agent (e.g. deep-backend)\")\n .requiredOption(\"--description <line>\", \"one-line hook shown in MEMORY.md\")\n .option(\"--body <text>\", \"memory body (markdown); repeat --body or use --file\")\n .option(\"--file <path>\", \"read body from a file (use '-' for stdin)\")\n .action(async (opts: { agent: string; type: string; name: string; description: string; body?: string; file?: string }) => {\n if (!VALID_TYPES.includes(opts.type as MemoryType)) {\n console.error(chalk.red(` --type must be one of: ${VALID_TYPES.join(\", \")}`))\n process.exitCode = 1; return\n }\n let body = opts.body ?? \"\"\n if (opts.file) {\n if (opts.file === \"-\") {\n body = await readStdin()\n } else {\n try { body = readFileSync(opts.file, \"utf-8\") }\n catch (e: any) { console.error(chalk.red(` could not read --file: ${e.message}`)); process.exitCode = 1; return }\n }\n }\n if (!body.trim()) {\n console.error(chalk.red(\" memory body is required (use --body or --file)\"))\n process.exitCode = 1; return\n }\n const store = new AgentMemory()\n const rec = store.save({\n agentId: opts.agent,\n type: opts.type as MemoryType,\n name: opts.name,\n description: opts.description,\n body,\n })\n console.log(chalk.green(` ✓ memory \"${rec.name}\" saved (${rec.type}) for agent ${opts.agent}`))\n })\n\nmemory\n .command(\"list\")\n .description(\"list memories for an agent\")\n .requiredOption(\"--agent <id>\", \"agent id\")\n .option(\"--type <type>\", \"filter by memory type\")\n .action((opts: { agent: string; type?: string }) => {\n const store = new AgentMemory()\n let records = store.list(opts.agent)\n if (opts.type) {\n if (!VALID_TYPES.includes(opts.type as MemoryType)) {\n console.error(chalk.red(` --type must be one of: ${VALID_TYPES.join(\", \")}`))\n process.exitCode = 1; return\n }\n records = records.filter((r) => r.type === opts.type)\n }\n if (!records.length) {\n console.log(chalk.dim(` no memories for agent \"${opts.agent}\"${opts.type ? ` of type \"${opts.type}\"` : \"\"}`))\n return\n }\n console.log()\n let currentType: string | null = null\n for (const r of records) {\n if (r.type !== currentType) {\n console.log(chalk.bold(` ${r.type}`))\n currentType = r.type\n }\n console.log(` ${chalk.cyan(r.name.padEnd(28))} ${r.description}`)\n }\n console.log()\n console.log(chalk.dim(` ${records.length} memor${records.length === 1 ? \"y\" : \"ies\"} for ${opts.agent}`))\n })\n\nmemory\n .command(\"show\")\n .description(\"print the full body of a memory\")\n .requiredOption(\"--agent <id>\", \"agent id\")\n .argument(\"<name>\", \"memory name (slug)\")\n .action((name: string, opts: { agent: string }) => {\n const store = new AgentMemory()\n const rec = store.get(opts.agent, name)\n if (!rec) {\n console.error(chalk.red(` no memory \"${name}\" for agent \"${opts.agent}\"`))\n process.exitCode = 1; return\n }\n console.log(chalk.bold(`${rec.type}/${rec.name}`) + chalk.dim(` (${rec.description})`))\n console.log(chalk.dim(` updated ${rec.updatedAt}`))\n console.log()\n console.log(rec.body)\n })\n\nmemory\n .command(\"remove\")\n .alias(\"rm\")\n .description(\"remove a memory\")\n .requiredOption(\"--agent <id>\", \"agent id\")\n .argument(\"<name>\", \"memory name (slug)\")\n .action((name: string, opts: { agent: string }) => {\n const store = new AgentMemory()\n if (!store.remove(opts.agent, name)) {\n console.error(chalk.red(` no memory \"${name}\" for agent \"${opts.agent}\"`))\n process.exitCode = 1; return\n }\n console.log(chalk.green(` ✓ memory \"${name}\" removed`))\n })\n\nmemory\n .command(\"index\")\n .description(\"print the MEMORY.md index content an agent sees in its prompt\")\n .requiredOption(\"--agent <id>\", \"agent id\")\n .action((opts: { agent: string }) => {\n const store = new AgentMemory()\n const md = store.indexMarkdown(opts.agent)\n if (!md) {\n console.log(chalk.dim(` (no memories — MEMORY.md is empty for agent \"${opts.agent}\")`))\n return\n }\n console.log(md)\n })\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer)\n return Buffer.concat(chunks).toString(\"utf-8\")\n}\n","import { handleError } from \"@/utils/handle-error\"\nimport { logger } from \"@/utils/logger\"\nimport { startMcpServer } from \"@/mcp\"\nimport chalk from \"chalk\"\nimport { Command } from \"commander\"\nimport { resolve } from \"path\"\n\n// --- `agentx serve` — run as MCP server for AI editors ---\n\nexport const serve = new Command()\n .name(\"serve\")\n .description(\"run agentx as an MCP server for AI editors (Claude Code, Cursor, Windsurf, etc.)\")\n .option(\"--stdio\", \"use stdio transport (default)\", true)\n .option(\n \"-c, --cwd <cwd>\",\n \"working directory\",\n process.cwd()\n )\n .action(async (opts) => {\n try {\n process.chdir(resolve(opts.cwd))\n if (opts.stdio !== false) {\n // stdio mode — all logging goes to stderr, stdout is JSON-RPC\n await startMcpServer()\n } else {\n logger.error(\"Only stdio transport is currently supported.\")\n logger.info(\n `Usage: ${chalk.green(\"agentx serve --stdio\")} or configure in your MCP client.`\n )\n logger.break()\n logger.info(\"Add to Claude Code:\")\n logger.info(\n chalk.dim(\n ' claude mcp add agentx -- npx agentx serve --stdio'\n )\n )\n logger.break()\n logger.info(\"Add to Cursor/MCP config:\")\n logger.info(\n chalk.dim(\n JSON.stringify(\n {\n mcpServers: {\n agentx: {\n command: \"npx\",\n args: [\"agentx\", \"serve\", \"--stdio\"],\n },\n },\n },\n null,\n 2\n )\n )\n )\n }\n } catch (error) {\n handleError(error)\n }\n })\n","// --- agentx demo: the zero-key mesh walkthrough ---\n//\n// Boots three real daemons on loopback ports, pairs them into a real\n// A2A mesh (bearer-token verified), and plays a scripted scenario\n// through the genuine plumbing: /task dispatch on node A, a mesh hop\n// to node B via /send/agent, and a wrap-up turn — every step visible\n// in the /live dashboards and recorded in each node's intent ledger.\n//\n// Honesty contract: the ONLY fake thing is the model (a scripted\n// provider, src/agent/providers/demo.ts). Daemons, HTTP, mesh\n// discovery, auth, ledger rows: all real. The banner says so.\n\nimport { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { spawn, type ChildProcess } from \"child_process\"\nimport { mkdirSync, writeFileSync, rmSync, openSync, existsSync } from \"fs\"\nimport { resolve, join } from \"path\"\nimport { randomBytes } from \"crypto\"\nimport { demoReportWorkflow } from \"./demo-workflow\"\n\ninterface NodeSpec {\n dir: string\n id: string\n name: string\n port: number\n agentId: string\n agentName: string\n persona: string\n script: object\n}\n\nconst KICKOFF = \"[demo] Customer reports checkout is broken and CI is red on demo/shop. Handle it.\"\nconst DELEGATION = \"CI is red on demo/shop — checkout.test.ts failing on Node 22. Diagnose, fix, and report back.\"\n\nfunction buildSpecs(root: string, basePort: number): NodeSpec[] {\n return [\n {\n dir: join(root, \"node-a\"),\n id: \"demo-laptop\",\n name: \"laptop-paris\",\n port: basePort,\n agentId: \"cx\",\n agentName: \"CX\",\n persona: \"You are CX, the customer-facing coordinator. You triage inbound issues and delegate technical work to @builder on the vps node.\",\n script: {\n steps: [\n {\n match: \"USER: Build the demo report workflow\",\n reply: \"Here is a scripted example: start it manually, ask CX for a report, then finish. It is saved disabled so you can review it before running.\\n\\n```json\\n\" + JSON.stringify(demoReportWorkflow, null, 2) + \"\\n```\",\n delayMs: 300,\n chunkMs: 2,\n },\n {\n match: \"Prepare the demo shop report\",\n reply: \"Demo shop report: checkout checks passed, MR !47 is ready for review, and CX has drafted the customer update. This is a scripted example.\",\n delayMs: 500,\n },\n {\n match: \"checkout is broken\",\n thinking: \"Checkout failure + red CI — this is a build problem, not a support question. @builder on vps-nyc owns demo/shop.\",\n reply:\n \"Checkout failure traced to the red pipeline on demo/shop. This needs a code fix — delegating to @builder on the vps-nyc node over the mesh. I'll report back on this thread.\",\n delayMs: 900,\n },\n {\n match: \"Builder reports\",\n thinking: \"Fix confirmed and pipeline green — close the loop with the customer.\",\n reply:\n \"Resolved ✅ — builder patched checkout.test.ts (Node 22 crypto import), MR !47 merged, pipeline green. Customer thread updated. Every hop of this run is in the ledger: `agentx ledger`.\",\n delayMs: 800,\n },\n ],\n fallback: {\n reply: \"Demo mode — I answer from a script. Try the scripted scenario, or run `agentx setup` to connect a real model.\",\n },\n },\n },\n {\n dir: join(root, \"node-b\"),\n id: \"demo-vps\",\n name: \"vps-nyc\",\n port: basePort + 1,\n agentId: \"builder\",\n agentName: \"Builder\",\n persona: \"You are Builder, the engineering agent on the vps node. You fix code, open MRs, and report results tersely.\",\n script: {\n steps: [\n {\n match: \"checkout\\\\.test\\\\.ts|CI is red\",\n thinking: \"Reproducing on Node 22… crypto.webcrypto import moved. Patching the test setup, rerunning the suite.\",\n reply:\n \"Fixed. checkout.test.ts assumed the legacy crypto.webcrypto import — patched for Node 22, suite green locally. Opened MR !47 on demo/shop; pipeline is green. Handing back to @cx.\",\n delayMs: 1400,\n chunkMs: 40,\n },\n ],\n fallback: { reply: \"Builder here (demo script). Send me a failing pipeline.\" },\n },\n },\n {\n dir: join(root, \"node-c\"),\n id: \"demo-pi\",\n name: \"pi-office\",\n port: basePort + 2,\n agentId: \"scout\",\n agentName: \"Scout\",\n persona: \"You are Scout, the monitoring agent on the office Raspberry Pi. You watch schedules and report status.\",\n script: {\n fallback: { reply: \"Scout here (demo script) — all monitors green on pi-office.\" },\n steps: [],\n },\n },\n ]\n}\n\nfunction writeNode(spec: NodeSpec, all: NodeSpec[], meshToken: string): void {\n const ws = join(spec.dir, \"workspaces\", spec.agentId)\n mkdirSync(ws, { recursive: true })\n writeFileSync(join(ws, \"CLAUDE.md\"), `# ${spec.agentName}\\n\\n${spec.persona}\\n`)\n writeFileSync(join(spec.dir, \"demo-script.json\"), JSON.stringify(spec.script, null, 2))\n\n const peers = all\n .filter((n) => n.id !== spec.id)\n .map((n) => ({ name: n.name, url: `http://127.0.0.1:${n.port}`, token: meshToken }))\n\n const config = {\n node: { id: spec.id, name: spec.name, bind: `127.0.0.1:${spec.port}`, defaultAgent: spec.agentId },\n // The dashboard block is read by the `agentx board serve` child the\n // demo starts for node A — it discovers the other nodes through the\n // daemon's /mesh directory, so one dashboard shows the whole mesh.\n dashboard: { enabled: true, port: spec.port + 10, bind: \"127.0.0.1\", daemonUrl: `http://127.0.0.1:${spec.port}` },\n providers: { demo: { apiKey: \"demo-mode\" } },\n agents: {\n [spec.agentId]: {\n name: spec.agentName,\n description: spec.persona,\n workspace: \"./workspaces/\" + spec.agentId,\n tier: \"orchestrator\",\n provider: \"demo\",\n mentions: [`@${spec.agentId}`, spec.agentId],\n maxConcurrent: 2,\n systemPrompt: spec.persona,\n },\n },\n mesh: { enabled: true, peers, discovery: \"static\", healthCheck: { interval: 3, timeout: 5 } },\n workflows: { enabled: true },\n }\n writeFileSync(join(spec.dir, \"agentx.json\"), JSON.stringify(config, null, 2))\n}\n\nasync function waitFor(desc: string, fn: () => Promise<boolean>, timeoutMs: number): Promise<void> {\n const start = Date.now()\n while (Date.now() - start < timeoutMs) {\n try { if (await fn()) return } catch { /* not ready */ }\n await new Promise((r) => setTimeout(r, 500))\n }\n throw new Error(`Timed out waiting for ${desc} (${Math.round(timeoutMs / 1000)}s)`)\n}\n\nasync function post(port: number, path: string, body: object): Promise<any> {\n const res = await fetch(`http://127.0.0.1:${port}${path}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n })\n const data: any = await res.json().catch(() => ({}))\n if (!res.ok || data.error) throw new Error(data.error || `${path} HTTP ${res.status}`)\n return data\n}\n\nfunction say(role: string, text: string, color: (s: string) => string): void {\n console.log()\n console.log(color(` ${role}`))\n console.log(` ${text.split(\"\\n\").join(\"\\n \")}`)\n}\n\nexport const demo = new Command()\n .name(\"demo\")\n .description(\"zero-key demo: three daemons, a real A2A mesh, a scripted scenario\")\n .option(\"--base-port <port>\", \"first of three consecutive loopback ports\", \"18921\")\n .option(\"--once\", \"play the scenario once and exit (default: keep daemons up until Ctrl-C)\")\n .option(\"--keep\", \"keep the .agentx-demo directory on exit\")\n .option(\"--no-open\", \"don't open the dashboard in a browser\")\n .action(async (opts) => {\n const basePort = parseInt(opts.basePort, 10)\n const root = resolve(process.cwd(), \".agentx-demo\")\n const specs = buildSpecs(root, basePort)\n const meshToken = randomBytes(24).toString(\"hex\")\n const children: ChildProcess[] = []\n\n const cli = process.argv[1]\n if (!cli || !existsSync(cli)) {\n console.error(chalk.red(\"Cannot resolve the agentx CLI entrypoint — run via the installed `agentx` binary.\"))\n process.exit(1)\n }\n\n if (existsSync(root)) rmSync(root, { recursive: true, force: true })\n for (const spec of specs) writeNode(spec, specs, meshToken)\n\n console.log()\n console.log(chalk.bold(\" agentx demo — one message, three machines (simulated on loopback)\"))\n console.log(chalk.yellow(\" Canned model responses. Real daemons, real A2A mesh, real ledger.\"))\n console.log(chalk.dim(\" Run `agentx setup` to wire real agents.\\n\"))\n\n let tearingDown = false\n const teardown = (code: number) => {\n if (tearingDown) return\n tearingDown = true\n for (const c of children) { try { c.kill(\"SIGTERM\") } catch { /* gone */ } }\n setTimeout(() => {\n if (!opts.keep) { try { rmSync(root, { recursive: true, force: true }) } catch { /* busy */ } }\n process.exit(code)\n }, 800)\n }\n process.on(\"SIGINT\", () => teardown(0))\n process.on(\"SIGTERM\", () => teardown(0))\n\n // Environment for the child daemons: demo script + shared mesh token.\n // Strip inherited model credentials so nothing real can be billed —\n // the demo must be able to say \"zero keys touched\" truthfully.\n const baseEnv = { ...process.env }\n delete baseEnv.ANTHROPIC_API_KEY\n delete baseEnv.ANTHROPIC_API_KEY_OLD\n delete baseEnv.OPENAI_API_KEY\n delete baseEnv.DEEPSEEK_API_KEY\n\n try {\n for (const spec of specs) {\n const logFd = openSync(join(spec.dir, \"daemon.log\"), \"a\")\n const child = spawn(process.execPath, [cli, \"daemon\", \"start\", \"-c\", join(spec.dir, \"agentx.json\")], {\n cwd: spec.dir,\n env: { ...baseEnv, MESH_TOKEN: meshToken, AGENTX_DEMO_SCRIPT: join(spec.dir, \"demo-script.json\") },\n stdio: [\"ignore\", logFd, logFd],\n })\n children.push(child)\n console.log(chalk.dim(` ▸ ${spec.name} starting on 127.0.0.1:${spec.port} (log: ${join(spec.dir, \"daemon.log\")})`))\n }\n\n for (const spec of specs) {\n await waitFor(`${spec.name} /health`, async () => {\n const r = await fetch(`http://127.0.0.1:${spec.port}/health`)\n return r.ok\n }, 30_000)\n }\n console.log(chalk.green(\" ✓ three daemons up\"))\n\n // One dashboard process, attached to laptop-paris — it discovers the\n // other two nodes over the mesh, so /live shows the whole fleet.\n const dashPort = specs[0].port + 10\n {\n const logFd = openSync(join(specs[0].dir, \"board.log\"), \"a\")\n const child = spawn(process.execPath, [cli, \"board\", \"serve\"], {\n cwd: specs[0].dir,\n env: { ...baseEnv, MESH_TOKEN: meshToken },\n stdio: [\"ignore\", logFd, logFd],\n })\n children.push(child)\n }\n await waitFor(\"dashboard /live\", async () => {\n const r = await fetch(`http://127.0.0.1:${dashPort}/live`)\n return r.ok\n }, 30_000)\n console.log(chalk.green(\" ✓ dashboard up\"))\n\n await waitFor(\"mesh discovery (laptop sees both peers)\", async () => {\n const r = await fetch(`http://127.0.0.1:${specs[0].port}/health`)\n const h: any = await r.json()\n const healthy = (h.mesh || []).filter((p: any) => p.healthy && p.skills?.length)\n return healthy.length >= 2\n }, 30_000)\n // Note: on loopback the daemon's mesh-auth gate exempts callers by\n // design, so don't claim token *verification* here — tokens are sent\n // and the gate is exercised only on non-loopback deployments.\n console.log(chalk.green(\" ✓ A2A mesh healthy — agent cards exchanged across three nodes\"))\n\n const liveUrl = `http://127.0.0.1:${dashPort}/live`\n console.log()\n console.log(` Dashboard: ${chalk.cyan(liveUrl)} (all three nodes via the mesh)`)\n console.log(chalk.dim(` Daemon APIs: ${specs.map((s) => `127.0.0.1:${s.port}`).join(\" · \")}`))\n\n if (opts.open !== false) {\n const opener = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\"\n try { spawn(opener, [liveUrl], { stdio: \"ignore\", detached: true }).unref() } catch { /* headless */ }\n }\n\n const playScenario = async () => {\n console.log()\n console.log(chalk.bold(\" ── Scenario: red pipeline, cross-node fix ──\"))\n say(\"You → @cx (laptop-paris)\", KICKOFF, chalk.cyan)\n\n const s1 = await post(specs[0].port, \"/task\", { agent: \"cx\", message: KICKOFF })\n say(\"@cx (laptop-paris)\", s1.content || \"(no content)\", chalk.green)\n\n console.log()\n console.log(chalk.magenta(\" ⇄ mesh hop: laptop-paris → vps-nyc (A2A /task)\"))\n const s2 = await post(specs[0].port, \"/send/agent\", {\n agentId: \"builder\",\n senderAgentId: \"cx\",\n text: DELEGATION,\n })\n const builderReply = typeof s2.messageId === \"string\" ? s2.messageId : s2.content || \"(no reply)\"\n say(\"@builder (vps-nyc)\", builderReply, chalk.yellow)\n\n const s3 = await post(specs[0].port, \"/task\", {\n agent: \"cx\",\n message: `[demo] Builder reports: ${builderReply}`,\n })\n say(\"@cx (laptop-paris)\", s3.content || \"(no content)\", chalk.green)\n\n console.log()\n console.log(chalk.dim(` Inspect the run: ${liveUrl} · ledger rows on each node record every dispatch`))\n console.log(chalk.dim(` Worth your time? A star helps others find it: ${chalk.cyan(\"https://github.com/anis-marrouchi/agentx\")}`))\n }\n\n await playScenario()\n\n if (opts.once) {\n console.log()\n console.log(chalk.dim(\" --once: shutting down.\"))\n teardown(0)\n return\n }\n\n console.log()\n console.log(chalk.bold(\" Daemons stay up — browse the dashboards. Press Enter to replay, Ctrl-C to exit.\"))\n process.stdin.setEncoding(\"utf8\")\n process.stdin.on(\"data\", () => { playScenario().catch((e) => console.error(chalk.red(` Replay failed: ${e.message}`))) })\n process.stdin.resume()\n } catch (e: any) {\n console.error()\n console.error(chalk.red(` Demo failed: ${e.message}`))\n console.error(chalk.dim(` Node logs: ${specs.map((s) => join(s.dir, \"daemon.log\")).join(\", \")}`))\n teardown(1)\n }\n })\n","/** Publication-safe fixture, used only by the scripted demo provider. */\nexport const demoReportWorkflow = {\n id: \"demo-report\",\n version: 2 as const,\n title: \"Draft the demo shop report\",\n description: \"Scripted documentation example. Review and enable before running.\",\n status: \"draft\",\n state: \"disabled\",\n nodes: [\n { id: \"start\", type: \"trigger.manual\", config: {}, position: { x: 80, y: 180 } },\n { id: \"report\", type: \"agent\", config: { agentId: \"cx\", prompt: \"Prepare the demo shop report.\" }, position: { x: 380, y: 180 } },\n { id: \"done\", type: \"end\", config: { status: \"completed\" }, position: { x: 680, y: 180 } },\n ],\n edges: [{ from: \"start\", to: \"report\" }, { from: \"report\", to: \"done\" }],\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx whatsapp: list & ingest WhatsApp data into the wiki ---\n//\n// Talks to the running daemon's HTTP API (same pattern as `agentx usage`).\n// The daemon owns the Baileys socket; the CLI is just a thin client that\n// renders the results. Keeps auth state on the daemon and avoids making\n// the CLI ship Baileys + pair-again.\n\nexport const whatsapp = new Command()\n .name(\"whatsapp\")\n .description(\"list WhatsApp chats/contacts and ingest them into the wiki as a data source\")\n\nwhatsapp\n .command(\"list-chats\")\n .description(\"list chats observed by the WhatsApp socket (cached, no live fetch)\")\n .option(\"--format <format>\", \"output format: table | json\", \"table\")\n .option(\"--group\", \"groups only\")\n .option(\"--dm\", \"DMs only\")\n .action(async (opts) => {\n try {\n const data = await getJSON(\"/whatsapp/chats\") as { chats?: Array<any> }\n let chats = data.chats ?? []\n if (opts.group) chats = chats.filter((c) => c.isGroup)\n if (opts.dm) chats = chats.filter((c) => !c.isGroup)\n if (opts.format === \"json\") {\n console.log(JSON.stringify(chats, null, 2))\n return\n }\n if (chats.length === 0) { console.log(chalk.dim(\" no chats cached yet\")); return }\n console.log()\n console.log(chalk.bold(` ${chats.length} chat${chats.length === 1 ? \"\" : \"s\"}`))\n console.log()\n for (const c of chats) {\n const kind = c.isGroup ? chalk.cyan(\"group\") : chalk.dim(\"dm\")\n const when = c.lastMessageAt ? new Date(c.lastMessageAt * 1000).toISOString().slice(0, 16).replace(\"T\", \" \") : \"—\"\n console.log(` ${kind} ${c.name.padEnd(30)} ${chalk.dim(c.jid.padEnd(40))} ${chalk.dim(when)}`)\n }\n console.log()\n } catch (e: any) {\n fail(e)\n }\n })\n\nwhatsapp\n .command(\"list-contacts\")\n .description(\"list contacts observed by the WhatsApp socket (cached, no live fetch)\")\n .option(\"--format <format>\", \"output format: table | json\", \"table\")\n .action(async (opts) => {\n try {\n const data = await getJSON(\"/whatsapp/contacts\") as { contacts?: Array<any> }\n const contacts = data.contacts ?? []\n if (opts.format === \"json\") {\n console.log(JSON.stringify(contacts, null, 2))\n return\n }\n if (contacts.length === 0) { console.log(chalk.dim(\" no contacts cached yet\")); return }\n console.log()\n console.log(chalk.bold(` ${contacts.length} contact${contacts.length === 1 ? \"\" : \"s\"}`))\n console.log()\n for (const c of contacts) {\n const name = (c.name || c.pushName || c.phone || c.jid).padEnd(30)\n const phone = c.phone ? `+${c.phone}`.padEnd(16) : \"—\".padEnd(16)\n console.log(` ${name} ${chalk.dim(phone)} ${chalk.dim(c.jid)}`)\n }\n console.log()\n } catch (e: any) {\n fail(e)\n }\n })\n\nwhatsapp\n .command(\"ingest-all\")\n .description(\"run a full ingest sweep against the configured allowlist (writes raw wiki entries)\")\n .option(\"--dry-run\", \"compute entries without writing them — review before enabling\")\n .option(\"--agent <id>\", \"owner agent for the entries (defaults to channels.whatsapp.defaultAgent)\")\n .option(\"--force\", \"bypass the channels.whatsapp.ingest.enabled guard\")\n .action(async (opts) => {\n try {\n const body: Record<string, unknown> = { dryRun: !!opts.dryRun, force: !!opts.force }\n if (opts.agent) body.agent = opts.agent\n const report = await postJSON(\"/whatsapp/ingest\", body)\n printReport(report, !!opts.dryRun)\n } catch (e: any) {\n fail(e)\n }\n })\n\nwhatsapp\n .command(\"ingest-contact <jid>\")\n .description(\"ingest one contact (skips scope allowlist for this JID only)\")\n .option(\"--dry-run\", \"compute entries without writing them\")\n .option(\"--agent <id>\", \"owner agent for the entries\")\n .action(async (jid, opts) => {\n try {\n const body: Record<string, unknown> = { dryRun: !!opts.dryRun, force: true, onlyJid: jid, onlyKind: \"contact\" }\n if (opts.agent) body.agent = opts.agent\n const report = await postJSON(\"/whatsapp/ingest\", body)\n printReport(report, !!opts.dryRun)\n } catch (e: any) {\n fail(e)\n }\n })\n\nwhatsapp\n .command(\"ingest-chat <jid>\")\n .description(\"ingest one chat (DM or group) including message window if `--messages` is set\")\n .option(\"--dry-run\", \"compute entries without writing them\")\n .option(\"--messages\", \"include the bounded message window for this chat (overrides config mode)\")\n .option(\"--agent <id>\", \"owner agent for the entries\")\n .action(async (jid, opts) => {\n try {\n const body: Record<string, unknown> = { dryRun: !!opts.dryRun, force: true, onlyJid: jid }\n if (opts.agent) body.agent = opts.agent\n if (opts.messages) body.forceMode = \"messages\"\n const report = await postJSON(\"/whatsapp/ingest\", body)\n printReport(report, !!opts.dryRun)\n } catch (e: any) {\n fail(e)\n }\n })\n\nwhatsapp\n .command(\"status\")\n .description(\"show WhatsApp channel + ingest status\")\n .action(async () => {\n try {\n const state = await getJSON(\"/whatsapp/state\")\n const chats = await getJSON(\"/whatsapp/chats\") as { chats?: any[] }\n const contacts = await getJSON(\"/whatsapp/contacts\") as { contacts?: any[] }\n console.log()\n console.log(chalk.bold(\" WhatsApp status\"))\n console.log()\n console.log(` connection: ${(state as any).connection || \"—\"}`)\n console.log(` cached chats: ${chats.chats?.length ?? 0}`)\n console.log(` cached contacts: ${contacts.contacts?.length ?? 0}`)\n console.log()\n } catch (e: any) {\n fail(e)\n }\n })\n\nfunction printReport(report: any, dryRun: boolean): void {\n console.log()\n console.log(chalk.bold(dryRun ? \" Ingest (dry-run)\" : \" Ingest report\"))\n console.log()\n console.log(` scanned: contacts=${report.scannedContacts}, groups=${report.scannedGroups}`)\n console.log(` wrote: contacts=${report.wroteContacts}, groups=${report.wroteGroups}, dm-windows=${report.wroteDmWindows}, group-windows=${report.wroteGroupWindows}`)\n if (report.skippedUnchanged) console.log(` skipped: ${report.skippedUnchanged} unchanged`)\n if (report.errors?.length) {\n console.log(chalk.yellow(` errors: ${report.errors.length}`))\n for (const err of report.errors.slice(0, 5)) {\n console.log(chalk.yellow(` - [${err.kind}] ${err.jid}: ${err.message}`))\n }\n }\n if (dryRun && report.dryRunEntries?.length) {\n console.log()\n console.log(chalk.dim(\" would-be entries:\"))\n for (const e of report.dryRunEntries.slice(0, 10)) {\n console.log(chalk.dim(` - ${e.id} (${e.source}, ${e.content.length} bytes)`))\n }\n if (report.dryRunEntries.length > 10) console.log(chalk.dim(` …and ${report.dryRunEntries.length - 10} more`))\n }\n console.log()\n}\n\nfunction daemonUrl(): string {\n try {\n const config = loadDaemonConfig()\n const [host, port] = config.node.bind.split(\":\")\n return `http://${host || \"127.0.0.1\"}:${port || \"19900\"}`\n } catch {\n return \"http://127.0.0.1:19900\"\n }\n}\n\nasync function getJSON(path: string): Promise<unknown> {\n const r = await fetch(`${daemonUrl()}${path}`, { signal: AbortSignal.timeout(10_000) })\n const data = await r.json().catch(() => ({}))\n if (!r.ok) throw new Error((data as any).error || `HTTP ${r.status}`)\n return data\n}\n\nasync function postJSON(path: string, body: unknown): Promise<any> {\n const r = await fetch(`${daemonUrl()}${path}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(10 * 60_000),\n })\n const data = await r.json().catch(() => ({}))\n if (!r.ok) throw new Error((data as any).error || `HTTP ${r.status}`)\n return data\n}\n\nfunction fail(e: any): never {\n console.error(chalk.red(` ${e.message || e}`))\n process.exit(1)\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { existsSync, mkdirSync, writeFileSync } from \"fs\"\nimport { join, resolve } from \"path\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\nimport { agentXPluginManifestSchema, type AgentXPlugin } from \"@/plugins/types\"\n\n// `agentx plugin` — surface the plugin loader's view from outside the\n// daemon. `list` shows the configured packages; `doctor` actually\n// imports them and reports whether the manifest validates without\n// starting the daemon. Useful for operators to validate before\n// restarting and useful in CI to catch a broken plugin install.\n\nexport const plugin = new Command()\n .name(\"plugin\")\n .description(\"manage agentx plugins (Move B)\")\n\nplugin\n .command(\"list\", { isDefault: true })\n .description(\"list plugins configured in agentx.json\")\n .action(() => {\n try {\n const config = loadDaemonConfig()\n const names = config.plugins ?? []\n console.log()\n if (names.length === 0) {\n console.log(chalk.dim(\" No plugins configured.\"))\n console.log(chalk.dim(\" Add a plugin: edit agentx.json's `plugins: [\\\"your-package\\\"]` and pnpm install it.\"))\n console.log()\n return\n }\n console.log(chalk.bold(` Plugins configured: ${names.length}`))\n console.log()\n for (const n of names) {\n console.log(` ${chalk.cyan(n)}`)\n }\n console.log()\n console.log(chalk.dim(\" Run `agentx plugin doctor` to verify each plugin loads.\"))\n console.log()\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exitCode = 1\n }\n })\n\nplugin\n .command(\"init <name>\")\n .description(\"scaffold a new plugin package (npm-publishable, with manifest + setup hook)\")\n .option(\"--cwd <cwd>\", \"directory to create the package under\", process.cwd())\n .option(\"--description <text>\", \"short package description\")\n .option(\"--force\", \"overwrite an existing directory\")\n .action((name: string, opts) => {\n if (!/^(@[a-z0-9-]+\\/)?[a-z0-9][a-z0-9._-]*$/i.test(name)) {\n console.log(chalk.red(` invalid package name \"${name}\". Use lowercase letters, digits, hyphens; optional @scope/ prefix.`))\n process.exit(1)\n }\n const dirName = name.startsWith(\"@\") ? name.split(\"/\")[1] : name\n const target = resolve(opts.cwd, dirName)\n if (existsSync(target) && !opts.force) {\n console.log(chalk.red(` ${target} already exists. Use --force to overwrite.`))\n process.exit(1)\n }\n mkdirSync(target, { recursive: true })\n mkdirSync(join(target, \"src\"), { recursive: true })\n\n const description = opts.description || `AgentX plugin: ${name}`\n writeFileSync(join(target, \"package.json\"), packageJson(name, description))\n writeFileSync(join(target, \"tsconfig.json\"), tsconfig())\n writeFileSync(join(target, \"src/index.ts\"), pluginSource(name))\n writeFileSync(join(target, \"README.md\"), readme(name, description))\n writeFileSync(join(target, \".gitignore\"), gitignore())\n\n console.log()\n console.log(chalk.green(` ✓ scaffolded plugin at ${target}`))\n console.log()\n console.log(chalk.bold(\" Next steps:\"))\n console.log(chalk.dim(` cd ${dirName}`))\n console.log(chalk.dim(` pnpm install`))\n console.log(chalk.dim(` pnpm build`))\n console.log(chalk.dim(` pnpm link --global # for local testing`))\n console.log(chalk.dim(` # then in your agentx project:`))\n console.log(chalk.dim(` pnpm link --global ${name}`))\n console.log(chalk.dim(` agentx config set plugins[0] \"${name}\"`))\n console.log(chalk.dim(` agentx plugin doctor`))\n console.log()\n })\n\nplugin\n .command(\"doctor\")\n .description(\"dynamic-import each configured plugin and report status\")\n .action(async () => {\n try {\n const config = loadDaemonConfig()\n const names = config.plugins ?? []\n console.log()\n if (names.length === 0) {\n console.log(chalk.dim(\" No plugins configured. Nothing to check.\"))\n console.log()\n return\n }\n let bad = 0\n for (const name of names) {\n const status = await checkOne(name)\n if (status.kind === \"ok\") {\n console.log(` ${chalk.green(\"✓\")} ${chalk.cyan(name)} — ${status.manifestName} v${status.manifestVersion}`)\n } else {\n bad++\n console.log(` ${chalk.red(\"✗\")} ${chalk.cyan(name)} — ${status.reason}`)\n }\n }\n console.log()\n if (bad > 0) {\n console.log(chalk.red(` ${bad}/${names.length} plugin(s) failed`))\n process.exitCode = 1\n }\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`))\n process.exitCode = 1\n }\n })\n\ntype DoctorStatus =\n | { kind: \"ok\"; manifestName: string; manifestVersion: string }\n | { kind: \"fail\"; reason: string }\n\nasync function checkOne(packageName: string): Promise<DoctorStatus> {\n let mod: unknown\n try {\n mod = await import(packageName)\n } catch (e: any) {\n return { kind: \"fail\", reason: `import failed: ${e?.message ?? e}` }\n }\n\n const candidate = pickDefault(mod)\n if (!isPlugin(candidate)) {\n return { kind: \"fail\", reason: \"no default AgentXPlugin export (manifest/setup pair not found)\" }\n }\n const parsed = agentXPluginManifestSchema.safeParse(candidate.manifest)\n if (!parsed.success) {\n const issues = parsed.error.issues.map((i) => i.message).join(\"; \")\n return { kind: \"fail\", reason: `manifest invalid: ${issues}` }\n }\n return { kind: \"ok\", manifestName: parsed.data.name, manifestVersion: parsed.data.version }\n}\n\n// Same ESM/CJS interop logic the loader uses — duplicated here so the CLI\n// can run without the daemon's dependency tree. Two ~10-line functions\n// don't justify a shared module yet.\nfunction pickDefault(mod: unknown): unknown {\n if (mod == null) return mod\n if (typeof mod !== \"object\") return mod\n const m = mod as Record<string, unknown>\n if (m.default && typeof m.default === \"object\") {\n const d = m.default as Record<string, unknown>\n if (d.manifest && typeof d.setup === \"function\") return d\n if (d.default && typeof d.default === \"object\") {\n const dd = d.default as Record<string, unknown>\n if (dd.manifest && typeof dd.setup === \"function\") return dd\n }\n }\n if (m.manifest && typeof m.setup === \"function\") return m\n return m.default ?? m\n}\n\nfunction isPlugin(c: unknown): c is AgentXPlugin {\n return (\n !!c &&\n typeof c === \"object\" &&\n \"manifest\" in (c as object) &&\n \"setup\" in (c as object) &&\n typeof (c as { setup: unknown }).setup === \"function\"\n )\n}\n\n// --- Scaffolding templates for `agentx plugin init` ---\n\nfunction packageJson(name: string, description: string): string {\n return JSON.stringify({\n name,\n version: \"0.1.0\",\n description,\n main: \"dist/index.js\",\n types: \"dist/index.d.ts\",\n files: [\"dist\"],\n scripts: {\n build: \"tsc\",\n prepublishOnly: \"pnpm build\",\n },\n keywords: [\"agentx\", \"agentx-plugin\"],\n license: \"MIT\",\n devDependencies: {\n typescript: \"^5.4.0\",\n \"@types/node\": \"^20.0.0\",\n },\n }, null, 2) + \"\\n\"\n}\n\nfunction tsconfig(): string {\n return JSON.stringify({\n compilerOptions: {\n target: \"es2020\",\n module: \"commonjs\",\n lib: [\"es2020\"],\n declaration: true,\n outDir: \"dist\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n moduleResolution: \"node\",\n },\n include: [\"src/**/*.ts\"],\n }, null, 2) + \"\\n\"\n}\n\nfunction pluginSource(name: string): string {\n return `// ${name} — AgentX plugin\n//\n// A plugin's default export is { manifest, setup }. The daemon calls\n// setup(ctx) once at boot. ctx.on() subscribes to the bus; ctx.addChannel()\n// registers a custom channel adapter; ctx.log() namespaces output.\n\nconst plugin = {\n manifest: {\n name: ${JSON.stringify(name)},\n version: \"0.1.0\",\n // agentxRange: \"0.x\", // optional — gate against the daemon's major.minor\n },\n\n setup(ctx: any) {\n ctx.log(\"hello from\", ${JSON.stringify(name)})\n\n // Example: log every completed task.\n ctx.on(\"task:completed\", (payload: any) => {\n ctx.log(\"task done:\", payload.agentId, payload.durationMs + \"ms\")\n })\n\n // Example: register a no-op channel adapter.\n // ctx.addChannel({\n // name: \"my-channel\",\n // start: async () => {},\n // stop: async () => {},\n // send: async (out) => { ctx.log(\"send:\", out) },\n // })\n },\n\n // Optional — only needed for resources you own (timers, sockets).\n // Bus subscriptions are removed automatically.\n // teardown() {},\n}\n\nexport default plugin\n`\n}\n\nfunction readme(name: string, description: string): string {\n return `# ${name}\n\n${description}\n\n## Install\n\n\\`\\`\\`bash\npnpm install ${name}\n\\`\\`\\`\n\n## Use\n\nAdd to \\`agentx.json\\`:\n\n\\`\\`\\`json\n{\n \"plugins\": [\"${name}\"]\n}\n\\`\\`\\`\n\nThen verify the load:\n\n\\`\\`\\`bash\nagentx plugin doctor\n\\`\\`\\`\n\nRestart the daemon to activate.\n`\n}\n\nfunction gitignore(): string {\n return \"node_modules/\\ndist/\\n*.log\\n.env\\n\"\n}\n","import { Command, Option } from \"commander\"\nimport chalk from \"chalk\"\nimport { writeFileSync, mkdirSync, existsSync, readFileSync, appendFileSync } from \"fs\"\nimport { resolve, dirname } from \"path\"\nimport { homedir } from \"os\"\n\n// --- agentx completion: generate shell completion scripts ---\n//\n// Walks the commander tree built in src/program.ts and emits a static\n// completion script. Pattern modelled after the openclaw zsh completion:\n// - one `_agentx_<path>` function per (sub)command,\n// - root `_agentx_root_completion` dispatches on $line[1],\n// - `compdef _agentx_root_completion agentx` at the bottom.\n//\n// Regenerate + reinstall whenever a command or flag is added:\n// agentx completion --install\n//\n// Shipped with the global install so `npm i -g agentix-cli && agentx\n// completion --install` is the full setup path for end users.\n\nexport const completion = new Command()\n .name(\"completion\")\n .description(\"generate a shell completion script for agentx\")\n .option(\"-s, --shell <shell>\", \"shell to generate completion for: zsh|bash|fish\", \"zsh\")\n .option(\"-i, --install\", \"install the completion script to a default path for the shell\")\n .option(\"-o, --output <path>\", \"write the script to this path (overrides default install path)\")\n .option(\"-y, --yes\", \"skip confirmation prompts (non-interactive)\")\n .action(async (opts) => {\n const { buildProgram } = await import(\"@/program\")\n const program = await buildProgram()\n const shell = String(opts.shell || \"zsh\").toLowerCase()\n\n let script: string\n switch (shell) {\n case \"zsh\":\n script = generateZsh(program)\n break\n case \"bash\":\n script = generateBash(program)\n break\n case \"fish\":\n script = generateFish(program)\n break\n default:\n console.error(chalk.red(`unsupported shell: ${shell}`))\n console.error(chalk.dim(`supported: zsh, bash, fish`))\n process.exit(1)\n }\n\n // Plain print mode: stream to stdout so users can pipe/redirect.\n if (!opts.install && !opts.output) {\n process.stdout.write(script)\n return\n }\n\n const dest = opts.output ? resolve(String(opts.output)) : defaultInstallPath(shell)\n mkdirSync(dirname(dest), { recursive: true })\n writeFileSync(dest, script)\n\n console.log(chalk.green(`✓ Wrote ${shell} completion to:`))\n console.log(` ${dest}`)\n console.log()\n printShellHookInstructions(shell, dest, !!opts.yes)\n })\n\nfunction defaultInstallPath(shell: string): string {\n const home = homedir()\n switch (shell) {\n case \"zsh\":\n return resolve(home, \".zsh\", \"completions\", \"_agentx\")\n case \"bash\":\n return resolve(home, \".bash_completion.d\", \"agentx.bash\")\n case \"fish\":\n return resolve(home, \".config\", \"fish\", \"completions\", \"agentx.fish\")\n default:\n throw new Error(`unsupported shell: ${shell}`)\n }\n}\n\nfunction printShellHookInstructions(shell: string, dest: string, autoPatch: boolean): void {\n if (shell === \"zsh\") {\n const rc = resolve(homedir(), \".zshrc\")\n const fpathDir = dirname(dest)\n const fpathLine = `fpath=(${fpathDir} $fpath)`\n const compinitLine = `autoload -U compinit && compinit`\n const rcExisting = existsSync(rc) ? readFileSync(rc, \"utf-8\") : \"\"\n const needsFpath = !rcExisting.includes(fpathDir)\n const needsCompinit = !/autoload\\s+-U\\s+compinit/.test(rcExisting)\n\n if (!needsFpath && !needsCompinit) {\n console.log(chalk.dim(\"~/.zshrc already has fpath + compinit wired up. Run `exec zsh` to pick up the new script.\"))\n return\n }\n\n if (autoPatch && existsSync(rc)) {\n const block: string[] = [\"\", \"# agentx completion\"]\n if (needsFpath) block.push(fpathLine)\n if (needsCompinit) block.push(compinitLine)\n appendFileSync(rc, block.join(\"\\n\") + \"\\n\")\n console.log(chalk.green(`✓ Patched ~/.zshrc`))\n console.log(chalk.dim(\"Reload your shell: exec zsh\"))\n return\n }\n\n console.log(chalk.dim(\"Add this to ~/.zshrc if not already present:\"))\n if (needsFpath) console.log(chalk.cyan(` ${fpathLine}`))\n if (needsCompinit) console.log(chalk.cyan(` ${compinitLine}`))\n console.log()\n console.log(chalk.dim(\"Then reload: exec zsh\"))\n console.log(chalk.dim(\"Or rerun with --yes to auto-patch ~/.zshrc\"))\n return\n }\n\n if (shell === \"bash\") {\n const rc = resolve(homedir(), \".bashrc\")\n const sourceLine = `[ -f \"${dest}\" ] && source \"${dest}\"`\n const rcExisting = existsSync(rc) ? readFileSync(rc, \"utf-8\") : \"\"\n const already = rcExisting.includes(dest)\n\n if (already) {\n console.log(chalk.dim(\"~/.bashrc already sources this file. Start a new shell to pick it up.\"))\n return\n }\n\n if (autoPatch && existsSync(rc)) {\n appendFileSync(rc, `\\n# agentx completion\\n${sourceLine}\\n`)\n console.log(chalk.green(`✓ Patched ~/.bashrc`))\n console.log(chalk.dim(\"Reload your shell: exec bash\"))\n return\n }\n\n console.log(chalk.dim(\"Add this to ~/.bashrc:\"))\n console.log(chalk.cyan(` ${sourceLine}`))\n console.log()\n console.log(chalk.dim(\"Or rerun with --yes to auto-patch ~/.bashrc\"))\n return\n }\n\n if (shell === \"fish\") {\n console.log(chalk.dim(\"Fish auto-loads completions from this directory — start a new shell to pick it up.\"))\n return\n }\n}\n\n// ---------------------------------------------------------------------------\n// Commander tree helpers\n// ---------------------------------------------------------------------------\n\nfunction cmdName(cmd: Command): string {\n // commander stores the registered name on _name; fall back to .name()\n return (cmd as any)._name || cmd.name() || \"\"\n}\n\nfunction subcommandsOf(cmd: Command): Command[] {\n return cmd.commands.filter((c) => {\n const n = cmdName(c)\n if (!n) return false\n if (n === \"help\") return false\n // Hidden commands ARE completed on purpose.\n //\n // `hidden` exists to shorten `agentx --help` — 30 advanced commands are\n // registered but kept out of the default listing. Dropping them from\n // completion too would turn \"not advertised\" into \"hard to use\", which is\n // the opposite of the intent: someone who already knows `agentx ledger`\n // should still get its subcommands on Tab.\n return true\n })\n}\n\nfunction optionsOf(cmd: Command): Option[] {\n return (cmd.options as Option[]).filter((o) => !(o as any).hidden)\n}\n\n// ---------------------------------------------------------------------------\n// zsh generator\n// ---------------------------------------------------------------------------\n\nfunction generateZsh(program: Command): string {\n const out: string[] = []\n out.push(`#compdef agentx`)\n out.push(``)\n emitZshFn(program, [], out)\n out.push(`compdef _agentx_root_completion agentx`)\n out.push(``)\n return out.join(\"\\n\")\n}\n\nfunction zshFnName(path: string[]): string {\n if (path.length === 0) return `_agentx_root_completion`\n return `_agentx_${path.join(\"_\").replace(/[^a-z0-9_]/gi, \"_\")}`\n}\n\nfunction emitZshFn(cmd: Command, path: string[], out: string[]): void {\n const subs = subcommandsOf(cmd)\n const opts = optionsOf(cmd)\n const optLines = opts.map(zshOptionLine).filter((s): s is string => !!s)\n const name = zshFnName(path)\n\n out.push(`${name}() {`)\n out.push(` local -a commands`)\n out.push(` local -a options`)\n out.push(` `)\n\n // Nothing to complete: emit an empty-but-valid function.\n if (optLines.length === 0 && subs.length === 0) {\n out.push(` return 0`)\n out.push(`}`)\n out.push(``)\n return\n }\n\n const argLines: string[] = []\n for (const line of optLines) argLines.push(line)\n\n if (subs.length > 0) {\n const entries = subs.map(zshCommandEntry).join(\" \")\n argLines.push(` \"1: :_values 'command' ${entries}\"`)\n argLines.push(` \"*::arg:->args\"`)\n }\n\n out.push(` _arguments -C \\\\`)\n for (let i = 0; i < argLines.length; i++) {\n const last = i === argLines.length - 1\n out.push(`${argLines[i]}${last ? \"\" : \" \\\\\"}`)\n }\n\n if (subs.length > 0) {\n out.push(``)\n out.push(` case $state in`)\n out.push(` (args)`)\n out.push(` case $line[1] in`)\n for (const sub of subs) {\n const subFn = zshFnName([...path, cmdName(sub)])\n out.push(` (${cmdName(sub)}) ${subFn} ;;`)\n }\n out.push(` esac`)\n out.push(` ;;`)\n out.push(` esac`)\n }\n\n out.push(`}`)\n out.push(``)\n\n for (const sub of subs) {\n emitZshFn(sub, [...path, cmdName(sub)], out)\n }\n}\n\nfunction escapeZshDesc(s: string): string {\n return String(s || \"\")\n .replace(/\\r?\\n/g, \" \")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\[/g, \"\\\\[\")\n .replace(/\\]/g, \"\\\\]\")\n}\n\nfunction escapeZshValue(s: string): string {\n return String(s || \"\")\n .replace(/\\r?\\n/g, \" \")\n .replace(/'/g, \"'\\\\''\")\n .replace(/\\[/g, \"\\\\[\")\n .replace(/\\]/g, \"\\\\]\")\n}\n\nfunction zshOptionLine(opt: Option): string | null {\n const short = opt.short || undefined\n const long = opt.long || undefined\n if (!short && !long) return null\n const desc = escapeZshDesc(opt.description || \"\")\n if (short && long) {\n return ` \"(${long} ${short})\"{${long},${short}}\"[${desc}]\"`\n }\n return ` \"${long || short}[${desc}]\"`\n}\n\nfunction zshCommandEntry(cmd: Command): string {\n const desc = escapeZshValue(cmd.description() || \"\")\n return `'${cmdName(cmd)}[${desc}]'`\n}\n\n// ---------------------------------------------------------------------------\n// bash generator (flat: root + first level)\n// ---------------------------------------------------------------------------\n\nfunction generateBash(program: Command): string {\n const tops = subcommandsOf(program)\n const lines: string[] = []\n lines.push(`# bash completion for agentx`)\n lines.push(`_agentx_complete() {`)\n lines.push(` local cur prev words cword`)\n lines.push(` COMPREPLY=()`)\n lines.push(` cur=\"\\${COMP_WORDS[COMP_CWORD]}\"`)\n lines.push(` prev=\"\\${COMP_WORDS[COMP_CWORD-1]}\"`)\n lines.push(``)\n lines.push(` local top=\"${tops.map(cmdName).join(\" \")}\"`)\n lines.push(``)\n lines.push(` if [[ $COMP_CWORD -eq 1 ]]; then`)\n lines.push(` COMPREPLY=( $(compgen -W \"$top\" -- \"$cur\") )`)\n lines.push(` return 0`)\n lines.push(` fi`)\n lines.push(``)\n lines.push(` local cmd=\"\\${COMP_WORDS[1]}\"`)\n lines.push(` local sub2=\"\\${COMP_WORDS[2]:-}\"`)\n lines.push(` case \"$cmd\" in`)\n for (const sub of tops) {\n const subsubs = subcommandsOf(sub).map(cmdName)\n const subOpts = collectBashFlags(sub)\n lines.push(` ${cmdName(sub)})`)\n if (subsubs.length > 0) {\n lines.push(` if [[ $COMP_CWORD -eq 2 ]]; then`)\n lines.push(` COMPREPLY=( $(compgen -W \"${subsubs.join(\" \")} ${subOpts}\" -- \"$cur\") )`)\n lines.push(` return 0`)\n lines.push(` fi`)\n lines.push(` case \"$sub2\" in`)\n for (const ss of subcommandsOf(sub)) {\n const ssOpts = collectBashFlags(ss)\n lines.push(` ${cmdName(ss)})`)\n lines.push(` COMPREPLY=( $(compgen -W \"${ssOpts}\" -- \"$cur\") )`)\n lines.push(` return 0`)\n lines.push(` ;;`)\n }\n lines.push(` esac`)\n } else {\n lines.push(` COMPREPLY=( $(compgen -W \"${subOpts}\" -- \"$cur\") )`)\n }\n lines.push(` ;;`)\n }\n lines.push(` esac`)\n lines.push(`}`)\n lines.push(``)\n lines.push(`complete -F _agentx_complete agentx`)\n lines.push(``)\n return lines.join(\"\\n\")\n}\n\nfunction collectBashFlags(cmd: Command): string {\n const flags: string[] = []\n for (const opt of optionsOf(cmd)) {\n if (opt.long) flags.push(opt.long)\n if (opt.short) flags.push(opt.short)\n }\n return flags.join(\" \")\n}\n\n// ---------------------------------------------------------------------------\n// fish generator\n// ---------------------------------------------------------------------------\n\nfunction generateFish(program: Command): string {\n const lines: string[] = []\n lines.push(`# fish completion for agentx`)\n lines.push(``)\n lines.push(`complete -c agentx -f`)\n lines.push(``)\n\n // Top-level subcommands: only when no subcommand entered.\n lines.push(`# top-level commands`)\n for (const sub of subcommandsOf(program)) {\n const desc = escapeFish(sub.description() || \"\")\n lines.push(`complete -c agentx -n \"__fish_use_subcommand\" -a \"${cmdName(sub)}\" -d \"${desc}\"`)\n }\n lines.push(``)\n\n // Root options (gated on no-subcommand to avoid polluting subcommand suggestions).\n for (const opt of optionsOf(program)) {\n const line = fishOptionLine(opt, [`__fish_use_subcommand`])\n if (line) lines.push(line)\n }\n lines.push(``)\n\n // Per-top-level: options + second-level subcommands.\n for (const sub of subcommandsOf(program)) {\n const name = cmdName(sub)\n lines.push(`# ${name}`)\n for (const opt of optionsOf(sub)) {\n const line = fishOptionLine(opt, [`__fish_seen_subcommand_from ${name}`])\n if (line) lines.push(line)\n }\n for (const subsub of subcommandsOf(sub)) {\n const desc = escapeFish(subsub.description() || \"\")\n lines.push(\n `complete -c agentx -n \"__fish_seen_subcommand_from ${name}; and not __fish_seen_subcommand_from ${subcommandsOf(sub).map(cmdName).join(\" \")}\" -a \"${cmdName(subsub)}\" -d \"${desc}\"`\n )\n for (const opt of optionsOf(subsub)) {\n const line = fishOptionLine(opt, [`__fish_seen_subcommand_from ${cmdName(subsub)}`])\n if (line) lines.push(line)\n }\n }\n lines.push(``)\n }\n return lines.join(\"\\n\")\n}\n\nfunction escapeFish(s: string): string {\n return String(s || \"\")\n .replace(/\\r?\\n/g, \" \")\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n}\n\nfunction fishOptionLine(opt: Option, conditions: string[]): string | null {\n const shortRaw = opt.short ? opt.short.replace(/^-/, \"\") : \"\"\n const longRaw = opt.long ? opt.long.replace(/^--/, \"\") : \"\"\n if (!shortRaw && !longRaw) return null\n const desc = escapeFish(opt.description || \"\")\n const cond = conditions.map((c) => `-n \"${c}\"`).join(\" \")\n const parts: string[] = [`complete -c agentx`, cond]\n if (shortRaw) parts.push(`-s ${shortRaw}`)\n if (longRaw) parts.push(`-l ${longRaw}`)\n parts.push(`-d \"${desc}\"`)\n return parts.join(\" \")\n}\n"],"mappings":"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","names":["Command","a2a","Command","opts","A2AServer","init_config","Command","execFileSync","cpSync","existsSync","mkdirSync","mkdtempSync","readFileSync","rmSync","writeFileSync","dirname","join","resolve","homedir","release","tmpdir","fileURLToPath","sleep","existsSync","join","DESKTOP_LABEL","DESKTOP_APP","HELPER_APP","desktopPlatformError","platform","arch","release","selectDesktopAgent","agents","requested","id","shellQuote","value","desktopPlist","opts","xml","s","env","k","v","installedHelper","home","resolveHelper","cwd","override","installed","checkPlatform","error","desktopPlatformError","release","launchTarget","DESKTOP_LABEL","plistPath","join","homedir","stop","execFileSync","i","sleep","start","existsSync","loaded","packageRoot","here","dirname","fileURLToPath","dir","resolve","readFileSync","desktop","Command","opts","config","loadDaemonConfig","agent","selectDesktopAgent","url","root","apps","DESKTOP_APP","HELPER_APP","stage","mkdtempSync","tmpdir","name","cpSync","source","log","plist","desktopPlist","installedHelper","stagedPlist","writeFileSync","mkdirSync","built","dest","rmSync","Command","open","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","resolve","ATTACH_MARKER","GUARD_MARKER","hookCommand","route","port","query","entry","matcher","e","attachHookBlock","guardHookEntries","command","isOurs","marker","h","userSettingsPath","configuredDaemonPort","root","dir","cfg","bind","installAttachHooks","opts","path","withGuard","settings","before","hooks","events","event","desired","others","guardInstalled","changed","uninstallAttachHooks","kept","attachHooksInstalled","monitor","Command","defaultUrl","configuredDaemonPort","post","url","path","body","token","res","opts","registrationSchema","e","file","open","transcript","stat","bytes","buffer","bytesRead","stopSchema","Command","Command","init_config","chalk","existsSync","readFileSync","isLikelyAgentxProcess","pid","execFileSync","cmd","daemon","Command","opts","spawn","openSync","writeFileSync","cli","args","logPath","logFd","e","child","ok","mkdirSync","resolve","lockDir","pidPath","oldPid","alive","loadDotenv","AgentXDaemon","path","text","raw","line","eq","key","val","unlinkSync","pidFiles","pidFile","r","execSync","config","loadDaemonConfig","host","port","url","data","formatDuration","a","active","errors","enabledCrons","icon","next","p","skills","warnings","validateWorkspaces","w","err","spawnProc","logFile","tail","res","reader","decoder","buffer","done","value","lines","time","msg","agent","messageParts","message","baseUrl","body","sshKey","remote","statSync","cliPath","ssh","seconds","Command","chalk","existsSync","readFileSync","writeFileSync","mkdirSync","hostname","resolve","init","opts","cwd","configPath","envPath","sessionsDir","examplePaths","example","p","claudeDir","Command","chalk","spawn","existsSync","dirname","resolve","fileURLToPath","init_config","setup","Command","opts","state","wizardState","port","resolveDashboardPort","url","chalk","probe","openBrowser","cli","resolveCliEntry","child","spawn","ok","loadDaemonConfig","candidate","resolve","dirname","fileURLToPath","existsSync","r","cmd","Command","chalk","token","Command","opts","store","TokenStore","scopes","s","days","secret","record","chalk","e","records","r","status","id","rec","init_config","Command","chalk","prompts","readFileSync","writeFileSync","existsSync","mkdirSync","cpSync","readdirSync","resolve","join","dirname","fileURLToPath","loadConfig","p","resolve","existsSync","readFileSync","saveConfig","config","applyConfigMutation","current","k","result","chalk","agent","Command","id","a","mentions","answers","prompts","v","ws","join","mkdirSync","agentDef","m","setupWorkspace","setup","args","wikiSkillSrc","wikiSkillDist","dirname","fileURLToPath","skillSrc","cpSync","opts","changes","s","n","integrations","agentId","list","enabled","statusBits","creds","meta","cfg","interactive","INTEGRATION_KINDS","kind","label","tokenEnv","auth","sessionDir","r","metadata","pair","rest","credentials","i","target","tk","tl","idx","removed","filtered","bad","issues","issue","channel","tg","name","acc","wa","route","gl","agentIds","agentChoices","channelType","data","botHandle","agentMentions","e","routes","addMore","prev","cron","c","icon","mesh","peer","status","card","skillCmd","skillPath","srcPath","skillName","targets","destDir","skillsDir","skills","readdirSync","f","createHash","cwd","candidates","src","srcContent","srcHash","srcVersion","loadDaemonConfig","entries","newN","updatedN","unchangedN","skippedN","def","dstDir","dst","writeFileSync","dstContent","dstVersion","verb","loadLocalSkills","auditAll","loadReferences","loadRecipes","skillsRoots","refsRoot","references","recipes","results","summary","tag","reason","task","agents","pickSkillForTask","pick","judged","namespace","exampleRoot","exampleRecipe","targetRoot","targetRecipes","exampleFiles","copied","skipped","file","dest","rewritten","recipeDest","discoverFromSkills","renderDiscovery","filter","counts","files","writeRoot","targetDir","content","l","written","cards","b","hook","settingsPath","settings","entry","migrate","configPath","searchPaths","ocPath","oc","bindings","bindMap","agentCount","axId","tgAccounts","tgCount","axAgentId","cronPath","cronData","cronCount","job","configCmd","warnings","validateWorkspaces","w","hasClaudeDir","hasClaudeMd","hasSettings","skillCount","checks","parseValue","raw","asString","formatValue","path","getAtPath","expandEnvVars","cfgPath","source","value","setAtPath","parsed","unsetAtPath","businessEnabled","projectsCount","configError","ledgerMode","pmGateRaw","pmGate","pmGateActive","ledgerValid","modeColor","pmStatus","Command","chalk","resolve","existsSync","db","Command","openReadOnly","cwd","path","resolve","existsSync","chalk","handle","openDb","emit","rows","asJson","cols","widths","c","fmt","cells","v","i","_","row","opts","where","params","sql","whereSql","t","e","Command","chalk","mkdtempSync","tmpdir","resolve","join","existsSync","Database","replay","target","events","decisions","resolutions","eventById","e","timeline","d","r","a","b","divergences","decisionsCount","entry","recorded","event","policy","buildPlaybackPolicy","eventInput","replayed","decideAndCommit","classifyDivergence","ledger","Command","openReadOnly","opts","root","resolve","path","existsSync","chalk","Database","e","emit","rows","asJson","cols","widths","c","fmt","cells","v","i","_","row","durationToMs","input","m","n","unit","parseSince","ms","db","since","sinceClause","sinceClauseDecisions","sinceClauseDivergences","eventsBySource","totalDecisions","decisionsByOutcome","totalDivergences","divergencesBySource","inFlight","where","params","whereSql","eventOrSubject","project","subject","idx","events","eventIds","placeholders","id","decisions","grouped","d","distinctAgents","dt","evDecisions","outcome","agent","reason","status","dur","sourceDb","eventWhere","eventParams","eventLimit","r","eventIdParams","resolutions","tmpDir","mkdtempSync","join","tmpdir","target","IntentLedger","result","replay","init_store","init_calibration","init_recalibrate","init_consistency","init_backend","init_decisions","init_questions","Command","chalk","existsSync","resolve","Database","decisions","Command","DEFAULT_PATH","storePath","opts","resolve","open","writable","path","existsSync","chalk","DecisionStore","e","emit","rows","asJson","cols","widths","c","fmt","cells","v","i","row","parseSince","value","rel","ms","parsed","filterFrom","store","since","policy","where","params","callId","r","question","a","b","dbPath","db","n","backfillMonitorLabels","report","calibrationReport","fit","skipRegion","gradeable","covariates","result","compareCalibrators","s","curve","coverageCurve","p","registerBuiltinDecisionBackends","backend","model","measureConsistency","q","listDecisionBackends","name","caps","getDecisionBackend","questions","criteria","label","choice","noul","res","Command","chalk","resolve","existsSync","Database","trace","Command","openReadOnly","opts","root","resolve","path","existsSync","chalk","Database","e","durationToMs","input","m","n","unit","parseSince","ms","fmtAge","s","statusColor","db","traces","listTraces","t","status","dur","wf","tokens","taskId","rec","getTrace","printTrace","steps","wfPart","stepStatus","action","lines","l","message","base","body","startedAt","res","reply","durationMs","printBlock","same","text","max","shown","Command","chalk","existsSync","mkdirSync","writeFileSync","resolve","join","dirname","SEED_POLICY_YAML","SEED_PRODUCTION_YAML","SEED_CODER_AGENT_YAML","SEED_FILES","guard","Command","actionColor","a","chalk","rootOf","opts","resolve","guessInstallRoot","runCheckFromStdin","command","root","modeOverride","verdict","mode","ms","runGuard","printVerdict","v","col","rows","listDecisions","r","when","eff","base","join","GUARDRAILS_DIR","created","f","SEED_FILES","path","existsSync","mkdirSync","dirname","writeFileSync","res","e","p","loadPolicy","init_seat","Command","execFile","promisify","existsSync","chalk","init_questions","UI_ELEMENT_SEAT","uiElementState","input","prior","p","clip","c","humanRole","uiElementQuestions","candidates","criteria","name","choice","noul","toSelection","answers","target","ranked","a","b","role","text","max","flat","homedir","execFile","promisify","existsSync","INTERESTING_ROLE","scopeToPage","elements","byId","e","rootIds","isDescendant","cur","hops","page","buildCandidates","max","rank","role","i","a","b","run","promisify","execFile","HELPER","resolveHelper","homedir","THIN_TREE","readScreen","opts","existsSync","stdout","snap","candidates","buildCandidates","ocrRects","raw","read","nextId","e","textCandidates","hit","id","rectFor","el","run","promisify","execFile","point","Command","request","opts","existsSync","HELPER","chalk","screen","readScreen","e","candidates","only","rectFor","result","askSeat","UI_ELEMENT_SEAT","uiElementState","uiElementQuestions","sel","toSelection","chosen","chosenLabel","c","fromOCR","minPresent","r","name","Command","chalk","execFile","promisify","existsSync","readFileSync","homedir","tmpdir","join","run","promisify","execFile","MAX_PIXELS","OPENROUTER","DEFAULT_VISION_MODEL","capture","region","maxPixels","existsSync","HELPER","args","join","tmpdir","stdout","res","bytes","readFileSync","SYSTEM","describe","question","shot","model","timeoutMs","apiKey","resolveOpenRouterKey","b64","body","describeRegion","ctrl","timer","detail","json","call","parsed","reading","look","opts","started","seen","x","y","width","height","cachedKey","raw","homedir","execFile","promisify","run","CAPTURING_WHEN_RUNNING","MIGHT_BE_RECORDING","probe","claim","text","probes","recordingProbe","capturing","running","maybe","names","found","name","stdout","pid","init_seat","init_questions","SCREEN_STATE_SEAT","screenStateQuestions","noul","screenStateState","input","toVerdict","answers","OBSERVABLE_FLOOR","HOLDS_TRUE","HOLDS_FALSE","verify","claim","opts","sighting","probes","look","probe","floor","seat","askSeat","SCREEN_STATE_SEAT","screenStateState","regionWords","screenStateQuestions","outcome","uncalibratedReason","observable","holds","toVerdict","pct","calibratedReason","s","detail","caveat","r","p","look","Command","question","opts","region","parts","chalk","v","verify","mark","s","readingColour","e","r","init_seat","Command","execFile","promisify","existsSync","readFileSync","writeFileSync","mkdirSync","homedir","join","dirname","chalk","init_questions","PASTE_TRANSFORM_SEAT","pasteState","input","pasteQuestions","options","criteria","option","noul","choice","toPasteChoice","answers","worth","shape","ranked","id","p","a","b","TRACKING","looksLikeUrl","t","TRANSFORMS","lines","wrapped","i","cur","next","para","l","trimmed","parsed","out","url","removed","key","slug","applicable","text","transform","result","previewFor","budget","head","tail","looksSecret","run","promisify","execFile","paste","Command","TRANSFORMS","t","opts","previous","takeStash","chalk","writeClipboard","text","readClipboard","looksSecret","report","options","applicable","destination","focusedDestination","forced","o","finish","result","askSeat","PASTE_TRANSFORM_SEAT","pasteState","previewFor","pasteQuestions","chosen","toPasteChoice","min","picked","id","original","reason","worth","changed","stash","HELPER","e","r","clip","s","max","l","STASH","join","homedir","mkdirSync","dirname","writeFileSync","readFileSync","stdout","resolve","reject","err","existsSync","f","humanRole","role","editable","Command","chalk","DAEMON","daemonSender","defaultChannel","defaultChatId","title","message","channel","chatId","text","res","notify","Command","opts","queue","NotificationQueue","state","readFocus","sound","waiting","chalk","focusLabel","w","when","send","n","flushHeld","result","mark","e","playSound","init_seat","init_decisions","init_store","init_questions","Command","readFileSync","decide","opts","raw","readStdin","e","fail","spec","validateQuestions","seat","registerBuiltinDecisionBackends","seatEnvVar","store","DecisionStore","configureDecisions","result","askSeat","message","chunks","c","init_seat","Command","execFile","spawn","promisify","existsSync","readFileSync","writeFileSync","unlinkSync","statSync","join","tmpdir","chalk","xAdvancedSearch","xBookmarkFolders","LESSONS","run","promisify","execFile","teach","Command","lessonId","opts","chalk","LESSONS","lesson","existsSync","HELPER","recorder","recordingPath","join","spawn","sleep","hud","setState","title","body","state","avoid","attempts","stopped","i","step","speaking","speak","target","locate","err","changed","act","checked","verify","e","mark","size","statSync","argv","stdout","parsed","description","priorAttempts","screen","readScreen","result","askSeat","UI_ELEMENT_SEAT","uiElementState","uiElementQuestions","sel","toSelection","rectFor","text","voiceId","key","elevenLabsKey","voice","res","file","tmpdir","writeFileSync","unlinkSync","p","v","readFileSync","ms","r","Command","chalk","attach","Command","DEFAULT_URL","configuredDaemonPort","currentSessionId","explicit","api","url","path","body","res","text","json","daemonHint","msg","chalk","modeColor","m","printSession","s","mark","who","pending","here","DELIVERY_MODES","agent","opts","sessionId","isDeliveryMode","attachHooksInstalled","r","e","sessions","userSettingsPath","bound","idle","port","installAttachHooks","uninstallAttachHooks","init_config","Command","chalk","process_","resolveDaemon","opts","baseUrl","token","cfg","loadDaemonConfig","authHeaders","contentType","h","fmtAge","ms","s","stateColor","res","e","procs","p","state","age","lastTurn","tokens","session","pending","agentId","channel","chatId","msg","body","Command","chalk","existsSync","rmSync","resolve","rag","Command","agentId","globs","opts","chalk","verbose","start","r","buildIndex","ms","root","resolve","existsSync","readdirSync","agents","d","a","info","indexInfo","query","k","hits","lexicalSearch","h","path","rmSync","init_config","Command","chalk","prompts","backlog","Command","loadCtx","configPath","config","loadDaemonConfig","ws","storePath","BacklogStore","fmtSource","s","chalk","fmtStatus","status","opts","store","items","i","it","assignee","id","agent","ctx","updated","usernames","resolveAssigneesForSource","result","syncBacklogItemToSource","a","gitlabReady","githubReady","source","choices","prompts","project","candidates","collectGitlabProjects","collectGithubProjects","p","search","issues","fetchGitlabIssues","fetchGithubIssues","projectId","existing","iss","sourceBacklogId","already","labels","selected","toAdd","src","hostnameFromGitlab","added","daemon","host","set","r","gl","params","res","arr","l","headers","url","q","githubMap","Command","chalk","existsSync","readFileSync","resolve","prompts","init_config","cronstrue","DAY_OF_WEEK","DEFAULT_TIMES","humanize","cron","extractTime","text","m","h","min","ampm","parseEnglishToCron","raw","n","time","dayKeywordTime","kw","t","resolvedTime","domMatch","tok","dom","dayTokens","dayWordsAlt","anchorRe","anchor","list","w","a","b","dow","v","slugifyScheduleId","phrase","agent","loadRawConfig","configPath","p","resolve","existsSync","chalk","readFileSync","parseOnError","flag","s","resolveNotifyTarget","cfg","dest","channel","chatId","accountId","prompts","parts","schedule","Command","when","opts","parsed","parseEnglishToCron","expanded","expandEnvVars","onErrorModes","notify","id","slugifyScheduleId","job","result","applyConfigMutation","c","setAtPath","verb","crons","entries","def","tag","human","enabled","getAtPath","unsetAtPath","words","r","Command","chalk","chalk","prompts","readFileSync","writeFileSync","existsSync","resolve","KV_RE","parseValue","raw","s","quoteIfNeeded","value","readDotEnv","path","abs","content","lines","m","serializeDotEnv","l","setDotEnv","key","idx","getDotEnv","key","path","readDotEnv","l","BOTFATHER_URL","getMe","token","res","j","pollFirstMessage","timeoutMs","deadline","offset","u","msg","connectTelegram","opts","chalk","openBrowser","prompts","spawn","opener","t","me","readFileSync","existsSync","resolve","cfgPath","raw","agents","agent","id","accounts","account","s","envVar","setDotEnv","result","applyConfigMutation","cfg","setAtPath","mentions","getAtPath","handle","capture","first","destResult","chalk","prompts","existsSync","mkdirSync","readdirSync","readFileSync","resolve","DEFAULT_SESSION_DIR","daemonRunning","pidFile","resolve","existsSync","pid","readFileSync","sessionExists","dir","readdirSync","f","pairSession","sessionDir","log","baileys","chalk","makeWASocket","useMultiFileAuthState","mkdirSync","state","saveCreds","version","silentLogger","sock","resolveP","deadline","u","qrcode","connectWhatsApp","opts","cont","prompts","cfgPath","raw","absSession","agents","agent","id","shouldPair","keep","s","result","applyConfigMutation","cfg","setAtPath","randomBytes","chalk","prompts","PROTOCOL","PATH_PREFIX","b64urlEncode","input","b64urlDecode","encodeInvite","payload","decodeInvite","link","raw","parsed","generateToken","randomBytes","resolveBindUrl","bind","host","port","nodeName","invite","opts","readFileSync","existsSync","resolve","cfgPath","chalk","token","getDotEnv","setDotEnv","url","entered","prompts","v","result","applyConfigMutation","cfg","setAtPath","join","e","existing","overwrite","peers","getAtPath","idx","p","peer","res","card","agents","connect","Command","opts","connectTelegram","connectWhatsApp","mesh","invite","link","join","chalk","init_config","Command","chalk","usage","config","loadDaemonConfig","host","port","data","fmt","n","agents","b","id","ag","total","avgMs","opts","execSync","existsSync","resolve","scriptPath","listSurfaceUse","kind","rows","buildProgram","program","seen","r","registered","walk","cmd","prefix","sub","name","unused","c","lastKind","count","days","Command","chalk","resolve","init_config","board","Command","opts","loadEnvFileIntoProcess","resolve","config","resolveServerConfig","startBoardDashboard","e","chalk","portOpt","bindOpt","cfg","loadDaemonConfig","b","src","id","mutateConfig","projects","s","x","changes","column","boardId","cols","c","map","columnId","col","before","mutator","summary","backupPath","mutateAgentxConfig","Command","chalk","resolve","relative","dirname","execSync","writeFileSync","mkdirSync","readFileSync","readdirSync","renameSync","rmSync","existsSync","getHub","dir","mode","WikiHub","wikiDir","modeLabel","wiki","Command","opts","hub","agents","totalEntries","chalk","agent","status","a","totalUnabsorbed","s","totalIssues","agentId","issues","issue","icon","maxEntries","graphStore","baseDir","GraphStore","fpToPath","idx","fp","e","knownPeople","lookupPath","entry","stamped","sender","pickGraphPath","sources","entries","counts","sid","path","key","cur","best","v","totalAbsorbed","totalWithPath","sinceDate","unabsorbed","agentWiki","existingIndex","worldview","entryTexts","factsBlock","extractHints","resolveFacts","mergeRecords","renderFactsBlock","installPrompts","defaultSources","recordsFromEntries","names","art","hints","fromEntries","records","results","merged","got","r","p","prompt","buildAbsorbPrompt","tmpDir","promptPath","rawOutput","stripAnthropicApiKey","execErr","responseText","envelope","articles","gaps","objStart","arrStart","jsonStart","openChar","closeChar","depth","jsonEnd","i","jsonStr","parsed","parseErr","article","now","graphPath","typeTag","relStr","tagStr","gap","QuestionStore","q","pct","sinceMs","parsePromoteSince","types","t","validTypes","badType","extraCandidates","reviewsToCandidates","Database","dbPath","db","rows","k","recurring","c","top","report","runPromotion","msg","cluster","corr","w","wmsg","err","input","m","n","unit","agenticQuery","rd","rf","ex","rv","jn","store","agentHistDir","tasks","days","day","dayDir","files","f","rec","lines","oldTitles","newBlock","cites","out","readline","randomUUID","WIKI_ARTICLE_TYPES","scripted","l","scriptCursor","rl","ask","answer","topic","type","picked","QUESTIONS","questions","qas","aborted","extra","catalogLines","synthesisPrompt","x","draft","cmd","raw","fence","fmStart","fmMatch","fm","line","body","title","slug","articlePath","choice","finalContent","finalMeta","editor","editPath","ef","mm","referenced","titleIdx","g","script","verdict","rounds","commit","transcript","applied","result","action","note","primary","patchPrompt","buildQuizPatchPrompt","patched","before","after","titleOrPath","relPath","resolveArticlePath","absPath","seenLinks","bodyLinks","currentRelated","b","instruction","buildWikiPatchPrompt","go","ans","seen","syncedRelated","relDrift","arg","lower","byTitle","normPath","byPath","argSlug","bySlug","titleSlug","content","instructions","wikiRoot","CANONICAL","LEGACY_MODES","totalLegacy","totalPromote","totalUpgrade","totalArchive","agentRoot","canonicalDir","legacyEntries","canonIdx","walkMd","abs","rel","parseWikiFrontmatter","legacy","modeStr","la","existing","arrow","where","target","archiveLegacy","verDir","ts","cb","meta","batchSize","maxArticles","totalScanned","totalNeeds","totalApplied","needs","remaining","limit","batch","buildMigratePrompt","classifications","arrMatch","norm","normalizeWikiType","related","newMeta","aliasNote","mapped","items","tags","port","peerUrls","loadDaemonConfig","startWikiServer","articleQualityQuestionsFor","articleQualityState","gradeArticle","ARTICLE_QUALITY_SEAT","fieldQuestions","reportFields","askSeat","min","outer","res","fr","cols","fmt","cells","unfit","question","chosen","id","cat","follow","query","found","totalArticles","totalEligible","totalMatched","totalWritten","sharedEntries","entriesById","agentEligible","agentMatched","agentWritten","shared","existingIds","totalSynced","peerUrl","data","nodeId","newCount","agentsRes","agentsData","stats","index","totalTags","dirs","label","fn","vals","max","winners","output","date","parent","base","args","spawnSync","statSync","size","formatWikiBytes","articleFieldsState","nextActions","TIER_MEANING","ARTICLE_FIELDS_SEAT","pending","checked","queued","plain","pad","auto","worst","TIER_RANK","floor","worth","cfg","dest","more","text","BACKFILL_ORDER","backfillArticle","stampedByName","considered","written","promptedInstall","wanted","own","edits","qs","tier","value","patchIdentityField","IDENTITY_SLOTS","store2","ok","ENTRY_TRIAGE_SEAT","entryTriageQuestions","triageState","triage","labelEntries","sample","scoreBacktest","toGradedRows","sweepPolicies","calibrationReport","all","labeled","backlog","policy","outcomes","failures","t0","cal","elapsed","d","points","loosest","archive","archivePath","init_extract_json","Command","chalk","resolve","existsSync","init_config","graph","Command","opts","config","loadDaemonConfig","chalk","agentId","daemonUrl","cap","store","GraphStore","resolve","pending","schema","nodes","approvedN","rejectedN","skippedN","errorN","i","c","label","pathLabel","prompt","buildReviewPrompt","decision","askAgent","e","verdict","reason","commitApproved","verb","baseDir","existsSync","migrateV2","result","hits","b","count","peer","limit","headers","localSchema","localNodes","localIds","n","peerSchema","peerNodes","peerClassifications","schemaRes","nodesRes","clRes","localLevels","l","peerLevels","schemaMatches","schemaForImport","levelOrder","sortedPeerNodes","a","nodesAdded","nodesSkipped","nodesFailed","fpAdded","fpSkipped","existingByLevel","levelsSummary","axesJson","message","token","ac","timer","r","data","extractJson","_existing","createdBy","graphStoreFrom","g","ReviewStore","buildQueue","rows","reviews","queue","conf","hash","match","labelStats","st","pct","x","gap","flag","Command","chalk","Command","chalk","existsSync","resolve","Database","parseSince","input","m","unit","n","chalk","openTraceDb","path","dbPath","resolve","existsSync","Database","extractCommand","Command","DEFAULT_MIN_OCCURRENCES","DEFAULT_MAX_CLUSTERS","opts","db","report","runExtraction","SessionStore","c","nm","d","s","w","CADENCE","watchCommand","schedule","minOccurrences","extraction","prompt","result","applyConfigMutation","setAtPath","verb","procedure","Command","extractCommand","watchCommand","opts","store","ProcedureStore","items","chalk","p","status","v","prev","body","e","id","text","matches","matchProcedures","m","Command","chalk","resolve","basename","existsSync","readFileSync","writeFileSync","Database","readFileSync","resolve","dirname","fileURLToPath","TEMPLATES","readTemplate","name","here","cliDir","candidates","path","workflow","Command","workflow","items","WorkflowStore","chalk","wf","cfg","n","filterParts","dispatch","id","opts","fmt","renderWorkflowYaml","file","path","resolve","existsSync","text","readFileSync","raw","parseYamlWorkflow","parsed","workflowSchema","i","lintIssues","lintWorkflow","l","e","msg","WorkflowYamlError","results","ok","bad","r","issue","TEMPLATES","t","tmplName","store","body","readTemplate","ext","dest","writeFileSync","isYaml","basename","url","res","nodeId","runs","RunStore","last","nextLabel","stateColor","idOrFile","payload","adhocId","written","runId","tailTraces","args","seen","collected","startedAt","maxMs","traces","status","color","tokens","dur","run","base","single","rec","printTrace","model","Command","chalk","prompts","readFileSync","existsSync","resolve","VALID_SOURCES","WIRED_SOURCES","SOURCE_HINTS","loadConfig","p","resolve","existsSync","readFileSync","statusBadge","w","chalk","printOneHuman","w","daemonUrl","url","wired","WIRED_SOURCES","chalk","statusBadge","triggers","triggerKeys","k","webhook","Command","opts","cfg","loadConfig","entries","VALID_SOURCES","idArg","knownAgents","meshPeers","node","id","source","agentId","secretEnv","description","interactive","prompts","v","s","SOURCE_HINTS","a","result","applyConfigMutation","c","entry","before","toggleEnabled","enabled","x","eventType","workflowId","clear","list","item","tag","Command","chalk","init_config","mutate","mutator","summary","backupPath","mutateAgentxConfig","cfg","chalk","readBusiness","loadDaemonConfig","business","Command","opts","b","orgChart","projects","contactMap","orgEntries","id","e","reports","sched","p","pm","client","c","key","ch","orgchart","entries","agentId","days","s","project","idx","next","list","before","contact","entry","Command","chalk","init_config","TIER_ALIAS","resolveTier","label","t","resolveStore","dir","loadDaemonConfig","DayPlanStore","plan","Command","tier","opts","store","body","readFileSync","p","chalk","result","items","parsePriorities","it","r","printPlan","rows","existing","unlinkSync","date","content","line","Command","chalk","init_config","readNotifications","loadDaemonConfig","mutate","mutator","summary","backupPath","mutateAgentxConfig","cfg","chalk","notifications","Command","opts","n","acct","on","name","state","known","onv","enabled","seconds","Command","chalk","readdirSync","statSync","unlinkSync","rmSync","existsSync","resolve","join","TARGETS","walkFiles","dir","recursive","out","entry","full","retention","total","t","root","files","bytes","oldest","f","s","oldestAge","formatBytes","opts","days","cutoff","filterTarget","totalRemoved","totalBytes","removed","pruneEmptyDirs","action","b","Command","chalk","actions","Command","opts","list","ActionStore","chalk","a","inputs","target","id","inp","req","def","desc","parseInputsCsv","base","parsed","actionSchema","issue","saved","action","kv","eq","result","runAction","e","name","res","t","x","input","body","csv","out","part","s","required","clean","colon","type","init_config","Command","chalk","watch","opts","baseUrl","token","cfg","loadDaemonConfig","qs","url","headers","res","reader","dec","buf","done","value","idx","frame","printFrame","e","event","data","line","payload","ts","tag","wf","runShort","node","note","actors","title","name","scope","peer","health","dir","label","preview","Command","chalk","spawn","execFileSync","checkOpenCodeVersion","runVersion","version","error","match","tui","Command","opts","chalk","resolveConn","conn","openCode","checkOpenCodeVersion","fetchAgents","agents","agentId","agent","inlineServerConfig","models","env","child","spawn","done","reject","code","App","render","React","pollMs","Command","chalk","randomUUID","createInterface","ora","chalk","deprecationNotice","d","CHAT_SURFACE_DEPRECATION","chat","Command","agentArg","opts","deprecationNotice","CHAT_SURFACE_DEPRECATION","conn","resolveConn","agentId","channel","chatId","randomUUID","agents","fetchAgents","e","chalk","a","render","ChatApp","React","printBanner","rl","createInterface","busy","closeRequested","line","fresh","marker","next","spinner","ora","startedAt","createStreamRenderer","r","streamTask","t","tool","elapsed","headerShown","atLineStart","anyText","seenTools","header","delta","ch","key","arg","elapsedS","usage","out","msg","baseUrl","Command","chalk","readFileSync","VALID_TYPES","memory","Command","opts","chalk","body","readStdin","readFileSync","e","rec","AgentMemory","records","r","currentType","name","md","chunks","chunk","init_logger","chalk","Command","resolve","serve","opts","startMcpServer","logger","error","handleError","Command","chalk","spawn","mkdirSync","writeFileSync","rmSync","openSync","existsSync","resolve","join","randomBytes","demoReportWorkflow","KICKOFF","DELEGATION","buildSpecs","root","basePort","join","demoReportWorkflow","writeNode","spec","all","meshToken","ws","mkdirSync","writeFileSync","peers","n","config","waitFor","desc","fn","timeoutMs","start","r","post","port","path","body","res","data","say","role","text","color","demo","Command","opts","resolve","specs","randomBytes","children","cli","existsSync","chalk","rmSync","tearingDown","teardown","code","c","baseEnv","logFd","openSync","child","spawn","dashPort","p","liveUrl","s","opener","playScenario","s1","s2","builderReply","s3","e","init_config","Command","chalk","whatsapp","opts","chats","getJSON","c","kind","when","e","fail","contacts","name","phone","body","report","postJSON","printReport","jid","state","dryRun","err","daemonUrl","config","loadDaemonConfig","host","port","path","r","data","init_config","Command","chalk","existsSync","mkdirSync","writeFileSync","join","resolve","plugin","Command","names","loadDaemonConfig","chalk","n","name","opts","dirName","target","resolve","existsSync","mkdirSync","join","description","writeFileSync","packageJson","tsconfig","pluginSource","readme","gitignore","bad","status","checkOne","packageName","mod","e","candidate","pickDefault","isPlugin","parsed","agentXPluginManifestSchema","m","d","dd","c","Command","chalk","writeFileSync","mkdirSync","existsSync","readFileSync","appendFileSync","resolve","dirname","homedir","completion","opts","buildProgram","program","shell","script","generateZsh","generateBash","generateFish","dest","defaultInstallPath","printShellHookInstructions","home","autoPatch","rc","fpathDir","fpathLine","compinitLine","rcExisting","needsFpath","needsCompinit","block","sourceLine","cmdName","cmd","subcommandsOf","c","n","optionsOf","out","emitZshFn","zshFnName","path","subs","optLines","zshOptionLine","s","name","argLines","line","entries","zshCommandEntry","i","last","sub","subFn","escapeZshDesc","escapeZshValue","opt","short","long","desc","tops","lines","subsubs","subOpts","collectBashFlags","ss","ssOpts","flags","escapeFish","fishOptionLine","subsub","conditions","shortRaw","longRaw","parts","buildProgram","packageInfo","getPackageInfo","program","Command","_thisCommand","actionCommand","path","commandPath","shouldRecordCommand","recordSurfaceUse","cmd","setup","init","connect","desktop","daemon","doctor","agent","channel","schedule","attach","monitor","tui","guard","point","look","paste","notify","decide","teach","usage","serve","token","configCmd","completion","ADVANCED","names","c","wrapNames","wiki","graph","memory","procedure","references","rag","workflow","webhook","board","backlog","business","plan","ledger","decisions","trace","process_","watch","db","mesh","a2a","skillCmd","plugin","hook","actions","cron","migrate","retention","notifications","whatsapp","demo","chat","width","indent","lines","line","n"]}
|