agentix-cli 0.4.0 → 0.5.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/README.md +107 -188
- package/dist/chunk-WT2UJMBC.js +68 -0
- package/dist/chunk-WT2UJMBC.js.map +1 -0
- package/dist/cli.js +8 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +176 -16
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-AIBBZF4E.js +0 -41
- package/dist/chunk-AIBBZF4E.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{d as
|
|
3
|
-
(${(
|
|
4
|
-
`)),console.log(
|
|
2
|
+
import{d as j,e as R,p as G,q as z}from"./chunk-WT2UJMBC.js";import"./chunk-Z4GC5D6D.js";import"./chunk-M7HKBG3V.js";import{a as H}from"./chunk-4YCH6IZV.js";import{Command as ne}from"commander";import{Command as V}from"commander";import r from"chalk";var v=new V().name("daemon").description("manage the agentx daemon \u2014 start, stop, status, logs");v.command("start").description("start the daemon (default if no subcommand)").option("-c, --config <path>","path to agentx.json").option("-d, --detach","run in background (detached)").option("--port <port>","override bind port").action(async e=>{if(e.detach){let{spawn:n}=await import("child_process"),a=["dist/cli.js","daemon","start"];e.config&&a.push("-c",e.config),e.port&&a.push("--port",e.port);let t=n("node",a,{detached:!0,stdio:["ignore","ignore","ignore"],cwd:process.cwd()});t.unref();let{writeFileSync:i}=await import("fs");i("/tmp/agentx-daemon.pid",String(t.pid)),console.log(r.green(`Daemon started in background (PID: ${t.pid})`)),console.log(r.dim(" Logs: tail -f /tmp/agentx-daemon.log")),console.log(r.dim(" Stop: agentx daemon stop"));return}await new G(e.config).start()});v.command("stop").description("stop the running daemon").action(async()=>{let{readFileSync:e,existsSync:o,unlinkSync:n}=await import("fs"),{resolve:a}=await import("path"),t=[a(process.cwd(),".agentx/daemon.pid"),"/tmp/agentx-daemon.pid"];for(let c of t)if(o(c))try{let d=parseInt(e(c,"utf-8").trim(),10);process.kill(d,"SIGTERM"),await new Promise(l=>setTimeout(l,2e3));try{n(c)}catch{}console.log(r.green(`Daemon stopped (PID: ${d})`));return}catch{try{n(c)}catch{}}let{execSync:i}=await import("child_process");try{i("pkill -f 'node dist/cli.js daemon'",{stdio:"ignore"}),console.log(r.green("Daemon stopped"))}catch{console.log(r.yellow("No daemon process found"))}});v.command("status").alias("st").description("show daemon status, agents, crons, and mesh").option("-c, --config <path>","path to agentx.json").option("--json","output as JSON").action(async e=>{try{let o=j(e.config),[n,a]=o.node.bind.split(":"),t=`http://${n||"127.0.0.1"}:${a}/health`,c=await(await fetch(t,{signal:AbortSignal.timeout(3e3)})).json();if(e.json){console.log(JSON.stringify(c,null,2));return}console.log(),console.log(r.bold(` ${c.node.name}`)+r.dim(` (${c.node.id})`)),console.log(r.green(" Status: running")+r.dim(` \u2014 uptime ${Z(c.uptime)}`)),console.log(),console.log(r.bold(" Agents:"));for(let l of c.agents){let u=l.active>0?r.yellow(` [${l.active} active]`):"",k=l.errors>0?r.red(` (${l.errors} errors)`):"";console.log(` ${r.cyan(l.name)} ${r.dim(`(${l.tier})`)}${u}${k}`),console.log(r.dim(` ${l.workspace}`))}let d=c.crons.filter(l=>l.enabled);if(c.crons.length){console.log(),console.log(r.bold(` Crons: ${d.length} enabled / ${c.crons.length} total`));for(let l of c.crons){let u=l.enabled?r.green("\u25CF"):r.dim("\u25CB"),k=l.nextRun?r.dim(` next: ${new Date(l.nextRun).toLocaleTimeString()}`):"";console.log(` ${u} ${l.id}${k}`)}}if(c.mesh?.length){console.log(),console.log(r.bold(" Mesh:"));for(let l of c.mesh){let u=l.healthy?r.green("\u25CF"):r.red("\u25CF"),k=l.skills?.length?r.dim(` (${l.skills.length} agents)`):"";console.log(` ${u} ${l.peer} ${r.dim(l.peerUrl)}${k}`)}}console.log()}catch(o){if(o.cause?.code==="ECONNREFUSED"||o.name==="TimeoutError")console.log(r.red(" Daemon is not running")),console.log(r.dim(" Start with: agentx daemon start"));else try{let n=j(e.config),a=R(n);if(console.log(),console.log(r.bold(` ${n.node.name}`)+r.dim(` (${n.node.id})`)),console.log(r.yellow(" Status: stopped")),console.log(r.dim(` ${Object.keys(n.agents).length} agents, ${Object.keys(n.crons).length} crons configured`)),a.length){console.log();for(let t of a)console.log(r.yellow(` \u26A0 ${t}`))}console.log()}catch(n){console.log(r.red(` ${n.message}`))}}});v.command("logs").description("tail daemon logs").option("-n, --lines <n>","number of lines","50").option("-f, --follow","follow log output",!1).action(async e=>{let{execSync:o,spawn:n}=await import("child_process"),a="/tmp/agentx-daemon.log",{existsSync:t}=await import("fs");if(!t(a)){console.log(r.yellow("No log file found at /tmp/agentx-daemon.log"));return}if(e.follow){let i=n("tail",["-f","-n",e.lines,a],{stdio:"inherit"});process.on("SIGINT",()=>{i.kill(),process.exit(0)})}else o(`tail -n ${e.lines} ${a}`,{stdio:"inherit"})});v.command("send <agent> <message...>").description("send a task to an agent via the daemon API").option("-c, --config <path>","path to agentx.json").option("--peer <peer>","send to a mesh peer's agent").option("--json","output raw JSON response").action(async(e,o,n)=>{let a=o.join(" ");try{let t=j(n.config),[i,c]=t.node.bind.split(":"),d=`http://${i||"127.0.0.1"}:${c}`,l,u;n.peer?(l=`${d}/mesh/task`,u={peer:n.peer,message:a,agent:e}):(l=`${d}/task`,u={agent:e,message:a}),console.log(r.dim(` Sending to ${n.peer?`${n.peer}/${e}`:e}...`));let y=await(await fetch(l,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)})).json();n.json?console.log(JSON.stringify(y,null,2)):y.error?console.log(r.red(` Error: ${y.error}`)):(console.log(),console.log(y.content||y.response||"No response"),y.duration&&console.log(r.dim(`
|
|
3
|
+
(${(y.duration/1e3).toFixed(1)}s)`)))}catch(t){console.log(r.red(` Failed: ${t.message}`)),console.log(r.dim(" Is the daemon running? Try: agentx daemon status"))}});v.command("deploy <host>").description("deploy agentx to a remote server via rsync").option("-i, --identity <key>","SSH identity file").option("-u, --user <user>","SSH user","clawd").option("-p, --path <path>","remote agentx path","~/agentx").option("--restart","restart remote daemon after deploy",!1).option("--skip-checks","skip build and test before deploy",!1).action(async(e,o)=>{let{execSync:n}=await import("child_process"),a=o.identity?`-e "ssh -i ${o.identity}"`:"",t=`${o.user}@${e}:${o.path}/dist/`;if(!o.skipChecks){try{console.log(r.dim(" Running tests...")),n("npx vitest run --reporter=dot",{stdio:"pipe",cwd:process.cwd()}),console.log(r.green(" \u2713 Tests passed"))}catch{console.log(r.red(" \u2717 Tests failed \u2014 aborting deploy")),console.log(r.dim(" Use --skip-checks to deploy anyway"));return}let{existsSync:i,statSync:c}=await import("fs"),{resolve:d}=await import("path"),l=d(process.cwd(),"dist/cli.js");if(!i(l)){console.log(r.red(" \u2717 dist/ not found \u2014 run build first"));return}Date.now()-c(l).mtimeMs>3e5&&(console.log(r.yellow(" \u26A0 dist/ is older than 5 minutes \u2014 rebuilding...")),n("npx tsup --no-dts",{stdio:"pipe",cwd:process.cwd()}),console.log(r.green(" \u2713 Build complete")))}console.log(r.dim(` Deploying to ${o.user}@${e}:${o.path}...`));try{if(n(`rsync -avzL --delete ${a} dist/ ${t}`,{stdio:"inherit",cwd:process.cwd()}),console.log(r.green(" \u2713 Deploy complete")),o.restart){console.log(r.dim(" Restarting remote daemon..."));let i=o.identity?`ssh -i ${o.identity}`:"ssh";n(`${i} ${o.user}@${e} "pkill -f 'node dist/cli.js daemon' 2>/dev/null; sleep 2; cd ${o.path} && nohup node dist/cli.js daemon start > /tmp/agentx-daemon.log 2>&1 &"`,{stdio:"inherit"}),console.log(r.green(" Remote daemon restarted"))}}catch(i){console.log(r.red(` Deploy failed: ${i.message}`))}});v.action(async e=>{await new G(e.config).start()});function Z(e){return e<60?`${Math.round(e)}s`:e<3600?`${Math.round(e/60)}m`:e<86400?`${Math.round(e/3600)}h ${Math.round(e%3600/60)}m`:`${Math.round(e/86400)}d ${Math.round(e%86400/3600)}h`}import{Command as ee}from"commander";import $ from"chalk";import{existsSync as O,readFileSync as oe,writeFileSync as _,mkdirSync as q}from"fs";import{resolve as C}from"path";var X=new ee().name("init").description("initialize agentx configuration in the current directory").option("--force","overwrite existing config").action(async e=>{let o=process.cwd(),n=C(o,"agentx.json"),a=C(o,".env"),t=C(o,".agentx/sessions");if(console.log(),console.log($.bold(" agentx init")),console.log(),O(n)&&!e.force){console.log($.yellow(" agentx.json already exists. Use --force to overwrite.")),console.log();return}let i=[C(o,"agentx.example.json"),C(o,"node_modules/agentix-cli/agentx.example.json")],c;for(let l of i)if(O(l)){c=oe(l,"utf-8");break}c||(c=JSON.stringify({node:{id:H("os").hostname().toLowerCase().replace(/[^a-z0-9-]/g,"-"),name:H("os").hostname(),bind:"127.0.0.1:18800"},providers:{claude:{apiKey:"${ANTHROPIC_API_KEY}"}},agents:{assistant:{name:"Assistant",workspace:o,tier:"claude-code",model:"claude-sonnet-4-6",mentions:["@assistant","assistant"],maxConcurrent:2,systemPrompt:"You are a helpful assistant.",permissionMode:"default"}},channels:{telegram:{enabled:!1,accounts:{},policy:{dm:"pair",group:"mention-required"}},whatsapp:{enabled:!1}},crons:{},mesh:{enabled:!1,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}}},null,2)),_(n,c),console.log($.green(" \u2713 Created agentx.json")),O(a)||(_(a,["# AgentX environment variables","# ANTHROPIC_API_KEY=sk-ant-...","# TG_BOT_TOKEN=123456:ABC...","# MESH_TOKEN=your-mesh-secret",""].join(`
|
|
4
|
+
`)),console.log($.green(" \u2713 Created .env template"))),O(t)||(q(t,{recursive:!0}),console.log($.green(" \u2713 Created .agentx/sessions/")));let d=C(o,".claude");O(d)||(q(d,{recursive:!0}),console.log($.green(" \u2713 Created .claude/"))),console.log(),console.log($.bold(" Next steps:")),console.log(` 1. Edit ${$.cyan("agentx.json")} \u2014 configure agents, channels, crons`),console.log(` 2. Edit ${$.cyan(".env")} \u2014 add API keys and bot tokens`),console.log(` 3. Run ${$.cyan("agentx daemon start")} \u2014 start the daemon`),console.log(` 4. Run ${$.cyan("agentx daemon status")} \u2014 verify everything`),console.log()});import{Command as S}from"commander";import s from"chalk";import w from"prompts";import{readFileSync as M,writeFileSync as E,existsSync as h,mkdirSync as A,cpSync as F,readdirSync as Y}from"fs";import{resolve as g,join as L}from"path";function p(){let e=g(process.cwd(),"agentx.json");if(!h(e))throw new Error("No agentx.json found. Run: agentx init");return JSON.parse(M(e,"utf-8"))}function b(e){E(g(process.cwd(),"agentx.json"),JSON.stringify(e,null,2))}var I=new S().name("agent").description("manage agents \u2014 add, list, remove");I.command("list").alias("ls").description("list configured agents").action(()=>{let e=p();console.log();for(let[o,n]of Object.entries(e.agents||{})){let a=n.mentions?.join(", ")||"";console.log(` ${s.cyan(o)} \u2014 ${n.name} (${n.tier})`),console.log(s.dim(` workspace: ${n.workspace}`)),a&&console.log(s.dim(` mentions: ${a}`))}console.log()});I.command("add").description("add a new agent interactively").action(async()=>{let e=p(),o=await w([{type:"text",name:"id",message:"Agent ID (kebab-case)",validate:d=>/^[a-z0-9-]+$/.test(d)||"Use lowercase, numbers, hyphens"},{type:"text",name:"name",message:"Display name"},{type:"text",name:"workspace",message:"Workspace path",initial:g(process.cwd(),"agents/")},{type:"select",name:"tier",message:"Execution tier",choices:[{title:"claude-code (subscription, full features)",value:"claude-code"},{title:"sdk (API key, programmatic)",value:"sdk"},{title:"orchestrator (any provider)",value:"orchestrator"}]},{type:"text",name:"model",message:"Model",initial:"claude-sonnet-4-6"},{type:"list",name:"mentions",message:"Mention patterns (comma-separated)",separator:","},{type:"number",name:"maxConcurrent",message:"Max concurrent tasks",initial:2},{type:"text",name:"systemPrompt",message:"System prompt"}]);if(!o.id)return;let n=o.workspace.endsWith(o.id)?o.workspace:L(o.workspace,o.id);A(g(n,".claude/skills"),{recursive:!0});let a=`# ${o.name}
|
|
5
5
|
|
|
6
|
-
${
|
|
7
|
-
`;
|
|
8
|
-
Agent "${n.id}" added`)),console.log(a.dim(` Workspace: ${o}`)),console.log(a.dim(" Wiki skill installed")),console.log(a.dim(" CLAUDE.md + settings.json created")),console.log()});P.command("remove <id>").alias("rm").description("remove an agent from config (keeps workspace)").action(e=>{let n=p();if(!n.agents?.[e]){console.log(a.red(` Agent "${e}" not found`));return}delete n.agents[e],w(n),console.log(a.green(` Agent "${e}" removed from config (workspace preserved)`))});var M=new S().name("channel").description("manage channels \u2014 add telegram/whatsapp/discord, list");M.command("list").alias("ls").description("list configured channels and bindings").action(()=>{let e=p();console.log();let n=e.channels?.telegram;if(n?.enabled){console.log(a.bold(" Telegram:"));for(let[t,i]of Object.entries(n.accounts||{}))console.log(` ${a.cyan(t)} -> agent: ${i.agentBinding}`)}else console.log(a.dim(" Telegram: disabled"));let o=e.channels?.whatsapp;if(o?.enabled){console.log(a.bold(" WhatsApp:")),console.log(` default agent: ${o.defaultAgent||"(none)"}`),console.log(` session: ${o.sessionDir||".agentx/whatsapp-sessions"}`);for(let t of o.routes||[]){let i=t.contact?`contact ${t.contact}`:`group "${t.group}"`;console.log(` ${i} -> agent: ${t.agent}`)}}else console.log(a.dim(" WhatsApp: disabled"));let s=e.channels?.discord;s?.enabled?(console.log(a.bold(" Discord:")),console.log(` agent: ${s.agentBinding||"(none)"}`)):console.log(a.dim(" Discord: disabled")),console.log()});M.command("add").description("add a channel (telegram, whatsapp, or discord)").action(async()=>{let e=p(),n=Object.keys(e.agents||{});if(!n.length){console.log(a.red(" No agents configured. Run: agentx agent add"));return}let o=n.map(t=>({title:`${t} (${e.agents[t].name})`,value:t})),{channelType:s}=await k({type:"select",name:"channelType",message:"Channel type",choices:[{title:"Telegram \u2014 bot via BotFather token",value:"telegram"},{title:"WhatsApp \u2014 link via QR code (self-chat or contacts)",value:"whatsapp"},{title:"Discord \u2014 bot via Discord developer portal",value:"discord"}]});if(s){if(e.channels=e.channels||{},s==="telegram"){let t=await k([{type:"text",name:"accountName",message:"Account name (e.g. 'default', 'devops')"},{type:"text",name:"token",message:"Bot token (from @BotFather)"},{type:"select",name:"agentBinding",message:"Bind to agent",choices:o}]);if(!t.accountName||!t.token)return;try{let l=await(await fetch(`https://api.telegram.org/bot${t.token}/getMe`)).json();if(!l.ok)throw new Error(l.description);console.log(a.green(` Bot verified: @${l.result.username}`));let d=`@${l.result.username}`,r=e.agents[t.agentBinding].mentions||[];r.includes(d)||(r.push(d,l.result.username),e.agents[t.agentBinding].mentions=r)}catch(i){console.log(a.red(` Invalid token: ${i.message}`));return}e.channels.telegram=e.channels.telegram||{enabled:!1,accounts:{},policy:{dm:"pair",group:"mention-required"}},e.channels.telegram.enabled=!0,e.channels.telegram.accounts[t.accountName]={token:t.token,agentBinding:t.agentBinding},w(e),console.log(a.green(` Telegram "${t.accountName}" added -> ${t.agentBinding}`))}if(s==="whatsapp"){let t=await k([{type:"select",name:"defaultAgent",message:"Default agent for WhatsApp messages",choices:o},{type:"text",name:"sessionDir",message:"Session directory",initial:".agentx/whatsapp-sessions"},{type:"confirm",name:"addRoute",message:"Add a contact/group route?",initial:!0}]);if(!t.defaultAgent)return;let i=[],l=t.addRoute;for(;l;){let d=await k([{type:"select",name:"type",message:"Route type",choices:[{title:"Contact (phone number)",value:"contact"},{title:"Group (name match)",value:"group"}]},{type:"text",name:"value",message:r=>r==="contact"?"Phone number (e.g. +21624309128)":"Group name (partial match)"},{type:"select",name:"agent",message:"Route to agent",choices:o},{type:"confirm",name:"more",message:"Add another route?",initial:!1}]);d.value&&d.agent&&i.push({[d.type]:d.value,agent:d.agent}),l=d.more}e.channels.whatsapp={enabled:!0,sessionDir:t.sessionDir,defaultAgent:t.defaultAgent,routes:i},w(e),C(m(process.cwd(),t.sessionDir),{recursive:!0}),console.log(a.green(` WhatsApp enabled (${i.length} routes, default: ${t.defaultAgent})`)),console.log(a.dim(" Start daemon to scan QR code: agentx daemon start"))}if(s==="discord"){let t=await k([{type:"text",name:"token",message:"Discord bot token (from developer portal)"},{type:"select",name:"agentBinding",message:"Bind to agent",choices:o}]);if(!t.token)return;e.channels.discord={enabled:!0,token:t.token,agentBinding:t.agentBinding},w(e),console.log(a.green(` Discord added -> ${t.agentBinding}`))}console.log(a.dim(" Restart daemon to apply: agentx daemon stop && agentx daemon start")),console.log()}});var A=new S().name("cron").description("manage cron jobs \u2014 add, list, enable, disable");A.command("list").alias("ls").description("list cron jobs").action(()=>{let e=p();console.log();for(let[n,o]of Object.entries(e.crons||{})){let s=o.enabled?a.green("\u25CF"):a.dim("\u25CB");console.log(` ${s} ${a.cyan(n)} \u2014 ${o.schedule} (${o.timezone})`),console.log(a.dim(` agent: ${o.agent} | timeout: ${o.timeout}s`))}Object.keys(e.crons||{}).length||console.log(a.dim(" No cron jobs configured")),console.log()});A.command("add").description("add a cron job").action(async()=>{let e=p(),n=Object.keys(e.agents||{}),o=await k([{type:"text",name:"id",message:"Job ID (kebab-case)"},{type:"text",name:"schedule",message:"Cron expression (e.g. '0 9 * * *')"},{type:"text",name:"timezone",message:"Timezone",initial:"UTC"},{type:"select",name:"agent",message:"Agent",choices:n.map(s=>({title:s,value:s}))},{type:"text",name:"prompt",message:"Task prompt"},{type:"number",name:"timeout",message:"Timeout (seconds)",initial:600},{type:"confirm",name:"enabled",message:"Enable now?",initial:!1}]);!o.id||!o.schedule||(e.crons=e.crons||{},e.crons[o.id]={enabled:o.enabled,schedule:o.schedule,timezone:o.timezone,agent:o.agent,prompt:o.prompt,timeout:o.timeout,onError:"log"},w(e),console.log(a.green(` Cron "${o.id}" added (${o.enabled?"enabled":"disabled"})`)),console.log())});A.command("enable <id>").description("enable a cron job").action(e=>{let n=p();if(!n.crons?.[e]){console.log(a.red(` Cron "${e}" not found`));return}n.crons[e].enabled=!0,w(n),console.log(a.green(` Cron "${e}" enabled`))});A.command("disable <id>").description("disable a cron job").action(e=>{let n=p();if(!n.crons?.[e]){console.log(a.red(` Cron "${e}" not found`));return}n.crons[e].enabled=!1,w(n),console.log(a.green(` Cron "${e}" disabled`))});var O=new S().name("mesh").description("manage mesh peers \u2014 add, list, remove");O.command("list").alias("ls").description("list mesh peers").action(async()=>{let e=p();if(console.log(),!e.mesh?.enabled)console.log(a.dim(" Mesh: disabled"));else{console.log(a.bold(" Mesh peers:"));for(let n of e.mesh.peers||[]){let o=a.red("unreachable");try{let t=await(await fetch(`${n.url}/health`,{signal:AbortSignal.timeout(3e3)})).json();o=a.green(`healthy \u2014 ${t.agents?.length||0} agents`)}catch{}console.log(` ${a.cyan(n.name)} ${a.dim(n.url)} ${o}`)}}console.log()});O.command("add").description("add a mesh peer (another agentx server)").action(async()=>{let e=p(),n=await k([{type:"text",name:"name",message:"Peer name (e.g. 'server-2')"},{type:"text",name:"url",message:"Peer URL (e.g. 'http://100.67.108.119:18800')"},{type:"text",name:"token",message:"Auth token (optional, press enter to skip)"}]);if(!(!n.name||!n.url)){try{let s=await(await fetch(`${n.url}/.well-known/agent-card.json`,{signal:AbortSignal.timeout(5e3)})).json();console.log(a.green(` Connected: ${s.name} (${s.skills?.length||0} agents)`))}catch{console.log(a.yellow(" Could not reach peer (adding anyway)"))}e.mesh=e.mesh||{enabled:!1,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},e.mesh.enabled=!0,e.mesh.peers=e.mesh.peers||[],e.mesh.peers.push({url:n.url,name:n.name,...n.token?{token:n.token}:{}}),w(e),console.log(a.green(` Peer "${n.name}" added`)),console.log()}});O.command("remove <name>").alias("rm").description("remove a mesh peer").action(e=>{let n=p();n.mesh?.peers&&(n.mesh.peers=n.mesh.peers.filter(o=>o.name!==e),n.mesh.peers.length===0&&(n.mesh.enabled=!1),w(n),console.log(a.green(` Peer "${e}" removed`)))});var E=new S().name("skill").description("manage skills \u2014 add to agent(s), list");E.command("add <skillPath>").description("add a skill to agent(s)").option("-a, --agent <agents...>","target agent ID(s)").option("--all","add to all agents").action(async(e,n)=>{let o=p(),s=m(e);if(!y(s)){console.log(a.red(` Skill not found: ${s}`));return}let t=y(T(s,"SKILL.md"))?s.split("/").pop():s.replace(/\/SKILL\.md$/,"").split("/").pop(),i;if(n.all)i=Object.keys(o.agents||{});else if(n.agent)i=n.agent;else{let l=Object.keys(o.agents||{});i=(await k({type:"multiselect",name:"agents",message:"Install to which agents?",choices:l.map(r=>({title:`${r} (${o.agents[r].name})`,value:r}))})).agents||[]}for(let l of i){let d=o.agents[l];if(!d){console.log(a.yellow(` Agent "${l}" not found, skipping`));continue}let r=m(d.workspace,".claude/skills",t);C(r,{recursive:!0}),y(T(s,"SKILL.md"))?W(s,r,{recursive:!0}):s.endsWith(".md")&&W(s,T(r,"SKILL.md")),console.log(a.green(` ${t} -> ${l} (${d.workspace})`))}console.log()});E.command("list").alias("ls").description("list skills per agent").action(()=>{let e=p();console.log();for(let[n,o]of Object.entries(e.agents||{})){let s=m(o.workspace,".claude/skills"),t=y(s)?ee(s).filter(i=>!i.startsWith(".")):[];console.log(` ${a.cyan(n)}: ${t.length?t.join(", "):a.dim("(none)")}`)}console.log()});var U=new S().name("hook").description("manage hooks \u2014 add to agent workspace");U.command("add <agent>").description("add a hook to an agent's workspace settings").action(async e=>{let o=p().agents?.[e];if(!o){console.log(a.red(` Agent "${e}" not found`));return}let s=m(o.workspace,".claude/settings.json"),t=y(s)?JSON.parse(R(s,"utf-8")):{},i=await k([{type:"select",name:"event",message:"Hook event",choices:[{title:"PreToolUse \u2014 before any tool runs",value:"PreToolUse"},{title:"PostToolUse \u2014 after any tool runs",value:"PostToolUse"},{title:"SessionStart \u2014 when session begins",value:"SessionStart"},{title:"Notification \u2014 on notifications",value:"Notification"},{title:"Stop \u2014 before session stops",value:"Stop"}]},{type:"select",name:"type",message:"Hook type",choices:[{title:"command \u2014 run a shell command",value:"command"},{title:"http \u2014 POST to a URL",value:"http"}]},{type:"text",name:"value",message:r=>r==="command"?"Shell command":"URL"},{type:"text",name:"matcher",message:"Matcher regex (optional, e.g. 'Bash' to match tool)"}]);if(!i.event||!i.value)return;t.hooks=t.hooks||{},t.hooks[i.event]=t.hooks[i.event]||[];let d={hooks:[{type:i.type,...i.type==="command"?{command:i.value}:{url:i.value}}]};i.matcher&&(d.matcher=i.matcher),t.hooks[i.event].push(d),C(m(o.workspace,".claude"),{recursive:!0}),B(s,JSON.stringify(t,null,2)),console.log(a.green(` Hook added to ${e}: ${i.event} -> ${i.type}`)),console.log()});var F=new S().name("migrate").description("import configuration from OpenClaw or other tools");F.command("openclaw [configPath]").description("import agents, channels, and crons from OpenClaw config").option("--dry-run","show what would be imported without writing").action(async(e,n)=>{let o=[e,m(process.env.HOME||"",".openclaw/openclaw.json"),m(process.env.HOME||"",".openclaw/clawdbot.json")].filter(Boolean),s;for(let g of o)if(g&&y(g)){s=g;break}if(!s){console.log(a.red(" OpenClaw config not found. Pass the path: agentx migrate openclaw /path/to/config.json"));return}console.log(a.dim(` Reading: ${s}`));let t=JSON.parse(R(s,"utf-8")),i=y(m(process.cwd(),"agentx.json"))?p():{node:{id:"imported",name:"Imported",bind:"127.0.0.1:18800"},providers:{},agents:{},channels:{telegram:{enabled:!1,accounts:{},policy:{dm:"pair",group:"mention-required"}},whatsapp:{enabled:!1}},crons:{},mesh:{enabled:!1,peers:[]}},l=t.agents?.list||[],d=t.bindings||[],r={};for(let g of d)g.match?.channel==="telegram"&&(r[g.match.accountId]=g.agentId);l.find(g=>g.id==="main"||g.default)&&(r.default="main");let f=0;for(let g of l){if(g.workspace?.startsWith("/data"))continue;let b=g.id.replace(/-agent$/,"").replace(/^main$/,"atlas"),u=g.groupChat?.mentionPatterns||[];u.some(D=>D===b)||u.push(b),i.agents[b]={name:g.name,workspace:g.workspace,tier:"claude-code",model:"claude-sonnet-4-6",mentions:u,maxConcurrent:g.id==="main"?2:1,systemPrompt:`You are ${g.name} on AgentX.`,permissionMode:"bypassPermissions"},f++,n.dryRun||C(m(g.workspace,".claude/skills"),{recursive:!0})}console.log(` ${a.green(f)} agents imported`);let v=t.channels?.telegram?.accounts||{},$=0;for(let[g,b]of Object.entries(v)){if(!b.botToken)continue;let D=r[g]?.replace(/-agent$/,"").replace(/^main$/,"atlas")||"atlas";i.channels.telegram.accounts[g]={token:b.botToken,agentBinding:D},i.channels.telegram.enabled=!0,$++}console.log(` ${a.green($)} Telegram accounts imported`);let J=m(s,"../cron/jobs.json");if(y(J)){let g=JSON.parse(R(J,"utf-8")),b=0;for(let u of g.jobs||[]){let D=u.name||u.id,Y=u.agentId?.replace(/-agent$/,"").replace(/^main$/,"atlas")||"atlas";i.crons[D]={enabled:u.enabled||!1,schedule:u.schedule?.expr||"0 9 * * *",timezone:u.schedule?.tz||"UTC",agent:Y,prompt:u.payload?.message||"",timeout:u.payload?.timeoutSeconds||600,onError:"log"},b++}console.log(` ${a.green(b)} cron jobs imported`)}n.dryRun?(console.log(a.yellow(`
|
|
9
|
-
Dry run \u2014 nothing written`)),console.log(JSON.stringify(i,null,2))):(
|
|
10
|
-
Migration complete! Review agentx.json and run: agentx daemon start`))),console.log()});process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function
|
|
6
|
+
${o.systemPrompt}
|
|
7
|
+
`;E(g(n,"CLAUDE.md"),a),E(g(n,".claude/settings.json"),JSON.stringify({permissions:{allow:["Bash(git *)","Bash(curl *)","Bash(node *)","Read","Write","Edit","Glob","Grep","WebFetch","WebSearch"]}},null,2));let t=g(process.cwd(),"src/wiki/SKILL.md"),i=g(__dirname,"../wiki/SKILL.md"),c=h(t)?t:i;h(c)&&(A(g(n,".claude/skills/wiki"),{recursive:!0}),F(c,g(n,".claude/skills/wiki/SKILL.md"))),e.agents=e.agents||{},e.agents[o.id]={name:o.name,workspace:n,tier:o.tier,model:o.model,mentions:o.mentions?.map(d=>d.trim()).filter(Boolean)||[],maxConcurrent:o.maxConcurrent,systemPrompt:o.systemPrompt,permissionMode:"default"},b(e),console.log(s.green(`
|
|
8
|
+
Agent "${o.id}" added`)),console.log(s.dim(` Workspace: ${n}`)),console.log(s.dim(" Wiki skill installed")),console.log(s.dim(" CLAUDE.md + settings.json created")),console.log()});I.command("remove <id>").alias("rm").description("remove an agent from config (keeps workspace)").action(e=>{let o=p();if(!o.agents?.[e]){console.log(s.red(` Agent "${e}" not found`));return}delete o.agents[e],b(o),console.log(s.green(` Agent "${e}" removed from config (workspace preserved)`))});var B=new S().name("channel").description("manage channels \u2014 add telegram/whatsapp/discord, list");B.command("list").alias("ls").description("list configured channels and bindings").action(()=>{let e=p();console.log();let o=e.channels?.telegram;if(o?.enabled){console.log(s.bold(" Telegram:"));for(let[i,c]of Object.entries(o.accounts||{}))console.log(` ${s.cyan(i)} -> agent: ${c.agentBinding}`)}else console.log(s.dim(" Telegram: disabled"));let n=e.channels?.whatsapp;if(n?.enabled){console.log(s.bold(" WhatsApp:")),console.log(` default agent: ${n.defaultAgent||"(none)"}`),console.log(` session: ${n.sessionDir||".agentx/whatsapp-sessions"}`);for(let i of n.routes||[]){let c=i.contact?`contact ${i.contact}`:`group "${i.group}"`;console.log(` ${c} -> agent: ${i.agent}`)}}else console.log(s.dim(" WhatsApp: disabled"));let a=e.channels?.discord;a?.enabled?(console.log(s.bold(" Discord:")),console.log(` agent: ${a.agentBinding||"(none)"}`)):console.log(s.dim(" Discord: disabled"));let t=e.channels?.gitlab;if(t?.enabled){console.log(s.bold(" GitLab:")),console.log(` host: ${t.host}`),console.log(` webhook: :${t.webhookPort}`);for(let i of t.routes||[])console.log(` ${i.project} -> agent: ${i.agent}`)}else console.log(s.dim(" GitLab: disabled"));console.log()});B.command("add").description("add a channel (telegram, whatsapp, or discord)").action(async()=>{let e=p(),o=Object.keys(e.agents||{});if(!o.length){console.log(s.red(" No agents configured. Run: agentx agent add"));return}let n=o.map(t=>({title:`${t} (${e.agents[t].name})`,value:t})),{channelType:a}=await w({type:"select",name:"channelType",message:"Channel type",choices:[{title:"Telegram \u2014 bot via BotFather token",value:"telegram"},{title:"WhatsApp \u2014 link via QR code (self-chat or contacts)",value:"whatsapp"},{title:"Discord \u2014 bot via Discord developer portal",value:"discord"},{title:"GitLab \u2014 webhook for issues, MRs, comments, pipelines",value:"gitlab"}]});if(a){if(e.channels=e.channels||{},a==="telegram"){let t=await w([{type:"text",name:"accountName",message:"Account name (e.g. 'default', 'devops')"},{type:"text",name:"token",message:"Bot token (from @BotFather)"},{type:"select",name:"agentBinding",message:"Bind to agent",choices:n}]);if(!t.accountName||!t.token)return;try{let c=await(await fetch(`https://api.telegram.org/bot${t.token}/getMe`)).json();if(!c.ok)throw new Error(c.description);console.log(s.green(` Bot verified: @${c.result.username}`));let d=`@${c.result.username}`,l=e.agents[t.agentBinding].mentions||[];l.includes(d)||(l.push(d,c.result.username),e.agents[t.agentBinding].mentions=l)}catch(i){console.log(s.red(` Invalid token: ${i.message}`));return}e.channels.telegram=e.channels.telegram||{enabled:!1,accounts:{},policy:{dm:"pair",group:"mention-required"}},e.channels.telegram.enabled=!0,e.channels.telegram.accounts[t.accountName]={token:t.token,agentBinding:t.agentBinding},b(e),console.log(s.green(` Telegram "${t.accountName}" added -> ${t.agentBinding}`))}if(a==="whatsapp"){let t=await w([{type:"select",name:"defaultAgent",message:"Default agent for WhatsApp messages",choices:n},{type:"text",name:"sessionDir",message:"Session directory",initial:".agentx/whatsapp-sessions"},{type:"confirm",name:"addRoute",message:"Add a contact/group route?",initial:!0}]);if(!t.defaultAgent)return;let i=[],c=t.addRoute;for(;c;){let d=await w([{type:"select",name:"type",message:"Route type",choices:[{title:"Contact (phone number)",value:"contact"},{title:"Group (name match)",value:"group"}]},{type:"text",name:"value",message:l=>l==="contact"?"Phone number (e.g. +21624309128)":"Group name (partial match)"},{type:"select",name:"agent",message:"Route to agent",choices:n},{type:"confirm",name:"more",message:"Add another route?",initial:!1}]);d.value&&d.agent&&i.push({[d.type]:d.value,agent:d.agent}),c=d.more}e.channels.whatsapp={enabled:!0,sessionDir:t.sessionDir,defaultAgent:t.defaultAgent,routes:i},b(e),A(g(process.cwd(),t.sessionDir),{recursive:!0}),console.log(s.green(` WhatsApp enabled (${i.length} routes, default: ${t.defaultAgent})`)),console.log(s.dim(" Start daemon to scan QR code: agentx daemon start"))}if(a==="discord"){let t=await w([{type:"text",name:"token",message:"Discord bot token (from developer portal)"},{type:"select",name:"agentBinding",message:"Bind to agent",choices:n}]);if(!t.token)return;e.channels.discord={enabled:!0,token:t.token,agentBinding:t.agentBinding},b(e),console.log(s.green(` Discord added -> ${t.agentBinding}`))}if(a==="gitlab"){let t=await w([{type:"text",name:"host",message:"GitLab instance URL",initial:"https://gitlab.noqta.tn"},{type:"text",name:"token",message:"GitLab API token (PRIVATE-TOKEN)"},{type:"number",name:"webhookPort",message:"Webhook listen port",initial:18810},{type:"text",name:"webhookSecret",message:"Webhook secret (X-Gitlab-Token, optional)"},{type:"confirm",name:"addRoute",message:"Add a project route?",initial:!0}]);if(!t.token)return;let i=[],c=t.addRoute;for(;c;){let d=await w([{type:"text",name:"project",message:"GitLab project path (e.g. noqta/mtgl-v2, or * for default)"},{type:"select",name:"agent",message:"Route to agent",choices:n},{type:"confirm",name:"more",message:"Add another route?",initial:!1}]);d.project&&d.agent&&i.push({project:d.project,agent:d.agent}),c=d.more}e.channels.gitlab={enabled:!0,host:t.host,token:t.token,webhookPort:t.webhookPort,webhookSecret:t.webhookSecret||void 0,routes:i},b(e),console.log(s.green(` GitLab enabled (${i.length} routes, webhook :${t.webhookPort})`)),console.log(s.dim(` Add webhook in GitLab: ${t.host}/<project>/-/hooks`)),console.log(s.dim(` URL: http://your-server:${t.webhookPort}/`)),t.webhookSecret&&console.log(s.dim(` Secret token: ${t.webhookSecret}`)),console.log(s.dim(" Events: Comments, Issues, Merge requests, Pipeline"))}console.log(s.dim(" Restart daemon to apply: agentx daemon stop && agentx daemon start")),console.log()}});var P=new S().name("cron").description("manage cron jobs \u2014 add, list, enable, disable");P.command("list").alias("ls").description("list cron jobs").action(()=>{let e=p();console.log();for(let[o,n]of Object.entries(e.crons||{})){let a=n.enabled?s.green("\u25CF"):s.dim("\u25CB");console.log(` ${a} ${s.cyan(o)} \u2014 ${n.schedule} (${n.timezone})`),console.log(s.dim(` agent: ${n.agent} | timeout: ${n.timeout}s`))}Object.keys(e.crons||{}).length||console.log(s.dim(" No cron jobs configured")),console.log()});P.command("add").description("add a cron job").action(async()=>{let e=p(),o=Object.keys(e.agents||{}),n=await w([{type:"text",name:"id",message:"Job ID (kebab-case)"},{type:"text",name:"schedule",message:"Cron expression (e.g. '0 9 * * *')"},{type:"text",name:"timezone",message:"Timezone",initial:"UTC"},{type:"select",name:"agent",message:"Agent",choices:o.map(a=>({title:a,value:a}))},{type:"text",name:"prompt",message:"Task prompt"},{type:"number",name:"timeout",message:"Timeout (seconds)",initial:600},{type:"confirm",name:"enabled",message:"Enable now?",initial:!1}]);!n.id||!n.schedule||(e.crons=e.crons||{},e.crons[n.id]={enabled:n.enabled,schedule:n.schedule,timezone:n.timezone,agent:n.agent,prompt:n.prompt,timeout:n.timeout,onError:"log"},b(e),console.log(s.green(` Cron "${n.id}" added (${n.enabled?"enabled":"disabled"})`)),console.log())});P.command("enable <id>").description("enable a cron job").action(e=>{let o=p();if(!o.crons?.[e]){console.log(s.red(` Cron "${e}" not found`));return}o.crons[e].enabled=!0,b(o),console.log(s.green(` Cron "${e}" enabled`))});P.command("disable <id>").description("disable a cron job").action(e=>{let o=p();if(!o.crons?.[e]){console.log(s.red(` Cron "${e}" not found`));return}o.crons[e].enabled=!1,b(o),console.log(s.green(` Cron "${e}" disabled`))});var T=new S().name("mesh").description("manage mesh peers \u2014 add, list, remove");T.command("list").alias("ls").description("list mesh peers").action(async()=>{let e=p();if(console.log(),!e.mesh?.enabled)console.log(s.dim(" Mesh: disabled"));else{console.log(s.bold(" Mesh peers:"));for(let o of e.mesh.peers||[]){let n=s.red("unreachable");try{let t=await(await fetch(`${o.url}/health`,{signal:AbortSignal.timeout(3e3)})).json();n=s.green(`healthy \u2014 ${t.agents?.length||0} agents`)}catch{}console.log(` ${s.cyan(o.name)} ${s.dim(o.url)} ${n}`)}}console.log()});T.command("add").description("add a mesh peer (another agentx server)").action(async()=>{let e=p(),o=await w([{type:"text",name:"name",message:"Peer name (e.g. 'server-2')"},{type:"text",name:"url",message:"Peer URL (e.g. 'http://100.67.108.119:18800')"},{type:"text",name:"token",message:"Auth token (optional, press enter to skip)"}]);if(!(!o.name||!o.url)){try{let a=await(await fetch(`${o.url}/.well-known/agent-card.json`,{signal:AbortSignal.timeout(5e3)})).json();console.log(s.green(` Connected: ${a.name} (${a.skills?.length||0} agents)`))}catch{console.log(s.yellow(" Could not reach peer (adding anyway)"))}e.mesh=e.mesh||{enabled:!1,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},e.mesh.enabled=!0,e.mesh.peers=e.mesh.peers||[],e.mesh.peers.push({url:o.url,name:o.name,...o.token?{token:o.token}:{}}),b(e),console.log(s.green(` Peer "${o.name}" added`)),console.log()}});T.command("remove <name>").alias("rm").description("remove a mesh peer").action(e=>{let o=p();o.mesh?.peers&&(o.mesh.peers=o.mesh.peers.filter(n=>n.name!==e),o.mesh.peers.length===0&&(o.mesh.enabled=!1),b(o),console.log(s.green(` Peer "${e}" removed`)))});var W=new S().name("skill").description("manage skills \u2014 add to agent(s), list");W.command("add <skillPath>").description("add a skill to agent(s)").option("-a, --agent <agents...>","target agent ID(s)").option("--all","add to all agents").action(async(e,o)=>{let n=p(),a=g(e);if(!h(a)){console.log(s.red(` Skill not found: ${a}`));return}let t=h(L(a,"SKILL.md"))?a.split("/").pop():a.replace(/\/SKILL\.md$/,"").split("/").pop(),i;if(o.all)i=Object.keys(n.agents||{});else if(o.agent)i=o.agent;else{let c=Object.keys(n.agents||{});i=(await w({type:"multiselect",name:"agents",message:"Install to which agents?",choices:c.map(l=>({title:`${l} (${n.agents[l].name})`,value:l}))})).agents||[]}for(let c of i){let d=n.agents[c];if(!d){console.log(s.yellow(` Agent "${c}" not found, skipping`));continue}let l=g(d.workspace,".claude/skills",t);A(l,{recursive:!0}),h(L(a,"SKILL.md"))?F(a,l,{recursive:!0}):a.endsWith(".md")&&F(a,L(l,"SKILL.md")),console.log(s.green(` ${t} -> ${c} (${d.workspace})`))}console.log()});W.command("list").alias("ls").description("list skills per agent").action(()=>{let e=p();console.log();for(let[o,n]of Object.entries(e.agents||{})){let a=g(n.workspace,".claude/skills"),t=h(a)?Y(a).filter(i=>!i.startsWith(".")):[];console.log(` ${s.cyan(o)}: ${t.length?t.join(", "):s.dim("(none)")}`)}console.log()});var J=new S().name("hook").description("manage hooks \u2014 add to agent workspace");J.command("add <agent>").description("add a hook to an agent's workspace settings").action(async e=>{let n=p().agents?.[e];if(!n){console.log(s.red(` Agent "${e}" not found`));return}let a=g(n.workspace,".claude/settings.json"),t=h(a)?JSON.parse(M(a,"utf-8")):{},i=await w([{type:"select",name:"event",message:"Hook event",choices:[{title:"PreToolUse \u2014 before any tool runs",value:"PreToolUse"},{title:"PostToolUse \u2014 after any tool runs",value:"PostToolUse"},{title:"SessionStart \u2014 when session begins",value:"SessionStart"},{title:"Notification \u2014 on notifications",value:"Notification"},{title:"Stop \u2014 before session stops",value:"Stop"}]},{type:"select",name:"type",message:"Hook type",choices:[{title:"command \u2014 run a shell command",value:"command"},{title:"http \u2014 POST to a URL",value:"http"}]},{type:"text",name:"value",message:l=>l==="command"?"Shell command":"URL"},{type:"text",name:"matcher",message:"Matcher regex (optional, e.g. 'Bash' to match tool)"}]);if(!i.event||!i.value)return;t.hooks=t.hooks||{},t.hooks[i.event]=t.hooks[i.event]||[];let d={hooks:[{type:i.type,...i.type==="command"?{command:i.value}:{url:i.value}}]};i.matcher&&(d.matcher=i.matcher),t.hooks[i.event].push(d),A(g(n.workspace,".claude"),{recursive:!0}),E(a,JSON.stringify(t,null,2)),console.log(s.green(` Hook added to ${e}: ${i.event} -> ${i.type}`)),console.log()});var K=new S().name("migrate").description("import configuration from OpenClaw or other tools");K.command("openclaw [configPath]").description("import agents, channels, and crons from OpenClaw config").option("--dry-run","show what would be imported without writing").action(async(e,o)=>{let n=[e,g(process.env.HOME||"",".openclaw/openclaw.json"),g(process.env.HOME||"",".openclaw/clawdbot.json")].filter(Boolean),a;for(let m of n)if(m&&h(m)){a=m;break}if(!a){console.log(s.red(" OpenClaw config not found. Pass the path: agentx migrate openclaw /path/to/config.json"));return}console.log(s.dim(` Reading: ${a}`));let t=JSON.parse(M(a,"utf-8")),i=h(g(process.cwd(),"agentx.json"))?p():{node:{id:"imported",name:"Imported",bind:"127.0.0.1:18800"},providers:{},agents:{},channels:{telegram:{enabled:!1,accounts:{},policy:{dm:"pair",group:"mention-required"}},whatsapp:{enabled:!1}},crons:{},mesh:{enabled:!1,peers:[]}},c=t.agents?.list||[],d=t.bindings||[],l={};for(let m of d)m.match?.channel==="telegram"&&(l[m.match.accountId]=m.agentId);c.find(m=>m.id==="main"||m.default)&&(l.default="main");let u=0;for(let m of c){if(m.workspace?.startsWith("/data"))continue;let x=m.id.replace(/-agent$/,"").replace(/^main$/,"atlas"),f=m.groupChat?.mentionPatterns||[];f.some(D=>D===x)||f.push(x),i.agents[x]={name:m.name,workspace:m.workspace,tier:"claude-code",model:"claude-sonnet-4-6",mentions:f,maxConcurrent:m.id==="main"?2:1,systemPrompt:`You are ${m.name} on AgentX.`,permissionMode:"bypassPermissions"},u++,o.dryRun||A(g(m.workspace,".claude/skills"),{recursive:!0})}console.log(` ${s.green(u)} agents imported`);let k=t.channels?.telegram?.accounts||{},y=0;for(let[m,x]of Object.entries(k)){if(!x.botToken)continue;let D=l[m]?.replace(/-agent$/,"").replace(/^main$/,"atlas")||"atlas";i.channels.telegram.accounts[m]={token:x.botToken,agentBinding:D},i.channels.telegram.enabled=!0,y++}console.log(` ${s.green(y)} Telegram accounts imported`);let N=g(a,"../cron/jobs.json");if(h(N)){let m=JSON.parse(M(N,"utf-8")),x=0;for(let f of m.jobs||[]){let D=f.name||f.id,Q=f.agentId?.replace(/-agent$/,"").replace(/^main$/,"atlas")||"atlas";i.crons[D]={enabled:f.enabled||!1,schedule:f.schedule?.expr||"0 9 * * *",timezone:f.schedule?.tz||"UTC",agent:Q,prompt:f.payload?.message||"",timeout:f.payload?.timeoutSeconds||600,onError:"log"},x++}console.log(` ${s.green(x)} cron jobs imported`)}o.dryRun?(console.log(s.yellow(`
|
|
9
|
+
Dry run \u2014 nothing written`)),console.log(JSON.stringify(i,null,2))):(b(i),console.log(s.green(`
|
|
10
|
+
Migration complete! Review agentx.json and run: agentx daemon start`))),console.log()});var U=new S().name("config").description("validate and inspect configuration");U.command("check").description("validate agentx.json and check all workspaces").option("-c, --config <path>","path to agentx.json").action(async e=>{console.log();try{let o=j(e.config);console.log(s.green(" \u2713 Config valid")),console.log(s.dim(` Node: ${o.node.name} (${o.node.id})`)),console.log(s.dim(` Bind: ${o.node.bind}`)),console.log(s.dim(` Agents: ${Object.keys(o.agents).length}`)),console.log(s.dim(` Crons: ${Object.keys(o.crons).length}`)),console.log(s.dim(` Mesh peers: ${o.mesh.peers.length}`));let n=Object.keys(o.channels.telegram.accounts).length;console.log(s.dim(` Telegram: ${o.channels.telegram.enabled?`${n} accounts`:"disabled"}`)),console.log(s.dim(` WhatsApp: ${o.channels.whatsapp.enabled?`${o.channels.whatsapp.routes.length} routes`:"disabled"}`)),console.log(s.dim(` Discord: ${o.channels.discord?.enabled?"enabled":"disabled"}`));let a=R(o);if(a.length){console.log(),console.log(s.yellow(" Warnings:"));for(let t of a)console.log(s.yellow(` \u26A0 ${t}`))}else console.log(s.green(" \u2713 All workspaces valid"));console.log();for(let[t,i]of Object.entries(o.agents)){let c=i.workspace,d=h(g(c,".claude")),l=h(g(c,"CLAUDE.md")),u=h(g(c,".claude/settings.json")),k=h(g(c,".claude/skills"))?Y(g(c,".claude/skills")).filter(N=>!N.startsWith(".")).length:0,y=[d?s.green("\u2713"):s.red("\u2717"),".claude",l?s.green("\u2713"):s.yellow("\u25CB"),"CLAUDE.md",u?s.green("\u2713"):s.yellow("\u25CB"),"settings",`${k} skills`];console.log(` ${s.cyan(t)}: ${y.join(" ")}`)}}catch(o){console.log(s.red(` \u2717 ${o.message}`))}console.log()});U.command("show").description("print the resolved configuration").option("-c, --config <path>","path to agentx.json").action(e=>{try{let o=j(e.config);console.log(JSON.stringify(o,null,2))}catch(o){console.log(s.red(o.message))}});process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function te(){let e=await z(),o=new ne().name("agentx").description("self-hosted multi-agent orchestrator \u2014 Telegram, WhatsApp, crons, A2A mesh, wiki knowledge").version(e.version||"1.0.0","-v, --version","display the version number");if(o.addCommand(v).addCommand(X).addCommand(I).addCommand(B).addCommand(P).addCommand(T).addCommand(W).addCommand(J).addCommand(K).addCommand(U),process.argv.slice(2).length===0){o.outputHelp();return}o.parse()}te();
|
|
11
11
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/daemon.ts","../src/commands/init.ts","../src/commands/manage.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\"\nimport { daemon } from \"@/commands/daemon\"\nimport { init } from \"@/commands/init\"\nimport { agent, channel, cron, mesh, skillCmd, hook, migrate } from \"@/commands/manage\"\nimport { getPackageInfo } from \"@/utils/get-package-info\"\n\nprocess.on(\"SIGINT\", () => process.exit(0))\nprocess.on(\"SIGTERM\", () => process.exit(0))\n\nasync function main() {\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(init)\n .addCommand(agent)\n .addCommand(channel)\n .addCommand(cron)\n .addCommand(mesh)\n .addCommand(skillCmd)\n .addCommand(hook)\n .addCommand(migrate)\n\n const args = process.argv.slice(2)\n if (args.length === 0) {\n program.outputHelp()\n return\n }\n\n program.parse()\n}\n\nmain()\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 const d = new AgentXDaemon(opts.config)\n await d.start()\n })\n\n// agentx daemon stop\ndaemon\n .command(\"stop\")\n .description(\"stop the running daemon\")\n .action(async () => {\n const { readFileSync, existsSync } = await import(\"fs\")\n const pidFile = \"/tmp/agentx-daemon.pid\"\n\n if (!existsSync(pidFile)) {\n console.log(chalk.yellow(\"No daemon PID file found. Trying to find process...\"))\n }\n\n try {\n // Try PID file first\n if (existsSync(pidFile)) {\n const pid = parseInt(readFileSync(pidFile, \"utf-8\").trim(), 10)\n process.kill(pid, \"SIGTERM\")\n console.log(chalk.green(`Daemon stopped (PID: ${pid})`))\n return\n }\n } catch {\n // PID might be stale\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 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\", \"clawd\")\n .option(\"-p, --path <path>\", \"remote agentx path\", \"~/agentx\")\n .option(\"--restart\", \"restart remote daemon after 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 console.log(chalk.dim(` Deploying to ${opts.user}@${host}:${opts.path}...`))\n\n try {\n execSync(`rsync -avz --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 prompts from \"prompts\"\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, cpSync, readdirSync } from \"fs\"\nimport { resolve, join } from \"path\"\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\nfunction saveConfig(config: any): void {\n writeFileSync(resolve(process.cwd(), \"agentx.json\"), JSON.stringify(config, null, 2))\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 // Create CLAUDE.md\n const claudeMd = `# ${answers.name}\\n\\n${answers.systemPrompt}\\n`\n writeFileSync(resolve(ws, \"CLAUDE.md\"), claudeMd)\n\n // Create default settings.json\n writeFileSync(resolve(ws, \".claude/settings.json\"), JSON.stringify({\n permissions: {\n allow: [\"Bash(git *)\", \"Bash(curl *)\", \"Bash(node *)\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\", \"WebFetch\", \"WebSearch\"],\n },\n }, null, 2))\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] = {\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 saveConfig(config)\n console.log(chalk.green(`\\n Agent \"${answers.id}\" added`))\n console.log(chalk.dim(` Workspace: ${ws}`))\n console.log(chalk.dim(` Wiki skill installed`))\n console.log(chalk.dim(` CLAUDE.md + settings.json created`))\n console.log()\n })\n\nagent\n .command(\"remove <id>\")\n .alias(\"rm\")\n .description(\"remove an agent from config (keeps workspace)\")\n .action((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 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 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 ],\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 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 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 saveConfig(config)\n console.log(chalk.green(` Discord added -> ${answers.agentBinding}`))\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 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((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 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((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 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 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((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 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// ==================== 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$/, \"atlas\")\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 }\n }\n console.log(` ${chalk.green(agentCount)} agents imported`)\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$/, \"atlas\") || \"atlas\"\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$/, \"atlas\") || \"atlas\"\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 saveConfig(config)\n console.log(chalk.green(\"\\n Migration complete! Review agentx.json and run: agentx daemon start\"))\n }\n console.log()\n })\n"],"mappings":"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","names":["Command","Command","chalk","daemon","Command","opts","spawn","args","child","writeFileSync","AgentXDaemon","readFileSync","existsSync","pidFile","pid","execSync","config","loadDaemonConfig","host","port","url","data","formatDuration","a","active","errors","enabledCrons","c","icon","next","p","skills","e","warnings","validateWorkspaces","w","err","spawnProc","logFile","tail","agent","messageParts","message","baseUrl","body","sshKey","remote","ssh","seconds","Command","chalk","existsSync","readFileSync","writeFileSync","mkdirSync","resolve","init","opts","cwd","configPath","envPath","sessionsDir","examplePaths","example","p","claudeDir","Command","chalk","prompts","readFileSync","writeFileSync","existsSync","mkdirSync","cpSync","readdirSync","resolve","join","loadConfig","p","saveConfig","config","agent","id","a","mentions","answers","v","ws","claudeMd","wikiSkillSrc","wikiSkillDist","skillSrc","m","channel","tg","name","acc","wa","route","target","dc","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","f","hook","settingsPath","settings","entry","migrate","configPath","searchPaths","ocPath","oc","agents","bindings","bindMap","b","agentCount","axId","tgAccounts","tgCount","axAgentId","cronPath","cronData","cronCount","job","main","packageInfo","getPackageInfo","program","Command","daemon","init","agent","channel","cron","mesh","skillCmd","hook","migrate"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/daemon.ts","../src/commands/init.ts","../src/commands/manage.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\"\nimport { daemon } from \"@/commands/daemon\"\nimport { init } from \"@/commands/init\"\nimport { agent, channel, cron, mesh, skillCmd, hook, migrate, configCmd } from \"@/commands/manage\"\nimport { getPackageInfo } from \"@/utils/get-package-info\"\n\nprocess.on(\"SIGINT\", () => process.exit(0))\nprocess.on(\"SIGTERM\", () => process.exit(0))\n\nasync function main() {\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(init)\n .addCommand(agent)\n .addCommand(channel)\n .addCommand(cron)\n .addCommand(mesh)\n .addCommand(skillCmd)\n .addCommand(hook)\n .addCommand(migrate)\n .addCommand(configCmd)\n\n const args = process.argv.slice(2)\n if (args.length === 0) {\n program.outputHelp()\n return\n }\n\n program.parse()\n}\n\nmain()\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 const d = new AgentXDaemon(opts.config)\n await d.start()\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 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\", \"clawd\")\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 prompts from \"prompts\"\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, cpSync, readdirSync } from \"fs\"\nimport { resolve, join } from \"path\"\nimport { loadDaemonConfig, validateWorkspaces } from \"@/daemon/config\"\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\nfunction saveConfig(config: any): void {\n writeFileSync(resolve(process.cwd(), \"agentx.json\"), JSON.stringify(config, null, 2))\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 // Create CLAUDE.md\n const claudeMd = `# ${answers.name}\\n\\n${answers.systemPrompt}\\n`\n writeFileSync(resolve(ws, \"CLAUDE.md\"), claudeMd)\n\n // Create default settings.json\n writeFileSync(resolve(ws, \".claude/settings.json\"), JSON.stringify({\n permissions: {\n allow: [\"Bash(git *)\", \"Bash(curl *)\", \"Bash(node *)\", \"Read\", \"Write\", \"Edit\", \"Glob\", \"Grep\", \"WebFetch\", \"WebSearch\"],\n },\n }, null, 2))\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] = {\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 saveConfig(config)\n console.log(chalk.green(`\\n Agent \"${answers.id}\" added`))\n console.log(chalk.dim(` Workspace: ${ws}`))\n console.log(chalk.dim(` Wiki skill installed`))\n console.log(chalk.dim(` CLAUDE.md + settings.json created`))\n console.log()\n })\n\nagent\n .command(\"remove <id>\")\n .alias(\"rm\")\n .description(\"remove an agent from config (keeps workspace)\")\n .action((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 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 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 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 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.noqta.tn\" },\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. noqta/mtgl-v2, 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 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 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((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 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((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 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 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((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 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// ==================== 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$/, \"atlas\")\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 }\n }\n console.log(` ${chalk.green(agentCount)} agents imported`)\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$/, \"atlas\") || \"atlas\"\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$/, \"atlas\") || \"atlas\"\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 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"],"mappings":"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","names":["Command","Command","chalk","daemon","Command","opts","spawn","args","child","writeFileSync","AgentXDaemon","readFileSync","existsSync","unlinkSync","resolve","pidFiles","pidFile","pid","r","execSync","config","loadDaemonConfig","host","port","url","data","formatDuration","a","active","errors","enabledCrons","c","icon","next","p","skills","e","warnings","validateWorkspaces","w","err","spawnProc","logFile","tail","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","prompts","readFileSync","writeFileSync","existsSync","mkdirSync","cpSync","readdirSync","resolve","join","loadConfig","p","resolve","existsSync","readFileSync","saveConfig","config","writeFileSync","agent","Command","id","a","mentions","chalk","answers","prompts","v","ws","join","mkdirSync","claudeMd","wikiSkillSrc","wikiSkillDist","skillSrc","cpSync","m","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","hook","settingsPath","settings","entry","migrate","configPath","searchPaths","ocPath","oc","agents","bindings","bindMap","b","agentCount","axId","tgAccounts","tgCount","axAgentId","cronPath","cronData","cronCount","job","configCmd","loadDaemonConfig","warnings","validateWorkspaces","w","hasClaudeDir","hasClaudeMd","hasSettings","skillCount","checks","main","packageInfo","getPackageInfo","program","Command","daemon","init","agent","channel","cron","mesh","skillCmd","hook","migrate","configCmd"]}
|