badgerclaw 0.2.26 → 0.2.27

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.
Files changed (2) hide show
  1. package/dist/index.js +23 -23
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var ho=Object.create;var ge=Object.defineProperty;var wo=Object.getOwnPropertyDescriptor;var yo=Object.getOwnPropertyNames;var _o=Object.getPrototypeOf,bo=Object.prototype.hasOwnProperty;var $o=(e,t)=>()=>(e&&(t=e(e=0)),t);var So=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Co=(e,t)=>{for(var o in t)ge(e,o,{get:t[o],enumerable:!0})},dt=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of yo(t))!bo.call(e,s)&&s!==o&&ge(e,s,{get:()=>t[s],enumerable:!(n=wo(t,s))||n.enumerable});return e};var c=(e,t,o)=>(o=e!=null?ho(_o(e)):{},dt(t||!e||!e.__esModule?ge(o,"default",{value:e,enumerable:!0}):o,e)),ut=e=>dt(ge({},"__esModule",{value:!0}),e);var W=So((ss,Do)=>{Do.exports={name:"badgerclaw",version:"0.2.26",description:"BadgerClaw CLI \u2014 one-click bot provisioning",main:"dist/index.js",bin:{badgerclaw:"./dist/index.js"},files:["dist/","README.md"],scripts:{build:"node build.mjs",test:'echo "Error: no test specified" && exit 1'},keywords:[],author:"",license:"ISC",dependencies:{"@modelcontextprotocol/sdk":"^1.29.0",axios:"^1.6.0",chalk:"^4.1.2",commander:"^12.0.0",eventsource:"^1.1.2",open:"^8.4.2",ora:"^5.4.1"},devDependencies:{"@types/eventsource":"^1.1.15","@types/node":"^20.0.0",esbuild:"^0.28.0",typescript:"^5.3.0"}}});var nt={};Co(nt,{getActiveSessions:()=>ot,launchClaudeCode:()=>Ze,launchMCPServer:()=>Qe,recordSession:()=>et,stopSession:()=>tt});function ze(){try{if(I.default.existsSync(Je))return JSON.parse(I.default.readFileSync(Je,"utf-8"))}catch{}return[]}function Ke(e){I.default.mkdirSync(q,{recursive:!0}),I.default.writeFileSync(Je,JSON.stringify(e,null,2))}function xe(e){try{return process.kill(e,0),!0}catch{return!1}}function Fo(){if(process.env.TMUX)return"tmux";try{if((0,U.execSync)(`osascript -e 'tell application "System Events" to (name of processes) contains "iTerm2"'`,{stdio:"pipe",timeout:3e3}),I.default.existsSync("/Applications/iTerm.app"))return"iterm2"}catch{}return process.platform==="darwin"?"terminal":"direct"}function Ye(e,t){let o=E.default.join(q,`claude-launcher-${t}.exp`),n=E.default.join(q,`pending-input-${t}.txt`);I.default.writeFileSync(n,"","utf-8");let s=`#!/usr/bin/expect -f
2
+ "use strict";var yo=Object.create;var fe=Object.defineProperty;var _o=Object.getOwnPropertyDescriptor;var bo=Object.getOwnPropertyNames;var $o=Object.getPrototypeOf,So=Object.prototype.hasOwnProperty;var Co=(e,t)=>()=>(e&&(t=e(e=0)),t);var vo=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Io=(e,t)=>{for(var o in t)fe(e,o,{get:t[o],enumerable:!0})},ut=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of bo(t))!So.call(e,s)&&s!==o&&fe(e,s,{get:()=>t[s],enumerable:!(n=_o(t,s))||n.enumerable});return e};var c=(e,t,o)=>(o=e!=null?yo($o(e)):{},ut(t||!e||!e.__esModule?fe(o,"default",{value:e,enumerable:!0}):o,e)),mt=e=>ut(fe({},"__esModule",{value:!0}),e);var W=vo((as,No)=>{No.exports={name:"badgerclaw",version:"0.2.27",description:"BadgerClaw CLI \u2014 one-click bot provisioning",main:"dist/index.js",bin:{badgerclaw:"./dist/index.js"},files:["dist/","README.md"],scripts:{build:"node build.mjs",test:'echo "Error: no test specified" && exit 1'},keywords:[],author:"",license:"ISC",dependencies:{"@modelcontextprotocol/sdk":"^1.29.0",axios:"^1.6.0",chalk:"^4.1.2",commander:"^12.0.0",eventsource:"^1.1.2",open:"^8.4.2",ora:"^5.4.1"},devDependencies:{"@types/eventsource":"^1.1.15","@types/node":"^20.0.0",esbuild:"^0.28.0",typescript:"^5.3.0"}}});var st={};Io(st,{getActiveSessions:()=>nt,launchClaudeCode:()=>et,launchMCPServer:()=>Ze,recordSession:()=>tt,stopSession:()=>ot});function Ke(){try{if(I.default.existsSync(ze))return JSON.parse(I.default.readFileSync(ze,"utf-8"))}catch{}return[]}function Ye(e){I.default.mkdirSync(q,{recursive:!0}),I.default.writeFileSync(ze,JSON.stringify(e,null,2))}function ke(e){try{return process.kill(e,0),!0}catch{return!1}}function Vo(){if(process.env.TMUX)return"tmux";try{if((0,U.execSync)(`osascript -e 'tell application "System Events" to (name of processes) contains "iTerm2"'`,{stdio:"pipe",timeout:3e3}),I.default.existsSync("/Applications/iTerm.app"))return"iterm2"}catch{}return process.platform==="darwin"?"terminal":"direct"}function Xe(e,t){let o=E.default.join(q,`claude-launcher-${t}.exp`),n=E.default.join(q,`pending-input-${t}.txt`);I.default.writeFileSync(n,"","utf-8");let s=`#!/usr/bin/expect -f
3
3
  set timeout -1
4
4
  set msgfile "${n}"
5
5
 
@@ -36,7 +36,7 @@ send "\\r"
36
36
  interact timeout 2 {
37
37
  check_and_send_messages
38
38
  }
39
- `;return I.default.mkdirSync(q,{recursive:!0}),I.default.writeFileSync(o,s,{mode:493}),o}function Xe(e){return Object.entries(e).map(([t,o])=>`export ${t}="${o}"`).join("; ")}function Go(e,t,o){let n=Ye(e,o.BADGERCLAW_SESSION_ID||"default"),s=Xe(o),r=`
39
+ `;return I.default.mkdirSync(q,{recursive:!0}),I.default.writeFileSync(o,s,{mode:493}),o}function Qe(e){return Object.entries(e).map(([t,o])=>`export ${t}="${o}"`).join("; ")}function Wo(e,t,o){let n=Xe(e,o.BADGERCLAW_SESSION_ID||"default"),s=Qe(o),r=`
40
40
  tell application "iTerm"
41
41
  activate
42
42
  set newWindow to (create window with default profile)
@@ -44,19 +44,19 @@ interact timeout 2 {
44
44
  write text "cd ${Ae(t)} && ${s} && ${Ae(n)}"
45
45
  end tell
46
46
  end tell
47
- `;(0,U.execSync)(`osascript -e '${r.replace(/'/g,`'"'"'`)}'`,{stdio:"pipe",timeout:1e4})}function Vo(e,t,o){let n=Ye(e,o.BADGERCLAW_SESSION_ID||"default"),s=Xe(o),a=`
47
+ `;(0,U.execSync)(`osascript -e '${r.replace(/'/g,`'"'"'`)}'`,{stdio:"pipe",timeout:1e4})}function Ho(e,t,o){let n=Xe(e,o.BADGERCLAW_SESSION_ID||"default"),s=Qe(o),a=`
48
48
  tell application "Terminal"
49
49
  activate
50
50
  do script "${`cd ${Ae(t)} && ${s} && ${Ae(n)}`.replace(/"/g,'\\"')}"
51
51
  end tell
52
- `;(0,U.execSync)(`osascript -e '${a.replace(/'/g,`'"'"'`)}'`,{stdio:"pipe",timeout:1e4})}function Wo(e,t,o){let n=Ye(e,o.BADGERCLAW_SESSION_ID||"default"),s=Xe(o),r=`badgerclaw-${o.BADGERCLAW_SESSION_ID||"default"}`,a=`cd ${t} && ${s} && ${n}`;(0,U.execSync)(`tmux new-session -d -s ${r} "${a}"`,{stdio:"pipe",timeout:1e4})}function Ae(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Qe(e){let t=E.default.join(__dirname,"..","claude-code","mcp-server.js"),o=I.default.existsSync(t)?t:E.default.join(__dirname,"mcp-server.js"),n=(0,U.spawn)("node",[o],{env:{...process.env,BADGERCLAW_MCP_PORT:String(e.port),BADGERCLAW_SESSION_ID:e.sessionId},cwd:e.projectDir,stdio:"ignore",detached:!0});return n.unref(),n}function Ze(e){let t=E.default.join(E.default.dirname(process.argv[1]||""),"..","lib","node_modules","badgerclaw","dist","claude-code","mcp-server.js"),o=E.default.join(__dirname,"..","claude-code","mcp-server.js"),n=E.default.join(__dirname,"mcp-server.js"),s=I.default.existsSync(t)?t:I.default.existsSync(o)?o:n,r={BADGERCLAW_MCP_PORT:String(e.port),BADGERCLAW_SESSION_ID:e.sessionId},a=JSON.stringify({mcpServers:{badgerclaw:{command:"node",args:[s],env:r}}}),i=E.default.join(q,`mcp-config-${e.sessionId}.json`);I.default.mkdirSync(q,{recursive:!0}),I.default.writeFileSync(i,a,"utf-8");let l=`claude --dangerously-skip-permissions --mcp-config ${i}`;switch(Fo()){case"iterm2":Go(l,e.projectDir,r);break;case"terminal":Vo(l,e.projectDir,r);break;case"tmux":Wo(l,e.projectDir,r);break;case"direct":(0,U.spawn)(l,[],{shell:!0,cwd:e.projectDir,env:{...process.env,...r},stdio:"ignore",detached:!0}).unref();break}}function et(e,t,o,n,s){let r=ze().filter(a=>a.sessionId!==e);r.push({sessionId:e,pid:t,mcpPid:o,port:n,projectDir:s,startedAt:new Date().toISOString()}),Ke(r)}function tt(e){let t=ze(),o=t.find(s=>s.sessionId===e);if(!o)return!1;if(o.mcpPid&&xe(o.mcpPid))try{process.kill(o.mcpPid,"SIGTERM")}catch{}if(o.pid&&xe(o.pid))try{process.kill(o.pid,"SIGTERM")}catch{}try{(0,U.execSync)(`tmux kill-session -t badgerclaw-${e} 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let n=t.filter(s=>s.sessionId!==e);return Ke(n),!0}function ot(){let e=ze(),t=e.filter(o=>xe(o.mcpPid)||xe(o.pid));return t.length!==e.length&&Ke(t),t}var U,I,E,Ht,q,Je,ke=$o(()=>{"use strict";U=require("child_process"),I=c(require("fs")),E=c(require("path")),Ht=c(require("os")),q=E.default.join(Ht.default.homedir(),".badgerclaw"),Je=E.default.join(q,"claude-sessions.json")});var fo=require("commander");var Dt=require("commander"),H=c(require("chalk")),Ot=c(require("ora")),Nt=c(require("open")),Y=c(require("os")),Tt=c(require("crypto"));var Ne=c(require("crypto"));function mt(){return Ne.default.randomBytes(32).toString("base64url")}function pt(e){return Ne.default.createHash("sha256").update(e).digest("base64url")}var te=c(require("fs")),Te=c(require("path")),gt=c(require("os")),ft=Te.default.join(gt.default.homedir(),".badgerclaw"),Le=Te.default.join(ft,"auth.json");function h(){try{let e=te.default.readFileSync(Le,"utf-8");return JSON.parse(e)}catch{return null}}function fe(e){te.default.mkdirSync(ft,{recursive:!0}),te.default.writeFileSync(Le,JSON.stringify(e,null,2),{mode:384})}function ht(){try{te.default.unlinkSync(Le)}catch{}}function he(){let e=h();return e?new Date(e.expires_at)>new Date:!1}function we(e){let t=e.match(/^@?([^:]+)/);return t?t[1]:e}var oe=c(require("axios"));var wt=process.env.BADGERCLAW_ENV==="local",k=process.env.BADGERCLAW_API_URL??(wt?"http://localhost:8000":"https://api.badger.signout.io"),yt=process.env.BADGERCLAW_AUTH_URL??(wt?"http://localhost:5500":"https://badgerclaw.ai");var _e=k,ye=null;async function je(){let e=h();if(!e?.refresh_token||!e?.email)return null;try{let t=await oe.default.post(`${_e}/api/v1/user/token/refresh`,{refresh_token:e.refresh_token,email:e.email}),o=t.data?.result??t.data,n=o?.access_token;if(!n)return null;let s=o.expires_in||3600,r=new Date(Date.now()+s*1e3).toISOString();return fe({...e,access_token:n,expires_at:r}),n}catch{return null}}function Be(e){return e.interceptors.response.use(t=>(t.data&&typeof t.data=="object"&&"result"in t.data&&"errors"in t.data&&(t.data=t.data.result),t),t=>{let o=t.response?.data?.errors;return o?.length&&(t.message=o[0]),Promise.reject(t)}),e}function _t(e){return e.interceptors.response.use(void 0,async t=>{let o=t.config;if(t.response?.status!==401||o._retried)return Promise.reject(t);o._retried=!0,ye||(ye=je().finally(()=>{ye=null}));let n=await ye;return n?(o.headers.Authorization=`Bearer ${n}`,e.request(o)):Promise.reject(t)}),e}function S(){let e=h(),t={"Content-Type":"application/json"};e&&(t.Authorization=`Bearer ${e.access_token}`);let o=oe.default.create({baseURL:_e,headers:t});return Be(o),_t(o),o}function bt(){return Be(oe.default.create({baseURL:_e,headers:{"Content-Type":"application/json"}}))}function be(e){let t=oe.default.create({baseURL:_e,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`}});return Be(t),_t(t),t}var $t=require("commander"),T=c(require("chalk")),Ue=c(require("ora")),St=c(require("os")),Ct=c(require("path"));var Kn=Ct.default.join(St.default.homedir(),".openclaw","openclaw.json");async function ne(e,t,o,n){let s=h();if(!s)return;let r=n?null:(0,Ue.default)(`Pairing bot: ${t}...`).start();try{let a=await fetch(`${k}/api/v1/pairing/redeem`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:e})});if(!a.ok){let O=await a.json().catch(()=>({errors:[a.statusText]}));r?.fail(T.default.red(`Failed to redeem ${t}: ${O.errors?.[0]||a.status}`));return}let i=await a.json(),l=i.result??i,{execSync:g}=await import("child_process"),f=`channels.badgerclaw.accounts.${l.user_id.split(":")[0].replace("@","").replace(/_bot$/,"")}`;g(`openclaw config set ${f}.userId "${l.user_id}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),g(`openclaw config set ${f}.accessToken "${l.access_token}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),g(`openclaw config set ${f}.homeserver "${l.homeserver}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),g(`openclaw config set ${f}.encryption true`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),l.device_id&&g(`openclaw config set ${f}.deviceId "${l.device_id}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),await fetch(`${k}/api/v1/openclaw/pending-pairs/${e}/claim`,{method:"POST",headers:{Authorization:`Bearer ${s.access_token}`}}).catch(()=>{}),r?.succeed(T.default.green(`\u2705 ${l.bot_name} (${l.user_id}) paired \u2014 bot is live!`))}catch(a){r?.fail(T.default.red(`Failed to pair ${t}: ${a.message}`))}}async function se(e=!1){let t=h();if(!t)return 0;let o=be(t.access_token);try{let{data:n}=await o.get("/api/v1/openclaw/pending-pairs");if(!n||n.length===0)return 0;let s=new Map;for(let a of n)s.set(a.bot_user_id,a);for(let a of n)s.get(a.bot_user_id)!==a&&await o.post(`/api/v1/openclaw/pending-pairs/${a.pair_code}/claim`).catch(()=>{});let r=0;for(let a of s.values()){let i=e?null:(0,Ue.default)(`Pairing bot: ${a.bot_name} (${a.bot_user_id})`).start();try{await ne(a.pair_code,a.bot_name,a.bot_user_id,e),await o.post(`/api/v1/openclaw/pending-pairs/${a.pair_code}/claim`).catch(()=>{}),r++}catch(l){i?.fail(T.default.red(`Error pairing ${a.bot_name}: ${l}`))}}if(r>0)try{let{execSync:a}=await import("child_process");a("openclaw gateway restart",{stdio:"ignore"}),e||console.log(T.default.green(`
52
+ `;(0,U.execSync)(`osascript -e '${a.replace(/'/g,`'"'"'`)}'`,{stdio:"pipe",timeout:1e4})}function qo(e,t,o){let n=Xe(e,o.BADGERCLAW_SESSION_ID||"default"),s=Qe(o),r=`badgerclaw-${o.BADGERCLAW_SESSION_ID||"default"}`,a=`cd ${t} && ${s} && ${n}`;(0,U.execSync)(`tmux new-session -d -s ${r} "${a}"`,{stdio:"pipe",timeout:1e4})}function Ae(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Ze(e){let t=E.default.join(__dirname,"..","claude-code","mcp-server.js"),o=I.default.existsSync(t)?t:E.default.join(__dirname,"mcp-server.js"),n=(0,U.spawn)("node",[o],{env:{...process.env,BADGERCLAW_MCP_PORT:String(e.port),BADGERCLAW_SESSION_ID:e.sessionId},cwd:e.projectDir,stdio:"ignore",detached:!0});return n.unref(),n}function et(e){let t=E.default.join(E.default.dirname(process.argv[1]||""),"..","lib","node_modules","badgerclaw","dist","claude-code","mcp-server.js"),o=E.default.join(__dirname,"..","claude-code","mcp-server.js"),n=E.default.join(__dirname,"mcp-server.js"),s=I.default.existsSync(t)?t:I.default.existsSync(o)?o:n,r={BADGERCLAW_MCP_PORT:String(e.port),BADGERCLAW_SESSION_ID:e.sessionId},a=JSON.stringify({mcpServers:{badgerclaw:{command:"node",args:[s],env:r}}}),i=E.default.join(q,`mcp-config-${e.sessionId}.json`);I.default.mkdirSync(q,{recursive:!0}),I.default.writeFileSync(i,a,"utf-8");let l=`claude --dangerously-skip-permissions --mcp-config ${i}`;switch(Vo()){case"iterm2":Wo(l,e.projectDir,r);break;case"terminal":Ho(l,e.projectDir,r);break;case"tmux":qo(l,e.projectDir,r);break;case"direct":(0,U.spawn)(l,[],{shell:!0,cwd:e.projectDir,env:{...process.env,...r},stdio:"ignore",detached:!0}).unref();break}}function tt(e,t,o,n,s){let r=Ke().filter(a=>a.sessionId!==e);r.push({sessionId:e,pid:t,mcpPid:o,port:n,projectDir:s,startedAt:new Date().toISOString()}),Ye(r)}function ot(e){let t=Ke(),o=t.find(s=>s.sessionId===e);if(!o)return!1;if(o.mcpPid&&ke(o.mcpPid))try{process.kill(o.mcpPid,"SIGTERM")}catch{}if(o.pid&&ke(o.pid))try{process.kill(o.pid,"SIGTERM")}catch{}try{(0,U.execSync)(`tmux kill-session -t badgerclaw-${e} 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let n=t.filter(s=>s.sessionId!==e);return Ye(n),!0}function nt(){let e=Ke(),t=e.filter(o=>ke(o.mcpPid)||ke(o.pid));return t.length!==e.length&&Ye(t),t}var U,I,E,Jt,q,ze,Re=Co(()=>{"use strict";U=require("child_process"),I=c(require("fs")),E=c(require("path")),Jt=c(require("os")),q=E.default.join(Jt.default.homedir(),".badgerclaw"),ze=E.default.join(q,"claude-sessions.json")});var wo=require("commander");var Nt=require("commander"),H=c(require("chalk")),Tt=c(require("ora")),jt=c(require("open")),Y=c(require("os")),Lt=c(require("crypto"));var Te=c(require("crypto"));function pt(){return Te.default.randomBytes(32).toString("base64url")}function gt(e){return Te.default.createHash("sha256").update(e).digest("base64url")}var te=c(require("fs")),je=c(require("path")),ft=c(require("os")),ht=je.default.join(ft.default.homedir(),".badgerclaw"),Le=je.default.join(ht,"auth.json");function h(){try{let e=te.default.readFileSync(Le,"utf-8");return JSON.parse(e)}catch{return null}}function he(e){te.default.mkdirSync(ht,{recursive:!0}),te.default.writeFileSync(Le,JSON.stringify(e,null,2),{mode:384})}function wt(){try{te.default.unlinkSync(Le)}catch{}}function we(){let e=h();return e?new Date(e.expires_at)>new Date:!1}function ye(e){let t=e.match(/^@?([^:]+)/);return t?t[1]:e}var ne=c(require("axios"));var yt=process.env.BADGERCLAW_ENV==="local",A=process.env.BADGERCLAW_API_URL??(yt?"http://localhost:8000":"https://api.badger.signout.io"),_t=process.env.BADGERCLAW_AUTH_URL??(yt?"http://localhost:5500":"https://badgerclaw.ai");var be=A,_e=null,oe=null;function bt(){return oe}async function Be(){let e=h();if(!e?.refresh_token||!e?.email)return oe=e?e.refresh_token?"no email in auth.json \u2014 re-run `badgerclaw login`":"no refresh_token in auth.json \u2014 re-run `badgerclaw login`":"not logged in (auth.json missing)",null;try{let t=await ne.default.post(`${be}/api/v1/user/token/refresh`,{refresh_token:e.refresh_token,email:e.email}),o=t.data?.result??t.data,n=o?.access_token;if(!n)return oe="server returned no access_token",null;let s=o.expires_in||3600,r=new Date(Date.now()+s*1e3).toISOString();return he({...e,access_token:n,expires_at:r}),oe=null,n}catch(t){let o=t?.response?.status,n=t?.response?.data?.errors?.[0]||t?.response?.data?.detail||t?.message||"unknown error";return oe=o?`HTTP ${o}: ${n}`:`network error: ${n}`,null}}function Ue(e){return e.interceptors.response.use(t=>(t.data&&typeof t.data=="object"&&"result"in t.data&&"errors"in t.data&&(t.data=t.data.result),t),t=>{let o=t.response?.data?.errors;return o?.length&&(t.message=o[0]),Promise.reject(t)}),e}function $t(e){return e.interceptors.response.use(void 0,async t=>{let o=t.config;if(t.response?.status!==401||o._retried)return Promise.reject(t);o._retried=!0,_e||(_e=Be().finally(()=>{_e=null}));let n=await _e;return n?(o.headers.Authorization=`Bearer ${n}`,e.request(o)):Promise.reject(t)}),e}function S(){let e=h(),t={"Content-Type":"application/json"};e&&(t.Authorization=`Bearer ${e.access_token}`);let o=ne.default.create({baseURL:be,headers:t});return Ue(o),$t(o),o}function St(){return Ue(ne.default.create({baseURL:be,headers:{"Content-Type":"application/json"}}))}function $e(e){let t=ne.default.create({baseURL:be,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`}});return Ue(t),$t(t),t}var Ct=require("commander"),T=c(require("chalk")),Me=c(require("ora")),vt=c(require("os")),It=c(require("path"));var Xn=It.default.join(vt.default.homedir(),".openclaw","openclaw.json");async function se(e,t,o,n){let s=h();if(!s)return;let r=n?null:(0,Me.default)(`Pairing bot: ${t}...`).start();try{let a=await fetch(`${A}/api/v1/pairing/redeem`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:e})});if(!a.ok){let O=await a.json().catch(()=>({errors:[a.statusText]}));r?.fail(T.default.red(`Failed to redeem ${t}: ${O.errors?.[0]||a.status}`));return}let i=await a.json(),l=i.result??i,{execSync:g}=await import("child_process"),f=`channels.badgerclaw.accounts.${l.user_id.split(":")[0].replace("@","").replace(/_bot$/,"")}`;g(`openclaw config set ${f}.userId "${l.user_id}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),g(`openclaw config set ${f}.accessToken "${l.access_token}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),g(`openclaw config set ${f}.homeserver "${l.homeserver}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),g(`openclaw config set ${f}.encryption true`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),l.device_id&&g(`openclaw config set ${f}.deviceId "${l.device_id}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),await fetch(`${A}/api/v1/openclaw/pending-pairs/${e}/claim`,{method:"POST",headers:{Authorization:`Bearer ${s.access_token}`}}).catch(()=>{}),r?.succeed(T.default.green(`\u2705 ${l.bot_name} (${l.user_id}) paired \u2014 bot is live!`))}catch(a){r?.fail(T.default.red(`Failed to pair ${t}: ${a.message}`))}}async function re(e=!1){let t=h();if(!t)return 0;let o=$e(t.access_token);try{let{data:n}=await o.get("/api/v1/openclaw/pending-pairs");if(!n||n.length===0)return 0;let s=new Map;for(let a of n)s.set(a.bot_user_id,a);for(let a of n)s.get(a.bot_user_id)!==a&&await o.post(`/api/v1/openclaw/pending-pairs/${a.pair_code}/claim`).catch(()=>{});let r=0;for(let a of s.values()){let i=e?null:(0,Me.default)(`Pairing bot: ${a.bot_name} (${a.bot_user_id})`).start();try{await se(a.pair_code,a.bot_name,a.bot_user_id,e),await o.post(`/api/v1/openclaw/pending-pairs/${a.pair_code}/claim`).catch(()=>{}),r++}catch(l){i?.fail(T.default.red(`Error pairing ${a.bot_name}: ${l}`))}}if(r>0)try{let{execSync:a}=await import("child_process");a("openclaw gateway restart",{stdio:"ignore"}),e||console.log(T.default.green(`
53
53
  \u26A1 ${r} bot(s) paired \u2014 gateway restarted, bots are live!`))}catch{e||console.log(T.default.yellow(`
54
- \u26A1 ${r} bot(s) paired. Run: openclaw gateway restart`))}return r}catch{return 0}}var vt=new $t.Command("autopair").description("Check for pending bot pairs and connect them to OpenClaw automatically").action(async()=>{if(!h()){console.log(T.default.yellow("Not logged in. Run `badgerclaw login` first."));return}console.log(T.default.dim("Checking for pending bot pairs...")),await se(!1)===0&&console.log(T.default.dim("No pending pairs found."))});var Pt=c(require("os"));var $e=c(require("fs")),K=c(require("path")),re=c(require("os")),ae=require("child_process"),It="ai.badgerclaw.watch",xt=K.default.join(re.default.homedir(),"Library","LaunchAgents"),Me=K.default.join(xt,`${It}.plist`);function vo(){try{return(0,ae.execSync)("which badgerclaw",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/badgerclaw"}}function Io(){try{return(0,ae.execSync)("which node",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/node"}}function xo(e){let t=K.default.join(re.default.homedir(),".badgerclaw"),o=Io(),n=K.default.dirname(o);return`<?xml version="1.0" encoding="UTF-8"?>
54
+ \u26A1 ${r} bot(s) paired. Run: openclaw gateway restart`))}return r}catch{return 0}}var xt=new Ct.Command("autopair").description("Check for pending bot pairs and connect them to OpenClaw automatically").action(async()=>{if(!h()){console.log(T.default.yellow("Not logged in. Run `badgerclaw login` first."));return}console.log(T.default.dim("Checking for pending bot pairs...")),await re(!1)===0&&console.log(T.default.dim("No pending pairs found."))});var Dt=c(require("os"));var Se=c(require("fs")),K=c(require("path")),ae=c(require("os")),ie=require("child_process"),kt="ai.badgerclaw.watch",At=K.default.join(ae.default.homedir(),"Library","LaunchAgents"),Fe=K.default.join(At,`${kt}.plist`);function xo(){try{return(0,ie.execSync)("which badgerclaw",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/badgerclaw"}}function ko(){try{return(0,ie.execSync)("which node",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/node"}}function Ao(e){let t=K.default.join(ae.default.homedir(),".badgerclaw"),o=ko(),n=K.default.dirname(o);return`<?xml version="1.0" encoding="UTF-8"?>
55
55
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
56
56
  <plist version="1.0">
57
57
  <dict>
58
58
  <key>Label</key>
59
- <string>${It}</string>
59
+ <string>${kt}</string>
60
60
  <key>ProgramArguments</key>
61
61
  <array>
62
62
  <string>${o}</string>
@@ -79,7 +79,7 @@ interact timeout 2 {
79
79
  <key>ThrottleInterval</key>
80
80
  <integer>30</integer>
81
81
  </dict>
82
- </plist>`}function At(){if(re.default.platform()==="darwin")try{let e=vo();$e.default.mkdirSync(xt,{recursive:!0}),$e.default.mkdirSync(K.default.join(re.default.homedir(),".badgerclaw"),{recursive:!0}),$e.default.writeFileSync(Me,xo(e));try{(0,ae.execSync)(`launchctl unload "${Me}" 2>/dev/null`)}catch{}(0,ae.execSync)(`launchctl load "${Me}"`),console.log("\x1B[2mPair-watcher registered as background service (auto-starts on login).\x1B[0m")}catch{console.log("\x1B[2mNote: could not register background service. Run `badgerclaw watch` manually.\x1B[0m")}}var Se=c(require("fs")),ie=c(require("path")),Ce=c(require("os")),B=require("child_process"),Fe="badgerclaw-watch.service",kt=ie.default.join(Ce.default.homedir(),".config","systemd","user"),Ao=ie.default.join(kt,Fe);function ko(){try{return(0,B.execSync)("which badgerclaw",{encoding:"utf-8"}).trim()}catch{return"/usr/local/bin/badgerclaw"}}function Ro(){try{return(0,B.execSync)("which node",{encoding:"utf-8"}).trim()}catch{return"/usr/bin/node"}}function Po(e){let t=Ro(),o=ie.default.dirname(t);return`[Unit]
82
+ </plist>`}function Rt(){if(ae.default.platform()==="darwin")try{let e=xo();Se.default.mkdirSync(At,{recursive:!0}),Se.default.mkdirSync(K.default.join(ae.default.homedir(),".badgerclaw"),{recursive:!0}),Se.default.writeFileSync(Fe,Ao(e));try{(0,ie.execSync)(`launchctl unload "${Fe}" 2>/dev/null`)}catch{}(0,ie.execSync)(`launchctl load "${Fe}"`),console.log("\x1B[2mPair-watcher registered as background service (auto-starts on login).\x1B[0m")}catch{console.log("\x1B[2mNote: could not register background service. Run `badgerclaw watch` manually.\x1B[0m")}}var Ce=c(require("fs")),ce=c(require("path")),ve=c(require("os")),B=require("child_process"),Ge="badgerclaw-watch.service",Pt=ce.default.join(ve.default.homedir(),".config","systemd","user"),Ro=ce.default.join(Pt,Ge);function Po(){try{return(0,B.execSync)("which badgerclaw",{encoding:"utf-8"}).trim()}catch{return"/usr/local/bin/badgerclaw"}}function Eo(){try{return(0,B.execSync)("which node",{encoding:"utf-8"}).trim()}catch{return"/usr/bin/node"}}function Do(e){let t=Eo(),o=ce.default.dirname(t);return`[Unit]
83
83
  Description=BadgerClaw background watcher (heartbeat + pair events)
84
84
  After=network-online.target
85
85
  Wants=network-online.target
@@ -95,9 +95,9 @@ StandardError=append:%h/.badgerclaw/heartbeat.log
95
95
 
96
96
  [Install]
97
97
  WantedBy=default.target
98
- `}function Eo(){try{return(0,B.execSync)("systemctl --user --version",{stdio:"ignore"}),!0}catch{return!1}}function Rt(){if(Ce.default.platform()==="linux"){if(!Eo()){console.log("\x1B[2mNote: systemctl --user not available. Run `badgerclaw heartbeat` manually or start it under a process manager.\x1B[0m");return}try{let e=ko();Se.default.mkdirSync(kt,{recursive:!0}),Se.default.mkdirSync(ie.default.join(Ce.default.homedir(),".badgerclaw"),{recursive:!0}),Se.default.writeFileSync(Ao,Po(e)),(0,B.execSync)("systemctl --user daemon-reload",{stdio:"ignore"});try{(0,B.execSync)(`systemctl --user restart ${Fe}`,{stdio:"ignore"})}catch{}(0,B.execSync)(`systemctl --user enable --now ${Fe}`,{stdio:"ignore"});try{let t=(0,B.execSync)("whoami",{encoding:"utf-8"}).trim();(0,B.execSync)(`loginctl enable-linger ${t}`,{stdio:"ignore"})}catch{}console.log("\x1B[2mHeartbeat daemon registered as systemd user service (auto-starts on login).\x1B[0m")}catch{console.log("\x1B[2mNote: could not register systemd user service. Run `badgerclaw heartbeat` manually.\x1B[0m")}}}function Et(){let e=Pt.default.platform();if(e==="darwin")return At();if(e==="linux")return Rt();console.log("\x1B[2mNote: background daemon install not supported on "+e+". Run `badgerclaw heartbeat` manually.\x1B[0m")}var Oo=2e3,No=12e4,Lt=new Dt.Command("login").description("Log in to BadgerClaw via browser").action(async()=>{let e=mt(),t=pt(e),o=`${yt}/cli-auth?code=${t}`;console.log(H.default.yellow("Opening browser for authentication...")),console.log(H.default.dim(`If the browser doesn't open, visit: ${o}`)),await(0,Nt.default)(o);let n=(0,Ot.default)("Waiting for authentication...").start(),s=bt(),r=Date.now();for(;Date.now()-r<No;){try{let a=await s.post(`/api/v1/openclaw/cli/auth/poll/${t}`,{code_verifier:e,code_challenge:t});if(a.status===429){await new Promise(i=>setTimeout(i,5e3));continue}if(a.data?.access_token){let{access_token:i,user_id:l,expires_at:g,refresh_token:C,email:f}=a.data,O=Tt.default.createHash("sha256").update(`${Y.default.hostname()}-${Y.default.platform()}-${Y.default.arch()}`).digest("hex").slice(0,16),P=`openclaw-${Y.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${O}`;fe({access_token:i,user_id:l,instance_id:P,expires_at:g,refresh_token:C,email:f});try{let{version:v}=W();await s.post("/api/v1/openclaw/register",{instance_id:P,label:Y.default.hostname(),version:v},{headers:{Authorization:`Bearer ${i}`}})}catch{}n.succeed(H.default.green(`Logged in as ${we(l)}`));let N=await se(!0);N>0&&(console.log(H.default.green(`\u2705 ${N} bot(s) automatically paired to OpenClaw.`)),console.log(H.default.yellow("Run: openclaw gateway restart to activate."))),Et();return}}catch{}await new Promise(a=>setTimeout(a,Oo))}n.fail(H.default.red("Authentication timed out. Please try again.")),process.exit(1)});var jt=require("commander"),Ge=c(require("chalk"));var Bt=new jt.Command("logout").description("Disconnect this machine and log out of BadgerClaw").action(async()=>{let e=h();if(!e){console.log(Ge.default.yellow("Not logged in."));return}try{let t=be(e.access_token),{version:o}=W();await t.post("/api/v1/openclaw/register",{instance_id:e.instance_id,label:require("os").hostname(),version:o,online:!1})}catch{}ht(),console.log(Ge.default.green("Logged out \u2014 this machine is now disconnected."))});var Ut=require("commander"),Ve=c(require("chalk"));var Mt=new Ut.Command("status").description("Show connected instance info").action(async()=>{let e=h();(!e||!he())&&(console.log(Ve.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1)),console.log(Ve.default.green("Authenticated")),console.log(` User: ${we(e.user_id)}`),console.log(` Instance: ${e.instance_id}`),console.log(` Expires: ${new Date(e.expires_at).toLocaleDateString()}`)});var ce=require("commander"),R=c(require("chalk")),ve=c(require("ora"));function We(){he()||(console.log(R.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1))}function To(e){return/^[a-z0-9_]{4,20}$/.test(e)}function Lo(e){return e.replace(/_bot$/,"")}var jo=new ce.Command("create").description("Create a new bot").argument("<name>","Bot name (4-20 chars, lowercase alphanumeric + underscores)").action(async e=>{We(),To(e)||(console.log(R.default.red("Invalid bot name. Must be 4-20 characters, lowercase alphanumeric and underscores only.")),process.exit(1));let t=(0,ve.default)(`Creating bot "${e}"...`).start();try{await S().post("/api/v1/openclaw/bots",{username:e}),t.succeed(R.default.green(`Bot "${e}" created successfully!`))}catch(o){let n=o.response?.data?.errors?.[0]||o.message;t.fail(R.default.red(`Failed to create bot: ${n}`)),process.exit(1)}}),Bo=new ce.Command("list").description("List your bots").action(async()=>{We();let e=(0,ve.default)("Fetching bots...").start();try{let n=(await S().get("/api/v1/openclaw/bots")).data?.bots||[];if(e.stop(),n.length===0){console.log(R.default.yellow("No bots found. Create one with `badgerclaw bot create <name>`."));return}console.log(R.default.green(`Your bots (${n.length}):
99
- `));for(let s of n){let r=Lo(s.username||s.name),a=s.active!==!1?R.default.green("active"):R.default.dim("inactive");console.log(` ${R.default.bold(r)} ${a}`)}}catch(t){let o=t.response?.data?.errors?.[0]||t.message;e.fail(R.default.red(`Failed to list bots: ${o}`)),process.exit(1)}}),Uo=new ce.Command("delete").description("Deactivate a bot").argument("<name>","Bot name to deactivate").action(async e=>{We();let t=(0,ve.default)(`Deactivating bot "${e}"...`).start();try{await S().delete(`/api/v1/openclaw/bots/${e}`),t.succeed(R.default.green(`Bot "${e}" deactivated.`))}catch(o){let n=o.response?.data?.errors?.[0]||o.message;t.fail(R.default.red(`Failed to deactivate bot: ${n}`)),process.exit(1)}}),Ft=new ce.Command("bot").description("Manage bots").addCommand(jo).addCommand(Bo).addCommand(Uo);var eo=require("commander"),m=c(require("chalk"));var qe=c(require("axios")),Mo=7331,Gt=`http://localhost:${Mo}`,He="unknown";async function le(){try{let t=(await qe.default.get(`${Gt}/health`,{timeout:5e3})).data;return t.pluginVersion&&t.pluginVersion!=="unknown"&&(He=t.pluginVersion),t}catch{return{status:"stopped",pid:null,lastRestart:null,pluginVersion:He,bots:[]}}}function Vt(e){e&&e!=="unknown"&&(He=e)}async function X(){try{return{success:!0,message:(await qe.default.post(`${Gt}/restart`,{},{timeout:15e3})).data?.message||"Gateway restart initiated"}}catch(e){try{let{execSync:t}=await import("child_process");return t("openclaw gateway restart",{stdio:"pipe",timeout:15e3}),{success:!0,message:"Gateway restarted via CLI fallback"}}catch{return{success:!1,message:e.message||"Failed to restart gateway"}}}}var zt=require("commander"),d=c(require("chalk")),Kt=c(require("axios"));var L=c(require("os")),Wt=c(require("crypto"));function de(){let e=h();if(e?.instance_id)return e.instance_id;let t=Wt.default.createHash("sha256").update(`${L.default.hostname()}-${L.default.platform()}-${L.default.arch()}`).digest("hex").slice(0,16);return`openclaw-${L.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${t}`}function Ie(){return{hostname:L.default.hostname(),os:L.default.platform(),arch:L.default.arch(),uptimeSeconds:Math.floor(L.default.uptime()),memFreeMb:Math.floor(L.default.freemem()/1024/1024)}}var $=require("child_process"),u=c(require("fs")),_=c(require("path")),ue=c(require("os")),x=c(require("axios"));async function M(e){return e.command_type==="update_cli"?qo(e.payload?.target_version):e.command_type==="update_plugin"?Jo(e.payload?.target_version):e.command_type==="restart_gateway"?Ho():e.command_type==="leave_room"?an(e.payload):e.command_type==="start_claude_code"?Qo(e.payload):e.command_type==="stop_claude_code"?Zo(e.payload):e.command_type==="start_claude_control"?en(e.payload):e.command_type==="stop_claude_control"?tn(e.payload):e.command_type==="update_claude_tools"?on(e.payload):e.command_type==="bot_share_notify"?nn(e.payload):e.command_type==="bot_share_revoked"?sn(e.payload):e.command_type==="bot_share_expired"?rn(e.payload):{success:!1,message:`Unknown command: ${e.command_type}`}}function Ho(){try{return(0,$.execSync)("openclaw gateway restart",{stdio:"pipe",timeout:15e3}),{success:!0,message:"Gateway restarted"}}catch{try{return{success:!0,message:`Gateway restarted via probe: ${(0,$.execSync)("curl -s -X POST http://localhost:7331/restart",{stdio:"pipe",timeout:1e4}).toString()}`}}catch(e){return{success:!1,message:`Gateway restart failed: ${e.message||"unknown error"}`}}}}function qo(e){let t=e?`badgerclaw@${e}`:"badgerclaw@latest";try{(0,$.execSync)(`npm install -g ${t}`,{stdio:"pipe",timeout:12e4});let o=(0,$.execSync)("npm list -g badgerclaw --json",{stdio:"pipe"}).toString(),s=JSON.parse(o)?.dependencies?.badgerclaw?.version||"unknown";return Ko(),{success:!0,message:`Updated CLI to ${s}`,newVersion:s}}catch(o){let n=o.stderr?.toString()||o.message||"Unknown error";return n.includes("EACCES")||n.includes("permission")?{success:!1,message:"Permission denied. Run: sudo npm install -g badgerclaw"}:{success:!1,message:`CLI update failed: ${n.slice(0,500)}`}}}async function Jo(e){let t=_.default.join(ue.default.homedir(),".openclaw","extensions","badgerclaw");if(!u.default.existsSync(t))return{success:!1,message:"Cannot find plugin directory (~/.openclaw/extensions/badgerclaw). Re-run: badgerclaw setup"};let o=e?`@badgerclaw/connect@${e}`:"@badgerclaw/connect@latest";try{(0,$.execSync)(`npm install ${o}`,{cwd:t,stdio:"pipe",timeout:12e4});let n=_.default.join(t,"node_modules","@badgerclaw","connect"),s=_.default.join(n,"package.json"),r="unknown";u.default.existsSync(s)&&(r=JSON.parse(u.default.readFileSync(s,"utf-8")).version||"unknown"),Vt(r),zo(n,t);let a=_.default.join(t,"package.json");if(u.default.existsSync(a)&&u.default.existsSync(s))try{let i=JSON.parse(u.default.readFileSync(a,"utf-8")),l=JSON.parse(u.default.readFileSync(s,"utf-8"));i.version=r,l.openclaw&&(i.openclaw={...i.openclaw,...l.openclaw}),u.default.writeFileSync(a,JSON.stringify(i,null,2)+`
100
- `)}catch{}try{(0,$.execSync)("openclaw gateway restart",{stdio:"pipe",timeout:1e4})}catch{}for(let i=0;i<15;i++){await new Promise(l=>setTimeout(l,1e3));try{let l=await x.default.get("http://localhost:7331/health",{timeout:3e3});if(l.data?.status==="running"&&l.data?.pluginVersion===r)break}catch{}}return{success:!0,message:`Updated plugin to ${r}, gateway restarted`,newVersion:r}}catch(n){return{success:!1,message:`Plugin update failed: ${(n.stderr?.toString()||n.message||"").slice(0,500)}`}}}function zo(e,t){let o=_.default.join(e,"dist"),n=_.default.join(t,"dist");u.default.existsSync(o)&&(u.default.mkdirSync(n,{recursive:!0}),st(o,n));let s=_.default.join(e,"openclaw.plugin.json");u.default.existsSync(s)&&u.default.copyFileSync(s,_.default.join(t,"openclaw.plugin.json"));let r=_.default.join(e,"scripts"),a=_.default.join(t,"scripts");u.default.existsSync(r)&&(u.default.mkdirSync(a,{recursive:!0}),st(r,a));for(let i of["index.ts","src","STREAMING.md","SETUP.md","CHANGELOG.md"]){let l=_.default.join(t,i);u.default.existsSync(l)&&(u.default.statSync(l).isDirectory()?u.default.rmSync(l,{recursive:!0,force:!0}):u.default.unlinkSync(l))}}function st(e,t){for(let o of u.default.readdirSync(e,{withFileTypes:!0})){let n=_.default.join(e,o.name),s=_.default.join(t,o.name);o.isDirectory()?(u.default.mkdirSync(s,{recursive:!0}),st(n,s)):u.default.copyFileSync(n,s)}}function Ko(){try{try{(0,$.execSync)('pkill -f "badgerclaw heartbeat"',{stdio:"pipe",timeout:5e3})}catch{}try{(0,$.execSync)('pkill -f "badgerclaw watch"',{stdio:"pipe",timeout:5e3})}catch{}(0,$.execSync)("sleep 1",{stdio:"pipe"});let e=(0,$.execSync)("which badgerclaw",{stdio:"pipe"}).toString().trim();(0,$.execSync)(`nohup ${e} heartbeat > /dev/null 2>&1 &`,{stdio:"pipe",shell:"/bin/zsh"}),(0,$.execSync)(`nohup ${e} watch > /dev/null 2>&1 &`,{stdio:"pipe",shell:"/bin/zsh"})}catch{}}function Yo(){let e=_.default.join(ue.default.homedir(),".badgerclaw","workspace");u.default.mkdirSync(e,{recursive:!0});let t=_.default.join(e,".git");return u.default.existsSync(t)||(0,$.execSync)("git init",{cwd:e,stdio:"pipe",timeout:5e3}),u.default.writeFileSync(_.default.join(e,"CLAUDE.md"),`You are a chat assistant connected to Matrix rooms via BadgerClaw.
98
+ `}function Oo(){try{return(0,B.execSync)("systemctl --user --version",{stdio:"ignore"}),!0}catch{return!1}}function Et(){if(ve.default.platform()==="linux"){if(!Oo()){console.log("\x1B[2mNote: systemctl --user not available. Run `badgerclaw heartbeat` manually or start it under a process manager.\x1B[0m");return}try{let e=Po();Ce.default.mkdirSync(Pt,{recursive:!0}),Ce.default.mkdirSync(ce.default.join(ve.default.homedir(),".badgerclaw"),{recursive:!0}),Ce.default.writeFileSync(Ro,Do(e)),(0,B.execSync)("systemctl --user daemon-reload",{stdio:"ignore"});try{(0,B.execSync)(`systemctl --user restart ${Ge}`,{stdio:"ignore"})}catch{}(0,B.execSync)(`systemctl --user enable --now ${Ge}`,{stdio:"ignore"});try{let t=(0,B.execSync)("whoami",{encoding:"utf-8"}).trim();(0,B.execSync)(`loginctl enable-linger ${t}`,{stdio:"ignore"})}catch{}console.log("\x1B[2mHeartbeat daemon registered as systemd user service (auto-starts on login).\x1B[0m")}catch{console.log("\x1B[2mNote: could not register systemd user service. Run `badgerclaw heartbeat` manually.\x1B[0m")}}}function Ot(){let e=Dt.default.platform();if(e==="darwin")return Rt();if(e==="linux")return Et();console.log("\x1B[2mNote: background daemon install not supported on "+e+". Run `badgerclaw heartbeat` manually.\x1B[0m")}var To=2e3,jo=12e4,Bt=new Nt.Command("login").description("Log in to BadgerClaw via browser").action(async()=>{let e=pt(),t=gt(e),o=`${_t}/cli-auth?code=${t}`;console.log(H.default.yellow("Opening browser for authentication...")),console.log(H.default.dim(`If the browser doesn't open, visit: ${o}`)),await(0,jt.default)(o);let n=(0,Tt.default)("Waiting for authentication...").start(),s=St(),r=Date.now();for(;Date.now()-r<jo;){try{let a=await s.post(`/api/v1/openclaw/cli/auth/poll/${t}`,{code_verifier:e,code_challenge:t});if(a.status===429){await new Promise(i=>setTimeout(i,5e3));continue}if(a.data?.access_token){let{access_token:i,user_id:l,expires_at:g,refresh_token:C,email:f}=a.data,O=Lt.default.createHash("sha256").update(`${Y.default.hostname()}-${Y.default.platform()}-${Y.default.arch()}`).digest("hex").slice(0,16),P=`openclaw-${Y.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${O}`;he({access_token:i,user_id:l,instance_id:P,expires_at:g,refresh_token:C,email:f});try{let{version:v}=W();await s.post("/api/v1/openclaw/register",{instance_id:P,label:Y.default.hostname(),version:v},{headers:{Authorization:`Bearer ${i}`}})}catch{}n.succeed(H.default.green(`Logged in as ${ye(l)}`));let N=await re(!0);N>0&&(console.log(H.default.green(`\u2705 ${N} bot(s) automatically paired to OpenClaw.`)),console.log(H.default.yellow("Run: openclaw gateway restart to activate."))),Ot();return}}catch{}await new Promise(a=>setTimeout(a,To))}n.fail(H.default.red("Authentication timed out. Please try again.")),process.exit(1)});var Ut=require("commander"),Ve=c(require("chalk"));var Mt=new Ut.Command("logout").description("Disconnect this machine and log out of BadgerClaw").action(async()=>{let e=h();if(!e){console.log(Ve.default.yellow("Not logged in."));return}try{let t=$e(e.access_token),{version:o}=W();await t.post("/api/v1/openclaw/register",{instance_id:e.instance_id,label:require("os").hostname(),version:o,online:!1})}catch{}wt(),console.log(Ve.default.green("Logged out \u2014 this machine is now disconnected."))});var Ft=require("commander"),We=c(require("chalk"));var Gt=new Ft.Command("status").description("Show connected instance info").action(async()=>{let e=h();(!e||!we())&&(console.log(We.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1)),console.log(We.default.green("Authenticated")),console.log(` User: ${ye(e.user_id)}`),console.log(` Instance: ${e.instance_id}`),console.log(` Expires: ${new Date(e.expires_at).toLocaleDateString()}`)});var le=require("commander"),R=c(require("chalk")),Ie=c(require("ora"));function He(){we()||(console.log(R.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1))}function Lo(e){return/^[a-z0-9_]{4,20}$/.test(e)}function Bo(e){return e.replace(/_bot$/,"")}var Uo=new le.Command("create").description("Create a new bot").argument("<name>","Bot name (4-20 chars, lowercase alphanumeric + underscores)").action(async e=>{He(),Lo(e)||(console.log(R.default.red("Invalid bot name. Must be 4-20 characters, lowercase alphanumeric and underscores only.")),process.exit(1));let t=(0,Ie.default)(`Creating bot "${e}"...`).start();try{await S().post("/api/v1/openclaw/bots",{username:e}),t.succeed(R.default.green(`Bot "${e}" created successfully!`))}catch(o){let n=o.response?.data?.errors?.[0]||o.message;t.fail(R.default.red(`Failed to create bot: ${n}`)),process.exit(1)}}),Mo=new le.Command("list").description("List your bots").action(async()=>{He();let e=(0,Ie.default)("Fetching bots...").start();try{let n=(await S().get("/api/v1/openclaw/bots")).data?.bots||[];if(e.stop(),n.length===0){console.log(R.default.yellow("No bots found. Create one with `badgerclaw bot create <name>`."));return}console.log(R.default.green(`Your bots (${n.length}):
99
+ `));for(let s of n){let r=Bo(s.username||s.name),a=s.active!==!1?R.default.green("active"):R.default.dim("inactive");console.log(` ${R.default.bold(r)} ${a}`)}}catch(t){let o=t.response?.data?.errors?.[0]||t.message;e.fail(R.default.red(`Failed to list bots: ${o}`)),process.exit(1)}}),Fo=new le.Command("delete").description("Deactivate a bot").argument("<name>","Bot name to deactivate").action(async e=>{He();let t=(0,Ie.default)(`Deactivating bot "${e}"...`).start();try{await S().delete(`/api/v1/openclaw/bots/${e}`),t.succeed(R.default.green(`Bot "${e}" deactivated.`))}catch(o){let n=o.response?.data?.errors?.[0]||o.message;t.fail(R.default.red(`Failed to deactivate bot: ${n}`)),process.exit(1)}}),Vt=new le.Command("bot").description("Manage bots").addCommand(Uo).addCommand(Mo).addCommand(Fo);var oo=require("commander"),m=c(require("chalk"));var Je=c(require("axios")),Go=7331,Wt=`http://localhost:${Go}`,qe="unknown";async function de(){try{let t=(await Je.default.get(`${Wt}/health`,{timeout:5e3})).data;return t.pluginVersion&&t.pluginVersion!=="unknown"&&(qe=t.pluginVersion),t}catch{return{status:"stopped",pid:null,lastRestart:null,pluginVersion:qe,bots:[]}}}function Ht(e){e&&e!=="unknown"&&(qe=e)}async function X(){try{return{success:!0,message:(await Je.default.post(`${Wt}/restart`,{},{timeout:15e3})).data?.message||"Gateway restart initiated"}}catch(e){try{let{execSync:t}=await import("child_process");return t("openclaw gateway restart",{stdio:"pipe",timeout:15e3}),{success:!0,message:"Gateway restarted via CLI fallback"}}catch{return{success:!1,message:e.message||"Failed to restart gateway"}}}}var Yt=require("commander"),d=c(require("chalk")),Xt=c(require("axios"));var j=c(require("os")),qt=c(require("crypto"));function ue(){let e=h();if(e?.instance_id)return e.instance_id;let t=qt.default.createHash("sha256").update(`${j.default.hostname()}-${j.default.platform()}-${j.default.arch()}`).digest("hex").slice(0,16);return`openclaw-${j.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${t}`}function xe(){return{hostname:j.default.hostname(),os:j.default.platform(),arch:j.default.arch(),uptimeSeconds:Math.floor(j.default.uptime()),memFreeMb:Math.floor(j.default.freemem()/1024/1024)}}var $=require("child_process"),u=c(require("fs")),_=c(require("path")),me=c(require("os")),x=c(require("axios"));async function M(e){return e.command_type==="update_cli"?zo(e.payload?.target_version):e.command_type==="update_plugin"?Ko(e.payload?.target_version):e.command_type==="restart_gateway"?Jo():e.command_type==="leave_room"?ln(e.payload):e.command_type==="start_claude_code"?en(e.payload):e.command_type==="stop_claude_code"?tn(e.payload):e.command_type==="start_claude_control"?on(e.payload):e.command_type==="stop_claude_control"?nn(e.payload):e.command_type==="update_claude_tools"?sn(e.payload):e.command_type==="bot_share_notify"?rn(e.payload):e.command_type==="bot_share_revoked"?an(e.payload):e.command_type==="bot_share_expired"?cn(e.payload):{success:!1,message:`Unknown command: ${e.command_type}`}}function Jo(){try{return(0,$.execSync)("openclaw gateway restart",{stdio:"pipe",timeout:15e3}),{success:!0,message:"Gateway restarted"}}catch{try{return{success:!0,message:`Gateway restarted via probe: ${(0,$.execSync)("curl -s -X POST http://localhost:7331/restart",{stdio:"pipe",timeout:1e4}).toString()}`}}catch(e){return{success:!1,message:`Gateway restart failed: ${e.message||"unknown error"}`}}}}function zo(e){let t=e?`badgerclaw@${e}`:"badgerclaw@latest";try{(0,$.execSync)(`npm install -g ${t}`,{stdio:"pipe",timeout:12e4});let o=(0,$.execSync)("npm list -g badgerclaw --json",{stdio:"pipe"}).toString(),s=JSON.parse(o)?.dependencies?.badgerclaw?.version||"unknown";return Xo(),{success:!0,message:`Updated CLI to ${s}`,newVersion:s}}catch(o){let n=o.stderr?.toString()||o.message||"Unknown error";return n.includes("EACCES")||n.includes("permission")?{success:!1,message:"Permission denied. Run: sudo npm install -g badgerclaw"}:{success:!1,message:`CLI update failed: ${n.slice(0,500)}`}}}async function Ko(e){let t=_.default.join(me.default.homedir(),".openclaw","extensions","badgerclaw");if(!u.default.existsSync(t))return{success:!1,message:"Cannot find plugin directory (~/.openclaw/extensions/badgerclaw). Re-run: badgerclaw setup"};let o=e?`@badgerclaw/connect@${e}`:"@badgerclaw/connect@latest";try{(0,$.execSync)(`npm install ${o}`,{cwd:t,stdio:"pipe",timeout:12e4});let n=_.default.join(t,"node_modules","@badgerclaw","connect"),s=_.default.join(n,"package.json"),r="unknown";u.default.existsSync(s)&&(r=JSON.parse(u.default.readFileSync(s,"utf-8")).version||"unknown"),Ht(r),Yo(n,t);let a=_.default.join(t,"package.json");if(u.default.existsSync(a)&&u.default.existsSync(s))try{let i=JSON.parse(u.default.readFileSync(a,"utf-8")),l=JSON.parse(u.default.readFileSync(s,"utf-8"));i.version=r,l.openclaw&&(i.openclaw={...i.openclaw,...l.openclaw}),u.default.writeFileSync(a,JSON.stringify(i,null,2)+`
100
+ `)}catch{}try{(0,$.execSync)("openclaw gateway restart",{stdio:"pipe",timeout:1e4})}catch{}for(let i=0;i<15;i++){await new Promise(l=>setTimeout(l,1e3));try{let l=await x.default.get("http://localhost:7331/health",{timeout:3e3});if(l.data?.status==="running"&&l.data?.pluginVersion===r)break}catch{}}return{success:!0,message:`Updated plugin to ${r}, gateway restarted`,newVersion:r}}catch(n){return{success:!1,message:`Plugin update failed: ${(n.stderr?.toString()||n.message||"").slice(0,500)}`}}}function Yo(e,t){let o=_.default.join(e,"dist"),n=_.default.join(t,"dist");u.default.existsSync(o)&&(u.default.mkdirSync(n,{recursive:!0}),rt(o,n));let s=_.default.join(e,"openclaw.plugin.json");u.default.existsSync(s)&&u.default.copyFileSync(s,_.default.join(t,"openclaw.plugin.json"));let r=_.default.join(e,"scripts"),a=_.default.join(t,"scripts");u.default.existsSync(r)&&(u.default.mkdirSync(a,{recursive:!0}),rt(r,a));for(let i of["index.ts","src","STREAMING.md","SETUP.md","CHANGELOG.md"]){let l=_.default.join(t,i);u.default.existsSync(l)&&(u.default.statSync(l).isDirectory()?u.default.rmSync(l,{recursive:!0,force:!0}):u.default.unlinkSync(l))}}function rt(e,t){for(let o of u.default.readdirSync(e,{withFileTypes:!0})){let n=_.default.join(e,o.name),s=_.default.join(t,o.name);o.isDirectory()?(u.default.mkdirSync(s,{recursive:!0}),rt(n,s)):u.default.copyFileSync(n,s)}}function Xo(){try{try{(0,$.execSync)('pkill -f "badgerclaw heartbeat"',{stdio:"pipe",timeout:5e3})}catch{}try{(0,$.execSync)('pkill -f "badgerclaw watch"',{stdio:"pipe",timeout:5e3})}catch{}(0,$.execSync)("sleep 1",{stdio:"pipe"});let e=(0,$.execSync)("which badgerclaw",{stdio:"pipe"}).toString().trim();(0,$.execSync)(`nohup ${e} heartbeat > /dev/null 2>&1 &`,{stdio:"pipe",shell:"/bin/zsh"}),(0,$.execSync)(`nohup ${e} watch > /dev/null 2>&1 &`,{stdio:"pipe",shell:"/bin/zsh"})}catch{}}function Qo(){let e=_.default.join(me.default.homedir(),".badgerclaw","workspace");u.default.mkdirSync(e,{recursive:!0});let t=_.default.join(e,".git");return u.default.existsSync(t)||(0,$.execSync)("git init",{cwd:e,stdio:"pipe",timeout:5e3}),u.default.writeFileSync(_.default.join(e,"CLAUDE.md"),`You are a chat assistant connected to Matrix rooms via BadgerClaw.
101
101
 
102
102
  When you receive a message, it will be formatted like:
103
103
  [Room: RoomName] Sender: message text
@@ -106,22 +106,22 @@ Reply using the reply tool with botId="..." and roomId="..."
106
106
  ALWAYS use the \`reply\` MCP tool to send your response back to the chat room.
107
107
  Use the exact botId and roomId provided in the message \u2014 do not modify them.
108
108
  Keep responses concise and helpful.
109
- `),e}var Re=_.default.join(ue.default.homedir(),".badgerclaw","claude-code.lock");function Xo(){try{u.default.mkdirSync(_.default.dirname(Re),{recursive:!0});try{let e=u.default.statSync(Re);if(Date.now()-e.mtimeMs<6e4)return!1;u.default.unlinkSync(Re)}catch{}return u.default.writeFileSync(Re,String(process.pid),{flag:"wx"}),!0}catch{return!1}}async function Qo(e){if(!e?.bot_id)return{success:!1,message:"Missing bot_id in payload"};if(!Xo())return{success:!0,message:"Claude Code start already in progress, skipping duplicate"};try{let t=e.bot_user_id?.startsWith("@")?e.bot_user_id:await me(e.bot_id),{launchClaudeCode:o,recordSession:n,getActiveSessions:s,stopSession:r}=(ke(),ut(nt)),a=new Set;try{let O=(await x.default.get("http://localhost:7331/claude-code/status",{timeout:5e3})).data?.bots||[];for(let P of O)if(P.botId!==t&&P.enabled!==!1){let N=P.port;typeof N=="number"&&N>=7332&&a.add(N)}}catch{}for(let f=7332;f<=7340;f++)try{(0,$.execSync)(`lsof -ti :${f} >/dev/null 2>&1`,{stdio:"pipe",timeout:2e3}),a.add(f)}catch{}let i=7332;for(;a.has(i);)i++;let l=s();for(let f of l)f.port===i&&(console.log(`[command-executor] Stopping existing session ${f.sessionId} on port ${i}`),r(f.sessionId));try{(0,$.execSync)(`lsof -ti :${i} | xargs kill -9 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let g=e.session_id||`session-${Date.now()}`;await x.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!0,sessionId:g,port:i},{timeout:1e4});let C=Yo();return o({sessionId:g,port:i,projectDir:C}),n(g,0,0,i,C),{success:!0,message:`Claude Code started globally for bot ${t} (session: ${g}, port: ${i})`}}catch(t){return{success:!1,message:`Failed to start Claude Code: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function me(e){if(e.startsWith("@"))return e;try{let o=(await x.default.get("http://localhost:7331/health",{timeout:1e4})).data?.bots||[],n=_.default.join(ue.default.homedir(),".badgerclaw","bot-mapping.json");if(u.default.existsSync(n)){let s=JSON.parse(u.default.readFileSync(n,"utf-8"));if(s[e])return s[e]}return o.length===1?o[0].botId:(console.warn(`[command-executor] Could not resolve bot UUID ${e} to Matrix ID, trying as-is`),e)}catch{return e}}async function Zo(e){if(!e?.bot_id)return{success:!1,message:"Missing bot_id in payload"};try{let t=e.bot_user_id?.startsWith("@")?e.bot_user_id:await me(e.bot_id),o=e.session_id;if(!o)try{let n=await x.default.get("http://localhost:7331/claude-code/status",{timeout:5e3}),r=(n.data?.bots||n.data?.rooms||[]).find(a=>a.botId===t);r&&(o=r.sessionId)}catch{}if(await x.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!1},{timeout:1e4}),o){let{stopSession:n}=(ke(),ut(nt));n(o)}return{success:!0,message:"Claude Code stopped"}}catch(t){return{success:!1,message:`Failed to stop Claude Code: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function en(e){try{let t=e?.bot_user_id||e?.bot_id;if(!t)return{success:!1,message:"Missing bot_id in payload"};let o=t;o.startsWith("@")||(o=await me(t));let n=e?.session_id||`cc-${Date.now()}`;return await x.default.post("http://localhost:7331/claude-code/toggle",{botId:o,enabled:!0,sessionId:n,mode:"primary",tools:e?.tools},{timeout:1e4}),console.log(`[claude-control] Primary mode enabled for ${o} (session: ${n})`),{success:!0,message:`Claude Control (primary) started for ${o}`}}catch(t){return{success:!1,message:`Failed to start Claude Control: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function tn(e){try{let t=e?.bot_user_id||e?.bot_id;if(!t)return{success:!1,message:"Missing bot_id in payload"};let o=t;return o.startsWith("@")||(o=await me(t)),await x.default.post("http://localhost:7331/claude-code/toggle",{botId:o,enabled:!1},{timeout:1e4}),console.log(`[claude-control] Primary mode disabled for ${o}`),{success:!0,message:`Claude Control stopped for ${o}`}}catch(t){return{success:!1,message:`Failed to stop Claude Control: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function on(e){try{let t=e?.bot_user_id||e?.bot_id;if(!t||!e?.tools)return{success:!1,message:"Missing bot_id or tools in payload"};let o=t;return o.startsWith("@")||(o=await me(t)),await x.default.post("http://localhost:7331/claude-code/tools",{botId:o,tools:e.tools},{timeout:1e4}),{success:!0,message:`Tools updated for ${o}`}}catch(t){return{success:!1,message:`Failed to update tools: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function nn(e){if(!e?.bot_user_id||!e?.shared_with_user_id)return{success:!1,message:"Missing bot_user_id or shared_with_user_id"};try{return await x.default.post("http://localhost:7331/bot-share/notify",{botId:e.bot_user_id,sharedWithUserId:e.shared_with_user_id,ownerDisplayName:e.owner_display_name||void 0,botDisplayName:e.bot_name||void 0,expiresAt:e.expires_at||void 0},{timeout:1e4}),console.log(`[bot-share] Notify: ${e.shared_with_user_id} can now access ${e.bot_user_id}`),{success:!0,message:`Share notification sent for ${e.shared_with_user_id}`}}catch(t){return{success:!1,message:`Failed to notify share: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function sn(e){if(!e?.bot_user_id||!e?.shared_with_user_id)return{success:!1,message:"Missing bot_user_id or shared_with_user_id"};try{return await x.default.post("http://localhost:7331/bot-share/revoked",{botId:e.bot_user_id,sharedWithUserId:e.shared_with_user_id,botDisplayName:e.bot_name||void 0},{timeout:1e4}),console.log(`[bot-share] Revoked: ${e.shared_with_user_id} lost access to ${e.bot_user_id}`),{success:!0,message:`Share revocation sent for ${e.shared_with_user_id}`}}catch(t){return{success:!1,message:`Failed to revoke share: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function rn(e){if(!e?.bot_user_id||!e?.shared_with_user_id)return{success:!1,message:"Missing bot_user_id or shared_with_user_id"};try{return await x.default.post("http://localhost:7331/bot-share/expired",{botId:e.bot_user_id,sharedWithUserId:e.shared_with_user_id,botDisplayName:e.bot_name||void 0},{timeout:1e4}),console.log(`[bot-share] Expired: ${e.shared_with_user_id} access to ${e.bot_user_id}`),{success:!0,message:`Share expiry sent for ${e.shared_with_user_id}`}}catch(t){return{success:!1,message:`Failed to expire share: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function an(e){if(!e?.bot_id||!e?.room_id)return{success:!1,message:"Missing bot_id or room_id in payload"};try{return{success:!0,message:(await x.default.post("http://localhost:7331/leave-room",{botId:e.bot_id,roomId:e.room_id},{timeout:15e3})).data?.message||"Left room"}}catch(t){return{success:!1,message:`Failed to leave room: ${t.response?.data?.message||t.message||"Unknown error"}`}}}var qt=3e4,cn=15e4,Yt="/api/v1/dashboard/heartbeat",ln="/api/v1/me/active-shares",Pe=new Map,dn=3e4;function Ee(e,t){if(e!=="start_claude_code"&&e!=="stop_claude_code")return!1;let o=`${e}:${t||"unknown"}`,n=Date.now();for(let[s,r]of Pe)n-r>dn&&Pe.delete(s);return Pe.has(o)?!0:(Pe.set(o,n),!1)}function Xt(e,t){let o=Ie();return{instance_id:de(),timestamp:new Date().toISOString(),cli_version:t,plugin_version:e.pluginVersion||"unknown",hostname:o.hostname,os:o.os,arch:o.arch,uptime_seconds:o.uptimeSeconds,mem_free_mb:o.memFreeMb,gateway_status:e.status,gateway_pid:e.pid,last_gateway_restart:e.lastRestart,bots:e.bots.map(n=>({bot_id:n.botId,bot_username:n.botUsername,status:n.status,activity_state:n.activityState||"idle",active_task:n.activeTask||null,last_activity_at:n.lastActivity,messages_received:n.messagesReceived,messages_sent:n.messagesSent,chunked_messages:n.chunkedMessages,total_chunks_sent:n.totalChunksSent,errors:n.errors,last_error:n.lastError,last_error_at:n.lastErrorAt,uptime_seconds:n.uptimeSeconds,rooms_active:n.roomsActive,room_details:(n.roomDetails||[]).map(s=>({roomId:s.roomId,roomName:s.roomName,workspaceName:s.workspaceName||null,messagesInRoom:s.messagesInRoom,lastActivityInRoom:s.lastActivityInRoom})),claude_code_enabled:n.claudeCodeEnabled??!1,claude_code_session_id:n.claudeCodeSessionId??null}))}}async function A(){let{version:e}=W(),t=await le(),o=Xt(t,e);await S().post(Yt,o)}function un(e,t){if(!e||e.status!==t.status)return!0;let o=new Map(e.bots.map(n=>[n.botId,n]));for(let n of t.bots){let s=o.get(n.botId);if(!s||s.status!==n.status||s.errors!==n.errors)return!0}return e.bots.length!==t.bots.length}async function Jt(){try{let o=(await S().get(ln)).data?.shares||[],n={shares:o.map(s=>({botUserId:s.bot_user_id,sharedWithUserId:s.shared_with_user_id,expiresAt:s.expires_at||null,shareId:s.share_id}))};await Kt.default.post("http://localhost:7331/bot-share/sync",n,{timeout:1e4}),console.log(d.default.dim(` [${y()}] Share sync: ${o.length} active share(s) pushed to plugin`))}catch(e){console.log(d.default.dim(` [${y()}] Share sync failed (non-fatal): ${e.message}`))}}var Qt=new zt.Command("heartbeat").description("Run heartbeat daemon \u2014 reports telemetry to the BadgerClaw dashboard every 30s").action(async()=>{let e=h();e||(console.log(d.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=W();console.log(d.default.green(`Heartbeat daemon started (v${t})`)),console.log(d.default.dim(` Instance: ${de()}`)),console.log(d.default.dim(` Interval: ${qt/1e3}s`)),console.log(d.default.dim(` Press Ctrl+C to stop.
110
- `));let o=null,n=10,s=0,r=async()=>{try{await Zt();let a=await le(),i=Xt(a,t);un(o,a)&&o!==null&&console.log(d.default.cyan(` [${new Date().toISOString()}] State change detected \u2014 pushing immediately`));let g=S(),C=await g.post(Yt,i);s=0;let f=a.bots.length,O=a.bots.filter(v=>v.status==="running").length;console.log(d.default.dim(` [${new Date().toISOString()}] gateway=${a.status} bots=${O}/${f} running mem=${i.mem_free_mb}MB free`)),o=a;let P=C.data?.pending_commands||[],N=!1;for(let v of P)try{if(console.log(d.default.cyan(` [${new Date().toISOString()}] Received command: ${v.command_type} (${v.id})`)),await g.post(`/api/v1/dashboard/commands/${v.id}/ack`),Ee(v.command_type,v.payload?.bot_id)){console.log(d.default.dim(` [${new Date().toISOString()}] Skipping duplicate ${v.command_type}`));continue}let j=await M(v);console.log(j.success?d.default.green(` [${new Date().toISOString()}] ${j.message}`):d.default.red(` [${new Date().toISOString()}] ${j.message}`)),await g.post(`/api/v1/dashboard/commands/${v.id}/result`,{status:j.success?"success":"failed",result:j.message,new_version:j.newVersion||null}),v.command_type==="update_cli"&&j.success&&(N=!0)}catch(j){console.log(d.default.dim(` [${new Date().toISOString()}] Command ${v.id} error: ${j.message}`))}if(N){console.log(d.default.cyan(` [${new Date().toISOString()}] CLI updated \u2014 restarting in 2s...`));try{await A()}catch{}setTimeout(()=>process.exit(0),2e3);return}}catch(a){s+=1,console.log(d.default.dim(` [${new Date().toISOString()}] Heartbeat failed (${s}/${n}): ${a.message}`)),s>=n&&(console.log(d.default.red(` [${new Date().toISOString()}] ${n} consecutive heartbeat failures \u2014 exiting so launchctl/systemd can restart the daemon.`)),process.exit(1))}};await r(),await Jt(),setInterval(r,qt),setInterval(Jt,cn),pn(e.access_token,t),await new Promise(()=>{})});async function Zt(){let e=h();if(!e?.expires_at)return;let t=new Date(e.expires_at).getTime(),o=Date.now(),n=300*1e3;if(t-o<n){console.log(d.default.dim(` [${y()}] Token expires soon \u2014 refreshing proactively...`));let s=await je();console.log(s?d.default.green(` [${y()}] Token refreshed successfully`):d.default.yellow(` [${y()}] Token refresh failed \u2014 no refresh_token available`))}}var mn=2700*1e3;function pn(e,t){let o=3e3,n=3e4,s=null;async function r(){try{await Zt();let i=h()?.access_token||e,l=require("eventsource"),g=new l(`${k}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${i}`}});g.onopen=()=>{o=3e3,console.log(d.default.dim(` [${y()}] SSE connected \u2014 listening for real-time events`)),s&&clearTimeout(s),s=setTimeout(()=>{console.log(d.default.dim(` [${y()}] SSE proactive reconnect \u2014 refreshing token before expiry`)),g.close(),r()},mn)},g.onmessage=async C=>{try{let f=JSON.parse(C.data);await gn(f)}catch{}},g.onerror=async()=>{g.close(),s&&(clearTimeout(s),s=null),console.log(d.default.dim(` [${y()}] SSE disconnected \u2014 reconnecting in ${o/1e3}s...`)),setTimeout(r,o),o=Math.min(o*1.5,n)}}catch(a){console.log(d.default.dim(` [${y()}] SSE connection failed: ${a.message}`)),setTimeout(r,o),o=Math.min(o*1.5,n)}}r()}function y(){return new Date().toISOString()}async function gn(e){if(e.type==="pair"){console.log(d.default.cyan(` [${y()}] Pair event: ${e.bot_name}`)),await ne(e.pair_code,e.bot_name,e.bot_user_id,!0);try{let{execSync:t}=await import("child_process");t("openclaw gateway restart",{stdio:"ignore"}),console.log(d.default.green(` [${y()}] Gateway restarted \u2014 ${e.bot_name} is live`))}catch{}try{await A()}catch{}}else if(e.type==="bot.delete"&&e.bot_user_id){let t=e.bot_user_id,o=t.split(":")[0].replace("@","").replace(/_bot$/,"");console.log(d.default.yellow(` [${y()}] Bot deleted: ${t}`));try{let n=await import("fs"),s=await import("path"),r=await import("os"),a=s.join(r.homedir(),".openclaw","openclaw.json"),i=JSON.parse(n.readFileSync(a,"utf-8")),l=!1;if(i.channels?.badgerclaw?.accounts?.[o]&&(delete i.channels.badgerclaw.accounts[o],l=!0),i.agents?.list){let g=i.agents.list.length;i.agents.list=i.agents.list.filter(C=>C.id!==o),i.agents.list.length!==g&&(l=!0)}if(l){n.writeFileSync(a,JSON.stringify(i,null,2)),console.log(d.default.green(` [${y()}] Removed "${o}" from openclaw.json`));let{execSync:g}=await import("child_process");try{g("openclaw gateway restart",{stdio:"ignore"}),console.log(d.default.green(` [${y()}] Gateway restarted`))}catch{}}}catch(n){console.log(d.default.red(` [${y()}] Failed to clean up bot: ${n}`))}try{await A()}catch{}}else if(e.type==="gateway-restart"){console.log(d.default.cyan(` [${y()}] Remote gateway-restart received`));let t=await X();console.log(t.success?d.default.green(` [${y()}] Gateway restarted`):d.default.red(` [${y()}] Gateway restart failed: ${t.message}`));try{await A()}catch{}}else if(e.type==="claude_code.start"&&e.bot_id){if(console.log(d.default.cyan(` [${y()}] Claude Code START: bot=${e.bot_id}`)),Ee("start_claude_code",e.bot_id)){console.log(d.default.dim(` [${y()}] Skipping duplicate start_claude_code (already processed)`));return}try{let t=await M({id:e.command_id||`cc-start-${Date.now()}`,command_type:"start_claude_code",payload:{bot_id:e.bot_id,bot_user_id:e.bot_user_id,room_id:e.room_id,session_id:e.session_id}});e.command_id&&await S().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await A()}catch{}}else if(e.type==="claude_code.stop"&&e.bot_id){if(console.log(d.default.cyan(` [${y()}] Claude Code STOP: bot=${e.bot_id}`)),Ee("stop_claude_code",e.bot_id)){console.log(d.default.dim(` [${y()}] Skipping duplicate stop_claude_code (already processed)`));return}try{let t=await M({id:e.command_id||`cc-stop-${Date.now()}`,command_type:"stop_claude_code",payload:{bot_id:e.bot_id,bot_user_id:e.bot_user_id,room_id:e.room_id,session_id:e.session_id}});e.command_id&&await S().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await A()}catch{}}else if(e.type==="command.execute"&&e.command_id){if(console.log(d.default.cyan(` [${y()}] Command: ${e.command_type} (${e.command_id})`)),Ee(e.command_type,e.payload?.bot_id)){console.log(d.default.dim(` [${y()}] Skipping duplicate ${e.command_type} (already processed)`));return}try{let t=S();await t.post(`/api/v1/dashboard/commands/${e.command_id}/ack`);let o=await M({id:e.command_id,command_type:e.command_type,payload:e.payload});await t.post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:o.success?"success":"failed",result:o.message,new_version:o.newVersion||null}),e.command_type==="update_cli"&&o.success&&(console.log(d.default.cyan(` [${y()}] CLI updated \u2014 restarting in 2s...`)),setTimeout(()=>process.exit(0),2e3))}catch{}try{await A()}catch{}}}var to=new eo.Command("watch").description("Watch for bot pair events in real-time (no polling)").action(async()=>{let e=h();e||(console.log(m.default.yellow("Not logged in.")),process.exit(1)),await se(!1),console.log(m.default.green("\u{1F534} Listening for pair events... (Ctrl+C to stop)"));let t=require("eventsource"),o=new t(`${k}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${e.access_token}`}});o.onmessage=async n=>{try{let s=JSON.parse(n.data);if(s.type==="pair"){console.log(m.default.cyan(`
111
- \u{1F4F1} Pair event received: ${s.bot_name}`)),await ne(s.pair_code,s.bot_name,s.bot_user_id,!1);try{let{execSync:r}=await import("child_process");r("openclaw gateway restart",{stdio:"ignore"}),console.log(m.default.green(" \u2705 Gateway restarted \u2014 bot is live!"))}catch{console.log(m.default.dim(" Gateway restart failed \u2014 run: openclaw gateway restart"))}}else if(s.type==="gateway-restart"){console.log(m.default.cyan(`
112
- \u{1F504} Remote gateway-restart command received`));let r=await X();r.success?console.log(m.default.green(` \u2705 Gateway restarted: ${r.message}`)):console.log(m.default.red(` \u274C Gateway restart failed: ${r.message}`));try{await A(),console.log(m.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(m.default.dim(" Could not push heartbeat."))}}else if(s.type==="bot.delete"&&s.bot_user_id){let r=s.bot_user_id,a=r.split(":")[0].replace("@","").replace(/_bot$/,"");console.log(m.default.yellow(`
109
+ `),e}var Pe=_.default.join(me.default.homedir(),".badgerclaw","claude-code.lock");function Zo(){try{u.default.mkdirSync(_.default.dirname(Pe),{recursive:!0});try{let e=u.default.statSync(Pe);if(Date.now()-e.mtimeMs<6e4)return!1;u.default.unlinkSync(Pe)}catch{}return u.default.writeFileSync(Pe,String(process.pid),{flag:"wx"}),!0}catch{return!1}}async function en(e){if(!e?.bot_id)return{success:!1,message:"Missing bot_id in payload"};if(!Zo())return{success:!0,message:"Claude Code start already in progress, skipping duplicate"};try{let t=e.bot_user_id?.startsWith("@")?e.bot_user_id:await pe(e.bot_id),{launchClaudeCode:o,recordSession:n,getActiveSessions:s,stopSession:r}=(Re(),mt(st)),a=new Set;try{let O=(await x.default.get("http://localhost:7331/claude-code/status",{timeout:5e3})).data?.bots||[];for(let P of O)if(P.botId!==t&&P.enabled!==!1){let N=P.port;typeof N=="number"&&N>=7332&&a.add(N)}}catch{}for(let f=7332;f<=7340;f++)try{(0,$.execSync)(`lsof -ti :${f} >/dev/null 2>&1`,{stdio:"pipe",timeout:2e3}),a.add(f)}catch{}let i=7332;for(;a.has(i);)i++;let l=s();for(let f of l)f.port===i&&(console.log(`[command-executor] Stopping existing session ${f.sessionId} on port ${i}`),r(f.sessionId));try{(0,$.execSync)(`lsof -ti :${i} | xargs kill -9 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let g=e.session_id||`session-${Date.now()}`;await x.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!0,sessionId:g,port:i},{timeout:1e4});let C=Qo();return o({sessionId:g,port:i,projectDir:C}),n(g,0,0,i,C),{success:!0,message:`Claude Code started globally for bot ${t} (session: ${g}, port: ${i})`}}catch(t){return{success:!1,message:`Failed to start Claude Code: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function pe(e){if(e.startsWith("@"))return e;try{let o=(await x.default.get("http://localhost:7331/health",{timeout:1e4})).data?.bots||[],n=_.default.join(me.default.homedir(),".badgerclaw","bot-mapping.json");if(u.default.existsSync(n)){let s=JSON.parse(u.default.readFileSync(n,"utf-8"));if(s[e])return s[e]}return o.length===1?o[0].botId:(console.warn(`[command-executor] Could not resolve bot UUID ${e} to Matrix ID, trying as-is`),e)}catch{return e}}async function tn(e){if(!e?.bot_id)return{success:!1,message:"Missing bot_id in payload"};try{let t=e.bot_user_id?.startsWith("@")?e.bot_user_id:await pe(e.bot_id),o=e.session_id;if(!o)try{let n=await x.default.get("http://localhost:7331/claude-code/status",{timeout:5e3}),r=(n.data?.bots||n.data?.rooms||[]).find(a=>a.botId===t);r&&(o=r.sessionId)}catch{}if(await x.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!1},{timeout:1e4}),o){let{stopSession:n}=(Re(),mt(st));n(o)}return{success:!0,message:"Claude Code stopped"}}catch(t){return{success:!1,message:`Failed to stop Claude Code: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function on(e){try{let t=e?.bot_user_id||e?.bot_id;if(!t)return{success:!1,message:"Missing bot_id in payload"};let o=t;o.startsWith("@")||(o=await pe(t));let n=e?.session_id||`cc-${Date.now()}`;return await x.default.post("http://localhost:7331/claude-code/toggle",{botId:o,enabled:!0,sessionId:n,mode:"primary",tools:e?.tools},{timeout:1e4}),console.log(`[claude-control] Primary mode enabled for ${o} (session: ${n})`),{success:!0,message:`Claude Control (primary) started for ${o}`}}catch(t){return{success:!1,message:`Failed to start Claude Control: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function nn(e){try{let t=e?.bot_user_id||e?.bot_id;if(!t)return{success:!1,message:"Missing bot_id in payload"};let o=t;return o.startsWith("@")||(o=await pe(t)),await x.default.post("http://localhost:7331/claude-code/toggle",{botId:o,enabled:!1},{timeout:1e4}),console.log(`[claude-control] Primary mode disabled for ${o}`),{success:!0,message:`Claude Control stopped for ${o}`}}catch(t){return{success:!1,message:`Failed to stop Claude Control: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function sn(e){try{let t=e?.bot_user_id||e?.bot_id;if(!t||!e?.tools)return{success:!1,message:"Missing bot_id or tools in payload"};let o=t;return o.startsWith("@")||(o=await pe(t)),await x.default.post("http://localhost:7331/claude-code/tools",{botId:o,tools:e.tools},{timeout:1e4}),{success:!0,message:`Tools updated for ${o}`}}catch(t){return{success:!1,message:`Failed to update tools: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function rn(e){if(!e?.bot_user_id||!e?.shared_with_user_id)return{success:!1,message:"Missing bot_user_id or shared_with_user_id"};try{return await x.default.post("http://localhost:7331/bot-share/notify",{botId:e.bot_user_id,sharedWithUserId:e.shared_with_user_id,ownerDisplayName:e.owner_display_name||void 0,botDisplayName:e.bot_name||void 0,expiresAt:e.expires_at||void 0},{timeout:1e4}),console.log(`[bot-share] Notify: ${e.shared_with_user_id} can now access ${e.bot_user_id}`),{success:!0,message:`Share notification sent for ${e.shared_with_user_id}`}}catch(t){return{success:!1,message:`Failed to notify share: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function an(e){if(!e?.bot_user_id||!e?.shared_with_user_id)return{success:!1,message:"Missing bot_user_id or shared_with_user_id"};try{return await x.default.post("http://localhost:7331/bot-share/revoked",{botId:e.bot_user_id,sharedWithUserId:e.shared_with_user_id,botDisplayName:e.bot_name||void 0},{timeout:1e4}),console.log(`[bot-share] Revoked: ${e.shared_with_user_id} lost access to ${e.bot_user_id}`),{success:!0,message:`Share revocation sent for ${e.shared_with_user_id}`}}catch(t){return{success:!1,message:`Failed to revoke share: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function cn(e){if(!e?.bot_user_id||!e?.shared_with_user_id)return{success:!1,message:"Missing bot_user_id or shared_with_user_id"};try{return await x.default.post("http://localhost:7331/bot-share/expired",{botId:e.bot_user_id,sharedWithUserId:e.shared_with_user_id,botDisplayName:e.bot_name||void 0},{timeout:1e4}),console.log(`[bot-share] Expired: ${e.shared_with_user_id} access to ${e.bot_user_id}`),{success:!0,message:`Share expiry sent for ${e.shared_with_user_id}`}}catch(t){return{success:!1,message:`Failed to expire share: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function ln(e){if(!e?.bot_id||!e?.room_id)return{success:!1,message:"Missing bot_id or room_id in payload"};try{return{success:!0,message:(await x.default.post("http://localhost:7331/leave-room",{botId:e.bot_id,roomId:e.room_id},{timeout:15e3})).data?.message||"Left room"}}catch(t){return{success:!1,message:`Failed to leave room: ${t.response?.data?.message||t.message||"Unknown error"}`}}}var zt=3e4,dn=15e4,Qt="/api/v1/dashboard/heartbeat",un="/api/v1/me/active-shares",Ee=new Map,mn=3e4;function De(e,t){if(e!=="start_claude_code"&&e!=="stop_claude_code")return!1;let o=`${e}:${t||"unknown"}`,n=Date.now();for(let[s,r]of Ee)n-r>mn&&Ee.delete(s);return Ee.has(o)?!0:(Ee.set(o,n),!1)}function Zt(e,t){let o=xe();return{instance_id:ue(),timestamp:new Date().toISOString(),cli_version:t,plugin_version:e.pluginVersion||"unknown",hostname:o.hostname,os:o.os,arch:o.arch,uptime_seconds:o.uptimeSeconds,mem_free_mb:o.memFreeMb,gateway_status:e.status,gateway_pid:e.pid,last_gateway_restart:e.lastRestart,bots:e.bots.map(n=>({bot_id:n.botId,bot_username:n.botUsername,status:n.status,activity_state:n.activityState||"idle",active_task:n.activeTask||null,last_activity_at:n.lastActivity,messages_received:n.messagesReceived,messages_sent:n.messagesSent,chunked_messages:n.chunkedMessages,total_chunks_sent:n.totalChunksSent,errors:n.errors,last_error:n.lastError,last_error_at:n.lastErrorAt,uptime_seconds:n.uptimeSeconds,rooms_active:n.roomsActive,room_details:(n.roomDetails||[]).map(s=>({roomId:s.roomId,roomName:s.roomName,workspaceName:s.workspaceName||null,messagesInRoom:s.messagesInRoom,lastActivityInRoom:s.lastActivityInRoom})),claude_code_enabled:n.claudeCodeEnabled??!1,claude_code_session_id:n.claudeCodeSessionId??null}))}}async function k(){let{version:e}=W(),t=await de(),o=Zt(t,e);await S().post(Qt,o)}function pn(e,t){if(!e||e.status!==t.status)return!0;let o=new Map(e.bots.map(n=>[n.botId,n]));for(let n of t.bots){let s=o.get(n.botId);if(!s||s.status!==n.status||s.errors!==n.errors)return!0}return e.bots.length!==t.bots.length}async function Kt(){try{let o=(await S().get(un)).data?.shares||[],n={shares:o.map(s=>({botUserId:s.bot_user_id,sharedWithUserId:s.shared_with_user_id,expiresAt:s.expires_at||null,shareId:s.share_id}))};await Xt.default.post("http://localhost:7331/bot-share/sync",n,{timeout:1e4}),console.log(d.default.dim(` [${y()}] Share sync: ${o.length} active share(s) pushed to plugin`))}catch(e){console.log(d.default.dim(` [${y()}] Share sync failed (non-fatal): ${e.message}`))}}var eo=new Yt.Command("heartbeat").description("Run heartbeat daemon \u2014 reports telemetry to the BadgerClaw dashboard every 30s").action(async()=>{let e=h();e||(console.log(d.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=W();console.log(d.default.green(`Heartbeat daemon started (v${t})`)),console.log(d.default.dim(` Instance: ${ue()}`)),console.log(d.default.dim(` Interval: ${zt/1e3}s`)),console.log(d.default.dim(` Press Ctrl+C to stop.
110
+ `));let o=null,n=10,s=0,r=async()=>{try{await to();let a=await de(),i=Zt(a,t);pn(o,a)&&o!==null&&console.log(d.default.cyan(` [${new Date().toISOString()}] State change detected \u2014 pushing immediately`));let g=S(),C=await g.post(Qt,i);s=0;let f=a.bots.length,O=a.bots.filter(v=>v.status==="running").length;console.log(d.default.dim(` [${new Date().toISOString()}] gateway=${a.status} bots=${O}/${f} running mem=${i.mem_free_mb}MB free`)),o=a;let P=C.data?.pending_commands||[],N=!1;for(let v of P)try{if(console.log(d.default.cyan(` [${new Date().toISOString()}] Received command: ${v.command_type} (${v.id})`)),await g.post(`/api/v1/dashboard/commands/${v.id}/ack`),De(v.command_type,v.payload?.bot_id)){console.log(d.default.dim(` [${new Date().toISOString()}] Skipping duplicate ${v.command_type}`));continue}let L=await M(v);console.log(L.success?d.default.green(` [${new Date().toISOString()}] ${L.message}`):d.default.red(` [${new Date().toISOString()}] ${L.message}`)),await g.post(`/api/v1/dashboard/commands/${v.id}/result`,{status:L.success?"success":"failed",result:L.message,new_version:L.newVersion||null}),v.command_type==="update_cli"&&L.success&&(N=!0)}catch(L){console.log(d.default.dim(` [${new Date().toISOString()}] Command ${v.id} error: ${L.message}`))}if(N){console.log(d.default.cyan(` [${new Date().toISOString()}] CLI updated \u2014 restarting in 2s...`));try{await k()}catch{}setTimeout(()=>process.exit(0),2e3);return}}catch(a){s+=1,console.log(d.default.dim(` [${new Date().toISOString()}] Heartbeat failed (${s}/${n}): ${a.message}`)),s>=n&&(console.log(d.default.red(` [${new Date().toISOString()}] ${n} consecutive heartbeat failures \u2014 exiting so launchctl/systemd can restart the daemon.`)),process.exit(1))}};await r(),await Kt(),setInterval(r,zt),setInterval(Kt,dn),fn(e.access_token,t),await new Promise(()=>{})});async function to(){let e=h();if(!e?.expires_at)return;let t=new Date(e.expires_at).getTime(),o=Date.now(),n=300*1e3;if(t-o<n)if(console.log(d.default.dim(` [${y()}] Token expires soon \u2014 refreshing proactively...`)),await Be())console.log(d.default.green(` [${y()}] Token refreshed successfully`));else{let r=bt()||"unknown reason";console.log(d.default.yellow(` [${y()}] Token refresh failed: ${r}`))}}var gn=2700*1e3;function fn(e,t){let o=3e3,n=3e4,s=null;async function r(){try{await to();let i=h()?.access_token||e,l=require("eventsource"),g=new l(`${A}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${i}`}});g.onopen=()=>{o=3e3,console.log(d.default.dim(` [${y()}] SSE connected \u2014 listening for real-time events`)),s&&clearTimeout(s),s=setTimeout(()=>{console.log(d.default.dim(` [${y()}] SSE proactive reconnect \u2014 refreshing token before expiry`)),g.close(),r()},gn)},g.onmessage=async C=>{try{let f=JSON.parse(C.data);await hn(f)}catch{}},g.onerror=async()=>{g.close(),s&&(clearTimeout(s),s=null),console.log(d.default.dim(` [${y()}] SSE disconnected \u2014 reconnecting in ${o/1e3}s...`)),setTimeout(r,o),o=Math.min(o*1.5,n)}}catch(a){console.log(d.default.dim(` [${y()}] SSE connection failed: ${a.message}`)),setTimeout(r,o),o=Math.min(o*1.5,n)}}r()}function y(){return new Date().toISOString()}async function hn(e){if(e.type==="pair"){console.log(d.default.cyan(` [${y()}] Pair event: ${e.bot_name}`)),await se(e.pair_code,e.bot_name,e.bot_user_id,!0);try{let{execSync:t}=await import("child_process");t("openclaw gateway restart",{stdio:"ignore"}),console.log(d.default.green(` [${y()}] Gateway restarted \u2014 ${e.bot_name} is live`))}catch{}try{await k()}catch{}}else if(e.type==="bot.delete"&&e.bot_user_id){let t=e.bot_user_id,o=t.split(":")[0].replace("@","").replace(/_bot$/,"");console.log(d.default.yellow(` [${y()}] Bot deleted: ${t}`));try{let n=await import("fs"),s=await import("path"),r=await import("os"),a=s.join(r.homedir(),".openclaw","openclaw.json"),i=JSON.parse(n.readFileSync(a,"utf-8")),l=!1;if(i.channels?.badgerclaw?.accounts?.[o]&&(delete i.channels.badgerclaw.accounts[o],l=!0),i.agents?.list){let g=i.agents.list.length;i.agents.list=i.agents.list.filter(C=>C.id!==o),i.agents.list.length!==g&&(l=!0)}if(l){n.writeFileSync(a,JSON.stringify(i,null,2)),console.log(d.default.green(` [${y()}] Removed "${o}" from openclaw.json`));let{execSync:g}=await import("child_process");try{g("openclaw gateway restart",{stdio:"ignore"}),console.log(d.default.green(` [${y()}] Gateway restarted`))}catch{}}}catch(n){console.log(d.default.red(` [${y()}] Failed to clean up bot: ${n}`))}try{await k()}catch{}}else if(e.type==="gateway-restart"){console.log(d.default.cyan(` [${y()}] Remote gateway-restart received`));let t=await X();console.log(t.success?d.default.green(` [${y()}] Gateway restarted`):d.default.red(` [${y()}] Gateway restart failed: ${t.message}`));try{await k()}catch{}}else if(e.type==="claude_code.start"&&e.bot_id){if(console.log(d.default.cyan(` [${y()}] Claude Code START: bot=${e.bot_id}`)),De("start_claude_code",e.bot_id)){console.log(d.default.dim(` [${y()}] Skipping duplicate start_claude_code (already processed)`));return}try{let t=await M({id:e.command_id||`cc-start-${Date.now()}`,command_type:"start_claude_code",payload:{bot_id:e.bot_id,bot_user_id:e.bot_user_id,room_id:e.room_id,session_id:e.session_id}});e.command_id&&await S().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await k()}catch{}}else if(e.type==="claude_code.stop"&&e.bot_id){if(console.log(d.default.cyan(` [${y()}] Claude Code STOP: bot=${e.bot_id}`)),De("stop_claude_code",e.bot_id)){console.log(d.default.dim(` [${y()}] Skipping duplicate stop_claude_code (already processed)`));return}try{let t=await M({id:e.command_id||`cc-stop-${Date.now()}`,command_type:"stop_claude_code",payload:{bot_id:e.bot_id,bot_user_id:e.bot_user_id,room_id:e.room_id,session_id:e.session_id}});e.command_id&&await S().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await k()}catch{}}else if(e.type==="command.execute"&&e.command_id){if(console.log(d.default.cyan(` [${y()}] Command: ${e.command_type} (${e.command_id})`)),De(e.command_type,e.payload?.bot_id)){console.log(d.default.dim(` [${y()}] Skipping duplicate ${e.command_type} (already processed)`));return}try{let t=S();await t.post(`/api/v1/dashboard/commands/${e.command_id}/ack`);let o=await M({id:e.command_id,command_type:e.command_type,payload:e.payload});await t.post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:o.success?"success":"failed",result:o.message,new_version:o.newVersion||null}),e.command_type==="update_cli"&&o.success&&(console.log(d.default.cyan(` [${y()}] CLI updated \u2014 restarting in 2s...`)),setTimeout(()=>process.exit(0),2e3))}catch{}try{await k()}catch{}}}var no=new oo.Command("watch").description("Watch for bot pair events in real-time (no polling)").action(async()=>{let e=h();e||(console.log(m.default.yellow("Not logged in.")),process.exit(1)),await re(!1),console.log(m.default.green("\u{1F534} Listening for pair events... (Ctrl+C to stop)"));let t=require("eventsource"),o=new t(`${A}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${e.access_token}`}});o.onmessage=async n=>{try{let s=JSON.parse(n.data);if(s.type==="pair"){console.log(m.default.cyan(`
111
+ \u{1F4F1} Pair event received: ${s.bot_name}`)),await se(s.pair_code,s.bot_name,s.bot_user_id,!1);try{let{execSync:r}=await import("child_process");r("openclaw gateway restart",{stdio:"ignore"}),console.log(m.default.green(" \u2705 Gateway restarted \u2014 bot is live!"))}catch{console.log(m.default.dim(" Gateway restart failed \u2014 run: openclaw gateway restart"))}}else if(s.type==="gateway-restart"){console.log(m.default.cyan(`
112
+ \u{1F504} Remote gateway-restart command received`));let r=await X();r.success?console.log(m.default.green(` \u2705 Gateway restarted: ${r.message}`)):console.log(m.default.red(` \u274C Gateway restart failed: ${r.message}`));try{await k(),console.log(m.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(m.default.dim(" Could not push heartbeat."))}}else if(s.type==="bot.delete"&&s.bot_user_id){let r=s.bot_user_id,a=r.split(":")[0].replace("@","").replace(/_bot$/,"");console.log(m.default.yellow(`
113
113
  \u{1F5D1}\uFE0F Bot deleted: ${r} \u2014 removing from OpenClaw config...`));try{let i=await import("fs"),l=await import("path"),g=await import("os"),C=l.join(g.homedir(),".openclaw","openclaw.json"),f=JSON.parse(i.readFileSync(C,"utf-8")),O=!1;if(f.channels?.badgerclaw?.accounts?.[a]&&(delete f.channels.badgerclaw.accounts[a],O=!0),f.agents?.list){let P=f.agents.list.length;f.agents.list=f.agents.list.filter(N=>N.id!==a),f.agents.list.length!==P&&(O=!0)}if(O){i.writeFileSync(C,JSON.stringify(f,null,2)),console.log(m.default.green(` \u2705 Removed "${a}" from openclaw.json`));let{execSync:P}=await import("child_process");try{P("openclaw gateway restart",{stdio:"ignore"}),console.log(m.default.green(" \u2705 Gateway restarted"))}catch{console.log(m.default.dim(" Gateway restart failed \u2014 restart manually"))}}else console.log(m.default.dim(` "${a}" not found in openclaw.json \u2014 nothing to remove`))}catch(i){console.log(m.default.red(` Failed to update openclaw.json: ${i}`))}}else if(s.type==="claude_code.start"&&s.bot_id&&s.room_id){console.log(m.default.cyan(`
114
- \u{1F916} Claude Code START received: bot=${s.bot_id} room=${s.room_id}`));try{let r=await M({id:s.command_id||`cc-start-${Date.now()}`,command_type:"start_claude_code",payload:{bot_id:s.bot_id,room_id:s.room_id,session_id:s.session_id}});if(console.log(r.success?m.default.green(` \u2705 ${r.message}`):m.default.red(` \u274C ${r.message}`)),s.command_id)try{await S().post(`/api/v1/dashboard/commands/${s.command_id}/result`,{status:r.success?"success":"failed",result:r.message})}catch{}try{await A()}catch{}}catch(r){console.log(m.default.red(` Claude Code start error: ${r.message}`))}}else if(s.type==="claude_code.stop"&&s.bot_id&&s.room_id){console.log(m.default.cyan(`
115
- \u{1F916} Claude Code STOP received: bot=${s.bot_id} room=${s.room_id}`));try{let r=await M({id:s.command_id||`cc-stop-${Date.now()}`,command_type:"stop_claude_code",payload:{bot_id:s.bot_id,room_id:s.room_id,session_id:s.session_id}});if(console.log(r.success?m.default.green(` \u2705 ${r.message}`):m.default.red(` \u274C ${r.message}`)),s.command_id)try{await S().post(`/api/v1/dashboard/commands/${s.command_id}/result`,{status:r.success?"success":"failed",result:r.message})}catch{}try{await A()}catch{}}catch(r){console.log(m.default.red(` Claude Code stop error: ${r.message}`))}}else if(s.type==="command.execute"&&s.command_id){console.log(m.default.cyan(`
116
- \u26A1 SSE command received: ${s.command_type} (${s.command_id})`));try{let r=S();await r.post(`/api/v1/dashboard/commands/${s.command_id}/ack`);let a=await M({id:s.command_id,command_type:s.command_type,payload:s.payload});console.log(a.success?m.default.green(` \u2705 ${a.message}`):m.default.red(` \u274C ${a.message}`)),await r.post(`/api/v1/dashboard/commands/${s.command_id}/result`,{status:a.success?"success":"failed",result:a.message,new_version:a.newVersion||null});try{await A()}catch{}s.command_type==="update_cli"&&a.success&&(console.log(m.default.cyan(" CLI updated \u2014 restarting in 2s...")),setTimeout(()=>process.exit(0),2e3))}catch(r){console.log(m.default.red(` Command ${s.command_id} error: ${r.message}`))}}}catch{}},o.onerror=()=>{console.log(m.default.dim(" Reconnecting..."))},await new Promise(()=>{})});var ao=require("commander"),w=c(require("chalk")),Q=require("child_process"),D=c(require("fs")),it=c(require("os")),ct=c(require("path"));var no=c(require("fs")),so=c(require("os")),De=c(require("path")),rt=require("child_process"),F=c(require("chalk"));var fn=`${k}/api/v1/dashboard/versions/latest`,hn=2500,wn=new Set(["setup","logout","help","--version","-V","--help","-h","heartbeat","watch","autopair"]),oo=De.default.join(so.default.homedir(),".openclaw/extensions/badgerclaw"),yn=[De.default.join(oo,"node_modules/@badgerclaw/connect/package.json"),De.default.join(oo,"package.json")];function at(){return"0.2.26"}function _n(){for(let e of yn)try{let t=no.default.readFileSync(e,"utf-8"),o=JSON.parse(t);if(o.version&&(!o.name||o.name==="@badgerclaw/connect"||o.name==="badgerclaw")||o.version)return o.version}catch{}return null}function bn(e){let t=e.trim(),o=t.match(/\d+(?:\.\d+){1,3}/);return o?o[0]:t}function Oe(){if((0,rt.spawnSync)("which",["openclaw"],{encoding:"utf-8"}).status!==0)return null;let t=(0,rt.spawnSync)("openclaw",["--version"],{encoding:"utf-8",timeout:3e3});return t.status!==0||!t.stdout?null:bn(t.stdout)||null}async function $n(){let e=new AbortController,t=setTimeout(()=>e.abort(),hn);try{let o=await fetch(fn,{signal:e.signal});if(!o.ok)return null;let n=await o.json(),s=n.result&&typeof n.result=="object"?n.result:n;return{cli:s.cli??"unknown",plugin:s.plugin??"unknown",supported_openclaw:s.supported_openclaw??"unknown"}}catch{return null}finally{clearTimeout(t)}}function Sn(e){let t=[];if(e.cli&&e.cli!=="unknown"){let o=at();o!==e.cli&&t.push({component:"cli",current:o,approved:e.cli})}if(e.plugin&&e.plugin!=="unknown"){let o=_n();(o===null||o!==e.plugin)&&t.push({component:"plugin",current:o??"not installed",approved:e.plugin})}if(e.supported_openclaw&&e.supported_openclaw!=="unknown"){let o=Oe();(o===null||o!==e.supported_openclaw)&&t.push({component:"openclaw",current:o??"not installed",approved:e.supported_openclaw})}return t}function Cn(e){return e[2]}function vn(e){return!e||e.startsWith("-")?!0:wn.has(e)}function In(e){let t=[];t.push(""),t.push(F.default.red.bold("\u2717 Unsupported versions detected")),t.push("");for(let o of e){let n=o.component.padEnd(8);t.push(` ${n} ${F.default.yellow(o.current)} \u2192 ${F.default.green(o.approved)} ${F.default.dim("(supported)")}`)}return t.push(""),t.push("This command is blocked until your installation matches the supported versions."),t.push(""),t.push(F.default.green(" To fix, run:")),t.push(F.default.green.bold(" badgerclaw setup")),t.push(""),t.push(F.default.dim(" (bypass temporarily: BADGERCLAW_NO_VERSION_CHECK=1 badgerclaw <cmd>)")),t.push(""),t.join(`
117
- `)}async function ro(e){if(process.env.BADGERCLAW_NO_VERSION_CHECK)return;let t=Cn(e);if(vn(t))return;let o=await $n();if(!o)return;let n=Sn(o);n.length!==0&&(process.stderr.write(In(n)),process.exit(1))}var Z=ct.default.join(it.default.homedir(),".openclaw","openclaw.json"),pe=Z+".badgerclaw-stash";async function xn(){try{let e=await fetch(`${k}/api/v1/dashboard/versions/latest`,{headers:{Accept:"application/json"}});if(!e.ok)return{cli:null,plugin:null,openclaw:null};let t=await e.json(),o=t.result&&typeof t.result=="object"?t.result:t,n=s=>typeof s!="string"||!s||s==="unknown"?null:s;return{cli:n(o.cli),plugin:n(o.plugin),openclaw:n(o.supported_openclaw)}}catch{return{cli:null,plugin:null,openclaw:null}}}function An(){if(!D.default.existsSync(Z))return null;try{let e=JSON.parse(D.default.readFileSync(Z,"utf-8")),t=e.channels?.badgerclaw;return t?(delete e.channels.badgerclaw,e.plugins?.entries?.badgerclaw&&delete e.plugins.entries.badgerclaw,D.default.writeFileSync(Z,JSON.stringify(e,null,2)),D.default.writeFileSync(pe,JSON.stringify(t,null,2)),t):null}catch{return null}}function kn(){if(D.default.existsSync(pe))try{let e=JSON.parse(D.default.readFileSync(pe,"utf-8")),t=JSON.parse(D.default.readFileSync(Z,"utf-8"));t.channels=t.channels||{},t.channels.badgerclaw=e,D.default.writeFileSync(Z,JSON.stringify(t,null,2)),D.default.unlinkSync(pe)}catch(e){console.log(w.default.yellow(` \u26A0\uFE0F Could not restore config: ${e.message}`)),console.log(w.default.yellow(` Your bot credentials are backed up at: ${pe}`))}}var io=new ao.Command("setup").description("Install or update the OpenClaw BadgerClaw plugin safely (handles config automatically)").action(async()=>{console.log(w.default.green(`
114
+ \u{1F916} Claude Code START received: bot=${s.bot_id} room=${s.room_id}`));try{let r=await M({id:s.command_id||`cc-start-${Date.now()}`,command_type:"start_claude_code",payload:{bot_id:s.bot_id,room_id:s.room_id,session_id:s.session_id}});if(console.log(r.success?m.default.green(` \u2705 ${r.message}`):m.default.red(` \u274C ${r.message}`)),s.command_id)try{await S().post(`/api/v1/dashboard/commands/${s.command_id}/result`,{status:r.success?"success":"failed",result:r.message})}catch{}try{await k()}catch{}}catch(r){console.log(m.default.red(` Claude Code start error: ${r.message}`))}}else if(s.type==="claude_code.stop"&&s.bot_id&&s.room_id){console.log(m.default.cyan(`
115
+ \u{1F916} Claude Code STOP received: bot=${s.bot_id} room=${s.room_id}`));try{let r=await M({id:s.command_id||`cc-stop-${Date.now()}`,command_type:"stop_claude_code",payload:{bot_id:s.bot_id,room_id:s.room_id,session_id:s.session_id}});if(console.log(r.success?m.default.green(` \u2705 ${r.message}`):m.default.red(` \u274C ${r.message}`)),s.command_id)try{await S().post(`/api/v1/dashboard/commands/${s.command_id}/result`,{status:r.success?"success":"failed",result:r.message})}catch{}try{await k()}catch{}}catch(r){console.log(m.default.red(` Claude Code stop error: ${r.message}`))}}else if(s.type==="command.execute"&&s.command_id){console.log(m.default.cyan(`
116
+ \u26A1 SSE command received: ${s.command_type} (${s.command_id})`));try{let r=S();await r.post(`/api/v1/dashboard/commands/${s.command_id}/ack`);let a=await M({id:s.command_id,command_type:s.command_type,payload:s.payload});console.log(a.success?m.default.green(` \u2705 ${a.message}`):m.default.red(` \u274C ${a.message}`)),await r.post(`/api/v1/dashboard/commands/${s.command_id}/result`,{status:a.success?"success":"failed",result:a.message,new_version:a.newVersion||null});try{await k()}catch{}s.command_type==="update_cli"&&a.success&&(console.log(m.default.cyan(" CLI updated \u2014 restarting in 2s...")),setTimeout(()=>process.exit(0),2e3))}catch(r){console.log(m.default.red(` Command ${s.command_id} error: ${r.message}`))}}}catch{}},o.onerror=()=>{console.log(m.default.dim(" Reconnecting..."))},await new Promise(()=>{})});var co=require("commander"),w=c(require("chalk")),Q=require("child_process"),D=c(require("fs")),ct=c(require("os")),lt=c(require("path"));var ro=c(require("fs")),ao=c(require("os")),Oe=c(require("path")),at=require("child_process"),F=c(require("chalk"));var wn=`${A}/api/v1/dashboard/versions/latest`,yn=2500,_n=new Set(["setup","logout","help","--version","-V","--help","-h","heartbeat","watch","autopair"]),so=Oe.default.join(ao.default.homedir(),".openclaw/extensions/badgerclaw"),bn=[Oe.default.join(so,"node_modules/@badgerclaw/connect/package.json"),Oe.default.join(so,"package.json")];function it(){return"0.2.27"}function $n(){for(let e of bn)try{let t=ro.default.readFileSync(e,"utf-8"),o=JSON.parse(t);if(o.version&&(!o.name||o.name==="@badgerclaw/connect"||o.name==="badgerclaw")||o.version)return o.version}catch{}return null}function Sn(e){let t=e.trim(),o=t.match(/\d+(?:\.\d+){1,3}/);return o?o[0]:t}function Ne(){if((0,at.spawnSync)("which",["openclaw"],{encoding:"utf-8"}).status!==0)return null;let t=(0,at.spawnSync)("openclaw",["--version"],{encoding:"utf-8",timeout:3e3});return t.status!==0||!t.stdout?null:Sn(t.stdout)||null}async function Cn(){let e=new AbortController,t=setTimeout(()=>e.abort(),yn);try{let o=await fetch(wn,{signal:e.signal});if(!o.ok)return null;let n=await o.json(),s=n.result&&typeof n.result=="object"?n.result:n;return{cli:s.cli??"unknown",plugin:s.plugin??"unknown",supported_openclaw:s.supported_openclaw??"unknown"}}catch{return null}finally{clearTimeout(t)}}function vn(e){let t=[];if(e.cli&&e.cli!=="unknown"){let o=it();o!==e.cli&&t.push({component:"cli",current:o,approved:e.cli})}if(e.plugin&&e.plugin!=="unknown"){let o=$n();(o===null||o!==e.plugin)&&t.push({component:"plugin",current:o??"not installed",approved:e.plugin})}if(e.supported_openclaw&&e.supported_openclaw!=="unknown"){let o=Ne();(o===null||o!==e.supported_openclaw)&&t.push({component:"openclaw",current:o??"not installed",approved:e.supported_openclaw})}return t}function In(e){return e[2]}function xn(e){return!e||e.startsWith("-")?!0:_n.has(e)}function kn(e){let t=[];t.push(""),t.push(F.default.red.bold("\u2717 Unsupported versions detected")),t.push("");for(let o of e){let n=o.component.padEnd(8);t.push(` ${n} ${F.default.yellow(o.current)} \u2192 ${F.default.green(o.approved)} ${F.default.dim("(supported)")}`)}return t.push(""),t.push("This command is blocked until your installation matches the supported versions."),t.push(""),t.push(F.default.green(" To fix, run:")),t.push(F.default.green.bold(" badgerclaw setup")),t.push(""),t.push(F.default.dim(" (bypass temporarily: BADGERCLAW_NO_VERSION_CHECK=1 badgerclaw <cmd>)")),t.push(""),t.join(`
117
+ `)}async function io(e){if(process.env.BADGERCLAW_NO_VERSION_CHECK)return;let t=In(e);if(xn(t))return;let o=await Cn();if(!o)return;let n=vn(o);n.length!==0&&(process.stderr.write(kn(n)),process.exit(1))}var Z=lt.default.join(ct.default.homedir(),".openclaw","openclaw.json"),ge=Z+".badgerclaw-stash";async function An(){try{let e=await fetch(`${A}/api/v1/dashboard/versions/latest`,{headers:{Accept:"application/json"}});if(!e.ok)return{cli:null,plugin:null,openclaw:null};let t=await e.json(),o=t.result&&typeof t.result=="object"?t.result:t,n=s=>typeof s!="string"||!s||s==="unknown"?null:s;return{cli:n(o.cli),plugin:n(o.plugin),openclaw:n(o.supported_openclaw)}}catch{return{cli:null,plugin:null,openclaw:null}}}function Rn(){if(!D.default.existsSync(Z))return null;try{let e=JSON.parse(D.default.readFileSync(Z,"utf-8")),t=e.channels?.badgerclaw;return t?(delete e.channels.badgerclaw,e.plugins?.entries?.badgerclaw&&delete e.plugins.entries.badgerclaw,D.default.writeFileSync(Z,JSON.stringify(e,null,2)),D.default.writeFileSync(ge,JSON.stringify(t,null,2)),t):null}catch{return null}}function Pn(){if(D.default.existsSync(ge))try{let e=JSON.parse(D.default.readFileSync(ge,"utf-8")),t=JSON.parse(D.default.readFileSync(Z,"utf-8"));t.channels=t.channels||{},t.channels.badgerclaw=e,D.default.writeFileSync(Z,JSON.stringify(t,null,2)),D.default.unlinkSync(ge)}catch(e){console.log(w.default.yellow(` \u26A0\uFE0F Could not restore config: ${e.message}`)),console.log(w.default.yellow(` Your bot credentials are backed up at: ${ge}`))}}var lo=new co.Command("setup").description("Install or update the OpenClaw BadgerClaw plugin safely (handles config automatically)").action(async()=>{console.log(w.default.green(`
118
118
  \u{1F9A1} BadgerClaw Setup
119
- `));let e=await xn();if(e.cli){let a=at();a!==e.cli?(console.log(w.default.dim(` Updating CLI: ${a} \u2192 ${e.cli} (supported)...`)),(0,Q.spawnSync)("npm",["install","-g",`badgerclaw@${e.cli}`],{stdio:"inherit",shell:!0}).status!==0&&(console.log(w.default.red("\n\u274C CLI update failed. Fix the npm error above, then re-run `badgerclaw setup`.")),process.exit(1)),console.log(w.default.green(` \u2705 CLI updated to ${e.cli}`))):console.log(w.default.dim(` CLI already at approved version ${a}.`))}if(e.openclaw){let a=Oe();a!==e.openclaw?(console.log(a===null?w.default.dim(` Installing OpenClaw ${e.openclaw} (supported)...`):w.default.dim(` Updating OpenClaw: ${a} \u2192 ${e.openclaw} (supported)...`)),(0,Q.spawnSync)("npm",["install","-g",`openclaw@${e.openclaw}`],{stdio:"inherit",shell:!0}).status!==0&&(console.log(w.default.red("\n\u274C OpenClaw install/update failed. Fix the npm error above, then re-run `badgerclaw setup`.")),process.exit(1)),console.log(w.default.green(` \u2705 OpenClaw at ${e.openclaw}`))):console.log(w.default.dim(` OpenClaw already at approved version ${a}.`))}else Oe()===null&&(console.log(w.default.yellow(" \u26A0\uFE0F No approved OpenClaw version and none installed \u2014 installing latest from npm.")),(0,Q.spawnSync)("npm",["install","-g","openclaw"],{stdio:"inherit",shell:!0}).status!==0&&(console.log(w.default.red(`
120
- \u274C OpenClaw install failed.`)),process.exit(1)));let t=An();t&&console.log(w.default.dim(" Existing bot config stashed temporarily..."));let o=ct.default.join(it.default.homedir(),".openclaw","extensions","badgerclaw");if(D.default.existsSync(o))try{D.default.rmSync(o,{recursive:!0,force:!0}),console.log(w.default.dim(" Cleared existing plugin directory."))}catch(a){console.log(w.default.yellow(` \u26A0\uFE0F Could not clear plugin directory (${a.message}); install may fail.`))}let n=e.plugin?`@badgerclaw/connect@${e.plugin}`:"@badgerclaw/connect";e.plugin?console.log(w.default.dim(` Installing ${n} (supported)...`)):console.log(w.default.yellow(" \u26A0\uFE0F Allow-list unavailable \u2014 installing @badgerclaw/connect unpinned."));let s=(0,Q.spawnSync)("openclaw",["plugins","install",n,"--dangerously-force-unsafe-install"],{stdio:"inherit",shell:!0});t&&(kn(),console.log(w.default.dim(" Bot config restored."))),s.status!==0&&(console.log(w.default.red(`
119
+ `));let e=await An();if(e.cli){let a=it();a!==e.cli?(console.log(w.default.dim(` Updating CLI: ${a} \u2192 ${e.cli} (supported)...`)),(0,Q.spawnSync)("npm",["install","-g",`badgerclaw@${e.cli}`],{stdio:"inherit",shell:!0}).status!==0&&(console.log(w.default.red("\n\u274C CLI update failed. Fix the npm error above, then re-run `badgerclaw setup`.")),process.exit(1)),console.log(w.default.green(` \u2705 CLI updated to ${e.cli}`))):console.log(w.default.dim(` CLI already at approved version ${a}.`))}if(e.openclaw){let a=Ne();a!==e.openclaw?(console.log(a===null?w.default.dim(` Installing OpenClaw ${e.openclaw} (supported)...`):w.default.dim(` Updating OpenClaw: ${a} \u2192 ${e.openclaw} (supported)...`)),(0,Q.spawnSync)("npm",["install","-g",`openclaw@${e.openclaw}`],{stdio:"inherit",shell:!0}).status!==0&&(console.log(w.default.red("\n\u274C OpenClaw install/update failed. Fix the npm error above, then re-run `badgerclaw setup`.")),process.exit(1)),console.log(w.default.green(` \u2705 OpenClaw at ${e.openclaw}`))):console.log(w.default.dim(` OpenClaw already at approved version ${a}.`))}else Ne()===null&&(console.log(w.default.yellow(" \u26A0\uFE0F No approved OpenClaw version and none installed \u2014 installing latest from npm.")),(0,Q.spawnSync)("npm",["install","-g","openclaw"],{stdio:"inherit",shell:!0}).status!==0&&(console.log(w.default.red(`
120
+ \u274C OpenClaw install failed.`)),process.exit(1)));let t=Rn();t&&console.log(w.default.dim(" Existing bot config stashed temporarily..."));let o=lt.default.join(ct.default.homedir(),".openclaw","extensions","badgerclaw");if(D.default.existsSync(o))try{D.default.rmSync(o,{recursive:!0,force:!0}),console.log(w.default.dim(" Cleared existing plugin directory."))}catch(a){console.log(w.default.yellow(` \u26A0\uFE0F Could not clear plugin directory (${a.message}); install may fail.`))}let n=e.plugin?`@badgerclaw/connect@${e.plugin}`:"@badgerclaw/connect";e.plugin?console.log(w.default.dim(` Installing ${n} (supported)...`)):console.log(w.default.yellow(" \u26A0\uFE0F Allow-list unavailable \u2014 installing @badgerclaw/connect unpinned."));let s=(0,Q.spawnSync)("openclaw",["plugins","install",n,"--dangerously-force-unsafe-install"],{stdio:"inherit",shell:!0});t&&(Pn(),console.log(w.default.dim(" Bot config restored."))),s.status!==0&&(console.log(w.default.red(`
121
121
  \u274C Plugin install failed. Your bot config has been restored.`)),process.exit(1)),console.log(w.default.green(`
122
122
  \u2705 BadgerClaw plugin installed successfully!`)),console.log(w.default.dim(`
123
- Restarting OpenClaw gateway to load plugin...`)),(0,Q.spawnSync)("openclaw",["gateway","restart"],{stdio:"inherit",shell:!0}).status===0?console.log(w.default.green(" Gateway restarted.")):console.log(w.default.yellow(" Gateway restart failed or not running \u2014 start it manually: openclaw gateway start")),console.log(w.default.dim("\nNext: run `badgerclaw login` to authenticate."))});var lo=require("commander"),b=c(require("chalk"));var uo=new lo.Command("dashboard").description("Show local diagnostic dashboard \u2014 machine health, gateway status, bot telemetry").action(async()=>{h()||(console.log(b.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=W(),o=Ie(),n=await le();console.log(b.default.bold.green(`
123
+ Restarting OpenClaw gateway to load plugin...`)),(0,Q.spawnSync)("openclaw",["gateway","restart"],{stdio:"inherit",shell:!0}).status===0?console.log(w.default.green(" Gateway restarted.")):console.log(w.default.yellow(" Gateway restart failed or not running \u2014 start it manually: openclaw gateway start")),console.log(w.default.dim("\nNext: run `badgerclaw login` to authenticate."))});var mo=require("commander"),b=c(require("chalk"));var po=new mo.Command("dashboard").description("Show local diagnostic dashboard \u2014 machine health, gateway status, bot telemetry").action(async()=>{h()||(console.log(b.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=W(),o=xe(),n=await de();console.log(b.default.bold.green(`
124
124
  BadgerClaw Dashboard
125
- `)),console.log(b.default.bold(" Instance")),console.log(` ID: ${de()}`),console.log(` CLI Version: ${t}`),console.log(` Plugin: ${n.pluginVersion}`),console.log(),console.log(b.default.bold(" Machine")),console.log(` Hostname: ${o.hostname}`),console.log(` OS: ${o.os} / ${o.arch}`),console.log(` Uptime: ${co(o.uptimeSeconds)}`),console.log(` Free Memory: ${o.memFreeMb} MB`),console.log();let s=n.status==="running"?b.default.green:n.status==="error"?b.default.red:b.default.yellow;if(console.log(b.default.bold(" Gateway")),console.log(` Status: ${s(n.status)}`),console.log(` PID: ${n.pid??"N/A"}`),console.log(` Last Restart: ${n.lastRestart??"N/A"}`),console.log(),n.bots.length===0)console.log(b.default.bold(" Bots")),console.log(b.default.dim(" No bots detected. Pair bots at https://badgerclaw.ai")),console.log();else{console.log(b.default.bold(` Bots (${n.bots.length})`)),console.log();for(let r of n.bots){let a=r.status==="running"?b.default.green:r.status==="error"?b.default.red:b.default.yellow;if(console.log(` ${b.default.bold(r.botUsername)} ${a(`[${r.status}]`)}`),console.log(` ID: ${r.botId}`),console.log(` Uptime: ${co(r.uptimeSeconds)}`),console.log(` Messages: ${r.messagesReceived} in / ${r.messagesSent} out`),r.chunkedMessages>0&&console.log(` Chunked: ${r.chunkedMessages} messages, ${r.totalChunksSent} chunks`),console.log(` Rooms: ${r.roomsActive} active`),console.log(` Errors: ${r.errors}`),r.lastError&&(console.log(` Last Error: ${b.default.red(r.lastError)}`),console.log(` Error At: ${r.lastErrorAt}`)),console.log(` Last Active: ${r.lastActivity??"N/A"}`),r.roomDetails&&r.roomDetails.length>0){console.log(b.default.dim(" Rooms:"));for(let i of r.roomDetails)console.log(b.default.dim(` ${i.roomName} \u2014 ${i.messagesInRoom} msgs, last: ${i.lastActivityInRoom??"N/A"}`))}console.log()}}console.log(b.default.dim(` Last checked: ${new Date().toISOString()}`)),console.log()});function co(e){if(e<60)return`${e}s`;if(e<3600)return`${Math.floor(e/60)}m ${e%60}s`;let t=Math.floor(e/3600),o=Math.floor(e%3600/60);return t<24?`${t}h ${o}m`:`${Math.floor(t/24)}d ${t%24}h ${o}m`}var lt=require("commander"),ee=c(require("chalk")),mo=c(require("ora"));var Rn=new lt.Command("restart").description("Restart the OpenClaw gateway via the plugin probe endpoint").action(async()=>{h()||(console.log(ee.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,mo.default)("Restarting gateway...").start(),o=await X();if(o.success){t.succeed(ee.default.green(`Gateway restarted: ${o.message}`));try{await A(),console.log(ee.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(ee.default.dim(" Could not push heartbeat \u2014 daemon may not be running."))}}else t.fail(ee.default.red(`Gateway restart failed: ${o.message}`)),process.exit(1)}),po=new lt.Command("gateway").description("Manage the OpenClaw gateway").addCommand(Rn);var V=require("commander"),p=c(require("chalk")),z=c(require("ora")),G=c(require("axios"));ke();var J="http://localhost:7331",Pn=new V.Command("start").description("Start a Claude Code session for a bot+room").requiredOption("--bot <botId>","Bot ID or username").requiredOption("--room <roomId>","Matrix room ID").option("--session-id <id>","Session ID (default: auto-generated)").option("--port <port>","MCP server port (default: 7332)","7332").option("--project <dir>","Project directory",process.cwd()).action(async e=>{h()||(console.log(p.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=e.sessionId||`session-${Date.now()}`,n=parseInt(e.port,10),s=e.project.replace(/^~/,process.env.HOME||""),r=(0,z.default)("Starting Claude Code session...").start();try{await G.default.post(`${J}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!0,sessionId:o},{timeout:1e4}),r.text="Gateway toggled \u2014 launching MCP server...";let i=Qe({sessionId:o,port:n,projectDir:s}).pid||0;await new Promise(l=>setTimeout(l,1500)),r.text="MCP server running \u2014 launching Claude Code...",Ze({sessionId:o,port:n,projectDir:s}),et(o,0,i,n,s),r.succeed(p.default.green("Claude Code session started")+p.default.dim(` (session: ${o}, port: ${n})`)),console.log(p.default.dim(` Bot: ${e.bot}`)),console.log(p.default.dim(` Room: ${e.room}`)),console.log(p.default.dim(` Project: ${s}`)),console.log(p.default.dim(" Claude Code should open in a new terminal window."))}catch(a){let i=a.response?.data?.message||a.message||"Unknown error";r.fail(p.default.red(`Failed to start Claude Code: ${i}`)),process.exit(1)}}),En=new V.Command("stop").description("Stop a Claude Code session").option("--bot <botId>","Bot ID or username").option("--room <roomId>","Matrix room ID").option("--session-id <id>","Session ID to stop").action(async e=>{h()||(console.log(p.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=(0,z.default)("Stopping Claude Code session...").start();try{e.bot&&e.room&&await G.default.post(`${J}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!1},{timeout:1e4});let n=e.sessionId;if(!n)try{let a=((await G.default.get(`${J}/claude-code/status`,{timeout:5e3})).data?.rooms||[]).find(i=>i.botId===e.bot&&i.roomId===e.room);a&&(n=a.sessionId)}catch{}n?(tt(n),o.succeed(p.default.green(`Claude Code session stopped (${n})`))):(o.succeed(p.default.green("Claude Code toggled off at gateway")),console.log(p.default.dim(" No local session found to kill \u2014 may need to close Claude Code manually.")))}catch(n){let s=n.response?.data?.message||n.message||"Unknown error";o.fail(p.default.red(`Failed to stop Claude Code: ${s}`)),process.exit(1)}}),Dn=new V.Command("status").description("Show active Claude Code sessions").action(async()=>{h()||(console.log(p.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,z.default)("Fetching Claude Code status...").start();try{let o=[];try{o=(await G.default.get(`${J}/claude-code/status`,{timeout:5e3})).data?.rooms||[]}catch{}let n=ot();if(t.stop(),o.length===0&&n.length===0){console.log(p.default.dim("No active Claude Code sessions."));return}if(o.length>0){console.log(p.default.bold(`
125
+ `)),console.log(b.default.bold(" Instance")),console.log(` ID: ${ue()}`),console.log(` CLI Version: ${t}`),console.log(` Plugin: ${n.pluginVersion}`),console.log(),console.log(b.default.bold(" Machine")),console.log(` Hostname: ${o.hostname}`),console.log(` OS: ${o.os} / ${o.arch}`),console.log(` Uptime: ${uo(o.uptimeSeconds)}`),console.log(` Free Memory: ${o.memFreeMb} MB`),console.log();let s=n.status==="running"?b.default.green:n.status==="error"?b.default.red:b.default.yellow;if(console.log(b.default.bold(" Gateway")),console.log(` Status: ${s(n.status)}`),console.log(` PID: ${n.pid??"N/A"}`),console.log(` Last Restart: ${n.lastRestart??"N/A"}`),console.log(),n.bots.length===0)console.log(b.default.bold(" Bots")),console.log(b.default.dim(" No bots detected. Pair bots at https://badgerclaw.ai")),console.log();else{console.log(b.default.bold(` Bots (${n.bots.length})`)),console.log();for(let r of n.bots){let a=r.status==="running"?b.default.green:r.status==="error"?b.default.red:b.default.yellow;if(console.log(` ${b.default.bold(r.botUsername)} ${a(`[${r.status}]`)}`),console.log(` ID: ${r.botId}`),console.log(` Uptime: ${uo(r.uptimeSeconds)}`),console.log(` Messages: ${r.messagesReceived} in / ${r.messagesSent} out`),r.chunkedMessages>0&&console.log(` Chunked: ${r.chunkedMessages} messages, ${r.totalChunksSent} chunks`),console.log(` Rooms: ${r.roomsActive} active`),console.log(` Errors: ${r.errors}`),r.lastError&&(console.log(` Last Error: ${b.default.red(r.lastError)}`),console.log(` Error At: ${r.lastErrorAt}`)),console.log(` Last Active: ${r.lastActivity??"N/A"}`),r.roomDetails&&r.roomDetails.length>0){console.log(b.default.dim(" Rooms:"));for(let i of r.roomDetails)console.log(b.default.dim(` ${i.roomName} \u2014 ${i.messagesInRoom} msgs, last: ${i.lastActivityInRoom??"N/A"}`))}console.log()}}console.log(b.default.dim(` Last checked: ${new Date().toISOString()}`)),console.log()});function uo(e){if(e<60)return`${e}s`;if(e<3600)return`${Math.floor(e/60)}m ${e%60}s`;let t=Math.floor(e/3600),o=Math.floor(e%3600/60);return t<24?`${t}h ${o}m`:`${Math.floor(t/24)}d ${t%24}h ${o}m`}var dt=require("commander"),ee=c(require("chalk")),go=c(require("ora"));var En=new dt.Command("restart").description("Restart the OpenClaw gateway via the plugin probe endpoint").action(async()=>{h()||(console.log(ee.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,go.default)("Restarting gateway...").start(),o=await X();if(o.success){t.succeed(ee.default.green(`Gateway restarted: ${o.message}`));try{await k(),console.log(ee.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(ee.default.dim(" Could not push heartbeat \u2014 daemon may not be running."))}}else t.fail(ee.default.red(`Gateway restart failed: ${o.message}`)),process.exit(1)}),fo=new dt.Command("gateway").description("Manage the OpenClaw gateway").addCommand(En);var V=require("commander"),p=c(require("chalk")),z=c(require("ora")),G=c(require("axios"));Re();var J="http://localhost:7331",Dn=new V.Command("start").description("Start a Claude Code session for a bot+room").requiredOption("--bot <botId>","Bot ID or username").requiredOption("--room <roomId>","Matrix room ID").option("--session-id <id>","Session ID (default: auto-generated)").option("--port <port>","MCP server port (default: 7332)","7332").option("--project <dir>","Project directory",process.cwd()).action(async e=>{h()||(console.log(p.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=e.sessionId||`session-${Date.now()}`,n=parseInt(e.port,10),s=e.project.replace(/^~/,process.env.HOME||""),r=(0,z.default)("Starting Claude Code session...").start();try{await G.default.post(`${J}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!0,sessionId:o},{timeout:1e4}),r.text="Gateway toggled \u2014 launching MCP server...";let i=Ze({sessionId:o,port:n,projectDir:s}).pid||0;await new Promise(l=>setTimeout(l,1500)),r.text="MCP server running \u2014 launching Claude Code...",et({sessionId:o,port:n,projectDir:s}),tt(o,0,i,n,s),r.succeed(p.default.green("Claude Code session started")+p.default.dim(` (session: ${o}, port: ${n})`)),console.log(p.default.dim(` Bot: ${e.bot}`)),console.log(p.default.dim(` Room: ${e.room}`)),console.log(p.default.dim(` Project: ${s}`)),console.log(p.default.dim(" Claude Code should open in a new terminal window."))}catch(a){let i=a.response?.data?.message||a.message||"Unknown error";r.fail(p.default.red(`Failed to start Claude Code: ${i}`)),process.exit(1)}}),On=new V.Command("stop").description("Stop a Claude Code session").option("--bot <botId>","Bot ID or username").option("--room <roomId>","Matrix room ID").option("--session-id <id>","Session ID to stop").action(async e=>{h()||(console.log(p.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=(0,z.default)("Stopping Claude Code session...").start();try{e.bot&&e.room&&await G.default.post(`${J}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!1},{timeout:1e4});let n=e.sessionId;if(!n)try{let a=((await G.default.get(`${J}/claude-code/status`,{timeout:5e3})).data?.rooms||[]).find(i=>i.botId===e.bot&&i.roomId===e.room);a&&(n=a.sessionId)}catch{}n?(ot(n),o.succeed(p.default.green(`Claude Code session stopped (${n})`))):(o.succeed(p.default.green("Claude Code toggled off at gateway")),console.log(p.default.dim(" No local session found to kill \u2014 may need to close Claude Code manually.")))}catch(n){let s=n.response?.data?.message||n.message||"Unknown error";o.fail(p.default.red(`Failed to stop Claude Code: ${s}`)),process.exit(1)}}),Nn=new V.Command("status").description("Show active Claude Code sessions").action(async()=>{h()||(console.log(p.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,z.default)("Fetching Claude Code status...").start();try{let o=[];try{o=(await G.default.get(`${J}/claude-code/status`,{timeout:5e3})).data?.rooms||[]}catch{}let n=nt();if(t.stop(),o.length===0&&n.length===0){console.log(p.default.dim("No active Claude Code sessions."));return}if(o.length>0){console.log(p.default.bold(`
126
126
  Gateway Claude Code Rooms:`)),console.log(p.default.dim(" Bot".padEnd(30)+"Room".padEnd(30)+"Session".padEnd(20)+"Enabled")),console.log(p.default.dim(" "+"-".repeat(88)));for(let s of o){let r=s.enabled?p.default.green("ON"):p.default.dim("OFF");console.log(` ${(s.botId||"").padEnd(30)}${(s.roomName||s.roomId||"").padEnd(30)}${(s.sessionId||"-").padEnd(20)}${r}`)}}if(n.length>0){console.log(p.default.bold(`
127
- Local Sessions:`)),console.log(p.default.dim(" Session".padEnd(25)+"Port".padEnd(8)+"MCP PID".padEnd(10)+"Project".padEnd(40)+"Started")),console.log(p.default.dim(" "+"-".repeat(90)));for(let s of n)console.log(` ${s.sessionId.padEnd(25)}${String(s.port).padEnd(8)}${String(s.mcpPid).padEnd(10)}${s.projectDir.padEnd(40)}${s.startedAt}`)}console.log("")}catch(o){t.fail(p.default.red(`Failed to get status: ${o.message}`)),process.exit(1)}}),On=new V.Command("group").description("Group bots/rooms into a shared Claude Code session").requiredOption("--session <id>","Session ID to group under").requiredOption("--bot <botId>","Bot ID or username").requiredOption("--room <roomId>","Matrix room ID").action(async e=>{let t=(0,z.default)("Grouping bot+room into session...").start();try{await G.default.post(`${J}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!0,sessionId:e.session},{timeout:1e4}),t.succeed(p.default.green(`Grouped ${e.bot} + ${e.room} into session "${e.session}"`))}catch(o){let n=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to group: ${n}`)),process.exit(1)}}),Nn=new V.Command("allow").description("Add a user to the Claude Code allowlist for a bot+room").requiredOption("--bot <botId>","Bot ID or username").requiredOption("--room <roomId>","Matrix room ID").requiredOption("--user <userId>","Matrix user ID to allow (e.g. @alice:server)").action(async e=>{let t=(0,z.default)("Adding user to allowlist...").start();try{await G.default.post(`${J}/claude-code/allow`,{botId:e.bot,roomId:e.room,userId:e.user},{timeout:1e4}),t.succeed(p.default.green(`Added ${e.user} to allowlist for ${e.bot} in ${e.room}`))}catch(o){let n=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to add user: ${n}`)),process.exit(1)}}),Tn=new V.Command("revoke").description("Remove a user from the Claude Code allowlist for a bot+room").requiredOption("--bot <botId>","Bot ID or username").requiredOption("--room <roomId>","Matrix room ID").requiredOption("--user <userId>","Matrix user ID to revoke").action(async e=>{let t=(0,z.default)("Removing user from allowlist...").start();try{await G.default.post(`${J}/claude-code/revoke`,{botId:e.bot,roomId:e.room,userId:e.user},{timeout:1e4}),t.succeed(p.default.green(`Removed ${e.user} from allowlist for ${e.bot} in ${e.room}`))}catch(o){let n=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to revoke user: ${n}`)),process.exit(1)}}),go=new V.Command("claude-code").description("Manage Claude Code sessions (relay Matrix messages to local Claude Code)").addCommand(Pn).addCommand(En).addCommand(Dn).addCommand(On).addCommand(Nn).addCommand(Tn);async function Ln(){await ro(process.argv);let e=new fo.Command;e.name("badgerclaw").description("BadgerClaw CLI \u2014 one-click bot provisioning").version("0.2.26"),e.addCommand(Lt),e.addCommand(Bt),e.addCommand(Mt),e.addCommand(Ft),e.addCommand(vt),e.addCommand(to),e.addCommand(io),e.addCommand(Qt),e.addCommand(uo),e.addCommand(po),e.addCommand(go),e.parse(process.argv)}Ln().catch(e=>{console.error(e),process.exit(1)});
127
+ Local Sessions:`)),console.log(p.default.dim(" Session".padEnd(25)+"Port".padEnd(8)+"MCP PID".padEnd(10)+"Project".padEnd(40)+"Started")),console.log(p.default.dim(" "+"-".repeat(90)));for(let s of n)console.log(` ${s.sessionId.padEnd(25)}${String(s.port).padEnd(8)}${String(s.mcpPid).padEnd(10)}${s.projectDir.padEnd(40)}${s.startedAt}`)}console.log("")}catch(o){t.fail(p.default.red(`Failed to get status: ${o.message}`)),process.exit(1)}}),Tn=new V.Command("group").description("Group bots/rooms into a shared Claude Code session").requiredOption("--session <id>","Session ID to group under").requiredOption("--bot <botId>","Bot ID or username").requiredOption("--room <roomId>","Matrix room ID").action(async e=>{let t=(0,z.default)("Grouping bot+room into session...").start();try{await G.default.post(`${J}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!0,sessionId:e.session},{timeout:1e4}),t.succeed(p.default.green(`Grouped ${e.bot} + ${e.room} into session "${e.session}"`))}catch(o){let n=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to group: ${n}`)),process.exit(1)}}),jn=new V.Command("allow").description("Add a user to the Claude Code allowlist for a bot+room").requiredOption("--bot <botId>","Bot ID or username").requiredOption("--room <roomId>","Matrix room ID").requiredOption("--user <userId>","Matrix user ID to allow (e.g. @alice:server)").action(async e=>{let t=(0,z.default)("Adding user to allowlist...").start();try{await G.default.post(`${J}/claude-code/allow`,{botId:e.bot,roomId:e.room,userId:e.user},{timeout:1e4}),t.succeed(p.default.green(`Added ${e.user} to allowlist for ${e.bot} in ${e.room}`))}catch(o){let n=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to add user: ${n}`)),process.exit(1)}}),Ln=new V.Command("revoke").description("Remove a user from the Claude Code allowlist for a bot+room").requiredOption("--bot <botId>","Bot ID or username").requiredOption("--room <roomId>","Matrix room ID").requiredOption("--user <userId>","Matrix user ID to revoke").action(async e=>{let t=(0,z.default)("Removing user from allowlist...").start();try{await G.default.post(`${J}/claude-code/revoke`,{botId:e.bot,roomId:e.room,userId:e.user},{timeout:1e4}),t.succeed(p.default.green(`Removed ${e.user} from allowlist for ${e.bot} in ${e.room}`))}catch(o){let n=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to revoke user: ${n}`)),process.exit(1)}}),ho=new V.Command("claude-code").description("Manage Claude Code sessions (relay Matrix messages to local Claude Code)").addCommand(Dn).addCommand(On).addCommand(Nn).addCommand(Tn).addCommand(jn).addCommand(Ln);async function Bn(){await io(process.argv);let e=new wo.Command;e.name("badgerclaw").description("BadgerClaw CLI \u2014 one-click bot provisioning").version("0.2.27"),e.addCommand(Bt),e.addCommand(Mt),e.addCommand(Gt),e.addCommand(Vt),e.addCommand(xt),e.addCommand(no),e.addCommand(lo),e.addCommand(eo),e.addCommand(po),e.addCommand(fo),e.addCommand(ho),e.parse(process.argv)}Bn().catch(e=>{console.error(e),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badgerclaw",
3
- "version": "0.2.26",
3
+ "version": "0.2.27",
4
4
  "description": "BadgerClaw CLI — one-click bot provisioning",
5
5
  "main": "dist/index.js",
6
6
  "bin": {