agentix-cli 0.16.0 → 0.17.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-4AOMVXRJ.js +2 -0
- package/dist/board-dashboard-CXIVJKDP.js +7282 -0
- package/dist/board-dashboard-CXIVJKDP.js.map +1 -0
- package/dist/chunk-34NG7UDX.js +11 -0
- package/dist/chunk-34NG7UDX.js.map +1 -0
- package/dist/chunk-4HP6UC2X.js +13 -0
- package/dist/chunk-4HP6UC2X.js.map +1 -0
- package/dist/chunk-5WNGHDFC.js +164 -0
- package/dist/chunk-5WNGHDFC.js.map +1 -0
- package/dist/{chunk-7MBTMCKY.js → chunk-63UYRJIC.js} +2 -2
- package/dist/chunk-6PPIFDOQ.js +1742 -0
- package/dist/chunk-6PPIFDOQ.js.map +1 -0
- package/dist/chunk-ABCHHNG6.js +625 -0
- package/dist/chunk-ABCHHNG6.js.map +1 -0
- package/dist/chunk-AFRHKA7B.js +2 -0
- package/dist/chunk-AFRHKA7B.js.map +1 -0
- package/dist/chunk-CDNWCYF7.js +2 -0
- package/dist/chunk-CDNWCYF7.js.map +1 -0
- package/dist/{chunk-6MKAXEE5.js → chunk-EKTPCSN4.js} +2 -2
- package/dist/{chunk-6MKAXEE5.js.map → chunk-EKTPCSN4.js.map} +1 -1
- package/dist/chunk-EW27SCCC.js +2 -0
- package/dist/chunk-EW27SCCC.js.map +1 -0
- package/dist/chunk-HCFSHGK4.js +46 -0
- package/dist/chunk-HCFSHGK4.js.map +1 -0
- package/dist/chunk-HHJGKD5B.js +71 -0
- package/dist/chunk-HHJGKD5B.js.map +1 -0
- package/dist/{chunk-YI2T5QYB.js → chunk-MBEQASP3.js} +2 -2
- package/dist/chunk-N67JZAXU.js +2 -0
- package/dist/chunk-N67JZAXU.js.map +1 -0
- package/dist/{chunk-FLOGK2U7.js → chunk-SRHLXZRF.js} +2 -2
- package/dist/chunk-TT2Q7YMZ.js +118 -0
- package/dist/chunk-TT2Q7YMZ.js.map +1 -0
- package/dist/{chunk-HI24KAEY.js → chunk-WJXU5F4Z.js} +3 -4
- package/dist/{chunk-HI24KAEY.js.map → chunk-WJXU5F4Z.js.map} +1 -1
- package/dist/chunk-XDJSYQST.js +6 -0
- package/dist/chunk-XDJSYQST.js.map +1 -0
- package/dist/chunk-YPOELN6Z.js +798 -0
- package/dist/chunk-YPOELN6Z.js.map +1 -0
- package/dist/{chunk-QZP65I2H.js → chunk-ZE2YFX4K.js} +2 -2
- package/dist/cli.js +1 -320
- package/dist/cli.js.map +1 -1
- package/dist/{compaction-JBZZ7I7Y.js → compaction-X46EQEPS.js} +6 -6
- package/dist/compaction-X46EQEPS.js.map +1 -0
- package/dist/{config-LN6JEHMF.js → config-KCYHMKCT.js} +2 -2
- package/dist/config-mutator-QP4GLBOE.js +2 -0
- package/dist/context-planner-G2J7FNNU.js +17 -0
- package/dist/context-planner-G2J7FNNU.js.map +1 -0
- package/dist/editor-chat-R54E65W5.js +137 -0
- package/dist/editor-chat-R54E65W5.js.map +1 -0
- package/dist/heal-JDXUPRET.js +2 -0
- package/dist/inbox-L5ZZ623Y.js +315 -0
- package/dist/inbox-L5ZZ623Y.js.map +1 -0
- package/dist/index.d.ts +2917 -1781
- package/dist/index.js +23 -53
- package/dist/index.js.map +1 -1
- package/dist/ingest-whatsapp-NS4OWDOU.js +6 -0
- package/dist/ingest-whatsapp-NS4OWDOU.js.map +1 -0
- package/dist/memory-extract-WH4FZ456.js +2 -0
- package/dist/processes-XF5CV4LK.js +256 -0
- package/dist/processes-XF5CV4LK.js.map +1 -0
- package/dist/program-FFWEILAS.js +2 -0
- package/dist/providers-AKQ4HTB4.js +2 -0
- package/dist/registry-IFMDJWQ7.js +2 -0
- package/dist/scheduler-63D5KFO7.js +2 -0
- package/dist/slack-PSQLVTGB.js +3 -0
- package/dist/slack-PSQLVTGB.js.map +1 -0
- package/dist/store-5MJOO74U.js +2 -0
- package/dist/store-5MJOO74U.js.map +1 -0
- package/dist/task-store-NM7VKNLE.js +2 -0
- package/dist/task-store-NM7VKNLE.js.map +1 -0
- package/dist/telegram-W4SLFMNY.js +3 -0
- package/dist/telegram-W4SLFMNY.js.map +1 -0
- package/dist/timers-PCB4ZIBD.js +2 -0
- package/dist/timers-PCB4ZIBD.js.map +1 -0
- package/dist/types-C7IFH42Z.js +2 -0
- package/dist/types-C7IFH42Z.js.map +1 -0
- package/dist/usage-dashboard-AXPXB2KP.js +803 -0
- package/dist/usage-dashboard-AXPXB2KP.js.map +1 -0
- package/dist/web/workflow-editor.global.js +1427 -0
- package/dist/web/workflow-editor.global.js.map +1 -0
- package/dist/whatsapp-DCHRBRVV.js +3 -0
- package/dist/whatsapp-DCHRBRVV.js.map +1 -0
- package/dist/workspace-setup-C4VB3QZV.js +2 -0
- package/dist/workspace-setup-C4VB3QZV.js.map +1 -0
- package/package.json +9 -2
- package/dist/agent-BCDPSPKU.js +0 -2
- package/dist/board-dashboard-LA7WW56M.js +0 -5668
- package/dist/board-dashboard-LA7WW56M.js.map +0 -1
- package/dist/chunk-6U2XOQHU.js +0 -7
- package/dist/chunk-6U2XOQHU.js.map +0 -1
- package/dist/chunk-7FJQGD6U.js +0 -6
- package/dist/chunk-7FJQGD6U.js.map +0 -1
- package/dist/chunk-ABDP7TDL.js +0 -71
- package/dist/chunk-ABDP7TDL.js.map +0 -1
- package/dist/chunk-CXY2RYNI.js +0 -11
- package/dist/chunk-CXY2RYNI.js.map +0 -1
- package/dist/chunk-HVC6FJNP.js +0 -108
- package/dist/chunk-HVC6FJNP.js.map +0 -1
- package/dist/chunk-K7BE4E35.js +0 -138
- package/dist/chunk-K7BE4E35.js.map +0 -1
- package/dist/chunk-KXJSLLSQ.js +0 -199
- package/dist/chunk-KXJSLLSQ.js.map +0 -1
- package/dist/chunk-KXZMYLHQ.js +0 -46
- package/dist/chunk-KXZMYLHQ.js.map +0 -1
- package/dist/chunk-M7HKBG3V.js +0 -2
- package/dist/chunk-M7HKBG3V.js.map +0 -1
- package/dist/chunk-RB7265LO.js +0 -12
- package/dist/chunk-RB7265LO.js.map +0 -1
- package/dist/compaction-JBZZ7I7Y.js.map +0 -1
- package/dist/config-mutator-24TH7PHM.js +0 -2
- package/dist/heal-WKY5I4KB.js +0 -2
- package/dist/memory-extract-AD7KMRPC.js +0 -2
- package/dist/providers-VUIWO3ZK.js +0 -2
- package/dist/registry-ASC2QS5K.js +0 -2
- package/dist/scheduler-A3TQOCKT.js +0 -2
- package/dist/usage-dashboard-QX3CF6KK.js +0 -404
- package/dist/usage-dashboard-QX3CF6KK.js.map +0 -1
- package/dist/workspace-setup-ZWTT42XT.js +0 -2
- /package/dist/{agent-BCDPSPKU.js.map → agent-4AOMVXRJ.js.map} +0 -0
- /package/dist/{chunk-7MBTMCKY.js.map → chunk-63UYRJIC.js.map} +0 -0
- /package/dist/{chunk-YI2T5QYB.js.map → chunk-MBEQASP3.js.map} +0 -0
- /package/dist/{chunk-FLOGK2U7.js.map → chunk-SRHLXZRF.js.map} +0 -0
- /package/dist/{chunk-QZP65I2H.js.map → chunk-ZE2YFX4K.js.map} +0 -0
- /package/dist/{config-LN6JEHMF.js.map → config-KCYHMKCT.js.map} +0 -0
- /package/dist/{config-mutator-24TH7PHM.js.map → config-mutator-QP4GLBOE.js.map} +0 -0
- /package/dist/{heal-WKY5I4KB.js.map → heal-JDXUPRET.js.map} +0 -0
- /package/dist/{memory-extract-AD7KMRPC.js.map → memory-extract-WH4FZ456.js.map} +0 -0
- /package/dist/{providers-VUIWO3ZK.js.map → program-FFWEILAS.js.map} +0 -0
- /package/dist/{registry-ASC2QS5K.js.map → providers-AKQ4HTB4.js.map} +0 -0
- /package/dist/{scheduler-A3TQOCKT.js.map → registry-IFMDJWQ7.js.map} +0 -0
- /package/dist/{workspace-setup-ZWTT42XT.js.map → scheduler-63D5KFO7.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/program.ts","../src/commands/daemon.ts","../src/commands/init.ts","../src/commands/setup.ts","../src/commands/token.ts","../src/commands/doctor.ts","../src/commands/manage.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/discord.ts","../src/connect/whatsapp.ts","../src/connect/mesh.ts","../src/commands/usage.ts","../src/commands/board.ts","../src/commands/wiki.ts","../src/wiki/serve.ts","../src/wiki/mesh.ts","../src/wiki/prompts.ts","../src/commands/graph.ts","../src/commands/procedure.ts","../src/procedures/store.ts","../src/procedures/types.ts","../src/commands/workflow.ts","../src/commands/actor.ts","../src/commands/serve.ts","../src/commands/bench.ts","../src/commands/whatsapp.ts","../src/commands/completion.ts"],"sourcesContent":["import { 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, hook, migrate, configCmd } from \"@/commands/manage\"\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 { actor, role } from \"@/commands/actor\"\nimport { serve } from \"@/commands/serve\"\nimport { bench } from \"@/commands/bench\"\nimport { whatsapp } from \"@/commands/whatsapp\"\nimport { completion } from \"@/commands/completion\"\nimport { getPackageInfo } from \"@/utils/get-package-info\"\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 program\n .addCommand(daemon)\n .addCommand(setup)\n .addCommand(init)\n .addCommand(agent)\n .addCommand(channel)\n .addCommand(connect)\n .addCommand(cron)\n .addCommand(schedule)\n .addCommand(mesh)\n .addCommand(skillCmd)\n .addCommand(hook)\n .addCommand(migrate)\n .addCommand(configCmd)\n .addCommand(usage)\n .addCommand(board)\n .addCommand(wiki)\n .addCommand(graph)\n .addCommand(procedure)\n .addCommand(workflow)\n .addCommand(actor)\n .addCommand(role)\n .addCommand(token)\n .addCommand(doctor)\n .addCommand(serve)\n .addCommand(bench)\n .addCommand(whatsapp)\n .addCommand(completion)\n\n return program\n}\n","import { Command } from \"commander\"\nimport { AgentXDaemon } from \"@/daemon\"\nimport { loadDaemonConfig, validateWorkspaces } from \"@/daemon/config\"\nimport chalk from \"chalk\"\n\n// --- agentx daemon: start/stop/status/logs ---\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 args = [\"dist/cli.js\", \"daemon\", \"start\"]\n if (opts.config) args.push(\"-c\", opts.config)\n if (opts.port) args.push(\"--port\", opts.port)\n\n const child = spawn(\"node\", args, {\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"ignore\"],\n cwd: process.cwd(),\n })\n child.unref()\n\n const { writeFileSync } = await import(\"fs\")\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 /tmp/agentx-daemon.log`))\n console.log(chalk.dim(` Stop: agentx daemon stop`))\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 try {\n process.kill(oldPid, 0) // throws if process doesn't exist\n console.error(`Another agentx daemon is already running (PID ${oldPid}). Exiting.`)\n process.exit(0)\n } catch {\n // Old process is dead — we can proceed\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 const { existsSync, readFileSync } = require(\"fs\") as typeof import(\"fs\")\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? Try: agentx daemon status\"))\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 { 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: require(\"os\").hostname().toLowerCase().replace(/[^a-z0-9-]/g, \"-\"),\n name: require(\"os\").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 { resolve } from \"path\"\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, __dirname points at dist/; cli.js sits beside it.\n // In dev, we resolve through the current script so `tsx` works too.\n const candidate = resolve(__dirname, \"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(cmd, [url], { stdio: \"ignore\", detached: true }).unref()\n } catch { /* best-effort; user can visit the URL manually */ }\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 { execFileSync } from \"child_process\"\nimport { existsSync, readFileSync, statSync } from \"fs\"\nimport { resolve } from \"path\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx doctor ---\n//\n// Pre-flight health check. Catches the common \"why isn't it working\" reasons\n// before the operator hits them at runtime:\n// - wrong Node version\n// - invalid / missing agentx.json\n// - agents with claude-code tier but no claude CLI installed\n// - ${FOO} references in agentx.json that have no matching env var\n// - agent workspace dirs that don't exist\n// - daemon reachable? (when --check-running, default true)\n//\n// Exit code: 0 if clean, 1 if any error, 0 if only warnings (so CI won't block\n// on advisory checks).\n\ntype Severity = \"ok\" | \"warn\" | \"fail\"\n\ninterface Check {\n severity: Severity\n group: string\n title: string\n detail?: string\n fix?: string\n}\n\nexport const doctor = new Command()\n .name(\"doctor\")\n .description(\"pre-flight health check: Node, config, credentials, daemon\")\n .option(\"--no-running\", \"skip the live daemon probe\")\n .option(\"--json\", \"emit machine-readable JSON (stable shape for CI)\")\n .action(async (opts) => {\n const checks: Check[] = []\n await runEnvChecks(checks)\n const cfg = runConfigChecks(checks)\n if (cfg) runReferenceChecks(checks, cfg)\n if (cfg) runWorkspaceChecks(checks, cfg)\n if (opts.running !== false && cfg) await runRuntimeChecks(checks, cfg)\n\n if (opts.json) {\n process.stdout.write(JSON.stringify({ checks, summary: summarize(checks) }, null, 2) + \"\\n\")\n } else {\n printHumanReport(checks)\n }\n\n const { errors } = summarize(checks)\n process.exit(errors > 0 ? 1 : 0)\n })\n\n// ---------------------------------------------------------------------------\n// Checks\n// ---------------------------------------------------------------------------\n\nasync function runEnvChecks(checks: Check[]): Promise<void> {\n const nodeMajor = Number(process.versions.node.split(\".\")[0])\n checks.push({\n severity: nodeMajor >= 20 ? \"ok\" : \"fail\",\n group: \"Environment\",\n title: `Node.js ${process.versions.node}`,\n detail: nodeMajor >= 20 ? undefined : \"AgentX needs Node 20 or newer.\",\n fix: nodeMajor >= 20 ? undefined : \"Install a newer Node (nvm install 20 && nvm use 20)\",\n })\n\n const which = (bin: string): string | null => {\n try { return execFileSync(process.platform === \"win32\" ? \"where\" : \"which\", [bin], { encoding: \"utf-8\" }).trim().split(\"\\n\")[0] }\n catch { return null }\n }\n const npmPath = which(\"npm\")\n checks.push({\n severity: npmPath ? \"ok\" : \"fail\",\n group: \"Environment\",\n title: npmPath ? \"npm on PATH\" : \"npm not found\",\n detail: npmPath || undefined,\n })\n\n // Claude CLI is only required if the config references claude-code agents;\n // we report it advisory here and promote to fail in the config step below.\n const claudePath = which(\"claude\")\n if (claudePath) {\n let ver: string | undefined\n try { ver = execFileSync(\"claude\", [\"--version\"], { encoding: \"utf-8\", timeout: 3000 }).trim() } catch { /* */ }\n checks.push({ severity: \"ok\", group: \"Environment\", title: `claude CLI ${ver || \"installed\"}`, detail: claudePath })\n } else {\n checks.push({\n severity: \"warn\",\n group: \"Environment\",\n title: \"claude CLI not on PATH\",\n detail: \"Only required for agents on the claude-code tier.\",\n fix: \"See https://docs.anthropic.com/en/docs/claude-code\",\n })\n }\n}\n\nfunction runConfigChecks(checks: Check[]): any {\n const cfgPath = resolve(process.cwd(), \"agentx.json\")\n if (!existsSync(cfgPath)) {\n checks.push({\n severity: \"fail\",\n group: \"Config\",\n title: \"agentx.json not found\",\n detail: `Looked in ${cfgPath}`,\n fix: \"Run `agentx setup` to create one via the web wizard.\",\n })\n return null\n }\n let cfg: any\n try { cfg = JSON.parse(readFileSync(cfgPath, \"utf-8\")) }\n catch (e: any) {\n checks.push({ severity: \"fail\", group: \"Config\", title: \"agentx.json is not valid JSON\", detail: e.message })\n return null\n }\n try {\n // Full schema validation — catches missing required fields.\n loadDaemonConfig(cfgPath)\n checks.push({ severity: \"ok\", group: \"Config\", title: `agentx.json valid (${Object.keys(cfg.agents || {}).length} agents, ${Object.keys(cfg.crons || {}).length} schedules)` })\n } catch (e: any) {\n checks.push({\n severity: \"fail\",\n group: \"Config\",\n title: \"agentx.json failed schema validation\",\n detail: e.message,\n fix: \"Open /admin → Advanced tab to edit and re-save.\",\n })\n }\n const claudeCodeAgents = Object.entries(cfg.agents || {}).filter(([, a]: [string, any]) => a.tier === \"claude-code\")\n if (claudeCodeAgents.length > 0) {\n const hasClaude = (() => {\n try { execFileSync(process.platform === \"win32\" ? \"where\" : \"which\", [\"claude\"], { stdio: \"ignore\" }); return true } catch { return false }\n })()\n if (!hasClaude) {\n checks.push({\n severity: \"fail\",\n group: \"Config\",\n title: `${claudeCodeAgents.length} agent(s) use claude-code tier but claude CLI is missing`,\n detail: claudeCodeAgents.map(([id]) => id).join(\", \"),\n fix: \"Install Claude Code (https://docs.anthropic.com/en/docs/claude-code) or switch these agents to tier=sdk.\",\n })\n }\n }\n return cfg\n}\n\nfunction runReferenceChecks(checks: Check[], cfg: any): void {\n // Parse ${VAR} references out of the config (recursively) and verify each\n // one has a matching value in .env or process.env.\n const refs = new Set<string>()\n collectEnvRefs(cfg, refs)\n if (refs.size === 0) {\n checks.push({ severity: \"ok\", group: \"Secrets\", title: \"No ${VAR} references in agentx.json\" })\n return\n }\n const envFile = resolve(process.cwd(), \".env\")\n const envFromFile: Record<string, string> = {}\n if (existsSync(envFile)) {\n for (const line of readFileSync(envFile, \"utf-8\").split(/\\r?\\n/)) {\n const m = line.match(/^\\s*([A-Z_][A-Z0-9_]*)\\s*=\\s*(.*)$/i)\n if (m) envFromFile[m[1]] = m[2]\n }\n }\n const missing: string[] = []\n const empty: string[] = []\n for (const name of refs) {\n const raw = process.env[name] ?? envFromFile[name]\n if (raw === undefined) missing.push(name)\n else if (!raw.trim() || /^[\"']?\\s*[\"']?$/.test(raw)) empty.push(name)\n }\n if (missing.length === 0 && empty.length === 0) {\n checks.push({ severity: \"ok\", group: \"Secrets\", title: `${refs.size} env reference(s) resolved` })\n } else {\n if (missing.length > 0) {\n checks.push({\n severity: \"fail\",\n group: \"Secrets\",\n title: `${missing.length} env var(s) referenced in agentx.json but missing`,\n detail: missing.join(\", \"),\n fix: `Add to .env — e.g. ${missing[0]}=<value>`,\n })\n }\n if (empty.length > 0) {\n checks.push({\n severity: \"warn\",\n group: \"Secrets\",\n title: `${empty.length} env var(s) set but empty`,\n detail: empty.join(\", \"),\n })\n }\n }\n}\n\nfunction collectEnvRefs(node: unknown, into: Set<string>): void {\n if (typeof node === \"string\") {\n for (const m of node.matchAll(/\\$\\{([A-Z_][A-Z0-9_]*)\\}/g)) into.add(m[1])\n } else if (Array.isArray(node)) {\n for (const item of node) collectEnvRefs(item, into)\n } else if (node && typeof node === \"object\") {\n for (const v of Object.values(node)) collectEnvRefs(v, into)\n }\n}\n\nfunction runWorkspaceChecks(checks: Check[], cfg: any): void {\n const missing: string[] = []\n for (const [id, a] of Object.entries(cfg.agents || {}) as [string, any][]) {\n if (!a.workspace) continue\n const abs = a.workspace.startsWith(\"/\") ? a.workspace : resolve(process.cwd(), a.workspace)\n try {\n const st = statSync(abs)\n if (!st.isDirectory()) missing.push(`${id}: ${abs} (exists but not a directory)`)\n } catch { missing.push(`${id}: ${abs}`) }\n }\n if (missing.length === 0) {\n checks.push({ severity: \"ok\", group: \"Workspaces\", title: \"All agent workspace folders exist\" })\n } else {\n checks.push({\n severity: \"warn\",\n group: \"Workspaces\",\n title: `${missing.length} agent workspace(s) missing`,\n detail: missing.join(\"\\n \"),\n fix: \"The daemon will create missing folders on first task, but you won't see CLAUDE.md / skills until you populate them.\",\n })\n }\n}\n\nasync function runRuntimeChecks(checks: Check[], cfg: any): Promise<void> {\n const url = cfg.dashboard?.daemonUrl?.replace(/\\/+$/, \"\") || \"http://127.0.0.1:18800\"\n const headers: Record<string, string> = {}\n if (cfg.dashboard?.token) headers[\"Authorization\"] = `Bearer ${cfg.dashboard.token}`\n try {\n const ac = new AbortController()\n const timer = setTimeout(() => ac.abort(), 2000)\n const r = await fetch(url + \"/health\", { headers, signal: ac.signal })\n clearTimeout(timer)\n if (!r.ok) {\n checks.push({ severity: \"warn\", group: \"Runtime\", title: `Daemon responded ${r.status}`, detail: url })\n return\n }\n const body: any = await r.json()\n checks.push({\n severity: \"ok\",\n group: \"Runtime\",\n title: `Daemon healthy — ${body.agents?.length ?? 0} agents live, uptime ${Math.round((body.uptime ?? 0) / 60)}m`,\n detail: url,\n })\n } catch {\n checks.push({\n severity: \"warn\",\n group: \"Runtime\",\n title: \"Daemon not reachable (not running?)\",\n detail: url,\n fix: \"Run `agentx daemon start`. Skip this check with `agentx doctor --no-running`.\",\n })\n }\n}\n\n// ---------------------------------------------------------------------------\n// Output\n// ---------------------------------------------------------------------------\n\nfunction summarize(checks: Check[]): { errors: number; warnings: number; ok: number } {\n return {\n errors: checks.filter((c) => c.severity === \"fail\").length,\n warnings: checks.filter((c) => c.severity === \"warn\").length,\n ok: checks.filter((c) => c.severity === \"ok\").length,\n }\n}\n\nfunction printHumanReport(checks: Check[]): void {\n console.log()\n console.log(chalk.bold(\" agentx doctor\"))\n console.log()\n\n const groups = new Map<string, Check[]>()\n for (const c of checks) {\n if (!groups.has(c.group)) groups.set(c.group, [])\n groups.get(c.group)!.push(c)\n }\n for (const [group, items] of groups) {\n console.log(chalk.bold(\" \" + group))\n for (const c of items) {\n const marker = c.severity === \"ok\" ? chalk.green(\"✓\")\n : c.severity === \"warn\" ? chalk.yellow(\"!\")\n : chalk.red(\"✗\")\n console.log(` ${marker} ${c.title}`)\n if (c.detail) console.log(chalk.dim(\" \" + c.detail.replace(/\\n/g, \"\\n \")))\n if (c.fix) console.log(chalk.dim(\" → \" + c.fix))\n }\n console.log()\n }\n\n const s = summarize(checks)\n if (s.errors > 0) {\n console.log(chalk.red.bold(` ${s.errors} error${s.errors === 1 ? \"\" : \"s\"}`) +\n (s.warnings ? chalk.yellow(`, ${s.warnings} warning${s.warnings === 1 ? \"\" : \"s\"}`) : \"\") +\n `. Fix the error${s.errors === 1 ? \"\" : \"s\"} and rerun.`)\n } else if (s.warnings > 0) {\n console.log(chalk.yellow.bold(` ${s.warnings} warning${s.warnings === 1 ? \"\" : \"s\"}.`) + chalk.dim(\" Review but not blocking.\"))\n } else {\n console.log(chalk.green.bold(` All checks passed (${s.ok}).`))\n }\n console.log()\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 } from \"path\"\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: \"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, \"../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 channel ====================\n\nexport const channel = new Command()\n .name(\"channel\")\n .description(\"manage channels — add telegram/whatsapp/discord, 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 // Discord\n const dc = config.channels?.discord\n if (dc?.enabled) {\n console.log(chalk.bold(\" Discord:\"))\n console.log(` agent: ${dc.agentBinding || \"(none)\"}`)\n } else {\n console.log(chalk.dim(\" Discord: 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 discord)\")\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: \"Discord — bot via Discord developer portal\", value: \"discord\" },\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. +21624309128)\" : \"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 // --- Discord ---\n if (channelType === \"discord\") {\n const answers = await prompts([\n { type: \"text\", name: \"token\", message: \"Discord bot token (from developer portal)\" },\n { type: \"select\", name: \"agentBinding\", message: \"Bind to agent\", choices: agentChoices },\n ])\n\n if (!answers.token) return\n\n config.channels.discord = {\n enabled: true,\n token: answers.token,\n agentBinding: answers.agentBinding,\n }\n\n await saveConfig(config)\n console.log(chalk.green(` Discord added -> ${answers.agentBinding}`))\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.67.108.119: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 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// ==================== 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/clawdbot.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 console.log(chalk.dim(` Discord: ${config.channels.discord?.enabled ? \"enabled\" : \"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","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/discord):\" },\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 { connectDiscord } from \"@/connect/discord\"\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// V1 surfaces two channels: telegram (highest-pain) and mesh (only remaining\n// manual .env step in Journey 8). WhatsApp / Discord / GitLab follow.\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(\"discord\")\n .description(\"pair a Discord bot — verify token, emit install URL, save to .env\")\n .option(\"--agent <id>\", \"agent to bind the bot to\")\n .option(\"-c, --config <path>\", \"path to agentx.json\")\n .action(async (opts) => {\n await connectDiscord({ agent: opts.agent, configPath: opts.config })\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 discord\")} — pair a Discord bot, emit install URL`)\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 { applyConfigMutation, setAtPath } from \"@/daemon/config-mutator\"\nimport { setDotEnv } from \"@/utils/dotenv-mutator\"\n\n// --- agentx connect discord ---\n//\n// Discord's flow is 2-step: create an application (with bot token) in the\n// Developer Portal, then install it to a server via an OAuth URL. We can't\n// automate step 1 (Discord has no API to create apps), but we can verify\n// the bot token, save it to .env, and compose the install URL for the user.\n\nconst DEV_PORTAL = \"https://discord.com/developers/applications\"\n\n// Default bot permissions: View Channels + Send Messages + Read Message History + Use Slash Commands\n// Integer is a bitfield. 274877991936 = send + view + read history + manage webhooks. Plain chatty bots use 67584.\nconst DEFAULT_PERMISSIONS = \"67584\"\n\nasync function fetchMe(token: string): Promise<{ id: string; username: string; discriminator?: string } | null> {\n try {\n const res = await fetch(\"https://discord.com/api/v10/users/@me\", {\n headers: { Authorization: `Bot ${token}` },\n signal: AbortSignal.timeout(8000),\n })\n if (!res.ok) return null\n return (await res.json()) as any\n } catch { return null }\n}\n\nexport interface ConnectDiscordOpts {\n agent?: string\n configPath?: string\n}\n\nfunction openInBrowser(url: string): void {\n try {\n const { spawn } = require(\"child_process\")\n const opener = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\"\n spawn(opener, [url], { stdio: \"ignore\", detached: true }).unref()\n } catch { /* non-fatal */ }\n}\n\nexport async function connectDiscord(opts: ConnectDiscordOpts = {}): Promise<void> {\n console.log()\n console.log(chalk.bold(\" Connect Discord\"))\n console.log()\n console.log(chalk.dim(\" 1. Open the Discord Developer Portal\"))\n console.log(chalk.dim(` ${DEV_PORTAL}`))\n console.log(chalk.dim(\" 2. New Application → Bot → Reset Token → copy the token\"))\n console.log(chalk.dim(\" 3. Under Bot → Privileged Gateway Intents,\"))\n console.log(chalk.dim(\" enable 'MESSAGE CONTENT INTENT'\"))\n console.log()\n\n const { openBrowser } = await prompts({\n type: \"confirm\",\n name: \"openBrowser\",\n message: \"Open the Developer Portal in your browser?\",\n initial: true,\n })\n if (openBrowser) openInBrowser(DEV_PORTAL)\n\n const { token } = await prompts({\n type: \"password\",\n name: \"token\",\n message: \"Paste the bot token:\",\n validate: (t: string) => t.trim().length > 20 || \"that looks too short for a Discord token\",\n })\n if (!token) { console.log(chalk.red(\" Aborted\")); process.exit(1) }\n\n process.stdout.write(\" Verifying token... \")\n const me = await fetchMe(token.trim())\n if (!me) {\n console.log(chalk.red(\"✗ invalid or revoked — did you enable MESSAGE CONTENT INTENT and copy the right token?\"))\n process.exit(1)\n }\n const displayName = me.discriminator && me.discriminator !== \"0\" ? `${me.username}#${me.discriminator}` : me.username\n console.log(chalk.green(`✓ ${displayName} (bot id ${me.id})`))\n\n // --- Agent binding ---\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 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 // --- Persist token + config ---\n const envVar = \"DISCORD_BOT_TOKEN\"\n setDotEnv(envVar, token.trim())\n process.env[envVar] = token.trim()\n\n const result = await applyConfigMutation((cfg) => {\n setAtPath(cfg, \"channels.discord.enabled\", true)\n setAtPath(cfg, \"channels.discord.token\", `\\${${envVar}}`)\n setAtPath(cfg, \"channels.discord.agentBinding\", 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(` ✓ Discord bot ${displayName} bound to agent \"${agent}\"`))\n console.log(chalk.dim(` Token stored in .env as ${envVar}`))\n if (result.reloaded) console.log(chalk.dim(\" Daemon hot-reloaded.\"))\n else console.log(chalk.dim(\" Restart the daemon to start Discord polling.\"))\n\n // --- Install URL (bot id = application id for a bot user) ---\n console.log()\n console.log(chalk.bold(\" Install the bot to a server\"))\n console.log()\n const installUrl = `https://discord.com/oauth2/authorize?client_id=${me.id}&scope=bot&permissions=${DEFAULT_PERMISSIONS}`\n console.log(` ${chalk.cyan(installUrl)}`)\n console.log()\n const { openInstall } = await prompts({\n type: \"confirm\",\n name: \"openInstall\",\n message: \"Open the install URL in your browser now?\",\n initial: true,\n })\n if (openInstall) openInBrowser(installUrl)\n\n console.log()\n console.log(chalk.dim(\" After you pick a server, the bot will come online on the next daemon restart.\"))\n console.log(chalk.dim(\" Mention the bot in any channel to route messages to the agent.\"))\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 — web dashboard\nusage\n .command(\"serve\")\n .description(\"start a web dashboard for token usage visualization\")\n .option(\"--port <n>\", \"port number\", \"4201\")\n .action(async (opts) => {\n const { startUsageDashboard } = await import(\"@/daemon/usage-dashboard\")\n startUsageDashboard(parseInt(opts.port))\n })\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","import { Command } from \"commander\"\nimport chalk from \"chalk\"\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 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. 'mtgl/system,mtgl/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 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 chalk from \"chalk\"\nimport { WikiHub } from \"@/wiki\"\nimport type { WikiMode } from \"@/wiki/hub\"\nimport { startWikiServer } from \"@/wiki/serve\"\nimport { buildAbsorbPrompt } from \"@/wiki/prompts\"\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(dir || resolve(process.cwd(), \".agentx/wiki\"), undefined, mode || \"graph\")\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(\"--max <n>\", \"max entries per agent\", \"10\")\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 let totalAbsorbed = 0\n\n for (const agentId of agents) {\n const unabsorbed = hub.getUnabsorbedEntries(agentId).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 const prompt = buildAbsorbPrompt(mode, agentId, worldview, existingIndex.articles, entryTexts, unabsorbed.length)\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 { 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[] }>\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 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 }, 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 totalAbsorbed++\n }\n\n // Show gaps (missing puzzle pieces)\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 }\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 }\n console.log()\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. 'MTGL 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, { 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 = require(\"fs\").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, { 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, { 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, { 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(\"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((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 = store.findRelevant(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 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.67.108.119: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.67.108.119: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","import { createServer, type IncomingMessage, type ServerResponse } from \"http\"\nimport { WikiStore } from \"./store\"\nimport { WikiHub } from \"./hub\"\nimport { MeshWikiClient } from \"./mesh\"\nimport type { AgentWikiSummary } from \"./hub\"\n\n// --- Lightweight Markdown → HTML (no deps) ---\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\")\n}\n\n/**\n * Strip legacy section-tag comments from the article body. The old absorb\n * prompt told the LLM to add `<!-- tags: runbook, staging -->` inside\n * sections; in the Farzapedia-aligned design, these are no longer\n * load-bearing and leak through as visible literal text once escaped.\n */\nfunction stripSectionTags(text: string): string {\n return text.replace(/<!--\\s*tags?:[^>]*-->\\s*\\n?/gi, \"\")\n}\n\n/** Render a single tag as a clickable link to the tag-filter route. */\nfunction tagLink(tag: string, agentId?: string): string {\n const href = agentId\n ? `/agent/${encodeURIComponent(agentId)}/tag/${encodeURIComponent(tag)}`\n : `/tag/${encodeURIComponent(tag)}`\n return `<a href=\"${href}\" class=\"tag\">${escapeHtml(tag)}</a>`\n}\n\n/** Render an array of tags as clickable links, space-separated. */\nfunction tagLinks(tags: string[] | undefined, agentId?: string): string {\n return (tags || []).map(t => tagLink(t, agentId)).join(\" \")\n}\n\n/**\n * Resolve the body of a `[[...]]` wikilink to a relative article path.\n *\n * Authors write wikilinks three ways: by title, by path (without `.md`), or\n * by full path (with `.md`). wikiArticles is a title→path map, so we build\n * a path-set on first call and try several normalisations:\n *\n * 1. Exact title lookup (handles [[My Article]])\n * 2. Exact path lookup (handles [[people/anis.md]])\n * 3. Path + \".md\" suffix (handles [[people/anis]])\n * 4. Case-insensitive title scan (forgives minor casing drift)\n *\n * Return the path if any matches, else undefined so the caller can render\n * a broken-link marker.\n */\nfunction resolveWikilink(target: string, wikiArticles: Map<string, string>): string | undefined {\n if (!target) return undefined\n // (1) exact title\n const byTitle = wikiArticles.get(target)\n if (byTitle) return byTitle\n\n // (2) + (3) path lookups\n const pathSet = new Set(wikiArticles.values())\n if (pathSet.has(target)) return target\n const withExt = target.endsWith('.md') ? target : `${target}.md`\n if (pathSet.has(withExt)) return withExt\n\n // (4) case-insensitive title fallback — common when the user writes\n // \"Anis Marrouchi\" but the canonical title is \"anis marrouchi\".\n const targetLower = target.toLowerCase()\n for (const [title, path] of wikiArticles) {\n if (title.toLowerCase() === targetLower) return path\n }\n return undefined\n}\n\nfunction md(text: string, wikiArticles: Map<string, string>, agentPrefix: string = \"\"): string {\n // Strip section-tag HTML comments before escaping so they don't render\n // as literal \"<!-- tags: ... -->\" in the output.\n let html = escapeHtml(stripSectionTags(text))\n\n // Code blocks (fenced)\n html = html.replace(/```(\\w*)\\n([\\s\\S]*?)```/g, (_m, lang, code) =>\n `<pre><code class=\"lang-${lang}\">${code.trim()}</code></pre>`)\n\n // Inline code\n html = html.replace(/`([^`]+)`/g, '<code>$1</code>')\n\n // Tables\n html = html.replace(/^(\\|.+\\|)\\n(\\|[-| :]+\\|)\\n((?:\\|.+\\|\\n?)*)/gm, (_m, header, _sep, body) => {\n const ths = header.split(\"|\").filter((c: string) => c.trim()).map((c: string) => `<th>${c.trim()}</th>`).join(\"\")\n const rows = body.trim().split(\"\\n\").map((row: string) => {\n const tds = row.split(\"|\").filter((c: string) => c.trim()).map((c: string) => `<td>${c.trim()}</td>`).join(\"\")\n return `<tr>${tds}</tr>`\n }).join(\"\")\n return `<table><thead><tr>${ths}</tr></thead><tbody>${rows}</tbody></table>`\n })\n\n // Headings\n html = html.replace(/^#### (.+)$/gm, '<h4>$1</h4>')\n html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>')\n html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>')\n html = html.replace(/^# (.+)$/gm, '<h1>$1</h1>')\n\n // Bold and italic\n html = html.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>')\n html = html.replace(/\\*(.+?)\\*/g, '<em>$1</em>')\n\n // Wikilinks — support three forms for the [[...]] body:\n // [[Title]] exact article title\n // [[path/to/article]] path without .md (e.g. \"people/anis\")\n // [[path/to/article.md]] full relative path\n // [[Title|custom display text]] optional display override (Obsidian-style)\n html = html.replace(/\\[\\[([^\\]]+)\\]\\]/g, (_m, body: string) => {\n const [rawTarget, rawDisplay] = body.split(\"|\", 2)\n const target = rawTarget.trim().replace(/^\\//, \"\")\n const display = (rawDisplay || rawTarget).trim()\n const path = resolveWikilink(target, wikiArticles)\n if (path) {\n return `<a href=\"${agentPrefix}/article/${encodeURIComponent(path)}\" class=\"wikilink\">${display}</a>`\n }\n return `<a href=\"${agentPrefix}/search?q=${encodeURIComponent(target)}\" class=\"wikilink broken\" title=\"Not found — click to search\">${display}</a>`\n })\n\n // External links\n html = html.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\" target=\"_blank\">$1</a>')\n\n // Blockquotes (consecutive `> ` lines → one <blockquote>)\n html = html.replace(/^(>\\s?.*(?:\\n>\\s?.*)*)/gm, (block: string) => {\n const inner = block.split(\"\\n\").map(l => l.replace(/^>\\s?/, \"\")).join(\"<br>\")\n return `<blockquote>${inner}</blockquote>`\n })\n\n // Task-list items (render as plain text with unicode checkbox)\n html = html.replace(/^[-*] \\[( |x|X)\\] (.+)$/gm, (_m, chk, rest) =>\n `<li class=\"task\">${chk.toLowerCase() === \"x\" ? \"☑\" : \"☐\"} ${rest}</li>`)\n\n // Unordered lists\n html = html.replace(/^[-*] (.+)$/gm, '<li>$1</li>')\n\n // Ordered lists — match lines like \"1. foo\" (number, dot, space)\n html = html.replace(/^\\d+\\. (.+)$/gm, '<li data-ordered=\"1\">$1</li>')\n\n // Wrap consecutive ordered <li>s into <ol>. Keep the data-ordered marker\n // on each <li> inside the <ol> so the subsequent <ul> regex below can\n // correctly skip them via negative lookahead. Marker is stripped once all\n // list-wrapping is done.\n html = html.replace(/(<li data-ordered=\"1\">.*?<\\/li>(?:\\n?<li data-ordered=\"1\">.*?<\\/li>)*)/g, '<ol>$1</ol>')\n\n // Wrap consecutive unordered <li>s — the negative lookahead `(?! data-ordered)`\n // ensures ordered <li>s inside the <ol> above are NOT re-wrapped in <ul>.\n html = html.replace(/((?:<li(?! data-ordered)[^>]*>.*?<\\/li>\\n?)+)/g, '<ul>$1</ul>')\n\n // Clean up the ordered marker now that wrapping is settled.\n html = html.replace(/ data-ordered=\"1\"/g, \"\")\n\n // Horizontal rules\n html = html.replace(/^---$/gm, '<hr>')\n\n // Paragraphs — only wrap non-block lines. A paragraph is a run of\n // text that isn't already wrapped in a block-level tag.\n html = html.replace(/\\n\\n+/g, '</p><p>')\n html = `<p>${html}</p>`\n // Unwrap <p>...</p> that now contain block-level elements.\n html = html.replace(/<p>\\s*(<(?:h[1-6]|ul|ol|blockquote|table|pre|hr)\\b[^>]*>[\\s\\S]*?<\\/(?:h[1-6]|ul|ol|blockquote|table|pre)>)\\s*<\\/p>/g, \"$1\")\n html = html.replace(/<p>\\s*<hr>\\s*<\\/p>/g, \"<hr>\")\n // Drop empty paragraphs that remain.\n html = html.replace(/<p>\\s*<\\/p>/g, \"\")\n\n html = html.replace(/<p>(<(?:h[1-4]|pre|table|ul|hr|div))/g, '$1')\n html = html.replace(/(<\\/(?:h[1-4]|pre|table|ul|hr|div)>)<\\/p>/g, '$1')\n html = html.replace(/<p>\\s*<\\/p>/g, '')\n\n return html\n}\n\n// --- CSS ---\n\nconst HEAD_FONTS = `<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,300..600;1,6..72,300..600&family=Inter+Tight:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap\" rel=\"stylesheet\">`\n\n// Paper/ink editorial palette — warm neutrals, Newsreader display font,\n// Inter Tight for UI, JetBrains Mono for code/meta. Ported from the\n// /Users/macbookpro/Downloads/wiki mockup.\nconst CSS = `\n:root {\n --bg: #FAF8F3;\n --bg-raised: #FFFFFF;\n --bg-sunk: #F2EFE7;\n --bg-hover: #EFEBE0;\n --ink: #1A1915;\n --ink-2: #3D3A32;\n --muted: #6B6860;\n --muted-2: #96918A;\n --line: #E4DED0;\n --line-2: #D1CAB8;\n --accent: oklch(55% 0.14 45);\n --accent-soft: oklch(55% 0.14 45 / 0.10);\n --accent-hover: oklch(48% 0.14 45);\n --cool: oklch(55% 0.08 230);\n --cool-soft: oklch(55% 0.08 230 / 0.10);\n --ok: oklch(55% 0.10 145);\n --warn: oklch(60% 0.14 75);\n --err: oklch(55% 0.16 20);\n --font-display: 'Newsreader', Georgia, serif;\n --font-ui: 'Inter Tight', -apple-system, system-ui, sans-serif;\n --font-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;\n --sidebar-w: 260px;\n --topbar-h: 52px;\n --radius: 6px;\n --radius-sm: 4px;\n --radius-lg: 10px;\n --shadow-sm: 0 1px 2px rgba(26,25,21,0.04), 0 1px 1px rgba(26,25,21,0.03);\n --shadow-md: 0 4px 12px rgba(26,25,21,0.06), 0 2px 4px rgba(26,25,21,0.04);\n --shadow-lg: 0 12px 40px rgba(26,25,21,0.12), 0 4px 12px rgba(26,25,21,0.06);\n}\n[data-theme=\"dark\"] {\n --bg: #0F0E0C;\n --bg-raised: #1A1815;\n --bg-sunk: #07060A;\n --bg-hover: #22201C;\n --ink: #EBE7DD;\n --ink-2: #C9C4B7;\n --muted: #8B867B;\n --muted-2: #5E5A52;\n --line: #2A2822;\n --line-2: #3A3830;\n --accent: oklch(70% 0.16 45);\n --accent-soft: oklch(70% 0.16 45 / 0.14);\n --accent-hover: oklch(78% 0.16 45);\n --cool: oklch(70% 0.10 230);\n --cool-soft: oklch(70% 0.10 230 / 0.14);\n --ok: oklch(70% 0.14 145);\n --warn: oklch(75% 0.16 75);\n --err: oklch(68% 0.18 20);\n --shadow-sm: 0 1px 2px rgba(0,0,0,0.4);\n --shadow-md: 0 4px 12px rgba(0,0,0,0.5);\n --shadow-lg: 0 12px 40px rgba(0,0,0,0.7);\n}\n\n* { box-sizing: border-box; margin: 0; padding: 0; }\nhtml, body {\n background: var(--bg); color: var(--ink);\n font-family: var(--font-ui); font-size: 14px; line-height: 1.55;\n font-feature-settings: 'ss01','cv11';\n -webkit-font-smoothing: antialiased; min-height: 100vh;\n}\na { color: var(--accent); text-decoration: none; }\na:hover { color: var(--accent-hover); }\nbutton { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }\ninput, textarea, select { font: inherit; color: inherit; }\ncode, pre, .mono { font-family: var(--font-mono); font-size: 0.92em; }\n.display { font-family: var(--font-display); font-weight: 400; letter-spacing: -0.01em; }\n\n/* ——— App shell ——— */\n.app {\n display: grid;\n grid-template-columns: var(--sidebar-w) 1fr;\n grid-template-rows: var(--topbar-h) 1fr;\n min-height: 100vh;\n}\n.topbar {\n grid-column: 1 / -1;\n display: flex; align-items: center; gap: 16px; padding: 0 20px;\n background: var(--bg); border-bottom: 1px solid var(--line);\n position: sticky; top: 0; z-index: 20; backdrop-filter: blur(8px);\n}\n.topbar-logo {\n display: flex; align-items: center; gap: 10px;\n font-family: var(--font-display); font-size: 18px; color: var(--ink);\n width: calc(var(--sidebar-w) - 20px); padding-right: 12px;\n border-right: 1px solid var(--line); height: 100%;\n text-decoration: none;\n}\n.topbar-logo .mark {\n width: 22px; height: 22px; flex: 0 0 auto;\n display: inline-flex; align-items: center; justify-content: center;\n background: var(--accent); color: var(--bg-raised);\n border-radius: 5px; font-family: var(--font-mono);\n font-size: 11px; font-weight: 700;\n}\n.topbar-search {\n flex: 1; max-width: 520px;\n display: flex; align-items: center; gap: 8px; padding: 6px 12px;\n background: var(--bg-raised); border: 1px solid var(--line);\n border-radius: var(--radius); color: var(--muted);\n transition: border-color 0.15s, background 0.15s;\n}\n.topbar-search:focus-within { border-color: var(--line-2); background: var(--bg-hover); }\n.topbar-search input {\n flex: 1; border: 0; outline: 0; background: transparent;\n color: var(--ink); font: inherit;\n}\n.topbar-search input::placeholder { color: var(--muted); }\n.topbar-search kbd {\n font-family: var(--font-mono); font-size: 11px;\n padding: 2px 6px; border: 1px solid var(--line); border-radius: 3px;\n background: var(--bg); color: var(--muted);\n}\n.topbar-tools { margin-left: auto; display: flex; align-items: center; gap: 4px; }\n.icon-btn {\n width: 32px; height: 32px;\n display: inline-flex; align-items: center; justify-content: center;\n border-radius: var(--radius-sm); color: var(--muted);\n transition: background 0.15s, color 0.15s;\n}\n.icon-btn:hover { background: var(--bg-hover); color: var(--ink); }\n.icon-btn.active { color: var(--accent); background: var(--accent-soft); }\n.icon-btn svg { width: 16px; height: 16px; }\n\n/* ——— Sidebar ——— */\n.sidebar {\n grid-column: 1; grid-row: 2;\n background: var(--bg); border-right: 1px solid var(--line);\n padding: 16px 12px 40px; overflow-y: auto;\n position: sticky; top: var(--topbar-h);\n height: calc(100vh - var(--topbar-h));\n}\n.nav-section { margin-bottom: 20px; }\n.nav-section-title {\n display: flex; align-items: center; justify-content: space-between;\n padding: 4px 10px; font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.06em;\n color: var(--muted); margin-bottom: 2px;\n}\n.nav-item {\n display: flex; align-items: center; gap: 8px;\n padding: 5px 10px; color: var(--ink-2);\n font-size: 13px; border-radius: var(--radius-sm);\n line-height: 1.35; cursor: pointer;\n transition: background 0.1s;\n text-decoration: none;\n}\n.nav-item:hover { background: var(--bg-hover); color: var(--ink); }\n.nav-item.active {\n background: var(--accent-soft); color: var(--accent); font-weight: 500;\n}\n.nav-item .count {\n margin-left: auto; font-family: var(--font-mono);\n font-size: 11px; color: var(--muted);\n}\n.nav-item.active .count { color: var(--accent); }\n.nav-agent-header {\n display: flex; align-items: center; gap: 8px;\n padding: 6px 10px; font-size: 13px; color: var(--ink);\n cursor: pointer; border-radius: var(--radius-sm);\n text-decoration: none;\n}\n.nav-agent-header:hover { color: var(--accent); background: var(--bg-hover); }\n.nav-agent-header .name { font-weight: 500; }\n.nav-agent-header .badge {\n margin-left: auto; font-family: var(--font-mono);\n font-size: 10.5px; color: var(--muted);\n}\n.nav-agent-type-label {\n padding: 6px 8px 2px; font-size: 10px;\n text-transform: uppercase; letter-spacing: 0.08em;\n color: var(--muted-2); font-weight: 600;\n}\n.nav-agent-children {\n padding-left: 14px; display: flex; flex-direction: column; gap: 1px;\n margin-top: 2px; border-left: 1px dashed var(--line); margin-left: 10px;\n}\n\n/* ——— Main ——— */\n.main {\n grid-column: 2; grid-row: 2;\n padding: 32px 48px 80px;\n max-width: 1180px; width: 100%;\n}\n.main.article { max-width: 1100px; }\n\n/* ——— Breadcrumb ——— */\n.breadcrumb {\n display: flex; align-items: center; gap: 6px;\n font-size: 12.5px; color: var(--muted);\n margin-bottom: 14px; font-family: var(--font-ui);\n}\n.breadcrumb a { color: var(--muted); }\n.breadcrumb a:hover { color: var(--accent); }\n.breadcrumb .sep { color: var(--muted-2); }\n.breadcrumb .current { color: var(--ink-2); }\n\n/* ——— Display heading ——— */\n.page-head {\n display: flex; align-items: flex-end; justify-content: space-between;\n gap: 24px; padding-bottom: 16px;\n border-bottom: 1px solid var(--line); margin-bottom: 28px;\n}\n.page-head h1 {\n font-family: var(--font-display); font-size: 38px;\n font-weight: 400; letter-spacing: -0.015em; line-height: 1.1;\n}\n.page-head .page-sub {\n font-size: 13.5px; color: var(--muted);\n margin-top: 6px; max-width: 60ch; line-height: 1.5;\n}\n.page-head .page-actions { display: flex; gap: 8px; flex: 0 0 auto; }\n\n/* ——— Buttons ——— */\n.btn {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 6px 12px; font-size: 13px;\n color: var(--ink-2); background: var(--bg-raised);\n border: 1px solid var(--line); border-radius: var(--radius-sm);\n transition: all 0.1s; text-decoration: none;\n}\n.btn:hover { background: var(--bg-hover); border-color: var(--line-2); color: var(--ink); }\n.btn.primary { background: var(--ink); color: var(--bg); border-color: var(--ink); }\n.btn.primary:hover { background: var(--ink-2); color: var(--bg); }\n.btn.ghost { background: transparent; border-color: transparent; }\n.btn.ghost:hover { background: var(--bg-hover); }\n.btn svg { width: 14px; height: 14px; }\n\n/* ——— Stat strip ——— */\n.stats, .stat-strip {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 0;\n background: var(--bg-raised); border: 1px solid var(--line);\n border-radius: var(--radius); overflow: hidden;\n margin-bottom: 28px;\n}\n.stat-card, .stat-cell {\n padding: 16px 20px;\n border-right: 1px solid var(--line);\n display: flex; flex-direction: column; gap: 4px;\n background: transparent; text-align: left;\n}\n.stat-card:last-child, .stat-cell:last-child { border-right: none; }\n.stat-card .label, .stat-cell .label {\n font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em;\n color: var(--muted); font-weight: 600;\n}\n.stat-card .number, .stat-cell .number {\n font-family: var(--font-display); font-size: 32px; font-weight: 400;\n line-height: 1; color: var(--ink);\n}\n\n/* ——— Section heading ——— */\n.section-head, h2.section {\n display: flex; align-items: baseline; justify-content: space-between;\n margin: 40px 0 14px;\n}\n.section-head h2 {\n font-family: var(--font-display); font-size: 22px;\n font-weight: 400; letter-spacing: -0.01em; color: var(--ink);\n border: none; padding: 0;\n}\n\n/* ——— Agent grid (hub home) ——— */\n.agent-grid {\n display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n gap: 14px;\n}\n.agent-card {\n background: var(--bg-raised); border: 1px solid var(--line);\n border-radius: var(--radius); padding: 18px 20px;\n display: flex; flex-direction: column; gap: 12px;\n transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;\n}\n.agent-card:hover {\n border-color: var(--line-2); box-shadow: var(--shadow-md);\n transform: translateY(-1px);\n}\n.agent-card h3 {\n font-family: var(--font-display); font-size: 20px; font-weight: 400;\n color: var(--ink); margin: 0;\n}\n.agent-card h3 a { color: inherit; text-decoration: none; }\n.agent-card h3 a:hover { color: var(--accent); }\n.agent-card .agent-stats {\n display: flex; gap: 20px; font-size: 13px; color: var(--muted);\n}\n.agent-card .agent-stats strong {\n color: var(--ink); font-weight: 600; font-family: var(--font-mono);\n}\n.agent-card .article-list {\n display: flex; flex-direction: column; gap: 4px; margin-top: 4px; font-size: 13px;\n}\n.agent-card .article-row {\n display: flex; flex-wrap: wrap; align-items: center; gap: 4px;\n padding: 2px 0;\n}\n.agent-card .article-row .article-title {\n color: var(--ink-2); text-decoration: none; margin-left: 4px; flex: 1;\n}\n.agent-card .article-row .article-title:hover { color: var(--accent); }\n\n/* ——— Tags ——— */\n.tag {\n display: inline-flex; align-items: center;\n font-family: var(--font-mono); font-size: 11.5px;\n padding: 1px 7px 2px; background: var(--bg-sunk);\n color: var(--ink-2); border-radius: 3px;\n line-height: 1.4; cursor: pointer;\n transition: background 0.1s, color 0.1s;\n text-decoration: none;\n}\n.tag:hover { background: var(--accent-soft); color: var(--accent); }\n.tag.lg { font-size: 12.5px; padding: 3px 10px; }\n\n/* ——— Article meta — inline dl below h1 ——— */\n.meta {\n background: var(--bg-raised); border: 1px solid var(--line);\n border-radius: var(--radius); padding: 14px 18px;\n margin-bottom: 24px; font-size: 13px;\n display: grid; grid-template-columns: auto 1fr;\n gap: 6px 18px;\n}\n.meta dt {\n font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em;\n color: var(--muted); font-weight: 600;\n align-self: center;\n}\n.meta dd { color: var(--ink-2); font-family: var(--font-mono); font-size: 12.5px; }\n\n/* ——— Prose body ——— */\n.prose {\n font-size: 15.5px; line-height: 1.65; color: var(--ink-2);\n max-width: 68ch;\n}\n.main h1, .prose h1 {\n font-family: var(--font-display); font-size: 40px;\n font-weight: 400; letter-spacing: -0.015em; line-height: 1.1;\n color: var(--ink); margin-bottom: 16px;\n border: none; padding: 0;\n}\n.main h2, .prose h2 {\n font-family: var(--font-display); font-size: 26px;\n font-weight: 400; letter-spacing: -0.01em;\n margin: 36px 0 12px; color: var(--ink);\n padding-bottom: 4px; border-bottom: 1px solid var(--line);\n}\n.main h3, .prose h3 {\n font-family: var(--font-display); font-size: 20px; font-weight: 500;\n margin: 28px 0 8px; color: var(--ink);\n}\n.main h4, .prose h4 {\n font-size: 15px; font-weight: 600; margin: 20px 0 6px; color: var(--ink);\n}\n.main p, .prose p { margin: 10px 0; }\n.main ul, .prose ul, .main ol, .prose ol { margin: 10px 0 10px 22px; }\n.main li, .prose li { margin: 4px 0; }\n.main code, .prose code {\n background: var(--bg-sunk); padding: 1px 5px; border-radius: 3px;\n font-family: var(--font-mono);\n}\n.main pre, .prose pre {\n background: var(--bg-sunk); border: 1px solid var(--line);\n border-radius: var(--radius-sm); padding: 14px 16px;\n overflow-x: auto; margin: 14px 0; font-size: 13px;\n}\n.main pre code, .prose pre code { background: none; padding: 0; }\n.main blockquote, .prose blockquote {\n border-left: 3px solid var(--accent);\n padding: 4px 0 4px 14px; color: var(--muted);\n font-style: italic; margin: 14px 0;\n}\n\n/* Wikilinks in prose */\n.prose a.wikilink, .main a.wikilink {\n color: var(--accent);\n text-decoration: underline;\n text-decoration-color: var(--accent-soft);\n text-underline-offset: 3px;\n text-decoration-thickness: 1.5px;\n}\n.prose a.wikilink:hover, .main a.wikilink:hover { text-decoration-color: var(--accent); }\n.prose a.wikilink.broken, .main a.wikilink.broken {\n color: var(--err); text-decoration-color: var(--err);\n text-decoration-style: dashed;\n}\n\n/* ——— Tables ——— */\ntable {\n width: 100%; border-collapse: collapse;\n margin: 14px 0; font-size: 14px;\n}\nth, td {\n border-bottom: 1px solid var(--line);\n padding: 8px 12px; text-align: left;\n}\nth {\n background: var(--bg-sunk); font-weight: 600;\n color: var(--ink); font-size: 12.5px;\n text-transform: uppercase; letter-spacing: 0.04em;\n}\ntr:hover td { background: var(--bg-hover); }\n\n/* ——— Entry cards ——— */\n.entry-card {\n background: var(--bg-raised); border: 1px solid var(--line);\n border-radius: var(--radius);\n padding: 14px 18px; margin: 10px 0;\n transition: border-color 0.15s, box-shadow 0.15s;\n}\n.entry-card:hover { border-color: var(--line-2); box-shadow: var(--shadow-sm); }\n.entry-card .meta-line {\n font-size: 11.5px; color: var(--muted);\n margin-bottom: 6px; font-family: var(--font-mono);\n}\n.entry-card h3 {\n font-family: var(--font-display); font-size: 19px; font-weight: 400;\n color: var(--ink); margin: 4px 0 6px;\n border: none; padding: 0;\n}\n.entry-card h3 a { color: inherit; }\n.entry-card h3 a:hover { color: var(--accent); }\n.entry-card p {\n color: var(--ink-2); font-size: 13.5px;\n line-height: 1.55; margin: 4px 0;\n}\n\n/* ——— Backlinks ——— */\n.backlinks {\n margin-top: 40px; padding: 16px 18px;\n background: var(--bg-raised); border: 1px solid var(--line);\n border-radius: var(--radius);\n}\n.backlinks h4 {\n font-size: 11px; text-transform: uppercase;\n letter-spacing: 0.08em; color: var(--muted);\n font-weight: 600; margin-bottom: 8px;\n}\n.backlinks ul { list-style: none; padding: 0; margin: 0; }\n.backlinks li { padding: 4px 0; font-size: 13.5px; }\n\n/* ——— Health issues list ——— */\n.health-list { display: flex; flex-direction: column; gap: 6px; }\n.health-row {\n display: grid; grid-template-columns: 96px 1fr 2fr;\n gap: 14px; align-items: center;\n padding: 10px 14px; background: var(--bg-raised);\n border: 1px solid var(--line); border-radius: var(--radius-sm);\n font-size: 13px;\n}\n.health-row .kind {\n font-family: var(--font-mono); font-size: 10.5px;\n text-transform: uppercase; letter-spacing: 0.06em;\n color: var(--muted);\n}\n.health-row .article { color: var(--ink); font-weight: 500; }\n.health-row .msg { color: var(--ink-2); }\n\n@media (max-width: 900px) {\n .app { grid-template-columns: 1fr; }\n .topbar-logo { width: auto; border-right: none; }\n .sidebar { display: none; }\n .main { padding: 20px; grid-column: 1; }\n}\n`\n\n// --- HTML Templates ---\n\nfunction pageLayout(title: string, sidebar: string, content: string, searchQuery: string = \"\"): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>${escapeHtml(title)} — AgentX Wiki</title>\n ${HEAD_FONTS}\n <style>${CSS}</style>\n <script>(function(){try{var t=localStorage.getItem('wiki-theme');if(t)document.documentElement.setAttribute('data-theme',t)}catch(e){}})();</script>\n</head>\n<body>\n <div class=\"app\">\n <header class=\"topbar\">\n <a href=\"/\" class=\"topbar-logo\">\n <span class=\"mark\">W</span>\n <span class=\"display\">AgentX Wiki</span>\n </a>\n <form class=\"topbar-search\" action=\"/search\" method=\"get\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"/><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"/></svg>\n <input type=\"search\" name=\"q\" placeholder=\"Search every wiki…\" value=\"${escapeHtml(searchQuery)}\" autocomplete=\"off\" />\n <kbd>⌘K</kbd>\n </form>\n <div class=\"topbar-tools\">\n <button class=\"icon-btn\" id=\"wiki-theme-toggle\" title=\"Toggle theme\" aria-label=\"Toggle theme\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"/></svg>\n </button>\n </div>\n </header>\n <nav class=\"sidebar\">${sidebar}</nav>\n <main class=\"main\">${content}</main>\n </div>\n <script>\n (function(){\n var btn = document.getElementById('wiki-theme-toggle');\n if (!btn) return;\n btn.addEventListener('click', function(){\n var cur = document.documentElement.getAttribute('data-theme') === 'dark' ? '' : 'dark';\n if (cur) document.documentElement.setAttribute('data-theme', 'dark');\n else document.documentElement.removeAttribute('data-theme');\n try { localStorage.setItem('wiki-theme', cur); } catch(e){}\n });\n // Cmd/Ctrl-K focuses search\n document.addEventListener('keydown', function(e){\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {\n e.preventDefault();\n var inp = document.querySelector('.topbar-search input');\n if (inp) inp.focus();\n }\n });\n })();\n </script>\n</body>\n</html>`\n}\n\n// --- Hub Mode (all agents) ---\n\nfunction groupByDir(articles: Array<{ title: string; path: string; tags?: string[] }>): Map<string, typeof articles> {\n const byDir = new Map<string, typeof articles>()\n for (const a of articles) {\n const dir = a.path.includes(\"/\") ? a.path.split(\"/\").slice(0, -1).join(\"/\") : \"/\"\n const list = byDir.get(dir) || []\n list.push(a)\n byDir.set(dir, list)\n }\n return new Map([...byDir].sort((a, b) => a[0].localeCompare(b[0])))\n}\n\nfunction dirLabel(dir: string): string {\n if (dir === \"/\") return \"Root\"\n return dir.split(\"/\").pop()!.replace(/-/g, \" \")\n}\n\nfunction hubSidebar(agents: AgentWikiSummary[], activePath?: string): string {\n let html = '<div class=\"nav-section\">'\n html += `<a class=\"nav-item${!activePath ? ' active' : ''}\" href=\"/\">Home</a>`\n html += `<a class=\"nav-item\" href=\"/entries\">All entries</a>`\n html += '</div>'\n\n for (const agent of agents) {\n const agentPrefix = `/agent/${encodeURIComponent(agent.agentId)}`\n html += '<div class=\"nav-section\">'\n html += `<a class=\"nav-agent-header\" href=\"${agentPrefix}\">`\n html += `<span class=\"name\">${escapeHtml(agent.agentId)}</span>`\n html += `<span class=\"badge\">${agent.totalArticles}</span>`\n html += `</a>`\n html += '<div class=\"nav-agent-children\">'\n\n const byType = groupByDir(agent.articles)\n for (const [type, articles] of byType) {\n html += `<div class=\"nav-agent-type-label\">${dirLabel(type)}</div>`\n for (const a of articles) {\n const fullPath = `${agent.agentId}/${a.path}`\n const isActive = fullPath === activePath\n html += `<a class=\"nav-item${isActive ? ' active' : ''}\" href=\"${agentPrefix}/article/${encodeURIComponent(a.path)}\">${escapeHtml(a.title)}</a>`\n }\n }\n html += '</div>'\n html += '</div>'\n }\n\n return html\n}\n\nfunction hubHome(hub: WikiHub, allAgents?: AgentWikiSummary[], remoteAgents?: Array<AgentWikiSummary & { nodeId: string }>): string {\n const agents = allAgents || hub.summary()\n const shared = hub.getSharedStore()\n const totalEntries = shared.listEntries().length\n const totalArticles = agents.reduce((s, a) => s + a.totalArticles, 0)\n const totalUnabsorbed = agents.reduce((s, a) => s + a.unabsorbed, 0)\n const remoteIds = new Set((remoteAgents || []).map(r => r.agentId))\n\n let content = `<div class=\"page-head\">\n <div>\n <h1>AgentX Wiki</h1>\n <p class=\"page-sub\">Agent-owned institutional knowledge, typed and cross-referenced. Everything here compiles from raw conversation entries through the nightly absorb pass.</p>\n </div>\n </div>`\n\n // Stat strip\n content += '<div class=\"stat-strip\">'\n content += `<div class=\"stat-cell\"><div class=\"label\">Agents</div><div class=\"number\">${agents.length}</div></div>`\n content += `<div class=\"stat-cell\"><div class=\"label\">Articles</div><div class=\"number\">${totalArticles}</div></div>`\n content += `<div class=\"stat-cell\"><div class=\"label\">Raw entries</div><div class=\"number\">${totalEntries}</div></div>`\n if (totalUnabsorbed > 0) {\n content += `<div class=\"stat-cell\"><div class=\"label\">Unabsorbed</div><div class=\"number\">${totalUnabsorbed}</div></div>`\n }\n if (remoteAgents && remoteAgents.length > 0) {\n const nodes = new Set(remoteAgents.map(r => r.nodeId))\n content += `<div class=\"stat-cell\"><div class=\"label\">Mesh nodes</div><div class=\"number\">${nodes.size}</div></div>`\n }\n content += '</div>'\n\n // Agent cards grid\n content += '<div class=\"section-head\"><h2>Agent wikis</h2></div>'\n content += '<div class=\"agent-grid\">'\n for (const agent of agents) {\n const statusChip = agent.unabsorbed > 0\n ? `<span class=\"tag\" style=\"color:var(--warn);background:color-mix(in oklch, var(--warn) 12%, transparent)\">${agent.unabsorbed} unabsorbed</span>`\n : `<span class=\"tag\" style=\"color:var(--ok);background:color-mix(in oklch, var(--ok) 12%, transparent)\">up to date</span>`\n\n const isRemote = remoteIds.has(agent.agentId) && !hub.listAgents().includes(agent.agentId)\n const remoteBadge = isRemote\n ? ` <span class=\"tag\" style=\"color:var(--cool);background:var(--cool-soft)\">remote</span>`\n : ''\n\n content += `<div class=\"agent-card\">`\n content += `<h3><a href=\"/agent/${encodeURIComponent(agent.agentId)}\">${escapeHtml(agent.agentId)}</a>${remoteBadge}</h3>`\n content += `<div class=\"agent-stats\">\n <span><strong>${agent.totalArticles}</strong> articles</span>\n <span><strong>${agent.totalEntries}</strong> entries</span>\n ${statusChip}\n </div>`\n\n if (agent.articles.length > 0) {\n content += '<div class=\"article-list\">'\n for (const a of agent.articles.slice(0, 6)) {\n const tagPart = tagLinks((a.tags || []).slice(0, 2), agent.agentId)\n content += `<div class=\"article-row\">${tagPart} <a class=\"article-title\" href=\"/agent/${encodeURIComponent(agent.agentId)}/article/${encodeURIComponent(a.path)}\">${escapeHtml(a.title)}</a></div>`\n }\n if (agent.articles.length > 6) {\n content += `<div class=\"article-row\"><a class=\"article-title\" style=\"color:var(--muted)\" href=\"/agent/${encodeURIComponent(agent.agentId)}\">+ ${agent.articles.length - 6} more →</a></div>`\n }\n content += '</div>'\n }\n content += '</div>'\n }\n content += '</div>'\n\n return pageLayout(\"Hub\", hubSidebar(agents), content)\n}\n\nfunction hubAgentOverview(hub: WikiHub, agentId: string, allAgents?: AgentWikiSummary[]): string {\n const agents = allAgents || hub.summary()\n const agentSummary = agents.find(a => a.agentId === agentId)\n if (!agentSummary) return pageLayout(\"Not Found\", hubSidebar(agents), \"<h1>Agent not found</h1>\")\n\n // Use summary articles (may come from remote peer if it has more)\n const isRemote = (agentSummary as any).peerUrl !== undefined\n const entries = hub.getAgentEntries(agentId)\n const articles = agentSummary.articles || []\n\n let content = `<nav class=\"breadcrumb\"><a href=\"/\">Hub</a> <span class=\"sep\">/</span> <span class=\"current\">${escapeHtml(agentId)}</span></nav>`\n content += `<div class=\"page-head\"><div><h1>${escapeHtml(agentId)}</h1>`\n if (isRemote) {\n content += `<p class=\"page-sub\"><span class=\"tag\" style=\"color:var(--cool);background:var(--cool-soft)\">remote @ ${escapeHtml((agentSummary as any).nodeId)}</span></p>`\n }\n content += `</div></div>`\n\n // Stats\n content += '<div class=\"stat-strip\">'\n content += `<div class=\"stat-cell\"><div class=\"label\">Articles</div><div class=\"number\">${agentSummary.totalArticles}</div></div>`\n content += `<div class=\"stat-cell\"><div class=\"label\">Entries</div><div class=\"number\">${agentSummary.totalEntries}</div></div>`\n content += `<div class=\"stat-cell\"><div class=\"label\">Unabsorbed</div><div class=\"number\">${agentSummary.unabsorbed}</div></div>`\n content += '</div>'\n\n // Articles grouped by type\n if (articles.length > 0) {\n content += '<div class=\"section-head\"><h2>Articles</h2><span class=\"mono\" style=\"font-size:12px;color:var(--muted)\">' + articles.length + ' total</span></div>'\n const byType = groupByDir(articles as Array<{ title: string; path: string; tags?: string[] }>)\n for (const [type, list] of byType) {\n content += `<h3 class=\"display\" style=\"font-size:17px;color:var(--muted);font-weight:500;margin:20px 0 8px\">${dirLabel(type)}</h3>`\n content += '<div class=\"agent-card\" style=\"padding:4px 14px\"><div class=\"article-list\">'\n for (const a of list) {\n content += `<div class=\"article-row\">${tagLinks(((a.tags || []) as string[]).slice(0, 3), agentId)} <a class=\"article-title\" href=\"/agent/${encodeURIComponent(agentId)}/article/${encodeURIComponent(a.path)}\">${escapeHtml(a.title)}</a></div>`\n }\n content += '</div></div>'\n }\n }\n\n // Recent entries\n const recent = entries.slice(-5).reverse()\n if (recent.length > 0) {\n content += '<div class=\"section-head\"><h2>Recent entries</h2><a class=\"btn ghost\" href=\"/entries\">See all →</a></div>'\n for (const e of recent) {\n content += `<div class=\"entry-card\">\n <div class=\"meta-line\">${e.date} · via ${escapeHtml(e.source)} · <code>${escapeHtml(e.id)}</code></div>\n <p>${escapeHtml(e.content.slice(0, 300))}${e.content.length > 300 ? \"…\" : \"\"}</p>\n </div>`\n }\n }\n\n // Lint\n const agentStore = hub.getAgentWiki(agentId)\n const issues = agentStore.lint()\n if (issues.length > 0) {\n content += `<div class=\"section-head\"><h2>Health issues</h2><span class=\"mono\" style=\"font-size:12px;color:var(--warn)\">${issues.length}</span></div>`\n content += '<div class=\"health-list\">'\n for (const issue of issues) {\n content += `<div class=\"health-row\">\n <span class=\"kind\">${escapeHtml(issue.type)}</span>\n <span class=\"article\">${escapeHtml(issue.article)}</span>\n <span class=\"msg\">${escapeHtml(issue.message)}</span>\n </div>`\n }\n content += '</div>'\n }\n\n return pageLayout(agentId, hubSidebar(agents, agentId), content)\n}\n\nfunction hubArticlePage(hub: WikiHub, agentId: string, articlePath: string, allAgents?: AgentWikiSummary[]): string | null {\n const store = hub.getAgentWiki(agentId)\n const article = store.readArticle(articlePath)\n if (!article) return null\n\n const agents = allAgents || hub.summary()\n const index = store.rebuildIndex()\n const titleToPath = new Map<string, string>()\n for (const a of index.articles) titleToPath.set(a.title, a.path)\n\n const prefix = `/agent/${encodeURIComponent(agentId)}`\n const backlinks = store.buildBacklinks()\n const inbound = backlinks[article.meta.title] || []\n\n let content = `<nav class=\"breadcrumb\"><a href=\"/\">Hub</a> <span class=\"sep\">/</span> <a href=\"${prefix}\">${escapeHtml(agentId)}</a> <span class=\"sep\">/</span> <span class=\"current\">${escapeHtml(article.meta.title)}</span></nav>`\n content += `<article class=\"prose\"><h1>${escapeHtml(article.meta.title)}</h1>`\n\n // Meta box\n content += '<dl class=\"meta\">'\n if (article.meta.type) {\n content += `<dt>Type</dt><dd>${tagLink(article.meta.type, agentId)}</dd>`\n }\n if (article.meta.tags?.length) {\n content += `<dt>Tags</dt><dd>${tagLinks(article.meta.tags, agentId)}</dd>`\n }\n if (article.meta.owner) content += `<dt>Owner</dt><dd>${escapeHtml(article.meta.owner)}</dd>`\n content += `<dt>Created</dt><dd>${escapeHtml(article.meta.created || '—')}</dd>`\n content += `<dt>Updated</dt><dd>${escapeHtml(article.meta.lastUpdated || '—')}</dd>`\n if (article.meta.sources?.length) {\n content += `<dt>Sources</dt><dd>${article.meta.sources.length} entries</dd>`\n }\n content += '</dl>'\n\n content += md(article.content, titleToPath, prefix)\n\n if (inbound.length > 0) {\n content += '<div class=\"backlinks\"><h4>Pages that link here</h4><ul>'\n for (const link of inbound) {\n const linked = store.readArticle(link)\n content += `<li><a href=\"${prefix}/article/${encodeURIComponent(link)}\">${escapeHtml(linked?.meta.title || link)}</a></li>`\n }\n content += '</ul></div>'\n }\n content += `</article>`\n\n return pageLayout(article.meta.title, hubSidebar(agents, `${agentId}/${articlePath}`), content)\n}\n\nfunction hubEntries(hub: WikiHub, allAgents?: AgentWikiSummary[]): string {\n const agents = allAgents || hub.summary()\n const shared = hub.getSharedStore()\n const entries = shared.listEntries()\n\n let content = '<nav class=\"breadcrumb\"><a href=\"/\">Hub</a> <span class=\"sep\">/</span> <span class=\"current\">Entries</span></nav>'\n content += `<div class=\"page-head\"><div><h1>All raw entries</h1><p class=\"page-sub\">Every conversation line that the ingest pipeline captured. Absorb compiles these into typed articles nightly.</p></div></div>`\n\n const byDate = new Map<string, typeof entries>()\n for (const e of entries) {\n const list = byDate.get(e.date) || []\n list.push(e)\n byDate.set(e.date, list)\n }\n\n for (const [date, dateEntries] of [...byDate].reverse()) {\n content += `<div class=\"section-head\"><h2>${date}</h2><span class=\"mono\" style=\"font-size:12px;color:var(--muted)\">${dateEntries.length} entries</span></div>`\n for (const e of dateEntries) {\n content += `<div class=\"entry-card\">\n <div class=\"meta-line\">\n <a href=\"/agent/${encodeURIComponent(e.agentId)}\">${escapeHtml(e.agentId)}</a>\n · via ${escapeHtml(e.source)} · <code>${escapeHtml(e.id)}</code>\n </div>\n <p>${escapeHtml(e.content.slice(0, 400))}${e.content.length > 400 ? \"…\" : \"\"}</p>\n </div>`\n }\n }\n\n return pageLayout(\"All Entries\", hubSidebar(agents), content)\n}\n\nfunction hubSearch(hub: WikiHub, query: string, allAgents?: AgentWikiSummary[]): string {\n const agents = allAgents || hub.summary()\n let content = `<nav class=\"breadcrumb\"><a href=\"/\">Hub</a> <span class=\"sep\">/</span> <span class=\"current\">Search</span></nav>`\n content += `<div class=\"page-head\"><div><h1>“${escapeHtml(query)}”</h1><p class=\"page-sub\">Full-text search across every agent's wiki.</p></div></div>`\n\n let totalResults = 0\n const blocks: string[] = []\n\n for (const agentSummary of agents) {\n const store = hub.getAgentWiki(agentSummary.agentId)\n const results = store.findRelevant(query, undefined, 10)\n\n if (results.length > 0) {\n blocks.push(`<div class=\"section-head\"><h2>${escapeHtml(agentSummary.agentId)}</h2><span class=\"mono\" style=\"font-size:12px;color:var(--muted)\">${results.length} match${results.length === 1 ? '' : 'es'}</span></div>`)\n for (const r of results) {\n const prefix = `/agent/${encodeURIComponent(agentSummary.agentId)}`\n blocks.push(`<div class=\"entry-card\">\n <div class=\"meta-line\">${tagLinks((r.meta.tags || []).slice(0, 3), agentSummary.agentId)}</div>\n <h3><a href=\"${prefix}/article/${encodeURIComponent(r.path)}\">${escapeHtml(r.meta.title)}</a></h3>\n <p>${escapeHtml(r.content.slice(0, 240))}…</p>\n </div>`)\n }\n totalResults += results.length\n }\n }\n content += blocks.join('')\n\n if (totalResults === 0) content += '<p style=\"color:var(--muted);margin-top:24px\">No matching articles found.</p>'\n\n return pageLayout(`Search: ${query}`, hubSidebar(agents), content, query)\n}\n\n/**\n * Hub-wide tag filter. Shows every article tagged with `tag` across all\n * local agents, grouped by agent. Exact-tag match (not BM25).\n */\nfunction hubTagPage(hub: WikiHub, tag: string, allAgents?: AgentWikiSummary[]): string {\n const agents = allAgents || hub.summary()\n let content = `<nav class=\"breadcrumb\"><a href=\"/\">Hub</a> <span class=\"sep\">/</span> <span class=\"current\">Tag</span></nav>`\n content += `<div class=\"page-head\"><div><h1>${escapeHtml(tag)}</h1><p class=\"page-sub\">All articles tagged <span class=\"tag\">${escapeHtml(tag)}</span>, across every agent.</p></div></div>`\n let total = 0\n for (const agentSummary of agents) {\n let store\n try { store = hub.getAgentWiki(agentSummary.agentId) } catch { continue }\n const matches = store.findByTags([tag], undefined, 100)\n if (matches.length === 0) continue\n content += `<div class=\"section-head\"><h2>${escapeHtml(agentSummary.agentId)}</h2><span class=\"mono\" style=\"font-size:12px;color:var(--muted)\">${matches.length}</span></div>`\n for (const a of matches) {\n const prefix = `/agent/${encodeURIComponent(agentSummary.agentId)}`\n content += `<div class=\"entry-card\">\n <div class=\"meta-line\">${tagLinks((a.meta.tags || []).slice(0, 6), agentSummary.agentId)}</div>\n <h3><a href=\"${prefix}/article/${encodeURIComponent(a.path)}\">${escapeHtml(a.meta.title)}</a></h3>\n </div>`\n }\n total += matches.length\n }\n if (total === 0) content += `<p style=\"color:var(--muted);margin-top:24px\">No articles tagged <code>${escapeHtml(tag)}</code>.</p>`\n return pageLayout(`Tag: ${tag}`, hubSidebar(agents), content)\n}\n\n/** Per-agent tag filter — narrows to one agent's corpus. */\nfunction hubAgentTagPage(hub: WikiHub, agentId: string, tag: string, allAgents?: AgentWikiSummary[]): string {\n const agents = allAgents || hub.summary()\n let store\n try { store = hub.getAgentWiki(agentId) } catch {\n return pageLayout(`Tag: ${tag}`, hubSidebar(agents), `<h1>Agent not found: ${escapeHtml(agentId)}</h1>`)\n }\n const matches = store.findByTags([tag], undefined, 100)\n const prefix = `/agent/${encodeURIComponent(agentId)}`\n let content = `<nav class=\"breadcrumb\"><a href=\"/\">Hub</a> <span class=\"sep\">/</span> <a href=\"${prefix}\">${escapeHtml(agentId)}</a> <span class=\"sep\">/</span> <span class=\"current\">${escapeHtml(tag)}</span></nav>`\n content += `<div class=\"page-head\"><div><h1>${escapeHtml(tag)}</h1><p class=\"page-sub\">${matches.length} article${matches.length === 1 ? \"\" : \"s\"} tagged <code>${escapeHtml(tag)}</code> in <b>${escapeHtml(agentId)}</b>.</p></div></div>`\n for (const a of matches) {\n content += `<div class=\"entry-card\">\n <div class=\"meta-line\">${tagLinks((a.meta.tags || []).slice(0, 6), agentId)}</div>\n <h3><a href=\"${prefix}/article/${encodeURIComponent(a.path)}\">${escapeHtml(a.meta.title)}</a></h3>\n </div>`\n }\n return pageLayout(`${agentId} · ${tag}`, hubSidebar(agents), content)\n}\n\n// --- Single Agent Mode ---\n\nfunction agentSidebar(store: WikiStore, agentId: string, activePath?: string): string {\n const index = store.rebuildIndex()\n const byType = groupByDir(index.articles.map(a => ({ title: a.title, path: a.path, tags: a.tags })))\n\n let html = '<div class=\"nav-section\">'\n html += `<div class=\"nav-section-title\">${escapeHtml(agentId)}</div>`\n html += `<a class=\"nav-item${!activePath ? ' active' : ''}\" href=\"/\">Home</a>`\n html += `<a class=\"nav-item\" href=\"/lint\">Health check</a>`\n html += '</div>'\n\n for (const [type, articles] of byType) {\n html += '<div class=\"nav-section\">'\n html += `<div class=\"nav-section-title\">${dirLabel(type)}</div>`\n for (const a of articles) {\n const isActive = a.path === activePath\n html += `<a class=\"nav-item${isActive ? ' active' : ''}\" href=\"/article/${encodeURIComponent(a.path)}\">${escapeHtml(a.title)}</a>`\n }\n html += '</div>'\n }\n\n return html\n}\n\n// --- Server ---\n\nexport function startWikiServer(wikiDir: string, port: number = 4200, agentFilter?: string, peerUrls: string[] = [], mode: \"flat\" | \"graph\" | \"unified\" = \"graph\"): void {\n const hub = new WikiHub(wikiDir, undefined, mode)\n const mesh = peerUrls.length > 0 ? new MeshWikiClient(peerUrls) : null\n\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n const url = new URL(req.url || \"/\", `http://localhost:${port}`)\n const path = decodeURIComponent(url.pathname)\n\n let html: string | null = null\n let status = 200\n\n try {\n // Handle remote article fetch: /remote/:peerIdx/:agentId/article/:path\n if (path.startsWith(\"/remote/\") && mesh) {\n const parts = path.slice(\"/remote/\".length).split(\"/article/\")\n if (parts.length === 2) {\n const [peerAgent, articlePath] = parts\n const slashIdx = peerAgent.indexOf(\"/\")\n const peerUrl = decodeURIComponent(peerAgent.slice(0, slashIdx))\n const agentId = peerAgent.slice(slashIdx + 1)\n\n const article = await mesh.getRemoteArticle(peerUrl, agentId, articlePath)\n if (article) {\n const remoteAgents = await mesh.getRemoteAgents()\n const allAgents = [...hub.summary(), ...remoteAgents.map(r => ({ ...r, agentId: `${r.agentId} @${r.nodeId}` }))]\n\n let content = `<div class=\"breadcrumb\"><a href=\"/\">Hub</a> / <span class=\"tag\">remote</span> ${escapeHtml(agentId)} @ ${escapeHtml(peerUrl)}</div>`\n content += `<h1>${escapeHtml(article.meta.title)}</h1>`\n content += '<dl class=\"meta\">'\n content += `<dt>Tags</dt><dd>${(article.meta.tags||[]).map(t => `<span class=\"tag\">${t}</span>`).join(\" \")}</dd>`\n content += `<dt>Owner</dt><dd>${escapeHtml(article.meta.owner)}</dd>`\n content += `<dt>Source</dt><dd><span class=\"tag\">remote</span> ${escapeHtml(peerUrl)}</dd>`\n content += `<dt>Updated</dt><dd>${article.meta.lastUpdated}</dd>`\n content += '</dl>'\n\n const titleToPath = new Map<string, string>()\n content += md(article.content, titleToPath)\n\n html = pageLayout(article.meta.title, hubSidebar(allAgents), content)\n }\n }\n }\n\n if (!html && agentFilter) {\n // Single agent mode\n const store = hub.getAgentWiki(agentFilter)\n\n if (path === \"/\" || path === \"\") {\n const index = store.rebuildIndex()\n const entries = hub.getAgentEntries(agentFilter)\n let content = `<h1>${escapeHtml(agentFilter)}</h1>`\n content += '<div class=\"stats\">'\n content += `<div class=\"stat-card\"><div class=\"number\">${index.articles.length}</div><div class=\"label\">Articles</div></div>`\n content += `<div class=\"stat-card\"><div class=\"number\">${entries.length}</div><div class=\"label\">Entries</div></div>`\n content += '</div>'\n if (index.articles.length > 0) {\n content += '<h2>Articles</h2><table><tr><th>Title</th><th>Type</th><th>Updated</th></tr>'\n for (const a of index.articles) {\n content += `<tr><td><a href=\"/article/${encodeURIComponent(a.path)}\">${escapeHtml(a.title)}</a></td><td><span class=\"tag\">${(a.tags||[]).slice(0,3).join(\", \")}</span></td><td>${a.lastUpdated || \"\"}</td></tr>`\n }\n content += '</table>'\n }\n html = pageLayout(agentFilter, agentSidebar(store, agentFilter), content)\n } else if (path.startsWith(\"/article/\")) {\n const articlePath = path.slice(\"/article/\".length)\n const article = store.readArticle(articlePath)\n if (article) {\n const index = store.rebuildIndex()\n const titleToPath = new Map<string, string>()\n for (const a of index.articles) titleToPath.set(a.title, a.path)\n let content = `<h1>${escapeHtml(article.meta.title)}</h1>`\n content += '<dl class=\"meta\">'\n content += `<dt>Tags</dt><dd>${(article.meta.tags||[]).map(t => `<span class=\"tag\">${t}</span>`).join(\" \")}</dd>`\n content += `<dt>Updated</dt><dd>${article.meta.lastUpdated}</dd>`\n if (article.meta.sources?.length) content += `<dt>Sources</dt><dd>${article.meta.sources.length} entries</dd>`\n content += '</dl>'\n content += md(article.content, titleToPath)\n html = pageLayout(article.meta.title, agentSidebar(store, agentFilter, articlePath), content)\n }\n } else if (path === \"/lint\") {\n const issues = store.lint()\n let content = '<h1>Health Check</h1>'\n if (issues.length === 0) { content += '<p style=\"color:green;\">No issues.</p>' }\n else {\n content += `<table><tr><th>Type</th><th>Article</th><th>Issue</th></tr>`\n for (const i of issues) content += `<tr><td><span class=\"tag\">${i.type}</span></td><td>${escapeHtml(i.article)}</td><td>${escapeHtml(i.message)}</td></tr>`\n content += '</table>'\n }\n html = pageLayout(\"Health Check\", agentSidebar(store, agentFilter), content)\n } else if (path === \"/search\") {\n const q = url.searchParams.get(\"q\") || \"\"\n const results = store.findRelevant(q, undefined, 20)\n let content = `<h1>Search: \"${escapeHtml(q)}\"</h1>`\n for (const r of results) {\n content += `<div class=\"entry-card\"><h3><a href=\"/article/${encodeURIComponent(r.path)}\">${escapeHtml(r.meta.title)}</a></h3><p>${escapeHtml(r.content.slice(0, 200))}...</p></div>`\n }\n if (results.length === 0) content += '<p>No results.</p>'\n html = pageLayout(`Search: ${q}`, agentSidebar(store, agentFilter), content)\n } else if (path.startsWith(\"/tag/\")) {\n const tag = decodeURIComponent(path.slice(\"/tag/\".length))\n const matches = store.findByTags([tag], undefined, 100)\n let content = `<h1>Tag: <a class=\"tag\" href=\"#\">${escapeHtml(tag)}</a></h1>`\n content += `<p>${matches.length} article${matches.length === 1 ? \"\" : \"s\"} tagged <code>${escapeHtml(tag)}</code></p>`\n for (const a of matches) {\n content += `<div class=\"entry-card\"><h3><a href=\"/article/${encodeURIComponent(a.path)}\">${escapeHtml(a.meta.title)}</a></h3><div class=\"meta-line\">${tagLinks((a.meta.tags || []).slice(0, 6))}</div></div>`\n }\n if (matches.length === 0) content += '<p>No articles with this tag.</p>'\n html = pageLayout(`Tag: ${tag}`, agentSidebar(store, agentFilter), content)\n }\n } else {\n // Hub mode — merge local + remote agents\n const remoteAgents = mesh ? await mesh.getRemoteAgents() : []\n const localAgents = hub.summary()\n // Merge: prefer whichever has more articles (local or remote)\n const localMap = new Map(localAgents.map(a => [a.agentId, a]))\n const allAgents: AgentWikiSummary[] = []\n const seen = new Set<string>()\n\n for (const local of localAgents) {\n const remote = remoteAgents.find(r => r.agentId === local.agentId)\n if (remote && remote.totalArticles > local.totalArticles) {\n // Remote has more articles — merge: keep remote articles, combine entry counts\n allAgents.push({\n ...remote,\n totalEntries: Math.max(local.totalEntries, remote.totalEntries),\n unabsorbed: Math.max(local.unabsorbed, remote.unabsorbed),\n })\n } else {\n allAgents.push(local)\n }\n seen.add(local.agentId)\n }\n // Add remote-only agents\n for (const remote of remoteAgents) {\n if (!seen.has(remote.agentId)) {\n allAgents.push(remote)\n seen.add(remote.agentId)\n }\n }\n\n if (path === \"/\" || path === \"\") {\n html = hubHome(hub, allAgents, remoteAgents)\n } else if (path === \"/entries\") {\n html = hubEntries(hub, allAgents)\n } else if (path === \"/search\") {\n html = hubSearch(hub, url.searchParams.get(\"q\") || \"\", allAgents)\n } else if (path.startsWith(\"/tag/\")) {\n html = hubTagPage(hub, decodeURIComponent(path.slice(\"/tag/\".length)), allAgents)\n } else if (path.match(/^\\/agent\\/[^/]+\\/tag\\/.+/)) {\n const m = path.match(/^\\/agent\\/([^/]+)\\/tag\\/(.+)$/)!\n html = hubAgentTagPage(hub, decodeURIComponent(m[1]), decodeURIComponent(m[2]), allAgents)\n } else if (path.startsWith(\"/agent/\")) {\n const rest = path.slice(\"/agent/\".length)\n const slashIdx = rest.indexOf(\"/article/\")\n if (slashIdx === -1) {\n // Agent overview\n html = hubAgentOverview(hub, rest, allAgents)\n } else {\n // Agent article\n const agentId = rest.slice(0, slashIdx)\n const articlePath = rest.slice(slashIdx + \"/article/\".length)\n html = hubArticlePage(hub, agentId, articlePath, allAgents)\n\n // If not found locally, try remote peers\n if (!html && mesh) {\n const remote = remoteAgents.find(r => r.agentId === agentId)\n if (remote) {\n const article = await mesh.getRemoteArticle(remote.peerUrl, agentId, articlePath)\n if (article) {\n let content = `<div class=\"breadcrumb\"><a href=\"/\">Hub</a> / <span class=\"tag\">remote @ ${escapeHtml(remote.nodeId)}</span> / ${escapeHtml(agentId)}</div>`\n content += `<h1>${escapeHtml(article.meta.title)}</h1>`\n content += '<dl class=\"meta\">'\n content += `<dt>Tags</dt><dd>${(article.meta.tags||[]).map(t => `<span class=\"tag\">${t}</span>`).join(\" \")}</dd>`\n content += `<dt>Source</dt><dd><span class=\"tag\">remote</span> ${escapeHtml(remote.nodeId)}</dd>`\n content += `<dt>Updated</dt><dd>${article.meta.lastUpdated}</dd>`\n content += '</dl>'\n content += md(article.content, new Map())\n html = pageLayout(article.meta.title, hubSidebar(allAgents), content)\n }\n }\n }\n }\n }\n }\n\n if (!html) {\n status = 404\n const sidebar = agentFilter\n ? agentSidebar(hub.getAgentWiki(agentFilter), agentFilter)\n : hubSidebar(hub.summary())\n html = pageLayout(\"Not Found\", sidebar, \"<h1>Page not found</h1>\")\n }\n } catch (err: any) {\n status = 500\n html = pageLayout(\"Error\", \"\", `<h1>Error</h1><pre>${escapeHtml(err.message)}</pre>`)\n }\n\n res.writeHead(status, { \"Content-Type\": \"text/html; charset=utf-8\" })\n res.end(html)\n })\n\n server.listen(port)\n}\n","import type { AgentWikiSummary } from \"./hub\"\nimport type { WikiArticle } from \"./types\"\n\n/**\n * Fetches wiki data from mesh peers over HTTP.\n * Each peer exposes /wiki/agents, /wiki/entries, /wiki/articles.\n */\nexport class MeshWikiClient {\n private peers: Array<{ url: string; nodeId?: string }>\n private cache: Map<string, { data: any; ts: number }> = new Map()\n private ttl = 30_000 // 30s cache\n\n constructor(peerUrls: string[]) {\n this.peers = peerUrls.map(url => ({ url: url.replace(/\\/$/, \"\") }))\n }\n\n /**\n * Get agent summaries from all peers.\n * Returns remote summaries with nodeId attached.\n */\n async getRemoteAgents(): Promise<Array<AgentWikiSummary & { nodeId: string; peerUrl: string }>> {\n const results: Array<AgentWikiSummary & { nodeId: string; peerUrl: string }> = []\n\n await Promise.all(this.peers.map(async (peer) => {\n try {\n const data = await this.fetchJson(`${peer.url}/wiki/agents`)\n peer.nodeId = data.nodeId\n for (const agent of (data.agents || [])) {\n if (agent.totalEntries > 0 || agent.totalArticles > 0) {\n results.push({ ...agent, nodeId: data.nodeId, peerUrl: peer.url })\n }\n }\n } catch { /* peer unreachable */ }\n }))\n\n return results\n }\n\n /**\n * Get articles for a specific agent from a specific peer.\n */\n async getRemoteArticles(peerUrl: string, agentId: string): Promise<Array<{\n path: string; title: string; tags: string[]; lastUpdated?: string; sources?: string[]\n }>> {\n try {\n const data = await this.fetchJson(`${peerUrl}/wiki/articles?agent=${encodeURIComponent(agentId)}`)\n return data.articles || []\n } catch {\n return []\n }\n }\n\n /**\n * Fetch a specific article's content from a peer.\n */\n async getRemoteArticle(peerUrl: string, agentId: string, articlePath: string): Promise<WikiArticle | null> {\n try {\n const data = await this.fetchJson(\n `${peerUrl}/wiki/article?agent=${encodeURIComponent(agentId)}&path=${encodeURIComponent(articlePath)}`\n )\n return {\n meta: {\n title: data.title,\n tags: data.tags || [],\n owner: data.owner,\n access: \"public\",\n created: data.created,\n lastUpdated: data.lastUpdated,\n sources: data.sources || [],\n },\n content: data.content,\n path: data.path,\n }\n } catch {\n return null\n }\n }\n\n private async fetchJson(url: string): Promise<any> {\n const cached = this.cache.get(url)\n if (cached && Date.now() - cached.ts < this.ttl) return cached.data\n\n const res = await fetch(url, { signal: AbortSignal.timeout(5000) })\n if (!res.ok) throw new Error(`HTTP ${res.status}`)\n const data = await res.json()\n this.cache.set(url, { data, ts: Date.now() })\n return data\n }\n}\n","import type { WikiMode } from \"./hub\"\n\n/**\n * Farzapedia-faithful absorb prompt.\n *\n * Replaces the legacy three-mode design (flat/graph/unified) with one prompt\n * that mirrors what Karpathy and Farza describe: article `type` is the\n * organizational spine, `[[wikilinks]]` are the navigation surface, tags are\n * a secondary hint. The LLM chooses paths and cross-references; it does not\n * produce a sprawling per-article tag cloud.\n *\n * The mode parameter is kept in the signature for backwards compatibility but\n * all values resolve to the same prompt — retained callers (hub.ts, wiki CLI)\n * still pass a mode but it no longer changes behavior.\n */\nexport function buildAbsorbPrompt(\n _mode: WikiMode,\n agentId: string,\n worldview: string,\n existingArticles: Array<{ title: string; path: string; type?: string; tags?: string[] }>,\n entryTexts: string,\n entryCount: number,\n): string {\n return buildFarzapediaPrompt(agentId, worldview, existingArticles, entryTexts, entryCount)\n}\n\nfunction buildFarzapediaPrompt(\n agentId: string,\n worldview: string,\n existingArticles: Array<{ title: string; path: string; type?: string; tags?: string[] }>,\n entryTexts: string,\n entryCount: number,\n): string {\n const worldviewSection = worldview ? `\\n## Worldview\\n\\n${worldview}\\n` : \"\"\n\n // Group the existing index by type so the LLM sees the structure.\n const byType = new Map<string, typeof existingArticles>()\n for (const a of existingArticles) {\n const t = a.type || \"untyped\"\n const list = byType.get(t) || []\n list.push(a)\n byType.set(t, list)\n }\n const existingList = existingArticles.length === 0 ? \"\" :\n \"\\n## Existing Articles (the current catalog)\\n\\n\" +\n Array.from(byType.entries()).sort()\n .map(([type, arr]) =>\n `**${type}**\\n` +\n arr.sort((x, y) => x.title.localeCompare(y.title))\n .map(a => `- [[${a.title}]] — ${a.path}`)\n .join(\"\\n\")\n ).join(\"\\n\\n\") + \"\\n\"\n\n return `You are compiling a personal wiki for the \"${agentId}\" agent in the Karpathy / Farzapedia pattern.\n\n## The Pattern (read this first — it shapes every decision below)\n\nThe wiki is a compounding knowledge base of interlinked markdown articles that a future LLM will read by walking the graph, NOT by bag-of-words search. Your job is to produce articles that another agent can navigate via \\`type\\` + wikilinks. If the wikilinks don't form a coherent graph, the wiki is useless regardless of how many tags you add.\n\n**Three rules, in priority order:**\n\n1. **\\`type\\` is the organizational spine.** Every article has exactly one of: \\`person | project | place | concept | event | decision | pattern\\`. Choose the type BEFORE writing; if you can't pick one, the article probably isn't needed.\n2. **\\`related\\` is the navigation surface.** Every article cross-references 2–5 other articles via \\`[[Article Title]]\\` wikilinks in the body AND lists them in the \\`related\\` frontmatter field. Links the reader could follow to learn more.\n3. **Tags are a secondary hint, not a retrieval spine.** 2–4 specific tags max. Do NOT tag aggressively. Do NOT tag with dates unless the article is an \\`event\\`. Do NOT tag with generic terms (\"deploy\", \"work\") that will match half the corpus.\n\n## Path convention\n\nPath reflects type: \\`<type>s/<slug>.md\\` where slug is a kebab-case title.\n\n- People: \\`people/anis-marrouchi.md\\`\n- Projects: \\`projects/mtgl-system-v2.md\\`\n- Concepts: \\`concepts/staging-deployment.md\\`\n- Events: \\`events/YYYY-MM-DD-<slug>.md\\` (date in path)\n- Decisions: \\`decisions/<slug>.md\\`\n- Patterns: \\`patterns/<slug>.md\\`\n- Places: \\`places/<slug>.md\\`\n\n## How to process entries\n\nFor each of the ${entryCount} raw entries below, ask in this order:\n\n1. **Does it extend an existing article?** If a person/project/concept mentioned in the entry already has an article in the catalog, produce an UPDATE with the full merged content. Prefer merging over proliferating.\n2. **Does it deserve a new article?** Only if the subject is a persistent entity (a person, a project, a recurring concept, a specific event/decision) that future queries will need to find. Not every conversation deserves an article.\n3. **Does it belong in an existing \\`event\\` or \\`decision\\`?** Most work entries fold into one of these.\n4. **Can you skip it?** If the entry is small talk, a transient status ping, or already covered elsewhere — skip. The wiki is curated, not exhaustive.\n\n## Writing standards\n\n- **Wikipedia-style, flat, factual, encyclopedic.** This is the agent's knowledge, not a diary. Write about the *role* of the entity in our work, not a product description.\n- **Synthesize, don't quote.** At most 2 short quoted lines per article.\n- **Organize by theme, not chronology.** An article about a person lists what they do, who they work with, how they prefer to be contacted — not a log of every interaction.\n- **Length: 20–100 lines.** Articles exceeding 100 lines should split into multiple type-specific articles.\n- **Every paragraph earns its place.** Cut narrative filler. If you can remove a sentence without losing a fact, remove it.\n\n## Wikilink discipline\n\n- Use \\`[[Article Title]]\\` **inside the body** every time another tracked entity is referenced.\n- List those same targets in the \\`related\\` frontmatter field.\n- If you reference something that has no article yet (\\`[[New Thing]]\\`), add \"New Thing\" to the output \\`gaps\\` array so the next pass can create it.\n\n## Article frontmatter (exact shape — do not invent fields)\n\n\\`\\`\\`yaml\n---\ntitle: \"Article Title\"\ntype: person | project | place | concept | event | decision | pattern\nrelated: [\"Other Article\", \"Another Article\"]\ntags: [\"2-4-specific-tags\", \"no-dates-unless-event\"]\nowner: ${agentId}\naccess: public | shared | private\ncreated: YYYY-MM-DD\nlast_updated: YYYY-MM-DD\nsources: [\"entry-id-1\", \"entry-id-2\"]\n---\n\\`\\`\\`\n\nAccess guidance: default \\`public\\`; \\`private\\` only for sensitive credentials or agent-specific learnings; \\`shared\\` with specific agent IDs when the article matters only to a subset.\n${worldviewSection}${existingList}\n## Gap Detection\n\nAfter compiling, populate a \\`gaps\\` array: wikilink targets you referenced but for which no article exists yet. Be specific:\n\n- Good: \"Karim Rahmouni — coach for Tunis Padel club, mentioned twice but no \\`people/\\` article\"\n- Bad: \"We need more content about deployments\"\n\n## Output — valid JSON only, no markdown fencing\n\n\\`\\`\\`\n{\n \"articles\": [\n {\n \"path\": \"projects/mtgl-system-v2.md\",\n \"title\": \"MTGL System V2\",\n \"type\": \"project\",\n \"related\": [\"Anis Marrouchi\", \"Laravel\", \"Staging Deployment\"],\n \"tags\": [\"mtgl\", \"laravel\", \"react\"],\n \"content\": \"MTGL System V2 is [[Anis Marrouchi]]'s production Laravel + React app for …\",\n \"sources\": [\"entry-id-1\", \"entry-id-2\"]\n }\n ],\n \"gaps\": [\n \"Karim Rahmouni — Tunis Padel coach, mentioned in entries but no people/ article\"\n ]\n}\n\\`\\`\\`\n\nENTRIES (${entryCount}):\n\n${entryTexts}`\n}\n","import { Command } from \"commander\"\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 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://clawd.noqta.tn: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→noqta 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\nfunction extractJson(text: string): any {\n if (!text) return null\n try { return JSON.parse(text) } catch {}\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/)\n if (fenced) { try { return JSON.parse(fenced[1]) } catch {} }\n const start = text.indexOf(\"{\")\n if (start < 0) return null\n let depth = 0\n for (let i = start; i < text.length; i++) {\n if (text[i] === \"{\") depth++\n else if (text[i] === \"}\") {\n depth--\n if (depth === 0) { try { return JSON.parse(text.slice(start, i + 1)) } catch { return null } }\n }\n }\n return null\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// subcommands want to regenerate pathId for display.\nvoid hashPath\nvoid existsSync\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { ProcedureStore } from \"@/procedures\"\n\n// --- agentx procedure — SOP definitions (foundation) ---\n//\n// v1: list / add / show. Delta extraction (per-run one-liner deltas against\n// the SOP, cheap O(runs)) is deferred. The data model lives here so those\n// later features have a stable shape to write against.\n\nexport const procedure = new Command()\n .name(\"procedure\")\n .description(\"procedures (SOPs) — list, add, show · delta extraction coming later\")\n\nprocedure\n .command(\"list\")\n .description(\"list all procedures with their trigger line\")\n .action(() => {\n const store = new ProcedureStore()\n const items = store.list()\n if (!items.length) {\n console.log(chalk.dim(\" no procedures yet. Add one with: agentx procedure add\"))\n return\n }\n console.log()\n for (const p of items) {\n console.log(` ${chalk.cyan(p.meta.id)} ${chalk.bold(p.meta.title)}`)\n console.log(` ${chalk.dim(\"trigger:\")} ${p.meta.trigger}`)\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-clawd)\")\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\")\n .action((id: string) => {\n const store = new ProcedureStore()\n const p = store.get(id)\n if (!p) {\n console.log(chalk.yellow(` no procedure matches \"${id}\". Try: agentx procedure list`))\n process.exit(1)\n }\n console.log()\n console.log(chalk.bold(` ${p!.meta.title}`) + chalk.dim(` (${p!.meta.id})`))\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.related?.length) console.log(chalk.dim(` related: ${p!.meta.related.join(\", \")}`))\n console.log()\n console.log(p!.body)\n console.log()\n })\n","import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from \"fs\"\nimport { resolve, relative } from \"path\"\nimport { procedureMetaSchema, type Procedure, type ProcedureMeta } from \"./types\"\n\n// --- ProcedureStore ---\n// Plain-file persistence (same convention as .agentx/wiki/ and .agentx/graph/).\n// One markdown file per procedure. Frontmatter = yaml-ish name:value lines\n// (arrays are JSON). This intentionally avoids pulling in a yaml lib — the\n// surface is small and the wiki store already uses the same hand-parser.\n\nexport interface ProcedureStoreOptions {\n baseDir?: string\n}\n\nfunction parseFrontmatter(raw: string): { meta: Record<string, any>; body: string } {\n const m = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/)\n if (!m) return { meta: {}, body: raw }\n const meta: Record<string, any> = {}\n for (const line of m[1].split(\"\\n\")) {\n const kv = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*):\\s*(.*)$/)\n if (!kv) continue\n const key = kv[1]\n let val = kv[2].trim()\n if (val.startsWith(\"[\") && val.endsWith(\"]\")) {\n try { meta[key] = JSON.parse(val); continue } catch { /* fallthrough */ }\n meta[key] = val.slice(1, -1).split(\",\").map(s => s.trim().replace(/^\"(.*)\"$/, \"$1\")).filter(Boolean)\n continue\n }\n if (val.startsWith('\"') && val.endsWith('\"')) val = val.slice(1, -1)\n meta[key] = val\n }\n return { meta, body: m[2] }\n}\n\nfunction serializeFrontmatter(meta: ProcedureMeta): string {\n const lines: string[] = [\"---\"]\n lines.push(`id: ${meta.id}`)\n lines.push(`title: \"${meta.title.replace(/\"/g, '\\\\\"')}\"`)\n lines.push(`trigger: \"${meta.trigger.replace(/\"/g, '\\\\\"')}\"`)\n if (meta.inputs?.length) lines.push(`inputs: ${JSON.stringify(meta.inputs)}`)\n if (meta.expected) lines.push(`expected: \"${meta.expected.replace(/\"/g, '\\\\\"')}\"`)\n if (meta.kpis?.length) lines.push(`kpis: ${JSON.stringify(meta.kpis)}`)\n if (meta.owner) lines.push(`owner: ${meta.owner}`)\n if (meta.tags?.length) lines.push(`tags: ${JSON.stringify(meta.tags)}`)\n if (meta.related?.length) lines.push(`related: ${JSON.stringify(meta.related)}`)\n if (meta.created) lines.push(`created: ${meta.created}`)\n if (meta.updated) lines.push(`updated: ${meta.updated}`)\n lines.push(\"---\")\n return lines.join(\"\\n\")\n}\n\nexport class ProcedureStore {\n readonly baseDir: string\n\n constructor(opts: ProcedureStoreOptions = {}) {\n this.baseDir = opts.baseDir ?? resolve(process.cwd(), \".agentx/procedures\")\n mkdirSync(this.baseDir, { recursive: true })\n }\n\n private pathFor(id: string): string {\n return resolve(this.baseDir, `${id}.md`)\n }\n\n list(): Procedure[] {\n if (!existsSync(this.baseDir)) return []\n const out: Procedure[] = []\n for (const entry of readdirSync(this.baseDir, { withFileTypes: true })) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\") || entry.name.startsWith(\"_\")) continue\n const full = resolve(this.baseDir, entry.name)\n const raw = readFileSync(full, \"utf-8\")\n const { meta, body } = parseFrontmatter(raw)\n const parsed = procedureMetaSchema.safeParse({\n ...meta,\n inputs: meta.inputs || [],\n kpis: meta.kpis || [],\n tags: meta.tags || [],\n related: meta.related || [],\n })\n if (!parsed.success) continue\n out.push({ meta: parsed.data, body: body.trim(), path: relative(this.baseDir, full) })\n }\n return out.sort((a, b) => a.meta.id.localeCompare(b.meta.id))\n }\n\n get(id: string): Procedure | null {\n const p = this.pathFor(id)\n if (!existsSync(p)) return null\n const raw = readFileSync(p, \"utf-8\")\n const { meta, body } = parseFrontmatter(raw)\n const parsed = procedureMetaSchema.safeParse({\n ...meta,\n inputs: meta.inputs || [],\n kpis: meta.kpis || [],\n tags: meta.tags || [],\n related: meta.related || [],\n })\n if (!parsed.success) return null\n return { meta: parsed.data, body: body.trim(), path: relative(this.baseDir, p) }\n }\n\n add(meta: ProcedureMeta, body: string): Procedure {\n const parsed = procedureMetaSchema.parse({\n ...meta,\n created: meta.created || new Date().toISOString().slice(0, 10),\n updated: new Date().toISOString().slice(0, 10),\n })\n const p = this.pathFor(parsed.id)\n if (existsSync(p)) throw new Error(`Procedure already exists: ${parsed.id}`)\n writeFileSync(p, serializeFrontmatter(parsed) + \"\\n\\n\" + body.trim() + \"\\n\")\n return { meta: parsed, body: body.trim(), path: relative(this.baseDir, p) }\n }\n\n update(id: string, patch: Partial<ProcedureMeta>, newBody?: string): Procedure {\n const existing = this.get(id)\n if (!existing) throw new Error(`Procedure not found: ${id}`)\n const merged = procedureMetaSchema.parse({\n ...existing.meta,\n ...patch,\n id: existing.meta.id, // immutable\n updated: new Date().toISOString().slice(0, 10),\n })\n const body = newBody !== undefined ? newBody : existing.body\n writeFileSync(this.pathFor(id), serializeFrontmatter(merged) + \"\\n\\n\" + body.trim() + \"\\n\")\n return { meta: merged, body: body.trim(), path: existing.path }\n }\n}\n","import { z } from \"zod\"\n\n// --- Procedures (foundation) ---\n//\n// Karpathy-style SOPs as first-class artifacts. Each procedure is a small\n// typed doc with a trigger, inputs, ordered steps, expected output, and KPIs.\n// v1 ships definition + list/add/show — the \"delta extraction\" flow\n// (agents emit one-line deltas when they run a procedure, cheap O(runs)\n// instead of O(entries × articles)) is deferred.\n//\n// Shape on disk (.agentx/procedures/):\n// <slug>.md — frontmatter (id/title/trigger/inputs/expected/kpis)\n// + markdown body (steps + notes)\n// _runs/<run-id>.json — future: one per procedure run, holds deltas\n\nexport const procedureMetaSchema = z.object({\n id: z.string().regex(/^[a-z0-9][a-z0-9_-]*$/, \"procedure id must be lower-kebab\"),\n title: z.string().min(1),\n trigger: z.string().min(1, \"procedures must describe when they apply\"),\n inputs: z.array(z.string()).default([]),\n expected: z.string().optional(),\n kpis: z.array(z.string()).default([]),\n owner: z.string().optional(),\n tags: z.array(z.string()).default([]),\n created: z.string().optional(),\n updated: z.string().optional(),\n /** Related procedures (ids) or wiki articles (titles). Drives the graph. */\n related: z.array(z.string()).default([]),\n})\n\nexport type ProcedureMeta = z.infer<typeof procedureMetaSchema>\n\nexport interface Procedure {\n meta: ProcedureMeta\n /** Markdown body — typically a \"## Steps\" section and optional notes. */\n body: string\n /** Relative path within the procedures root, e.g. \"deploy-clawd.md\". */\n path: string\n}\n","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { resolve } from \"path\"\nimport { existsSync, readFileSync } from \"fs\"\nimport { RunStore, WorkflowStore, lintWorkflow, workflowSchema } from \"@/workflows\"\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\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 console.log(` ${chalk.cyan(wf.id)} ${chalk.bold(wf.title)} ${chalk.dim(`v${wf.version}`)}`)\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 .action((id: 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 console.log(JSON.stringify(wf, null, 2))\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 raw = JSON.parse(readFileSync(path, \"utf-8\"))\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 // Lint-level checks\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 console.log(chalk.red(` parse error: ${e.message}`))\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(\"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>\")\n .description(\"manually trigger a workflow (trigger.manual by default; add --force for any)\")\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(\"--daemon <url>\", \"daemon API base URL\", \"http://127.0.0.1:18800\")\n .action(async (id: 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 const url = `${String(opts.daemon).replace(/\\/$/, \"\")}/workflows/${encodeURIComponent(id)}/run`\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 console.log(chalk.green(` ✓ run started: ${body.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\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","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { ActorStore } from \"@/actors/store\"\nimport type { ActorChannel, Actor, Role } from \"@/actors/types\"\n\n// --- agentx actor / role — identities for BPM workflows ---\n//\n// Actors are the humans a userTask node can be assigned to. Each actor\n// carries one or more channel handles (telegram user id, whatsapp phone,\n// slack member id, email address) so the task renderer knows where to\n// deliver the notification.\n//\n// Roles group actors together with an assignment strategy. A userTask\n// assigned to a role fans out (or round-robins, etc.) to its members.\n//\n// CLI:\n// agentx actor add <id> --name \"Alice\" --telegram 12345 --email a@co\n// agentx actor list\n// agentx actor show actor:alice\n// agentx actor remove actor:alice\n//\n// agentx role create <id> --name \"Reviewers\" --strategy first-available\n// agentx role grant <role-id> <actor-id>\n// agentx role revoke <role-id> <actor-id>\n// agentx role list\n// agentx role show role:reviewers\n\nexport const actor = new Command()\n .name(\"actor\")\n .description(\"manage actors (humans) that can be assigned to workflow userTasks\")\n\nactor\n .command(\"add\")\n .description(\"add a new actor\")\n .argument(\"<id>\", \"actor id (e.g. alice; 'actor:' prefix is added if missing)\")\n .requiredOption(\"--name <name>\", \"human-readable name\")\n .option(\"--email <email>\", \"email address\")\n .option(\"--telegram <handle>\", \"Telegram user id (numeric)\")\n .option(\"--whatsapp <phone>\", \"WhatsApp phone in E.164 (no +)\")\n .option(\"--slack <memberId>\", \"Slack member id\")\n .option(\"--discord <userId>\", \"Discord user id\")\n .option(\"--timezone <tz>\", \"IANA timezone, e.g. Africa/Tunis\")\n .option(\"--prefer <channel>\", \"mark this channel as preferred for task notifications\", \"\")\n .action((rawId: string, opts: {\n name: string; email?: string\n telegram?: string; whatsapp?: string; slack?: string; discord?: string\n timezone?: string; prefer?: string\n }) => {\n const id = rawId.startsWith(\"actor:\") ? rawId : `actor:${rawId}`\n const store = new ActorStore()\n if (store.getActor(id)) {\n console.error(chalk.red(` actor \"${id}\" already exists. Use 'actor remove' first.`))\n process.exitCode = 1\n return\n }\n const channels: ActorChannel[] = []\n const add = (ch: ActorChannel[\"channel\"], handle?: string) => {\n if (!handle) return\n channels.push({ channel: ch, handle, preferredForTasks: opts.prefer === ch || undefined })\n }\n add(\"telegram\", opts.telegram)\n add(\"whatsapp\", opts.whatsapp)\n add(\"slack\", opts.slack)\n add(\"discord\", opts.discord)\n if (opts.email) add(\"email\", opts.email)\n if (channels.length === 0) {\n console.error(chalk.red(\" at least one channel handle is required (--telegram, --whatsapp, --slack, --discord, --email)\"))\n process.exitCode = 1\n return\n }\n const a: Actor = {\n id,\n name: opts.name,\n email: opts.email,\n channels,\n timezone: opts.timezone,\n }\n const saved = store.saveActor(a)\n console.log(chalk.green(` ✓ actor \"${saved.id}\" saved (${saved.channels.length} channel${saved.channels.length === 1 ? \"\" : \"s\"})`))\n })\n\nactor\n .command(\"list\")\n .description(\"list all actors\")\n .action(() => {\n const store = new ActorStore()\n const actors = store.listActors()\n if (!actors.length) {\n console.log(chalk.dim(\" no actors yet. Try: agentx actor add alice --name 'Alice' --telegram 12345\"))\n return\n }\n console.log()\n for (const a of actors) {\n const channels = a.channels.map((c) => `${c.channel}:${c.handle}${c.preferredForTasks ? \"*\" : \"\"}`).join(\", \")\n console.log(` ${chalk.cyan(a.id.padEnd(24))} ${chalk.bold(a.name)}`)\n console.log(` ${chalk.dim(channels)}`)\n }\n console.log()\n console.log(chalk.dim(` ${actors.length} actor${actors.length === 1 ? \"\" : \"s\"}. * = preferred for tasks.`))\n })\n\nactor\n .command(\"show\")\n .description(\"print full JSON for an actor\")\n .argument(\"<id>\", \"actor id (with or without 'actor:' prefix)\")\n .action((rawId: string) => {\n const id = rawId.startsWith(\"actor:\") ? rawId : `actor:${rawId}`\n const store = new ActorStore()\n const a = store.getActor(id)\n if (!a) { console.error(chalk.red(` actor \"${id}\" not found`)); process.exitCode = 1; return }\n console.log(JSON.stringify(a, null, 2))\n })\n\nactor\n .command(\"remove\")\n .alias(\"rm\")\n .description(\"remove an actor (does not clean up role memberships)\")\n .argument(\"<id>\", \"actor id\")\n .action((rawId: string) => {\n const id = rawId.startsWith(\"actor:\") ? rawId : `actor:${rawId}`\n const store = new ActorStore()\n if (!store.deleteActor(id)) { console.error(chalk.red(` actor \"${id}\" not found`)); process.exitCode = 1; return }\n console.log(chalk.green(` ✓ actor \"${id}\" removed`))\n })\n\n// --- roles ---\n\nexport const role = new Command()\n .name(\"role\")\n .description(\"manage roles (groups of actors) for workflow userTasks\")\n\nrole\n .command(\"create\")\n .description(\"create a new role\")\n .argument(\"<id>\", \"role id (e.g. reviewers; 'role:' prefix is added if missing)\")\n .requiredOption(\"--name <name>\", \"human-readable name\")\n .option(\"--strategy <strategy>\", \"first-available | round-robin | all | manager-of\", \"first-available\")\n .action((rawId: string, opts: { name: string; strategy: string }) => {\n const id = rawId.startsWith(\"role:\") ? rawId : `role:${rawId}`\n const store = new ActorStore()\n if (store.getRole(id)) { console.error(chalk.red(` role \"${id}\" already exists`)); process.exitCode = 1; return }\n const strategy = opts.strategy as Role[\"assignmentStrategy\"]\n const saved = store.saveRole({\n id, name: opts.name, members: [],\n assignmentStrategy: strategy,\n rotationCursor: 0,\n })\n console.log(chalk.green(` ✓ role \"${saved.id}\" created (strategy: ${saved.assignmentStrategy})`))\n })\n\nrole\n .command(\"grant\")\n .description(\"add an actor (or nested role) to a role's members\")\n .argument(\"<roleId>\", \"target role\")\n .argument(\"<memberId>\", \"actor:<id> or role:<id>\")\n .action((rawRole: string, memberRaw: string) => {\n const roleId = rawRole.startsWith(\"role:\") ? rawRole : `role:${rawRole}`\n const store = new ActorStore()\n const r = store.getRole(roleId)\n if (!r) { console.error(chalk.red(` role \"${roleId}\" not found`)); process.exitCode = 1; return }\n const member = memberRaw.startsWith(\"actor:\") ? { actor: memberRaw }\n : memberRaw.startsWith(\"role:\") ? { role: memberRaw }\n : null\n if (!member) { console.error(chalk.red(\" member must be 'actor:<id>' or 'role:<id>'\")); process.exitCode = 1; return }\n // Dedup\n if (r.members.some((m) => JSON.stringify(m) === JSON.stringify(member))) {\n console.log(chalk.dim(` already a member`)); return\n }\n const updated = store.saveRole({ ...r, members: [...r.members, member] })\n console.log(chalk.green(` ✓ ${memberRaw} granted to ${roleId} (${updated.members.length} member${updated.members.length === 1 ? \"\" : \"s\"})`))\n })\n\nrole\n .command(\"revoke\")\n .description(\"remove an actor or nested role from a role\")\n .argument(\"<roleId>\", \"target role\")\n .argument(\"<memberId>\", \"actor:<id> or role:<id>\")\n .action((rawRole: string, memberRaw: string) => {\n const roleId = rawRole.startsWith(\"role:\") ? rawRole : `role:${rawRole}`\n const store = new ActorStore()\n const r = store.getRole(roleId)\n if (!r) { console.error(chalk.red(` role \"${roleId}\" not found`)); process.exitCode = 1; return }\n const before = r.members.length\n const nextMembers = r.members.filter((m) => {\n if (\"actor\" in m) return m.actor !== memberRaw\n return m.role !== memberRaw\n })\n if (nextMembers.length === before) { console.log(chalk.dim(` \"${memberRaw}\" was not a member`)); return }\n store.saveRole({ ...r, members: nextMembers })\n console.log(chalk.green(` ✓ ${memberRaw} revoked from ${roleId}`))\n })\n\nrole\n .command(\"list\")\n .description(\"list all roles with member counts\")\n .action(() => {\n const store = new ActorStore()\n const roles = store.listRoles()\n if (!roles.length) {\n console.log(chalk.dim(\" no roles yet. Try: agentx role create reviewers --name 'Reviewers'\"))\n return\n }\n console.log()\n for (const r of roles) {\n console.log(` ${chalk.cyan(r.id.padEnd(24))} ${chalk.bold(r.name)} ${chalk.dim(r.assignmentStrategy)}`)\n for (const m of r.members) {\n const ref = \"actor\" in m ? m.actor : m.role\n console.log(` ${chalk.dim(\"•\")} ${ref}`)\n }\n }\n console.log()\n console.log(chalk.dim(` ${roles.length} role${roles.length === 1 ? \"\" : \"s\"}.`))\n })\n\nrole\n .command(\"show\")\n .description(\"print full JSON for a role, including resolved members\")\n .argument(\"<id>\", \"role id\")\n .action((rawId: string) => {\n const id = rawId.startsWith(\"role:\") ? rawId : `role:${rawId}`\n const store = new ActorStore()\n const r = store.getRole(id)\n if (!r) { console.error(chalk.red(` role \"${id}\" not found`)); process.exitCode = 1; return }\n const resolved = store.resolveMembers({ kind: \"role\", id: r.id })\n console.log(JSON.stringify({ ...r, _resolvedActors: resolved }, null, 2))\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\"\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 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","import { Command } from \"commander\"\nimport chalk from \"chalk\"\nimport { loadDaemonConfig } from \"@/daemon/config\"\n\n// --- agentx bench: run the same request under both context strategies and\n// print a side-by-side quality + token comparison ---\n//\n// Intended as a lightweight, repeatable way to answer \"is the planner worth\n// it?\" for a given agent + conversation shape. Hits the running daemon via\n// POST /task so it exercises the full production path (session lookup,\n// memory retrieval, Claude CLI invocation). Does NOT mock anything.\n\nexport const bench = new Command()\n .name(\"bench\")\n .description(\"benchmark harnesses (context strategies, ...)\")\n\nbench\n .command(\"context\")\n .description(\"run the same message under 'layered' vs 'planner' strategies and compare\")\n .requiredOption(\"--agent <id>\", \"agent id to send the message to\")\n .requiredOption(\"--message <text>\", \"the user message to bench\")\n .option(\"--channel <name>\", \"channel label for the request context\", \"bench\")\n .option(\"--chat-id <id>\", \"chatId for session scoping\", \"bench-harness\")\n .option(\"--sender <name>\", \"sender label for the request context\", \"bench\")\n .option(\"--runs <n>\", \"number of runs per strategy (averaged)\", \"1\")\n .option(\"--preview <chars>\", \"how many response chars to print\", \"280\")\n .option(\"--url <url>\", \"daemon URL override (default: from agentx.json)\")\n .action(async (opts) => {\n const runs = Math.max(1, parseInt(opts.runs as string, 10) || 1)\n const previewChars = Math.max(0, parseInt(opts.preview as string, 10) || 280)\n const daemonUrl = (opts.url as string) || daemonUrlFromConfig()\n\n console.log()\n console.log(chalk.bold(` Context-strategy benchmark`))\n console.log(chalk.dim(` agent=${opts.agent}, channel=${opts.channel}, chatId=${opts.chatId}, runs=${runs}`))\n console.log(chalk.dim(` daemon=${daemonUrl}`))\n console.log()\n\n const layered = await runStrategy(daemonUrl, \"layered\", opts, runs)\n const planner = await runStrategy(daemonUrl, \"planner\", opts, runs)\n\n printComparison(layered, planner, previewChars)\n })\n\ntype RunResult = {\n strategy: \"layered\" | \"planner\"\n runs: number\n errors: number\n avgDurationMs: number\n avgInput: number\n avgOutput: number\n avgCacheRead: number\n avgCacheCreate: number\n avgTotalInput: number\n avgCost: number\n lastResponse: string\n lastError?: string\n}\n\nasync function runStrategy(\n daemonUrl: string,\n strategy: \"layered\" | \"planner\",\n opts: Record<string, unknown>,\n runs: number,\n): Promise<RunResult> {\n let totalDuration = 0\n let totalInput = 0\n let totalOutput = 0\n let totalCacheRead = 0\n let totalCacheCreate = 0\n let totalCost = 0\n let errors = 0\n let lastResponse = \"\"\n let lastError: string | undefined\n\n for (let i = 0; i < runs; i++) {\n const started = Date.now()\n try {\n const r = await fetch(`${daemonUrl}/task`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n agent: opts.agent,\n message: opts.message,\n contextStrategy: strategy,\n context: {\n channel: opts.channel,\n chatId: opts.chatId,\n sender: opts.sender,\n },\n }),\n // Agents can legitimately take minutes for heavy tasks; keep the\n // timeout loose so the bench doesn't misreport a slow-but-cheap run.\n signal: AbortSignal.timeout(10 * 60_000),\n })\n const data = (await r.json()) as {\n content?: string\n error?: string\n duration?: number\n usage?: {\n inputTokens?: number\n outputTokens?: number\n cacheReadTokens?: number\n cacheCreateTokens?: number\n }\n }\n if (data.error) {\n errors++\n lastError = data.error\n continue\n }\n totalDuration += data.duration ?? Date.now() - started\n totalInput += data.usage?.inputTokens ?? 0\n totalOutput += data.usage?.outputTokens ?? 0\n totalCacheRead += data.usage?.cacheReadTokens ?? 0\n totalCacheCreate += data.usage?.cacheCreateTokens ?? 0\n totalCost += estimateCost(data.usage)\n lastResponse = data.content ?? \"\"\n } catch (err: any) {\n errors++\n lastError = err.message ?? String(err)\n }\n }\n\n const n = runs - errors || 1\n return {\n strategy,\n runs,\n errors,\n avgDurationMs: Math.round(totalDuration / n),\n avgInput: Math.round(totalInput / n),\n avgOutput: Math.round(totalOutput / n),\n avgCacheRead: Math.round(totalCacheRead / n),\n avgCacheCreate: Math.round(totalCacheCreate / n),\n avgTotalInput: Math.round((totalInput + totalCacheRead + totalCacheCreate) / n),\n avgCost: totalCost / n,\n lastResponse,\n lastError,\n }\n}\n\n/** Rough cost estimator — Sonnet 4.6 rates. Bench output is directional;\n * for exact costs use the daemon's per-day usage JSON (which is what the\n * token tracker writes) where per-model pricing is honored. */\nfunction estimateCost(usage: RunResult[\"avgInput\"] extends number ? any : never): number {\n if (!usage) return 0\n const inputRate = 3 / 1_000_000\n const outputRate = 15 / 1_000_000\n const cacheReadRate = 0.3 / 1_000_000\n const cacheCreateRate = 3.75 / 1_000_000\n return (\n (usage.inputTokens ?? 0) * inputRate +\n (usage.outputTokens ?? 0) * outputRate +\n (usage.cacheReadTokens ?? 0) * cacheReadRate +\n (usage.cacheCreateTokens ?? 0) * cacheCreateRate\n )\n}\n\nfunction printComparison(a: RunResult, b: RunResult, previewChars: number): void {\n const pad = (s: string, w: number) => s.length >= w ? s : s + \" \".repeat(w - s.length)\n const fmt = (n: number) => n.toLocaleString()\n\n console.log(chalk.bold(\" \" + pad(\"metric\", 22) + pad(\"layered\", 18) + pad(\"planner\", 18) + \"delta\"))\n console.log(chalk.dim(\" \" + \"-\".repeat(74)))\n\n const rows: Array<[string, number, number, (n: number) => string]> = [\n [\"input tokens\", a.avgInput, b.avgInput, fmt],\n [\"output tokens\", a.avgOutput, b.avgOutput, fmt],\n [\"cache read\", a.avgCacheRead, b.avgCacheRead, fmt],\n [\"cache create\", a.avgCacheCreate, b.avgCacheCreate, fmt],\n [\"total input\", a.avgTotalInput, b.avgTotalInput, fmt],\n [\"est. cost ($)\", a.avgCost, b.avgCost, (n) => n.toFixed(4)],\n [\"duration (ms)\", a.avgDurationMs, b.avgDurationMs, fmt],\n ]\n for (const [label, av, bv, fmtFn] of rows) {\n const delta = bv - av\n const deltaPct = av === 0 ? 0 : (delta / av) * 100\n const deltaStr =\n delta === 0\n ? chalk.dim(\"±0\")\n : delta < 0\n ? chalk.green(`${fmtFn(delta)} (${deltaPct.toFixed(0)}%)`)\n : chalk.red(`+${fmtFn(delta)} (+${deltaPct.toFixed(0)}%)`)\n console.log(\" \" + pad(label, 22) + pad(fmtFn(av), 18) + pad(fmtFn(bv), 18) + deltaStr)\n }\n console.log(chalk.dim(\" \" + \"-\".repeat(74)))\n if (a.errors > 0 || b.errors > 0) {\n console.log(chalk.yellow(` errors: layered=${a.errors} (${a.lastError ?? \"\"}), planner=${b.errors} (${b.lastError ?? \"\"})`))\n }\n console.log()\n\n if (previewChars > 0) {\n console.log(chalk.bold(\" Response preview (last run of each):\"))\n console.log(chalk.dim(\" layered:\"))\n console.log(\" \" + clip(a.lastResponse, previewChars).split(\"\\n\").join(\"\\n \"))\n console.log(chalk.dim(\" planner:\"))\n console.log(\" \" + clip(b.lastResponse, previewChars).split(\"\\n\").join(\"\\n \"))\n console.log()\n }\n\n const tokenDelta = b.avgTotalInput - a.avgTotalInput\n if (tokenDelta < 0) {\n const pct = a.avgTotalInput === 0 ? 0 : Math.abs(tokenDelta / a.avgTotalInput) * 100\n console.log(chalk.green(` Planner saved ${fmt(Math.abs(tokenDelta))} input tokens/run (${pct.toFixed(0)}% less).`))\n } else if (tokenDelta > 0) {\n console.log(chalk.yellow(` Planner used ${fmt(tokenDelta)} MORE input tokens — investigate before enabling.`))\n }\n console.log()\n}\n\nfunction clip(s: string, n: number): string {\n if (!s) return \"(empty)\"\n return s.length > n ? s.slice(0, n) + \"…\" : s\n}\n\nfunction daemonUrlFromConfig(): 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","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, 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 if ((c as any)._hidden) return false\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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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":["Command","Command","init_config","chalk","daemon","Command","opts","spawn","args","child","writeFileSync","readFileSync","mkdirSync","existsSync","resolve","lockDir","pidPath","oldPid","loadDotenv","AgentXDaemon","path","text","raw","line","eq","key","val","unlinkSync","pidFiles","pidFile","pid","r","execSync","config","loadDaemonConfig","host","port","url","data","formatDuration","a","active","errors","enabledCrons","icon","next","p","skills","e","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","resolve","init","opts","cwd","configPath","envPath","sessionsDir","examplePaths","example","p","claudeDir","Command","chalk","spawn","existsSync","resolve","init_config","setup","Command","opts","state","wizardState","port","resolveDashboardPort","url","chalk","probe","openBrowser","cli","resolveCliEntry","child","spawn","ok","loadDaemonConfig","candidate","resolve","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","execFileSync","existsSync","readFileSync","statSync","resolve","doctor","opts","checks","runEnvChecks","cfg","runConfigChecks","runReferenceChecks","runWorkspaceChecks","runRuntimeChecks","summarize","printHumanReport","errors","nodeMajor","which","bin","npmPath","claudePath","ver","cfgPath","e","loadDaemonConfig","claudeCodeAgents","a","id","refs","collectEnvRefs","envFile","envFromFile","line","m","missing","empty","name","raw","node","into","item","v","abs","url","headers","ac","timer","r","body","c","groups","group","items","marker","s","init_config","Command","chalk","prompts","readFileSync","writeFileSync","existsSync","mkdirSync","cpSync","readdirSync","resolve","join","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","skillSrc","cpSync","channel","tg","name","acc","wa","route","target","dc","gl","agentIds","agentChoices","channelType","data","botHandle","agentMentions","e","routes","addMore","prev","cron","c","icon","mesh","peer","status","card","skillCmd","skillPath","opts","srcPath","skillName","targets","agentId","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","hook","settingsPath","settings","entry","migrate","configPath","searchPaths","ocPath","oc","agents","bindings","bindMap","b","agentCount","axId","tgAccounts","tgCount","axAgentId","cronPath","cronData","cronCount","job","configCmd","warnings","validateWorkspaces","w","hasClaudeDir","hasClaudeMd","hasSettings","skillCount","checks","parseValue","raw","asString","s","formatValue","path","getAtPath","expandEnvVars","cfgPath","source","value","setAtPath","parsed","cfg","written","unsetAtPath","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","DEV_PORTAL","DEFAULT_PERMISSIONS","fetchMe","token","res","openInBrowser","url","spawn","opener","connectDiscord","opts","chalk","openBrowser","prompts","t","me","displayName","readFileSync","existsSync","resolve","cfgPath","raw","agents","agent","id","envVar","setDotEnv","result","applyConfigMutation","cfg","setAtPath","installUrl","openInstall","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","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","connectDiscord","connectWhatsApp","mesh","invite","link","join","chalk","init_config","Command","chalk","usage","config","loadDaemonConfig","host","port","data","fmt","n","agents","a","b","id","ag","total","avgMs","opts","startUsageDashboard","execSync","existsSync","resolve","scriptPath","init_config","Command","chalk","board","Command","opts","config","resolveServerConfig","startBoardDashboard","e","chalk","portOpt","bindOpt","cfg","loadDaemonConfig","b","src","id","mutateConfig","projects","s","before","mutator","summary","backupPath","mutateAgentxConfig","Command","chalk","createServer","MeshWikiClient","peerUrls","url","results","peer","data","agent","peerUrl","agentId","articlePath","cached","res","escapeHtml","s","stripSectionTags","text","tagLink","tag","agentId","tagLinks","tags","t","resolveWikilink","target","wikiArticles","byTitle","pathSet","withExt","targetLower","title","path","md","agentPrefix","html","_m","lang","code","header","_sep","body","ths","c","rows","row","rawTarget","rawDisplay","display","block","l","chk","rest","HEAD_FONTS","CSS","pageLayout","sidebar","content","searchQuery","groupByDir","articles","byDir","a","dir","list","b","dirLabel","hubSidebar","agents","activePath","agent","byType","type","isActive","hubHome","hub","allAgents","remoteAgents","totalEntries","totalArticles","totalUnabsorbed","remoteIds","r","nodes","statusChip","remoteBadge","tagPart","hubAgentOverview","agentSummary","isRemote","entries","recent","e","issues","issue","hubArticlePage","articlePath","store","article","index","titleToPath","prefix","inbound","link","linked","hubEntries","byDate","date","dateEntries","hubSearch","query","totalResults","blocks","results","hubTagPage","total","matches","hubAgentTagPage","agentSidebar","startWikiServer","wikiDir","port","agentFilter","peerUrls","mode","WikiHub","mesh","MeshWikiClient","createServer","req","res","url","status","parts","peerAgent","slashIdx","peerUrl","i","q","localAgents","localMap","seen","local","remote","m","err","buildAbsorbPrompt","_mode","agentId","worldview","existingArticles","entryTexts","entryCount","buildFarzapediaPrompt","worldviewSection","byType","a","t","list","existingList","type","arr","x","y","resolve","relative","dirname","execSync","writeFileSync","mkdirSync","readFileSync","readdirSync","renameSync","rmSync","existsSync","getHub","dir","mode","WikiHub","modeLabel","wiki","Command","opts","hub","agents","totalEntries","chalk","agent","status","a","totalUnabsorbed","s","totalIssues","agentId","issues","issue","icon","maxEntries","totalAbsorbed","unabsorbed","e","agentWiki","existingIndex","worldview","entryTexts","prompt","buildAbsorbPrompt","tmpDir","promptPath","rawOutput","execErr","responseText","envelope","articles","gaps","objStart","arrStart","jsonStart","openChar","closeChar","depth","jsonEnd","i","jsonStr","parsed","parseErr","article","now","typeTag","relStr","tagStr","gap","agenticQuery","rd","rf","ex","rv","jn","store","n","agentHistDir","tasks","days","day","dayDir","files","f","rec","msg","lines","t","oldTitles","newBlock","q","cites","c","out","readline","randomUUID","WIKI_ARTICLE_TYPES","scripted","l","scriptCursor","rl","ask","answer","topic","type","validTypes","picked","QUESTIONS","questions","qas","aborted","extra","catalogLines","synthesisPrompt","x","draft","cmd","raw","fence","fmStart","fmMatch","fm","line","m","body","title","slug","articlePath","choice","finalContent","finalMeta","editor","editPath","ef","mm","referenced","titleIdx","r","g","script","entries","entry","verdict","rounds","commit","transcript","applied","result","action","note","primary","patchPrompt","buildQuizPatchPrompt","patched","before","after","titleOrPath","relPath","resolveArticlePath","absPath","seenLinks","bodyLinks","w","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","key","existing","arrow","where","target","archiveLegacy","verDir","ts","cb","meta","batchSize","maxArticles","totalScanned","totalNeeds","totalApplied","needs","remaining","limit","baseDir","batch","buildMigratePrompt","classifications","arrMatch","norm","normalizeWikiType","related","newMeta","aliasNote","mapped","items","tags","port","peerUrls","loadDaemonConfig","p","startWikiServer","question","chosen","id","cat","follow","query","found","results","shared","existingIds","totalSynced","peerUrl","res","data","nodeId","newCount","agentsRes","agentsData","stats","index","totalTags","sources","dirs","rows","label","fn","vals","best","max","winners","Command","chalk","resolve","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","peer","limit","headers","localSchema","localNodes","localIds","n","peerSchema","peerNodes","peerClassifications","schemaRes","nodesRes","clRes","localLevels","l","peerLevels","schemaMatches","schemaForImport","levelOrder","sortedPeerNodes","a","b","nodesAdded","nodesSkipped","nodesFailed","fpAdded","fpSkipped","existingByLevel","levelsSummary","axesJson","message","token","ac","timer","r","data","extractJson","_existing","createdBy","text","fenced","start","depth","Command","chalk","existsSync","mkdirSync","readFileSync","readdirSync","writeFileSync","resolve","relative","z","procedureMetaSchema","parseFrontmatter","raw","m","meta","line","kv","key","val","s","serializeFrontmatter","lines","ProcedureStore","opts","resolve","mkdirSync","id","existsSync","out","entry","readdirSync","full","readFileSync","body","parsed","procedureMetaSchema","relative","a","b","p","writeFileSync","patch","newBody","existing","merged","procedure","Command","items","ProcedureStore","chalk","p","v","prev","opts","store","body","e","id","Command","chalk","resolve","existsSync","readFileSync","workflow","Command","items","WorkflowStore","chalk","wf","cfg","n","filterParts","id","file","path","resolve","existsSync","raw","readFileSync","parsed","workflowSchema","i","lintIssues","lintWorkflow","e","results","ok","bad","issue","opts","nodeId","runs","RunStore","r","last","nextLabel","stateColor","payload","url","res","text","body","runId","Command","chalk","actor","Command","rawId","opts","id","store","ActorStore","chalk","channels","add","ch","handle","saved","actors","a","c","role","strategy","rawRole","memberRaw","roleId","r","member","m","updated","before","nextMembers","roles","ref","resolved","chalk","Command","serve","opts","startMcpServer","logger","error","handleError","init_config","Command","chalk","bench","opts","runs","previewChars","daemonUrl","daemonUrlFromConfig","layered","runStrategy","planner","printComparison","strategy","totalDuration","totalInput","totalOutput","totalCacheRead","totalCacheCreate","totalCost","errors","lastResponse","lastError","i","started","data","estimateCost","err","n","usage","inputRate","outputRate","cacheReadRate","cacheCreateRate","a","b","pad","s","w","fmt","rows","label","av","bv","fmtFn","delta","deltaPct","deltaStr","clip","tokenDelta","pct","config","loadDaemonConfig","host","port","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","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","o","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","daemon","setup","init","agent","channel","connect","cron","schedule","mesh","skillCmd","hook","migrate","configCmd","usage","board","wiki","graph","procedure","workflow","actor","role","token","doctor","serve","bench","whatsapp","completion"]}
|