badgerclaw 0.2.11 → 0.2.13

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.
@@ -352,7 +352,7 @@ var BadgerclawMCPServer = class {
352
352
  */
353
353
  async pushToClaudeCode(message) {
354
354
  try {
355
- const msgFile = import_path.default.join(import_os.default.homedir(), ".badgerclaw", "pending-input.txt");
355
+ const msgFile = import_path.default.join(import_os.default.homedir(), ".badgerclaw", `pending-input-${this.sessionId}.txt`);
356
356
  import_fs.default.writeFileSync(msgFile, message, "utf-8");
357
357
  } catch (err) {
358
358
  console.error(`[mcp-server] Failed to write pending input: ${err.message}`);
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var ho=Object.create;var ge=Object.defineProperty;var yo=Object.getOwnPropertyDescriptor;var wo=Object.getOwnPropertyNames;var bo=Object.getPrototypeOf,_o=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})},lt=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of wo(t))!_o.call(e,n)&&n!==o&&ge(e,n,{get:()=>t[n],enumerable:!(s=yo(t,n))||s.enumerable});return e};var c=(e,t,o)=>(o=e!=null?ho(bo(e)):{},lt(t||!e||!e.__esModule?ge(o,"default",{value:e,enumerable:!0}):o,e)),dt=e=>lt(ge({},"__esModule",{value:!0}),e);var U=So((Vn,Bo)=>{Bo.exports={name:"badgerclaw",version:"0.2.11",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={};Co(st,{getActiveSessions:()=>nt,launchClaudeCode:()=>et,launchMCPServer:()=>Ze,recordSession:()=>tt,stopSession:()=>ot});function Ke(){try{if(k.default.existsSync(ze))return JSON.parse(k.default.readFileSync(ze,"utf-8"))}catch{}return[]}function Ye(e){k.default.mkdirSync(H,{recursive:!0}),k.default.writeFileSync(ze,JSON.stringify(e,null,2))}function xe(e){try{return process.kill(e,0),!0}catch{return!1}}function qo(){if(process.env.TMUX)return"tmux";try{if((0,L.execSync)(`osascript -e 'tell application "System Events" to (name of processes) contains "iTerm2"'`,{stdio:"pipe",timeout:3e3}),k.default.existsSync("/Applications/iTerm.app"))return"iterm2"}catch{}return process.platform==="darwin"?"terminal":"direct"}function Xe(e){let t=R.default.join(H,"claude-launcher.exp"),o=R.default.join(H,"pending-input.txt");k.default.writeFileSync(o,"","utf-8");let s=`#!/usr/bin/expect -f
2
+ "use strict";var ho=Object.create;var ge=Object.defineProperty;var yo=Object.getOwnPropertyDescriptor;var wo=Object.getOwnPropertyNames;var bo=Object.getPrototypeOf,_o=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})},lt=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of wo(t))!_o.call(e,n)&&n!==o&&ge(e,n,{get:()=>t[n],enumerable:!(s=yo(t,n))||s.enumerable});return e};var c=(e,t,o)=>(o=e!=null?ho(bo(e)):{},lt(t||!e||!e.__esModule?ge(o,"default",{value:e,enumerable:!0}):o,e)),dt=e=>lt(ge({},"__esModule",{value:!0}),e);var U=So((Vn,Bo)=>{Bo.exports={name:"badgerclaw",version:"0.2.13",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={};Co(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(W,{recursive:!0}),I.default.writeFileSync(ze,JSON.stringify(e,null,2))}function xe(e){try{return process.kill(e,0),!0}catch{return!1}}function qo(){if(process.env.TMUX)return"tmux";try{if((0,L.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(W,`claude-launcher-${t}.exp`),s=E.default.join(W,`pending-input-${t}.txt`);I.default.writeFileSync(s,"","utf-8");let n=`#!/usr/bin/expect -f
3
3
  set timeout -1
4
- set msgfile "${o}"
4
+ set msgfile "${s}"
5
5
 
6
6
  proc check_and_send_messages {} {
7
7
  global msgfile
@@ -36,7 +36,7 @@ send "\\r"
36
36
  interact timeout 2 {
37
37
  check_and_send_messages
38
38
  }
39
- `;return k.default.mkdirSync(H,{recursive:!0}),k.default.writeFileSync(t,s,{mode:493}),t}function Qe(e){return Object.entries(e).map(([t,o])=>`export ${t}="${o}"`).join("; ")}function Jo(e,t,o){let s=Xe(e),n=Qe(o),r=`
39
+ `;return I.default.mkdirSync(W,{recursive:!0}),I.default.writeFileSync(o,n,{mode:493}),o}function Qe(e){return Object.entries(e).map(([t,o])=>`export ${t}="${o}"`).join("; ")}function Jo(e,t,o){let s=Xe(e,o.BADGERCLAW_SESSION_ID||"default"),n=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)} && ${n} && ${Ae(s)}"
45
45
  end tell
46
46
  end tell
47
- `;(0,L.execSync)(`osascript -e '${r.replace(/'/g,`'"'"'`)}'`,{stdio:"pipe",timeout:1e4})}function zo(e,t,o){let s=Xe(e),n=Qe(o),a=`
47
+ `;(0,L.execSync)(`osascript -e '${r.replace(/'/g,`'"'"'`)}'`,{stdio:"pipe",timeout:1e4})}function zo(e,t,o){let s=Xe(e,o.BADGERCLAW_SESSION_ID||"default"),n=Qe(o),a=`
48
48
  tell application "Terminal"
49
49
  activate
50
50
  do script "${`cd ${Ae(t)} && ${n} && ${Ae(s)}`.replace(/"/g,'\\"')}"
51
51
  end tell
52
- `;(0,L.execSync)(`osascript -e '${a.replace(/'/g,`'"'"'`)}'`,{stdio:"pipe",timeout:1e4})}function Ko(e,t,o){let s=Xe(e),n=Qe(o),r=`badgerclaw-${o.BADGERCLAW_SESSION_ID||"default"}`,a=`cd ${t} && ${n} && ${s}`;(0,L.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=R.default.join(__dirname,"..","claude-code","mcp-server.js"),o=k.default.existsSync(t)?t:R.default.join(__dirname,"mcp-server.js"),s=(0,L.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 s.unref(),s}function et(e){let t=R.default.join(R.default.dirname(process.argv[1]||""),"..","lib","node_modules","badgerclaw","dist","claude-code","mcp-server.js"),o=R.default.join(__dirname,"..","claude-code","mcp-server.js"),s=R.default.join(__dirname,"mcp-server.js"),n=k.default.existsSync(t)?t:k.default.existsSync(o)?o:s,r={BADGERCLAW_MCP_PORT:String(e.port),BADGERCLAW_SESSION_ID:e.sessionId},a=JSON.stringify({mcpServers:{badgerclaw:{command:"node",args:[n],env:r}}}),i=R.default.join(H,"mcp-config.json");k.default.mkdirSync(H,{recursive:!0}),k.default.writeFileSync(i,a,"utf-8");let l=`claude --dangerously-skip-permissions --mcp-config ${i}`;switch(qo()){case"iterm2":Jo(l,e.projectDir,r);break;case"terminal":zo(l,e.projectDir,r);break;case"tmux":Ko(l,e.projectDir,r);break;case"direct":(0,L.spawn)(l,[],{shell:!0,cwd:e.projectDir,env:{...process.env,...r},stdio:"ignore",detached:!0}).unref();break}}function tt(e,t,o,s,n){let r=Ke().filter(a=>a.sessionId!==e);r.push({sessionId:e,pid:t,mcpPid:o,port:s,projectDir:n,startedAt:new Date().toISOString()}),Ye(r)}function ot(e){let t=Ke(),o=t.find(n=>n.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,L.execSync)(`tmux kill-session -t badgerclaw-${e} 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let s=t.filter(n=>n.sessionId!==e);return Ye(s),!0}function nt(){let e=Ke(),t=e.filter(o=>xe(o.mcpPid)||xe(o.pid));return t.length!==e.length&&Ye(t),t}var L,k,R,Jt,H,ze,Pe=$o(()=>{"use strict";L=require("child_process"),k=c(require("fs")),R=c(require("path")),Jt=c(require("os")),H=R.default.join(Jt.default.homedir(),".badgerclaw"),ze=R.default.join(H,"claude-sessions.json")});var po=require("commander");var Nt=require("commander"),V=c(require("chalk")),Ot=c(require("ora")),jt=c(require("open")),K=c(require("os")),Bt=c(require("crypto"));var Te=c(require("crypto"));function mt(){return Te.default.randomBytes(32).toString("base64url")}function ut(e){return Te.default.createHash("sha256").update(e).digest("base64url")}var Z=c(require("fs")),Ne=c(require("path")),gt=c(require("os")),pt=Ne.default.join(gt.default.homedir(),".badgerclaw"),Oe=Ne.default.join(pt,"auth.json");function f(){try{let e=Z.default.readFileSync(Oe,"utf-8");return JSON.parse(e)}catch{return null}}function pe(e){Z.default.mkdirSync(pt,{recursive:!0}),Z.default.writeFileSync(Oe,JSON.stringify(e,null,2),{mode:384})}function ft(){try{Z.default.unlinkSync(Oe)}catch{}}function fe(){let e=f();return e?new Date(e.expires_at)>new Date:!1}function he(e){let t=e.match(/^@?([^:]+)/);return t?t[1]:e}var ee=c(require("axios"));var ht=process.env.BADGERCLAW_ENV==="local",j=process.env.BADGERCLAW_API_URL??(ht?"http://localhost:8000":"https://api.badger.signout.io"),yt=process.env.BADGERCLAW_AUTH_URL??(ht?"http://localhost:5500":"https://badgerclaw.ai");var we=j,ye=null;async function je(){let e=f();if(!e?.refresh_token||!e?.email)return null;try{let t=await ee.default.post(`${we}/api/v1/user/token/refresh`,{refresh_token:e.refresh_token,email:e.email}),o=t.data?.result??t.data,s=o?.access_token;if(!s)return null;let n=o.expires_in||3600,r=new Date(Date.now()+n*1e3).toISOString();return pe({...e,access_token:s,expires_at:r}),s}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 wt(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 s=await ye;return s?(o.headers.Authorization=`Bearer ${s}`,e.request(o)):Promise.reject(t)}),e}function v(){let e=f(),t={"Content-Type":"application/json"};e&&(t.Authorization=`Bearer ${e.access_token}`);let o=ee.default.create({baseURL:we,headers:t});return Be(o),wt(o),o}function bt(){return Be(ee.default.create({baseURL:we,headers:{"Content-Type":"application/json"}}))}function be(e){let t=ee.default.create({baseURL:we,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`}});return Be(t),wt(t),t}var _t=require("commander"),T=c(require("chalk")),Le=c(require("ora")),$t=c(require("os")),St=c(require("path"));var Tn=St.default.join($t.default.homedir(),".openclaw","openclaw.json");async function te(e,t,o,s){let n=f();if(!n)return;let r=s?null:(0,Le.default)(`Pairing bot: ${t}...`).start();try{let a=await fetch(`${j}/api/v1/pairing/redeem`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:e})});if(!a.ok){let D=await a.json().catch(()=>({errors:[a.statusText]}));r?.fail(T.default.red(`Failed to redeem ${t}: ${D.errors?.[0]||a.status}`));return}let i=await a.json(),l=i.result??i,{execSync:m}=await import("child_process"),w=`channels.badgerclaw.accounts.${l.user_id.split(":")[0].replace("@","").replace(/_bot$/,"")}`;m(`openclaw config set ${w}.userId "${l.user_id}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),m(`openclaw config set ${w}.accessToken "${l.access_token}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),m(`openclaw config set ${w}.homeserver "${l.homeserver}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),m(`openclaw config set ${w}.encryption true`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),l.device_id&&m(`openclaw config set ${w}.deviceId "${l.device_id}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),await fetch(`${j}/api/v1/openclaw/pending-pairs/${e}/claim`,{method:"POST",headers:{Authorization:`Bearer ${n.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 oe(e=!1){let t=f();if(!t)return 0;let o=be(t.access_token);try{let{data:s}=await o.get("/api/v1/openclaw/pending-pairs");if(!s||s.length===0)return 0;let n=new Map;for(let a of s)n.set(a.bot_user_id,a);for(let a of s)n.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 n.values()){let i=e?null:(0,Le.default)(`Pairing bot: ${a.bot_name} (${a.bot_user_id})`).start();try{await te(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,L.execSync)(`osascript -e '${a.replace(/'/g,`'"'"'`)}'`,{stdio:"pipe",timeout:1e4})}function Ko(e,t,o){let s=Xe(e,o.BADGERCLAW_SESSION_ID||"default"),n=Qe(o),r=`badgerclaw-${o.BADGERCLAW_SESSION_ID||"default"}`,a=`cd ${t} && ${n} && ${s}`;(0,L.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"),s=(0,L.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 s.unref(),s}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"),s=E.default.join(__dirname,"mcp-server.js"),n=I.default.existsSync(t)?t:I.default.existsSync(o)?o:s,r={BADGERCLAW_MCP_PORT:String(e.port),BADGERCLAW_SESSION_ID:e.sessionId},a=JSON.stringify({mcpServers:{badgerclaw:{command:"node",args:[n],env:r}}}),i=E.default.join(W,`mcp-config-${e.sessionId}.json`);I.default.mkdirSync(W,{recursive:!0}),I.default.writeFileSync(i,a,"utf-8");let l=`claude --dangerously-skip-permissions --mcp-config ${i}`;switch(qo()){case"iterm2":Jo(l,e.projectDir,r);break;case"terminal":zo(l,e.projectDir,r);break;case"tmux":Ko(l,e.projectDir,r);break;case"direct":(0,L.spawn)(l,[],{shell:!0,cwd:e.projectDir,env:{...process.env,...r},stdio:"ignore",detached:!0}).unref();break}}function tt(e,t,o,s,n){let r=Ke().filter(a=>a.sessionId!==e);r.push({sessionId:e,pid:t,mcpPid:o,port:s,projectDir:n,startedAt:new Date().toISOString()}),Ye(r)}function ot(e){let t=Ke(),o=t.find(n=>n.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,L.execSync)(`tmux kill-session -t badgerclaw-${e} 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let s=t.filter(n=>n.sessionId!==e);return Ye(s),!0}function nt(){let e=Ke(),t=e.filter(o=>xe(o.mcpPid)||xe(o.pid));return t.length!==e.length&&Ye(t),t}var L,I,E,Jt,W,ze,Pe=$o(()=>{"use strict";L=require("child_process"),I=c(require("fs")),E=c(require("path")),Jt=c(require("os")),W=E.default.join(Jt.default.homedir(),".badgerclaw"),ze=E.default.join(W,"claude-sessions.json")});var po=require("commander");var Nt=require("commander"),H=c(require("chalk")),Ot=c(require("ora")),jt=c(require("open")),K=c(require("os")),Bt=c(require("crypto"));var Te=c(require("crypto"));function mt(){return Te.default.randomBytes(32).toString("base64url")}function ut(e){return Te.default.createHash("sha256").update(e).digest("base64url")}var Z=c(require("fs")),Ne=c(require("path")),gt=c(require("os")),pt=Ne.default.join(gt.default.homedir(),".badgerclaw"),Oe=Ne.default.join(pt,"auth.json");function h(){try{let e=Z.default.readFileSync(Oe,"utf-8");return JSON.parse(e)}catch{return null}}function pe(e){Z.default.mkdirSync(pt,{recursive:!0}),Z.default.writeFileSync(Oe,JSON.stringify(e,null,2),{mode:384})}function ft(){try{Z.default.unlinkSync(Oe)}catch{}}function fe(){let e=h();return e?new Date(e.expires_at)>new Date:!1}function he(e){let t=e.match(/^@?([^:]+)/);return t?t[1]:e}var ee=c(require("axios"));var ht=process.env.BADGERCLAW_ENV==="local",j=process.env.BADGERCLAW_API_URL??(ht?"http://localhost:8000":"https://api.badger.signout.io"),yt=process.env.BADGERCLAW_AUTH_URL??(ht?"http://localhost:5500":"https://badgerclaw.ai");var we=j,ye=null;async function je(){let e=h();if(!e?.refresh_token||!e?.email)return null;try{let t=await ee.default.post(`${we}/api/v1/user/token/refresh`,{refresh_token:e.refresh_token,email:e.email}),o=t.data?.result??t.data,s=o?.access_token;if(!s)return null;let n=o.expires_in||3600,r=new Date(Date.now()+n*1e3).toISOString();return pe({...e,access_token:s,expires_at:r}),s}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 wt(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 s=await ye;return s?(o.headers.Authorization=`Bearer ${s}`,e.request(o)):Promise.reject(t)}),e}function v(){let e=h(),t={"Content-Type":"application/json"};e&&(t.Authorization=`Bearer ${e.access_token}`);let o=ee.default.create({baseURL:we,headers:t});return Be(o),wt(o),o}function bt(){return Be(ee.default.create({baseURL:we,headers:{"Content-Type":"application/json"}}))}function be(e){let t=ee.default.create({baseURL:we,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`}});return Be(t),wt(t),t}var _t=require("commander"),T=c(require("chalk")),Le=c(require("ora")),$t=c(require("os")),St=c(require("path"));var Tn=St.default.join($t.default.homedir(),".openclaw","openclaw.json");async function te(e,t,o,s){let n=h();if(!n)return;let r=s?null:(0,Le.default)(`Pairing bot: ${t}...`).start();try{let a=await fetch(`${j}/api/v1/pairing/redeem`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:e})});if(!a.ok){let R=await a.json().catch(()=>({errors:[a.statusText]}));r?.fail(T.default.red(`Failed to redeem ${t}: ${R.errors?.[0]||a.status}`));return}let i=await a.json(),l=i.result??i,{execSync:m}=await import("child_process"),f=`channels.badgerclaw.accounts.${l.user_id.split(":")[0].replace("@","").replace(/_bot$/,"")}`;m(`openclaw config set ${f}.userId "${l.user_id}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),m(`openclaw config set ${f}.accessToken "${l.access_token}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),m(`openclaw config set ${f}.homeserver "${l.homeserver}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),m(`openclaw config set ${f}.encryption true`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),l.device_id&&m(`openclaw config set ${f}.deviceId "${l.device_id}"`,{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),await fetch(`${j}/api/v1/openclaw/pending-pairs/${e}/claim`,{method:"POST",headers:{Authorization:`Bearer ${n.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 oe(e=!1){let t=h();if(!t)return 0;let o=be(t.access_token);try{let{data:s}=await o.get("/api/v1/openclaw/pending-pairs");if(!s||s.length===0)return 0;let n=new Map;for(let a of s)n.set(a.bot_user_id,a);for(let a of s)n.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 n.values()){let i=e?null:(0,Le.default)(`Pairing bot: ${a.bot_name} (${a.bot_user_id})`).start();try{await te(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 Ct=new _t.Command("autopair").description("Check for pending bot pairs and connect them to OpenClaw automatically").action(async()=>{if(!f()){console.log(T.default.yellow("Not logged in. Run `badgerclaw login` first."));return}console.log(T.default.dim("Checking for pending bot pairs...")),await oe(!1)===0&&console.log(T.default.dim("No pending pairs found."))});var E=c(require("chalk")),ne=c(require("fs")),se=c(require("path")),Ue=c(require("os")),Me=se.default.join(Ue.default.homedir(),".badgerclaw","update-check.json"),vo=1440*60*1e3,ko="https://registry.npmjs.org/badgerclaw/latest",Io="https://registry.npmjs.org/@badgerclaw%2Fconnect/latest";function xo(){try{return JSON.parse(ne.default.readFileSync(Me,"utf-8"))}catch{return null}}function Ao(e){try{ne.default.mkdirSync(se.default.dirname(Me),{recursive:!0}),ne.default.writeFileSync(Me,JSON.stringify(e))}catch{}}function _e(e,t){let o=m=>m.replace(/[^0-9.]/g,"").split(".").map(Number),[s,n,r]=o(e),[a,i,l]=o(t);return a!==s?a>s:i!==n?i>n:l>r}function vt(){try{let e=se.default.join(Ue.default.homedir(),".openclaw"),t=se.default.join(e,"node_modules","@badgerclaw","connect","package.json");return JSON.parse(ne.default.readFileSync(t,"utf-8")).version||null}catch{return null}}async function $e(e,t=!1){try{let o=xo(),s=Date.now();if(o&&s-o.lastCheck<vo){if(_e(e,o.latestVersion)&&kt(e,o.latestVersion),o.latestPluginVersion){let h=vt();h&&_e(h,o.latestPluginVersion)&&It(h,o.latestPluginVersion)}return}let n=new AbortController,r=setTimeout(()=>n.abort(),3e3),[a,i]=await Promise.allSettled([fetch(ko,{signal:n.signal}),fetch(Io,{signal:n.signal})]);clearTimeout(r);let l=e,m;if(a.status==="fulfilled"&&a.value.ok&&(l=(await a.value.json()).version),i.status==="fulfilled"&&i.value.ok&&(m=(await i.value.json()).version),Ao({lastCheck:s,latestVersion:l,latestPluginVersion:m}),_e(e,l)&&kt(e,l),m){let h=vt();h&&_e(h,m)&&It(h,m)}}catch{}}function kt(e,t){console.log(E.default.yellow(`
55
- \u26A0\uFE0F Update available: badgerclaw ${E.default.dim(e)} \u2192 ${E.default.green(t)}`)+E.default.dim(`
56
- Run: `)+E.default.cyan("npm install -g badgerclaw")+`
57
- `)}function It(e,t){console.log(E.default.yellow(`
58
- \u26A0\uFE0F Plugin update available: @badgerclaw/connect ${E.default.dim(e)} \u2192 ${E.default.green(t)}`)+E.default.dim(`
59
- Run: `)+E.default.cyan("badgerclaw setup")+`
54
+ \u26A1 ${r} bot(s) paired. Run: openclaw gateway restart`))}return r}catch{return 0}}var Ct=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 oe(!1)===0&&console.log(T.default.dim("No pending pairs found."))});var D=c(require("chalk")),ne=c(require("fs")),se=c(require("path")),Ue=c(require("os")),Me=se.default.join(Ue.default.homedir(),".badgerclaw","update-check.json"),vo=1440*60*1e3,Io="https://registry.npmjs.org/badgerclaw/latest",ko="https://registry.npmjs.org/@badgerclaw%2Fconnect/latest";function xo(){try{return JSON.parse(ne.default.readFileSync(Me,"utf-8"))}catch{return null}}function Ao(e){try{ne.default.mkdirSync(se.default.dirname(Me),{recursive:!0}),ne.default.writeFileSync(Me,JSON.stringify(e))}catch{}}function _e(e,t){let o=m=>m.replace(/[^0-9.]/g,"").split(".").map(Number),[s,n,r]=o(e),[a,i,l]=o(t);return a!==s?a>s:i!==n?i>n:l>r}function vt(){try{let e=se.default.join(Ue.default.homedir(),".openclaw"),t=se.default.join(e,"node_modules","@badgerclaw","connect","package.json");return JSON.parse(ne.default.readFileSync(t,"utf-8")).version||null}catch{return null}}async function $e(e,t=!1){try{let o=xo(),s=Date.now();if(o&&s-o.lastCheck<vo){if(_e(e,o.latestVersion)&&It(e,o.latestVersion),o.latestPluginVersion){let y=vt();y&&_e(y,o.latestPluginVersion)&&kt(y,o.latestPluginVersion)}return}let n=new AbortController,r=setTimeout(()=>n.abort(),3e3),[a,i]=await Promise.allSettled([fetch(Io,{signal:n.signal}),fetch(ko,{signal:n.signal})]);clearTimeout(r);let l=e,m;if(a.status==="fulfilled"&&a.value.ok&&(l=(await a.value.json()).version),i.status==="fulfilled"&&i.value.ok&&(m=(await i.value.json()).version),Ao({lastCheck:s,latestVersion:l,latestPluginVersion:m}),_e(e,l)&&It(e,l),m){let y=vt();y&&_e(y,m)&&kt(y,m)}}catch{}}function It(e,t){console.log(D.default.yellow(`
55
+ \u26A0\uFE0F Update available: badgerclaw ${D.default.dim(e)} \u2192 ${D.default.green(t)}`)+D.default.dim(`
56
+ Run: `)+D.default.cyan("npm install -g badgerclaw")+`
57
+ `)}function kt(e,t){console.log(D.default.yellow(`
58
+ \u26A0\uFE0F Plugin update available: @badgerclaw/connect ${D.default.dim(e)} \u2192 ${D.default.green(t)}`)+D.default.dim(`
59
+ Run: `)+D.default.cyan("badgerclaw setup")+`
60
60
  `)}var Dt=c(require("os"));var Se=c(require("fs")),z=c(require("path")),re=c(require("os")),ae=require("child_process"),xt="ai.badgerclaw.watch",At=z.default.join(re.default.homedir(),"Library","LaunchAgents"),Fe=z.default.join(At,`${xt}.plist`);function Po(){try{return(0,ae.execSync)("which badgerclaw",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/badgerclaw"}}function Ro(){try{return(0,ae.execSync)("which node",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/node"}}function Eo(e){let t=z.default.join(re.default.homedir(),".badgerclaw"),o=Ro(),s=z.default.dirname(o);return`<?xml version="1.0" encoding="UTF-8"?>
61
61
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
62
62
  <plist version="1.0">
@@ -101,9 +101,9 @@ StandardError=append:%h/.badgerclaw/heartbeat.log
101
101
 
102
102
  [Install]
103
103
  WantedBy=default.target
104
- `}function jo(){try{return(0,B.execSync)("systemctl --user --version",{stdio:"ignore"}),!0}catch{return!1}}function Et(){if(ve.default.platform()==="linux"){if(!jo()){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=To();Ce.default.mkdirSync(Rt,{recursive:!0}),Ce.default.mkdirSync(ie.default.join(ve.default.homedir(),".badgerclaw"),{recursive:!0}),Ce.default.writeFileSync(Do,Oo(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 Tt(){let e=Dt.default.platform();if(e==="darwin")return Pt();if(e==="linux")return Et();console.log("\x1B[2mNote: background daemon install not supported on "+e+". Run `badgerclaw heartbeat` manually.\x1B[0m")}var Lo=2e3,Mo=12e4,Lt=new Nt.Command("login").description("Log in to BadgerClaw via browser").action(async()=>{let{version:e}=U();$e(e);let t=mt(),o=ut(t),s=`${yt}/cli-auth?code=${o}`;console.log(V.default.yellow("Opening browser for authentication...")),console.log(V.default.dim(`If the browser doesn't open, visit: ${s}`)),await(0,jt.default)(s);let n=(0,Ot.default)("Waiting for authentication...").start(),r=bt(),a=Date.now();for(;Date.now()-a<Mo;){try{let i=await r.post(`/api/v1/openclaw/cli/auth/poll/${o}`,{code_verifier:t,code_challenge:o});if(i.status===429){await new Promise(l=>setTimeout(l,5e3));continue}if(i.data?.access_token){let{access_token:l,user_id:m,expires_at:h,refresh_token:w,email:D}=i.data,$=Bt.default.createHash("sha256").update(`${K.default.hostname()}-${K.default.platform()}-${K.default.arch()}`).digest("hex").slice(0,16),C=`openclaw-${K.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${$}`;pe({access_token:l,user_id:m,instance_id:C,expires_at:h,refresh_token:w,email:D});try{let{version:fo}=U();await r.post("/api/v1/openclaw/register",{instance_id:C,label:K.default.hostname(),version:fo},{headers:{Authorization:`Bearer ${l}`}})}catch{}n.succeed(V.default.green(`Logged in as ${he(m)}`));let ct=await oe(!0);ct>0&&(console.log(V.default.green(`\u2705 ${ct} bot(s) automatically paired to OpenClaw.`)),console.log(V.default.yellow("Run: openclaw gateway restart to activate."))),Tt();return}}catch{}await new Promise(i=>setTimeout(i,Lo))}n.fail(V.default.red("Authentication timed out. Please try again.")),process.exit(1)});var Mt=require("commander"),Ve=c(require("chalk"));var Ut=new Mt.Command("logout").description("Disconnect this machine and log out of BadgerClaw").action(async()=>{let e=f();if(!e){console.log(Ve.default.yellow("Not logged in."));return}try{let t=be(e.access_token),{version:o}=U();await t.post("/api/v1/openclaw/register",{instance_id:e.instance_id,label:require("os").hostname(),version:o,online:!1})}catch{}ft(),console.log(Ve.default.green("Logged out \u2014 this machine is now disconnected."))});var Ft=require("commander"),He=c(require("chalk"));var Gt=new Ft.Command("status").description("Show connected instance info").action(async()=>{let{version:e}=U();await $e(e);let t=f();(!t||!fe())&&(console.log(He.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1)),console.log(He.default.green("Authenticated")),console.log(` User: ${he(t.user_id)}`),console.log(` Instance: ${t.instance_id}`),console.log(` Expires: ${new Date(t.expires_at).toLocaleDateString()}`)});var ce=require("commander"),x=c(require("chalk")),ke=c(require("ora"));function We(){fe()||(console.log(x.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1))}function Uo(e){return/^[a-z0-9_]{4,20}$/.test(e)}function Fo(e){return e.replace(/_bot$/,"")}var Go=new ce.Command("create").description("Create a new bot").argument("<name>","Bot name (4-20 chars, lowercase alphanumeric + underscores)").action(async e=>{We(),Uo(e)||(console.log(x.default.red("Invalid bot name. Must be 4-20 characters, lowercase alphanumeric and underscores only.")),process.exit(1));let t=(0,ke.default)(`Creating bot "${e}"...`).start();try{await v().post("/api/v1/openclaw/bots",{username:e}),t.succeed(x.default.green(`Bot "${e}" created successfully!`))}catch(o){let s=o.response?.data?.errors?.[0]||o.message;t.fail(x.default.red(`Failed to create bot: ${s}`)),process.exit(1)}}),Vo=new ce.Command("list").description("List your bots").action(async()=>{We();let e=(0,ke.default)("Fetching bots...").start();try{let s=(await v().get("/api/v1/openclaw/bots")).data?.bots||[];if(e.stop(),s.length===0){console.log(x.default.yellow("No bots found. Create one with `badgerclaw bot create <name>`."));return}console.log(x.default.green(`Your bots (${s.length}):
105
- `));for(let n of s){let r=Fo(n.username||n.name),a=n.active!==!1?x.default.green("active"):x.default.dim("inactive");console.log(` ${x.default.bold(r)} ${a}`)}}catch(t){let o=t.response?.data?.errors?.[0]||t.message;e.fail(x.default.red(`Failed to list bots: ${o}`)),process.exit(1)}}),Ho=new ce.Command("delete").description("Deactivate a bot").argument("<name>","Bot name to deactivate").action(async e=>{We();let t=(0,ke.default)(`Deactivating bot "${e}"...`).start();try{await v().delete(`/api/v1/openclaw/bots/${e}`),t.succeed(x.default.green(`Bot "${e}" deactivated.`))}catch(o){let s=o.response?.data?.errors?.[0]||o.message;t.fail(x.default.red(`Failed to deactivate bot: ${s}`)),process.exit(1)}}),Vt=new ce.Command("bot").description("Manage bots").addCommand(Go).addCommand(Vo).addCommand(Ho);var to=require("commander"),g=c(require("chalk"));var Je=c(require("axios")),Wo=7331,Ht=`http://localhost:${Wo}`,qe="unknown";async function le(){try{let t=(await Je.default.get(`${Ht}/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 Wt(e){e&&e!=="unknown"&&(qe=e)}async function Y(){try{return{success:!0,message:(await Je.default.post(`${Ht}/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"));var N=c(require("os")),qt=c(require("crypto"));function de(){let e=f();if(e?.instance_id)return e.instance_id;let t=qt.default.createHash("sha256").update(`${N.default.hostname()}-${N.default.platform()}-${N.default.arch()}`).digest("hex").slice(0,16);return`openclaw-${N.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${t}`}function Ie(){return{hostname:N.default.hostname(),os:N.default.platform(),arch:N.default.arch(),uptimeSeconds:Math.floor(N.default.uptime()),memFreeMb:Math.floor(N.default.freemem()/1024/1024)}}var S=require("child_process"),u=c(require("fs")),b=c(require("path")),me=c(require("os")),W=c(require("axios"));async function M(e){return e.command_type==="update_cli"?Xo(e.payload?.target_version):e.command_type==="update_plugin"?Qo(e.payload?.target_version):e.command_type==="restart_gateway"?Yo():e.command_type==="leave_room"?rn(e.payload):e.command_type==="start_claude_code"?nn(e.payload):e.command_type==="stop_claude_code"?sn(e.payload):{success:!1,message:`Unknown command: ${e.command_type}`}}function Yo(){try{return(0,S.execSync)("openclaw gateway restart",{stdio:"pipe",timeout:15e3}),{success:!0,message:"Gateway restarted"}}catch{try{return{success:!0,message:`Gateway restarted via probe: ${(0,S.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 Xo(e){let t=e?`badgerclaw@${e}`:"badgerclaw@latest";try{(0,S.execSync)(`npm install -g ${t}`,{stdio:"pipe",timeout:12e4});let o=(0,S.execSync)("npm list -g badgerclaw --json",{stdio:"pipe"}).toString(),n=JSON.parse(o)?.dependencies?.badgerclaw?.version||"unknown";return en(),{success:!0,message:`Updated CLI to ${n}`,newVersion:n}}catch(o){let s=o.stderr?.toString()||o.message||"Unknown error";return s.includes("EACCES")||s.includes("permission")?{success:!1,message:"Permission denied. Run: sudo npm install -g badgerclaw"}:{success:!1,message:`CLI update failed: ${s.slice(0,500)}`}}}async function Qo(e){let t=b.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,S.execSync)(`npm install ${o}`,{cwd:t,stdio:"pipe",timeout:12e4});let s=b.default.join(t,"node_modules","@badgerclaw","connect"),n=b.default.join(s,"package.json"),r="unknown";u.default.existsSync(n)&&(r=JSON.parse(u.default.readFileSync(n,"utf-8")).version||"unknown"),Wt(r),Zo(s,t);let a=b.default.join(t,"package.json");if(u.default.existsSync(a)&&u.default.existsSync(n))try{let i=JSON.parse(u.default.readFileSync(a,"utf-8")),l=JSON.parse(u.default.readFileSync(n,"utf-8"));i.version=r,l.openclaw&&(i.openclaw={...i.openclaw,...l.openclaw}),u.default.writeFileSync(a,JSON.stringify(i,null,2)+`
106
- `)}catch{}try{(0,S.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 W.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(s){return{success:!1,message:`Plugin update failed: ${(s.stderr?.toString()||s.message||"").slice(0,500)}`}}}function Zo(e,t){let o=b.default.join(e,"dist"),s=b.default.join(t,"dist");u.default.existsSync(o)&&(u.default.mkdirSync(s,{recursive:!0}),rt(o,s));let n=b.default.join(e,"openclaw.plugin.json");u.default.existsSync(n)&&u.default.copyFileSync(n,b.default.join(t,"openclaw.plugin.json"));let r=b.default.join(e,"scripts"),a=b.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=b.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 s=b.default.join(e,o.name),n=b.default.join(t,o.name);o.isDirectory()?(u.default.mkdirSync(n,{recursive:!0}),rt(s,n)):u.default.copyFileSync(s,n)}}function en(){try{try{(0,S.execSync)('pkill -f "badgerclaw heartbeat"',{stdio:"pipe",timeout:5e3})}catch{}try{(0,S.execSync)('pkill -f "badgerclaw watch"',{stdio:"pipe",timeout:5e3})}catch{}(0,S.execSync)("sleep 1",{stdio:"pipe"});let e=(0,S.execSync)("which badgerclaw",{stdio:"pipe"}).toString().trim();(0,S.execSync)(`nohup ${e} heartbeat > /dev/null 2>&1 &`,{stdio:"pipe",shell:"/bin/zsh"}),(0,S.execSync)(`nohup ${e} watch > /dev/null 2>&1 &`,{stdio:"pipe",shell:"/bin/zsh"})}catch{}}function tn(){let e=b.default.join(me.default.homedir(),".badgerclaw","workspace");u.default.mkdirSync(e,{recursive:!0});let t=b.default.join(e,".git");return u.default.existsSync(t)||(0,S.execSync)("git init",{cwd:e,stdio:"pipe",timeout:5e3}),u.default.writeFileSync(b.default.join(e,"CLAUDE.md"),`You are a chat assistant connected to Matrix rooms via BadgerClaw.
104
+ `}function jo(){try{return(0,B.execSync)("systemctl --user --version",{stdio:"ignore"}),!0}catch{return!1}}function Et(){if(ve.default.platform()==="linux"){if(!jo()){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=To();Ce.default.mkdirSync(Rt,{recursive:!0}),Ce.default.mkdirSync(ie.default.join(ve.default.homedir(),".badgerclaw"),{recursive:!0}),Ce.default.writeFileSync(Do,Oo(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 Tt(){let e=Dt.default.platform();if(e==="darwin")return Pt();if(e==="linux")return Et();console.log("\x1B[2mNote: background daemon install not supported on "+e+". Run `badgerclaw heartbeat` manually.\x1B[0m")}var Lo=2e3,Mo=12e4,Lt=new Nt.Command("login").description("Log in to BadgerClaw via browser").action(async()=>{let{version:e}=U();$e(e);let t=mt(),o=ut(t),s=`${yt}/cli-auth?code=${o}`;console.log(H.default.yellow("Opening browser for authentication...")),console.log(H.default.dim(`If the browser doesn't open, visit: ${s}`)),await(0,jt.default)(s);let n=(0,Ot.default)("Waiting for authentication...").start(),r=bt(),a=Date.now();for(;Date.now()-a<Mo;){try{let i=await r.post(`/api/v1/openclaw/cli/auth/poll/${o}`,{code_verifier:t,code_challenge:o});if(i.status===429){await new Promise(l=>setTimeout(l,5e3));continue}if(i.data?.access_token){let{access_token:l,user_id:m,expires_at:y,refresh_token:f,email:R}=i.data,b=Bt.default.createHash("sha256").update(`${K.default.hostname()}-${K.default.platform()}-${K.default.arch()}`).digest("hex").slice(0,16),S=`openclaw-${K.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${b}`;pe({access_token:l,user_id:m,instance_id:S,expires_at:y,refresh_token:f,email:R});try{let{version:fo}=U();await r.post("/api/v1/openclaw/register",{instance_id:S,label:K.default.hostname(),version:fo},{headers:{Authorization:`Bearer ${l}`}})}catch{}n.succeed(H.default.green(`Logged in as ${he(m)}`));let ct=await oe(!0);ct>0&&(console.log(H.default.green(`\u2705 ${ct} bot(s) automatically paired to OpenClaw.`)),console.log(H.default.yellow("Run: openclaw gateway restart to activate."))),Tt();return}}catch{}await new Promise(i=>setTimeout(i,Lo))}n.fail(H.default.red("Authentication timed out. Please try again.")),process.exit(1)});var Mt=require("commander"),Ve=c(require("chalk"));var Ut=new Mt.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=be(e.access_token),{version:o}=U();await t.post("/api/v1/openclaw/register",{instance_id:e.instance_id,label:require("os").hostname(),version:o,online:!1})}catch{}ft(),console.log(Ve.default.green("Logged out \u2014 this machine is now disconnected."))});var Ft=require("commander"),He=c(require("chalk"));var Gt=new Ft.Command("status").description("Show connected instance info").action(async()=>{let{version:e}=U();await $e(e);let t=h();(!t||!fe())&&(console.log(He.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1)),console.log(He.default.green("Authenticated")),console.log(` User: ${he(t.user_id)}`),console.log(` Instance: ${t.instance_id}`),console.log(` Expires: ${new Date(t.expires_at).toLocaleDateString()}`)});var ce=require("commander"),x=c(require("chalk")),Ie=c(require("ora"));function We(){fe()||(console.log(x.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1))}function Uo(e){return/^[a-z0-9_]{4,20}$/.test(e)}function Fo(e){return e.replace(/_bot$/,"")}var Go=new ce.Command("create").description("Create a new bot").argument("<name>","Bot name (4-20 chars, lowercase alphanumeric + underscores)").action(async e=>{We(),Uo(e)||(console.log(x.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 v().post("/api/v1/openclaw/bots",{username:e}),t.succeed(x.default.green(`Bot "${e}" created successfully!`))}catch(o){let s=o.response?.data?.errors?.[0]||o.message;t.fail(x.default.red(`Failed to create bot: ${s}`)),process.exit(1)}}),Vo=new ce.Command("list").description("List your bots").action(async()=>{We();let e=(0,Ie.default)("Fetching bots...").start();try{let s=(await v().get("/api/v1/openclaw/bots")).data?.bots||[];if(e.stop(),s.length===0){console.log(x.default.yellow("No bots found. Create one with `badgerclaw bot create <name>`."));return}console.log(x.default.green(`Your bots (${s.length}):
105
+ `));for(let n of s){let r=Fo(n.username||n.name),a=n.active!==!1?x.default.green("active"):x.default.dim("inactive");console.log(` ${x.default.bold(r)} ${a}`)}}catch(t){let o=t.response?.data?.errors?.[0]||t.message;e.fail(x.default.red(`Failed to list bots: ${o}`)),process.exit(1)}}),Ho=new ce.Command("delete").description("Deactivate a bot").argument("<name>","Bot name to deactivate").action(async e=>{We();let t=(0,Ie.default)(`Deactivating bot "${e}"...`).start();try{await v().delete(`/api/v1/openclaw/bots/${e}`),t.succeed(x.default.green(`Bot "${e}" deactivated.`))}catch(o){let s=o.response?.data?.errors?.[0]||o.message;t.fail(x.default.red(`Failed to deactivate bot: ${s}`)),process.exit(1)}}),Vt=new ce.Command("bot").description("Manage bots").addCommand(Go).addCommand(Vo).addCommand(Ho);var to=require("commander"),g=c(require("chalk"));var Je=c(require("axios")),Wo=7331,Ht=`http://localhost:${Wo}`,qe="unknown";async function le(){try{let t=(await Je.default.get(`${Ht}/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 Wt(e){e&&e!=="unknown"&&(qe=e)}async function Y(){try{return{success:!0,message:(await Je.default.post(`${Ht}/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"));var N=c(require("os")),qt=c(require("crypto"));function de(){let e=h();if(e?.instance_id)return e.instance_id;let t=qt.default.createHash("sha256").update(`${N.default.hostname()}-${N.default.platform()}-${N.default.arch()}`).digest("hex").slice(0,16);return`openclaw-${N.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${t}`}function ke(){return{hostname:N.default.hostname(),os:N.default.platform(),arch:N.default.arch(),uptimeSeconds:Math.floor(N.default.uptime()),memFreeMb:Math.floor(N.default.freemem()/1024/1024)}}var C=require("child_process"),u=c(require("fs")),_=c(require("path")),me=c(require("os")),F=c(require("axios"));async function M(e){return e.command_type==="update_cli"?Xo(e.payload?.target_version):e.command_type==="update_plugin"?Qo(e.payload?.target_version):e.command_type==="restart_gateway"?Yo():e.command_type==="leave_room"?rn(e.payload):e.command_type==="start_claude_code"?nn(e.payload):e.command_type==="stop_claude_code"?sn(e.payload):{success:!1,message:`Unknown command: ${e.command_type}`}}function Yo(){try{return(0,C.execSync)("openclaw gateway restart",{stdio:"pipe",timeout:15e3}),{success:!0,message:"Gateway restarted"}}catch{try{return{success:!0,message:`Gateway restarted via probe: ${(0,C.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 Xo(e){let t=e?`badgerclaw@${e}`:"badgerclaw@latest";try{(0,C.execSync)(`npm install -g ${t}`,{stdio:"pipe",timeout:12e4});let o=(0,C.execSync)("npm list -g badgerclaw --json",{stdio:"pipe"}).toString(),n=JSON.parse(o)?.dependencies?.badgerclaw?.version||"unknown";return en(),{success:!0,message:`Updated CLI to ${n}`,newVersion:n}}catch(o){let s=o.stderr?.toString()||o.message||"Unknown error";return s.includes("EACCES")||s.includes("permission")?{success:!1,message:"Permission denied. Run: sudo npm install -g badgerclaw"}:{success:!1,message:`CLI update failed: ${s.slice(0,500)}`}}}async function Qo(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,C.execSync)(`npm install ${o}`,{cwd:t,stdio:"pipe",timeout:12e4});let s=_.default.join(t,"node_modules","@badgerclaw","connect"),n=_.default.join(s,"package.json"),r="unknown";u.default.existsSync(n)&&(r=JSON.parse(u.default.readFileSync(n,"utf-8")).version||"unknown"),Wt(r),Zo(s,t);let a=_.default.join(t,"package.json");if(u.default.existsSync(a)&&u.default.existsSync(n))try{let i=JSON.parse(u.default.readFileSync(a,"utf-8")),l=JSON.parse(u.default.readFileSync(n,"utf-8"));i.version=r,l.openclaw&&(i.openclaw={...i.openclaw,...l.openclaw}),u.default.writeFileSync(a,JSON.stringify(i,null,2)+`
106
+ `)}catch{}try{(0,C.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 F.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(s){return{success:!1,message:`Plugin update failed: ${(s.stderr?.toString()||s.message||"").slice(0,500)}`}}}function Zo(e,t){let o=_.default.join(e,"dist"),s=_.default.join(t,"dist");u.default.existsSync(o)&&(u.default.mkdirSync(s,{recursive:!0}),rt(o,s));let n=_.default.join(e,"openclaw.plugin.json");u.default.existsSync(n)&&u.default.copyFileSync(n,_.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 s=_.default.join(e,o.name),n=_.default.join(t,o.name);o.isDirectory()?(u.default.mkdirSync(n,{recursive:!0}),rt(s,n)):u.default.copyFileSync(s,n)}}function en(){try{try{(0,C.execSync)('pkill -f "badgerclaw heartbeat"',{stdio:"pipe",timeout:5e3})}catch{}try{(0,C.execSync)('pkill -f "badgerclaw watch"',{stdio:"pipe",timeout:5e3})}catch{}(0,C.execSync)("sleep 1",{stdio:"pipe"});let e=(0,C.execSync)("which badgerclaw",{stdio:"pipe"}).toString().trim();(0,C.execSync)(`nohup ${e} heartbeat > /dev/null 2>&1 &`,{stdio:"pipe",shell:"/bin/zsh"}),(0,C.execSync)(`nohup ${e} watch > /dev/null 2>&1 &`,{stdio:"pipe",shell:"/bin/zsh"})}catch{}}function tn(){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,C.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.
107
107
 
108
108
  When you receive a message, it will be formatted like:
109
109
  [Room: RoomName] Sender: message text
@@ -112,20 +112,20 @@ Reply using the reply tool with botId="..." and roomId="..."
112
112
  ALWAYS use the \`reply\` MCP tool to send your response back to the chat room.
113
113
  Use the exact botId and roomId provided in the message \u2014 do not modify them.
114
114
  Keep responses concise and helpful.
115
- `),e}var Re=b.default.join(me.default.homedir(),".badgerclaw","claude-code.lock");function on(){try{u.default.mkdirSync(b.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 nn(e){if(!e?.bot_id)return{success:!1,message:"Missing bot_id in payload"};if(!on())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 zt(e.bot_id),o=7332,{launchClaudeCode:s,recordSession:n,getActiveSessions:r,stopSession:a}=(Pe(),dt(st)),i=r();for(let h of i)console.log(`[command-executor] Stopping existing session ${h.sessionId}`),a(h.sessionId);try{(0,S.execSync)(`lsof -ti :${o} | xargs kill -9 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let l=e.session_id||`session-${Date.now()}`;await W.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!0,sessionId:l},{timeout:1e4});let m=tn();return s({sessionId:l,port:o,projectDir:m}),n(l,0,0,o,m),{success:!0,message:`Claude Code started globally for bot ${t} (session: ${l}, port: ${o})`}}catch(t){return{success:!1,message:`Failed to start Claude Code: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function zt(e){if(e.startsWith("@"))return e;try{let o=(await W.default.get("http://localhost:7331/health",{timeout:1e4})).data?.bots||[],s=b.default.join(me.default.homedir(),".badgerclaw","bot-mapping.json");if(u.default.existsSync(s)){let n=JSON.parse(u.default.readFileSync(s,"utf-8"));if(n[e])return n[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 sn(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 zt(e.bot_id),o=e.session_id;if(!o)try{let s=await W.default.get("http://localhost:7331/claude-code/status",{timeout:5e3}),r=(s.data?.bots||s.data?.rooms||[]).find(a=>a.botId===t);r&&(o=r.sessionId)}catch{}if(await W.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!1},{timeout:1e4}),o){let{stopSession:s}=(Pe(),dt(st));s(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 rn(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 W.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 Kt=3e4,Xt="/api/v1/dashboard/heartbeat",Ee=new Map,an=3e4;function De(e,t){if(e!=="start_claude_code"&&e!=="stop_claude_code")return!1;let o=`${e}:${t||"unknown"}`,s=Date.now();for(let[n,r]of Ee)s-r>an&&Ee.delete(n);return Ee.has(o)?!0:(Ee.set(o,s),!1)}function Qt(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(s=>({bot_id:s.botId,bot_username:s.botUsername,status:s.status,activity_state:s.activityState||"idle",active_task:s.activeTask||null,last_activity_at:s.lastActivity,messages_received:s.messagesReceived,messages_sent:s.messagesSent,chunked_messages:s.chunkedMessages,total_chunks_sent:s.totalChunksSent,errors:s.errors,last_error:s.lastError,last_error_at:s.lastErrorAt,uptime_seconds:s.uptimeSeconds,rooms_active:s.roomsActive,room_details:(s.roomDetails||[]).map(n=>({roomId:n.roomId,roomName:n.roomName,workspaceName:n.workspaceName||null,messagesInRoom:n.messagesInRoom,lastActivityInRoom:n.lastActivityInRoom}))}))}}async function I(){let{version:e}=U(),t=await le(),o=Qt(t,e);await v().post(Xt,o)}function cn(e,t){if(!e||e.status!==t.status)return!0;let o=new Map(e.bots.map(s=>[s.botId,s]));for(let s of t.bots){let n=o.get(s.botId);if(!n||n.status!==s.status||n.errors!==s.errors)return!0}return e.bots.length!==t.bots.length}var Zt=new Yt.Command("heartbeat").description("Run heartbeat daemon \u2014 reports telemetry to the BadgerClaw dashboard every 30s").action(async()=>{let e=f();e||(console.log(d.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=U();console.log(d.default.green(`Heartbeat daemon started (v${t})`)),console.log(d.default.dim(` Instance: ${de()}`)),console.log(d.default.dim(` Interval: ${Kt/1e3}s`)),console.log(d.default.dim(` Press Ctrl+C to stop.
116
- `));let o=null,s=async()=>{try{await eo();let n=await le(),r=Qt(n,t);cn(o,n)&&o!==null&&console.log(d.default.cyan(` [${new Date().toISOString()}] State change detected \u2014 pushing immediately`));let i=v(),l=await i.post(Xt,r),m=n.bots.length,h=n.bots.filter($=>$.status==="running").length;console.log(d.default.dim(` [${new Date().toISOString()}] gateway=${n.status} bots=${h}/${m} running mem=${r.mem_free_mb}MB free`)),o=n;let w=l.data?.pending_commands||[],D=!1;for(let $ of w)try{if(console.log(d.default.cyan(` [${new Date().toISOString()}] Received command: ${$.command_type} (${$.id})`)),await i.post(`/api/v1/dashboard/commands/${$.id}/ack`),De($.command_type,$.payload?.bot_id)){console.log(d.default.dim(` [${new Date().toISOString()}] Skipping duplicate ${$.command_type}`));continue}let C=await M($);console.log(C.success?d.default.green(` [${new Date().toISOString()}] ${C.message}`):d.default.red(` [${new Date().toISOString()}] ${C.message}`)),await i.post(`/api/v1/dashboard/commands/${$.id}/result`,{status:C.success?"success":"failed",result:C.message,new_version:C.newVersion||null}),$.command_type==="update_cli"&&C.success&&(D=!0)}catch(C){console.log(d.default.dim(` [${new Date().toISOString()}] Command ${$.id} error: ${C.message}`))}if(D){console.log(d.default.cyan(` [${new Date().toISOString()}] CLI updated \u2014 restarting in 2s...`));try{await I()}catch{}setTimeout(()=>process.exit(0),2e3);return}}catch(n){console.log(d.default.dim(` [${new Date().toISOString()}] Heartbeat failed: ${n.message}`))}};await s(),setInterval(s,Kt),dn(e.access_token,t),await new Promise(()=>{})});async function eo(){let e=f();if(!e?.expires_at)return;let t=new Date(e.expires_at).getTime(),o=Date.now(),s=300*1e3;if(t-o<s){console.log(d.default.dim(` [${y()}] Token expires soon \u2014 refreshing proactively...`));let n=await je();console.log(n?d.default.green(` [${y()}] Token refreshed successfully`):d.default.yellow(` [${y()}] Token refresh failed \u2014 no refresh_token available`))}}var ln=2700*1e3;function dn(e,t){let o=3e3,s=3e4,n=null;async function r(){try{await eo();let i=f()?.access_token||e,l=require("eventsource"),m=new l(`${j}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${i}`}});m.onopen=()=>{o=3e3,console.log(d.default.dim(` [${y()}] SSE connected \u2014 listening for real-time events`)),n&&clearTimeout(n),n=setTimeout(()=>{console.log(d.default.dim(` [${y()}] SSE proactive reconnect \u2014 refreshing token before expiry`)),m.close(),r()},ln)},m.onmessage=async h=>{try{let w=JSON.parse(h.data);await mn(w)}catch{}},m.onerror=async()=>{m.close(),n&&(clearTimeout(n),n=null),console.log(d.default.dim(` [${y()}] SSE disconnected \u2014 reconnecting in ${o/1e3}s...`)),setTimeout(r,o),o=Math.min(o*1.5,s)}}catch(a){console.log(d.default.dim(` [${y()}] SSE connection failed: ${a.message}`)),setTimeout(r,o),o=Math.min(o*1.5,s)}}r()}function y(){return new Date().toISOString()}async function mn(e){if(e.type==="pair"){console.log(d.default.cyan(` [${y()}] Pair event: ${e.bot_name}`)),await te(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 I()}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 s=await import("fs"),n=await import("path"),r=await import("os"),a=n.join(r.homedir(),".openclaw","openclaw.json"),i=JSON.parse(s.readFileSync(a,"utf-8")),l=!1;if(i.channels?.badgerclaw?.accounts?.[o]&&(delete i.channels.badgerclaw.accounts[o],l=!0),i.agents?.list){let m=i.agents.list.length;i.agents.list=i.agents.list.filter(h=>h.id!==o),i.agents.list.length!==m&&(l=!0)}if(l){s.writeFileSync(a,JSON.stringify(i,null,2)),console.log(d.default.green(` [${y()}] Removed "${o}" from openclaw.json`));let{execSync:m}=await import("child_process");try{m("openclaw gateway restart",{stdio:"ignore"}),console.log(d.default.green(` [${y()}] Gateway restarted`))}catch{}}}catch(s){console.log(d.default.red(` [${y()}] Failed to clean up bot: ${s}`))}try{await I()}catch{}}else if(e.type==="gateway-restart"){console.log(d.default.cyan(` [${y()}] Remote gateway-restart received`));let t=await Y();console.log(t.success?d.default.green(` [${y()}] Gateway restarted`):d.default.red(` [${y()}] Gateway restart failed: ${t.message}`));try{await I()}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 v().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await I()}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 v().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await I()}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=v();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 I()}catch{}}}var oo=new to.Command("watch").description("Watch for bot pair events in real-time (no polling)").action(async()=>{let e=f();e||(console.log(g.default.yellow("Not logged in.")),process.exit(1)),await oe(!1),console.log(g.default.green("\u{1F534} Listening for pair events... (Ctrl+C to stop)"));let t=require("eventsource"),o=new t(`${j}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${e.access_token}`}});o.onmessage=async s=>{try{let n=JSON.parse(s.data);if(n.type==="pair"){console.log(g.default.cyan(`
115
+ `),e}var Re=_.default.join(me.default.homedir(),".badgerclaw","claude-code.lock");function on(){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 nn(e){if(!e?.bot_id)return{success:!1,message:"Missing bot_id in payload"};if(!on())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 zt(e.bot_id),{launchClaudeCode:o,recordSession:s,getActiveSessions:n,stopSession:r}=(Pe(),dt(st)),a=new Set;try{let R=(await F.default.get("http://localhost:7331/claude-code/status",{timeout:5e3})).data?.bots||[];for(let b of R)if(b.botId!==t&&b.enabled!==!1){let S=b.port;typeof S=="number"&&S>=7332&&a.add(S)}}catch{}for(let f=7332;f<=7340;f++)try{(0,C.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=n();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,C.execSync)(`lsof -ti :${i} | xargs kill -9 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let m=e.session_id||`session-${Date.now()}`;await F.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!0,sessionId:m,port:i},{timeout:1e4});let y=tn();return o({sessionId:m,port:i,projectDir:y}),s(m,0,0,i,y),{success:!0,message:`Claude Code started globally for bot ${t} (session: ${m}, port: ${i})`}}catch(t){return{success:!1,message:`Failed to start Claude Code: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function zt(e){if(e.startsWith("@"))return e;try{let o=(await F.default.get("http://localhost:7331/health",{timeout:1e4})).data?.bots||[],s=_.default.join(me.default.homedir(),".badgerclaw","bot-mapping.json");if(u.default.existsSync(s)){let n=JSON.parse(u.default.readFileSync(s,"utf-8"));if(n[e])return n[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 sn(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 zt(e.bot_id),o=e.session_id;if(!o)try{let s=await F.default.get("http://localhost:7331/claude-code/status",{timeout:5e3}),r=(s.data?.bots||s.data?.rooms||[]).find(a=>a.botId===t);r&&(o=r.sessionId)}catch{}if(await F.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!1},{timeout:1e4}),o){let{stopSession:s}=(Pe(),dt(st));s(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 rn(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 F.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 Kt=3e4,Xt="/api/v1/dashboard/heartbeat",Ee=new Map,an=3e4;function De(e,t){if(e!=="start_claude_code"&&e!=="stop_claude_code")return!1;let o=`${e}:${t||"unknown"}`,s=Date.now();for(let[n,r]of Ee)s-r>an&&Ee.delete(n);return Ee.has(o)?!0:(Ee.set(o,s),!1)}function Qt(e,t){let o=ke();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(s=>({bot_id:s.botId,bot_username:s.botUsername,status:s.status,activity_state:s.activityState||"idle",active_task:s.activeTask||null,last_activity_at:s.lastActivity,messages_received:s.messagesReceived,messages_sent:s.messagesSent,chunked_messages:s.chunkedMessages,total_chunks_sent:s.totalChunksSent,errors:s.errors,last_error:s.lastError,last_error_at:s.lastErrorAt,uptime_seconds:s.uptimeSeconds,rooms_active:s.roomsActive,room_details:(s.roomDetails||[]).map(n=>({roomId:n.roomId,roomName:n.roomName,workspaceName:n.workspaceName||null,messagesInRoom:n.messagesInRoom,lastActivityInRoom:n.lastActivityInRoom}))}))}}async function k(){let{version:e}=U(),t=await le(),o=Qt(t,e);await v().post(Xt,o)}function cn(e,t){if(!e||e.status!==t.status)return!0;let o=new Map(e.bots.map(s=>[s.botId,s]));for(let s of t.bots){let n=o.get(s.botId);if(!n||n.status!==s.status||n.errors!==s.errors)return!0}return e.bots.length!==t.bots.length}var Zt=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}=U();console.log(d.default.green(`Heartbeat daemon started (v${t})`)),console.log(d.default.dim(` Instance: ${de()}`)),console.log(d.default.dim(` Interval: ${Kt/1e3}s`)),console.log(d.default.dim(` Press Ctrl+C to stop.
116
+ `));let o=null,s=async()=>{try{await eo();let n=await le(),r=Qt(n,t);cn(o,n)&&o!==null&&console.log(d.default.cyan(` [${new Date().toISOString()}] State change detected \u2014 pushing immediately`));let i=v(),l=await i.post(Xt,r),m=n.bots.length,y=n.bots.filter(b=>b.status==="running").length;console.log(d.default.dim(` [${new Date().toISOString()}] gateway=${n.status} bots=${y}/${m} running mem=${r.mem_free_mb}MB free`)),o=n;let f=l.data?.pending_commands||[],R=!1;for(let b of f)try{if(console.log(d.default.cyan(` [${new Date().toISOString()}] Received command: ${b.command_type} (${b.id})`)),await i.post(`/api/v1/dashboard/commands/${b.id}/ack`),De(b.command_type,b.payload?.bot_id)){console.log(d.default.dim(` [${new Date().toISOString()}] Skipping duplicate ${b.command_type}`));continue}let S=await M(b);console.log(S.success?d.default.green(` [${new Date().toISOString()}] ${S.message}`):d.default.red(` [${new Date().toISOString()}] ${S.message}`)),await i.post(`/api/v1/dashboard/commands/${b.id}/result`,{status:S.success?"success":"failed",result:S.message,new_version:S.newVersion||null}),b.command_type==="update_cli"&&S.success&&(R=!0)}catch(S){console.log(d.default.dim(` [${new Date().toISOString()}] Command ${b.id} error: ${S.message}`))}if(R){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(n){console.log(d.default.dim(` [${new Date().toISOString()}] Heartbeat failed: ${n.message}`))}};await s(),setInterval(s,Kt),dn(e.access_token,t),await new Promise(()=>{})});async function eo(){let e=h();if(!e?.expires_at)return;let t=new Date(e.expires_at).getTime(),o=Date.now(),s=300*1e3;if(t-o<s){console.log(d.default.dim(` [${w()}] Token expires soon \u2014 refreshing proactively...`));let n=await je();console.log(n?d.default.green(` [${w()}] Token refreshed successfully`):d.default.yellow(` [${w()}] Token refresh failed \u2014 no refresh_token available`))}}var ln=2700*1e3;function dn(e,t){let o=3e3,s=3e4,n=null;async function r(){try{await eo();let i=h()?.access_token||e,l=require("eventsource"),m=new l(`${j}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${i}`}});m.onopen=()=>{o=3e3,console.log(d.default.dim(` [${w()}] SSE connected \u2014 listening for real-time events`)),n&&clearTimeout(n),n=setTimeout(()=>{console.log(d.default.dim(` [${w()}] SSE proactive reconnect \u2014 refreshing token before expiry`)),m.close(),r()},ln)},m.onmessage=async y=>{try{let f=JSON.parse(y.data);await mn(f)}catch{}},m.onerror=async()=>{m.close(),n&&(clearTimeout(n),n=null),console.log(d.default.dim(` [${w()}] SSE disconnected \u2014 reconnecting in ${o/1e3}s...`)),setTimeout(r,o),o=Math.min(o*1.5,s)}}catch(a){console.log(d.default.dim(` [${w()}] SSE connection failed: ${a.message}`)),setTimeout(r,o),o=Math.min(o*1.5,s)}}r()}function w(){return new Date().toISOString()}async function mn(e){if(e.type==="pair"){console.log(d.default.cyan(` [${w()}] Pair event: ${e.bot_name}`)),await te(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(` [${w()}] 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(` [${w()}] Bot deleted: ${t}`));try{let s=await import("fs"),n=await import("path"),r=await import("os"),a=n.join(r.homedir(),".openclaw","openclaw.json"),i=JSON.parse(s.readFileSync(a,"utf-8")),l=!1;if(i.channels?.badgerclaw?.accounts?.[o]&&(delete i.channels.badgerclaw.accounts[o],l=!0),i.agents?.list){let m=i.agents.list.length;i.agents.list=i.agents.list.filter(y=>y.id!==o),i.agents.list.length!==m&&(l=!0)}if(l){s.writeFileSync(a,JSON.stringify(i,null,2)),console.log(d.default.green(` [${w()}] Removed "${o}" from openclaw.json`));let{execSync:m}=await import("child_process");try{m("openclaw gateway restart",{stdio:"ignore"}),console.log(d.default.green(` [${w()}] Gateway restarted`))}catch{}}}catch(s){console.log(d.default.red(` [${w()}] Failed to clean up bot: ${s}`))}try{await k()}catch{}}else if(e.type==="gateway-restart"){console.log(d.default.cyan(` [${w()}] Remote gateway-restart received`));let t=await Y();console.log(t.success?d.default.green(` [${w()}] Gateway restarted`):d.default.red(` [${w()}] 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(` [${w()}] Claude Code START: bot=${e.bot_id}`)),De("start_claude_code",e.bot_id)){console.log(d.default.dim(` [${w()}] 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 v().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(` [${w()}] Claude Code STOP: bot=${e.bot_id}`)),De("stop_claude_code",e.bot_id)){console.log(d.default.dim(` [${w()}] 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 v().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(` [${w()}] Command: ${e.command_type} (${e.command_id})`)),De(e.command_type,e.payload?.bot_id)){console.log(d.default.dim(` [${w()}] Skipping duplicate ${e.command_type} (already processed)`));return}try{let t=v();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(` [${w()}] CLI updated \u2014 restarting in 2s...`)),setTimeout(()=>process.exit(0),2e3))}catch{}try{await k()}catch{}}}var oo=new to.Command("watch").description("Watch for bot pair events in real-time (no polling)").action(async()=>{let e=h();e||(console.log(g.default.yellow("Not logged in.")),process.exit(1)),await oe(!1),console.log(g.default.green("\u{1F534} Listening for pair events... (Ctrl+C to stop)"));let t=require("eventsource"),o=new t(`${j}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${e.access_token}`}});o.onmessage=async s=>{try{let n=JSON.parse(s.data);if(n.type==="pair"){console.log(g.default.cyan(`
117
117
  \u{1F4F1} Pair event received: ${n.bot_name}`)),await te(n.pair_code,n.bot_name,n.bot_user_id,!1);try{let{execSync:r}=await import("child_process");r("openclaw gateway restart",{stdio:"ignore"}),console.log(g.default.green(" \u2705 Gateway restarted \u2014 bot is live!"))}catch{console.log(g.default.dim(" Gateway restart failed \u2014 run: openclaw gateway restart"))}}else if(n.type==="gateway-restart"){console.log(g.default.cyan(`
118
- \u{1F504} Remote gateway-restart command received`));let r=await Y();r.success?console.log(g.default.green(` \u2705 Gateway restarted: ${r.message}`)):console.log(g.default.red(` \u274C Gateway restart failed: ${r.message}`));try{await I(),console.log(g.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(g.default.dim(" Could not push heartbeat."))}}else if(n.type==="bot.delete"&&n.bot_user_id){let r=n.bot_user_id,a=r.split(":")[0].replace("@","").replace(/_bot$/,"");console.log(g.default.yellow(`
119
- \u{1F5D1}\uFE0F Bot deleted: ${r} \u2014 removing from OpenClaw config...`));try{let i=await import("fs"),l=await import("path"),m=await import("os"),h=l.join(m.homedir(),".openclaw","openclaw.json"),w=JSON.parse(i.readFileSync(h,"utf-8")),D=!1;if(w.channels?.badgerclaw?.accounts?.[a]&&(delete w.channels.badgerclaw.accounts[a],D=!0),w.agents?.list){let $=w.agents.list.length;w.agents.list=w.agents.list.filter(C=>C.id!==a),w.agents.list.length!==$&&(D=!0)}if(D){i.writeFileSync(h,JSON.stringify(w,null,2)),console.log(g.default.green(` \u2705 Removed "${a}" from openclaw.json`));let{execSync:$}=await import("child_process");try{$("openclaw gateway restart",{stdio:"ignore"}),console.log(g.default.green(" \u2705 Gateway restarted"))}catch{console.log(g.default.dim(" Gateway restart failed \u2014 restart manually"))}}else console.log(g.default.dim(` "${a}" not found in openclaw.json \u2014 nothing to remove`))}catch(i){console.log(g.default.red(` Failed to update openclaw.json: ${i}`))}}else if(n.type==="claude_code.start"&&n.bot_id&&n.room_id){console.log(g.default.cyan(`
120
- \u{1F916} Claude Code START received: bot=${n.bot_id} room=${n.room_id}`));try{let r=await M({id:n.command_id||`cc-start-${Date.now()}`,command_type:"start_claude_code",payload:{bot_id:n.bot_id,room_id:n.room_id,session_id:n.session_id}});if(console.log(r.success?g.default.green(` \u2705 ${r.message}`):g.default.red(` \u274C ${r.message}`)),n.command_id)try{await v().post(`/api/v1/dashboard/commands/${n.command_id}/result`,{status:r.success?"success":"failed",result:r.message})}catch{}try{await I()}catch{}}catch(r){console.log(g.default.red(` Claude Code start error: ${r.message}`))}}else if(n.type==="claude_code.stop"&&n.bot_id&&n.room_id){console.log(g.default.cyan(`
121
- \u{1F916} Claude Code STOP received: bot=${n.bot_id} room=${n.room_id}`));try{let r=await M({id:n.command_id||`cc-stop-${Date.now()}`,command_type:"stop_claude_code",payload:{bot_id:n.bot_id,room_id:n.room_id,session_id:n.session_id}});if(console.log(r.success?g.default.green(` \u2705 ${r.message}`):g.default.red(` \u274C ${r.message}`)),n.command_id)try{await v().post(`/api/v1/dashboard/commands/${n.command_id}/result`,{status:r.success?"success":"failed",result:r.message})}catch{}try{await I()}catch{}}catch(r){console.log(g.default.red(` Claude Code stop error: ${r.message}`))}}else if(n.type==="command.execute"&&n.command_id){console.log(g.default.cyan(`
122
- \u26A1 SSE command received: ${n.command_type} (${n.command_id})`));try{let r=v();await r.post(`/api/v1/dashboard/commands/${n.command_id}/ack`);let a=await M({id:n.command_id,command_type:n.command_type,payload:n.payload});console.log(a.success?g.default.green(` \u2705 ${a.message}`):g.default.red(` \u274C ${a.message}`)),await r.post(`/api/v1/dashboard/commands/${n.command_id}/result`,{status:a.success?"success":"failed",result:a.message,new_version:a.newVersion||null});try{await I()}catch{}n.command_type==="update_cli"&&a.success&&(console.log(g.default.cyan(" CLI updated \u2014 restarting in 2s...")),setTimeout(()=>process.exit(0),2e3))}catch(r){console.log(g.default.red(` Command ${n.command_id} error: ${r.message}`))}}}catch{}},o.onerror=()=>{console.log(g.default.dim(" Reconnecting..."))},await new Promise(()=>{})});var no=require("commander"),A=c(require("chalk")),at=require("child_process"),O=c(require("fs")),so=c(require("os")),ro=c(require("path")),X=ro.default.join(so.default.homedir(),".openclaw","openclaw.json"),ue=X+".badgerclaw-stash";function un(){if(!O.default.existsSync(X))return null;try{let e=JSON.parse(O.default.readFileSync(X,"utf-8")),t=e.channels?.badgerclaw;return t?(delete e.channels.badgerclaw,e.plugins?.entries?.badgerclaw&&delete e.plugins.entries.badgerclaw,O.default.writeFileSync(X,JSON.stringify(e,null,2)),O.default.writeFileSync(ue,JSON.stringify(t,null,2)),t):null}catch{return null}}function gn(){if(O.default.existsSync(ue))try{let e=JSON.parse(O.default.readFileSync(ue,"utf-8")),t=JSON.parse(O.default.readFileSync(X,"utf-8"));t.channels=t.channels||{},t.channels.badgerclaw=e,O.default.writeFileSync(X,JSON.stringify(t,null,2)),O.default.unlinkSync(ue)}catch(e){console.log(A.default.yellow(` \u26A0\uFE0F Could not restore config: ${e.message}`)),console.log(A.default.yellow(` Your bot credentials are backed up at: ${ue}`))}}var ao=new no.Command("setup").description("Install or update the OpenClaw BadgerClaw plugin safely (handles config automatically)").action(async()=>{console.log(A.default.green(`
118
+ \u{1F504} Remote gateway-restart command received`));let r=await Y();r.success?console.log(g.default.green(` \u2705 Gateway restarted: ${r.message}`)):console.log(g.default.red(` \u274C Gateway restart failed: ${r.message}`));try{await k(),console.log(g.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(g.default.dim(" Could not push heartbeat."))}}else if(n.type==="bot.delete"&&n.bot_user_id){let r=n.bot_user_id,a=r.split(":")[0].replace("@","").replace(/_bot$/,"");console.log(g.default.yellow(`
119
+ \u{1F5D1}\uFE0F Bot deleted: ${r} \u2014 removing from OpenClaw config...`));try{let i=await import("fs"),l=await import("path"),m=await import("os"),y=l.join(m.homedir(),".openclaw","openclaw.json"),f=JSON.parse(i.readFileSync(y,"utf-8")),R=!1;if(f.channels?.badgerclaw?.accounts?.[a]&&(delete f.channels.badgerclaw.accounts[a],R=!0),f.agents?.list){let b=f.agents.list.length;f.agents.list=f.agents.list.filter(S=>S.id!==a),f.agents.list.length!==b&&(R=!0)}if(R){i.writeFileSync(y,JSON.stringify(f,null,2)),console.log(g.default.green(` \u2705 Removed "${a}" from openclaw.json`));let{execSync:b}=await import("child_process");try{b("openclaw gateway restart",{stdio:"ignore"}),console.log(g.default.green(" \u2705 Gateway restarted"))}catch{console.log(g.default.dim(" Gateway restart failed \u2014 restart manually"))}}else console.log(g.default.dim(` "${a}" not found in openclaw.json \u2014 nothing to remove`))}catch(i){console.log(g.default.red(` Failed to update openclaw.json: ${i}`))}}else if(n.type==="claude_code.start"&&n.bot_id&&n.room_id){console.log(g.default.cyan(`
120
+ \u{1F916} Claude Code START received: bot=${n.bot_id} room=${n.room_id}`));try{let r=await M({id:n.command_id||`cc-start-${Date.now()}`,command_type:"start_claude_code",payload:{bot_id:n.bot_id,room_id:n.room_id,session_id:n.session_id}});if(console.log(r.success?g.default.green(` \u2705 ${r.message}`):g.default.red(` \u274C ${r.message}`)),n.command_id)try{await v().post(`/api/v1/dashboard/commands/${n.command_id}/result`,{status:r.success?"success":"failed",result:r.message})}catch{}try{await k()}catch{}}catch(r){console.log(g.default.red(` Claude Code start error: ${r.message}`))}}else if(n.type==="claude_code.stop"&&n.bot_id&&n.room_id){console.log(g.default.cyan(`
121
+ \u{1F916} Claude Code STOP received: bot=${n.bot_id} room=${n.room_id}`));try{let r=await M({id:n.command_id||`cc-stop-${Date.now()}`,command_type:"stop_claude_code",payload:{bot_id:n.bot_id,room_id:n.room_id,session_id:n.session_id}});if(console.log(r.success?g.default.green(` \u2705 ${r.message}`):g.default.red(` \u274C ${r.message}`)),n.command_id)try{await v().post(`/api/v1/dashboard/commands/${n.command_id}/result`,{status:r.success?"success":"failed",result:r.message})}catch{}try{await k()}catch{}}catch(r){console.log(g.default.red(` Claude Code stop error: ${r.message}`))}}else if(n.type==="command.execute"&&n.command_id){console.log(g.default.cyan(`
122
+ \u26A1 SSE command received: ${n.command_type} (${n.command_id})`));try{let r=v();await r.post(`/api/v1/dashboard/commands/${n.command_id}/ack`);let a=await M({id:n.command_id,command_type:n.command_type,payload:n.payload});console.log(a.success?g.default.green(` \u2705 ${a.message}`):g.default.red(` \u274C ${a.message}`)),await r.post(`/api/v1/dashboard/commands/${n.command_id}/result`,{status:a.success?"success":"failed",result:a.message,new_version:a.newVersion||null});try{await k()}catch{}n.command_type==="update_cli"&&a.success&&(console.log(g.default.cyan(" CLI updated \u2014 restarting in 2s...")),setTimeout(()=>process.exit(0),2e3))}catch(r){console.log(g.default.red(` Command ${n.command_id} error: ${r.message}`))}}}catch{}},o.onerror=()=>{console.log(g.default.dim(" Reconnecting..."))},await new Promise(()=>{})});var no=require("commander"),A=c(require("chalk")),at=require("child_process"),O=c(require("fs")),so=c(require("os")),ro=c(require("path")),X=ro.default.join(so.default.homedir(),".openclaw","openclaw.json"),ue=X+".badgerclaw-stash";function un(){if(!O.default.existsSync(X))return null;try{let e=JSON.parse(O.default.readFileSync(X,"utf-8")),t=e.channels?.badgerclaw;return t?(delete e.channels.badgerclaw,e.plugins?.entries?.badgerclaw&&delete e.plugins.entries.badgerclaw,O.default.writeFileSync(X,JSON.stringify(e,null,2)),O.default.writeFileSync(ue,JSON.stringify(t,null,2)),t):null}catch{return null}}function gn(){if(O.default.existsSync(ue))try{let e=JSON.parse(O.default.readFileSync(ue,"utf-8")),t=JSON.parse(O.default.readFileSync(X,"utf-8"));t.channels=t.channels||{},t.channels.badgerclaw=e,O.default.writeFileSync(X,JSON.stringify(t,null,2)),O.default.unlinkSync(ue)}catch(e){console.log(A.default.yellow(` \u26A0\uFE0F Could not restore config: ${e.message}`)),console.log(A.default.yellow(` Your bot credentials are backed up at: ${ue}`))}}var ao=new no.Command("setup").description("Install or update the OpenClaw BadgerClaw plugin safely (handles config automatically)").action(async()=>{console.log(A.default.green(`
123
123
  \u{1F9A1} BadgerClaw Setup
124
124
  `));let e=un();e&&console.log(A.default.dim(" Existing bot config stashed temporarily...")),console.log(A.default.dim(" Installing @badgerclaw/connect plugin..."));let t=(0,at.spawnSync)("openclaw",["plugins","install","@badgerclaw/connect","--dangerously-force-unsafe-install"],{stdio:"inherit",shell:!0});e&&(gn(),console.log(A.default.dim(" Bot config restored."))),t.status!==0&&(console.log(A.default.red(`
125
125
  \u274C Plugin install failed. Your bot config has been restored.`)),process.exit(1)),console.log(A.default.green(`
126
126
  \u2705 BadgerClaw plugin installed successfully!`)),console.log(A.default.dim(`
127
- Restarting OpenClaw gateway to load plugin...`)),(0,at.spawnSync)("openclaw",["gateway","restart"],{stdio:"inherit",shell:!0}).status===0?console.log(A.default.green(" Gateway restarted.")):console.log(A.default.yellow(" Gateway restart failed or not running \u2014 start it manually: openclaw gateway start")),console.log(A.default.dim("\nNext: run `badgerclaw login` to authenticate."))});var co=require("commander"),_=c(require("chalk"));var lo=new co.Command("dashboard").description("Show local diagnostic dashboard \u2014 machine health, gateway status, bot telemetry").action(async()=>{f()||(console.log(_.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=U(),o=Ie(),s=await le();console.log(_.default.bold.green(`
127
+ Restarting OpenClaw gateway to load plugin...`)),(0,at.spawnSync)("openclaw",["gateway","restart"],{stdio:"inherit",shell:!0}).status===0?console.log(A.default.green(" Gateway restarted.")):console.log(A.default.yellow(" Gateway restart failed or not running \u2014 start it manually: openclaw gateway start")),console.log(A.default.dim("\nNext: run `badgerclaw login` to authenticate."))});var co=require("commander"),$=c(require("chalk"));var lo=new co.Command("dashboard").description("Show local diagnostic dashboard \u2014 machine health, gateway status, bot telemetry").action(async()=>{h()||(console.log($.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=U(),o=ke(),s=await le();console.log($.default.bold.green(`
128
128
  BadgerClaw Dashboard
129
- `)),console.log(_.default.bold(" Instance")),console.log(` ID: ${de()}`),console.log(` CLI Version: ${t}`),console.log(` Plugin: ${s.pluginVersion}`),console.log(),console.log(_.default.bold(" Machine")),console.log(` Hostname: ${o.hostname}`),console.log(` OS: ${o.os} / ${o.arch}`),console.log(` Uptime: ${io(o.uptimeSeconds)}`),console.log(` Free Memory: ${o.memFreeMb} MB`),console.log();let n=s.status==="running"?_.default.green:s.status==="error"?_.default.red:_.default.yellow;if(console.log(_.default.bold(" Gateway")),console.log(` Status: ${n(s.status)}`),console.log(` PID: ${s.pid??"N/A"}`),console.log(` Last Restart: ${s.lastRestart??"N/A"}`),console.log(),s.bots.length===0)console.log(_.default.bold(" Bots")),console.log(_.default.dim(" No bots detected. Pair bots at https://badgerclaw.ai")),console.log();else{console.log(_.default.bold(` Bots (${s.bots.length})`)),console.log();for(let r of s.bots){let a=r.status==="running"?_.default.green:r.status==="error"?_.default.red:_.default.yellow;if(console.log(` ${_.default.bold(r.botUsername)} ${a(`[${r.status}]`)}`),console.log(` ID: ${r.botId}`),console.log(` Uptime: ${io(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: ${_.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(_.default.dim(" Rooms:"));for(let i of r.roomDetails)console.log(_.default.dim(` ${i.roomName} \u2014 ${i.messagesInRoom} msgs, last: ${i.lastActivityInRoom??"N/A"}`))}console.log()}}console.log(_.default.dim(` Last checked: ${new Date().toISOString()}`)),console.log()});function io(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 it=require("commander"),Q=c(require("chalk")),mo=c(require("ora"));var pn=new it.Command("restart").description("Restart the OpenClaw gateway via the plugin probe endpoint").action(async()=>{f()||(console.log(Q.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,mo.default)("Restarting gateway...").start(),o=await Y();if(o.success){t.succeed(Q.default.green(`Gateway restarted: ${o.message}`));try{await I(),console.log(Q.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(Q.default.dim(" Could not push heartbeat \u2014 daemon may not be running."))}}else t.fail(Q.default.red(`Gateway restart failed: ${o.message}`)),process.exit(1)}),uo=new it.Command("gateway").description("Manage the OpenClaw gateway").addCommand(pn);var G=require("commander"),p=c(require("chalk")),J=c(require("ora")),F=c(require("axios"));Pe();var q="http://localhost:7331",fn=new G.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=>{f()||(console.log(p.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=e.sessionId||`session-${Date.now()}`,s=parseInt(e.port,10),n=e.project.replace(/^~/,process.env.HOME||""),r=(0,J.default)("Starting Claude Code session...").start();try{await F.default.post(`${q}/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:s,projectDir:n}).pid||0;await new Promise(l=>setTimeout(l,1500)),r.text="MCP server running \u2014 launching Claude Code...",et({sessionId:o,port:s,projectDir:n}),tt(o,0,i,s,n),r.succeed(p.default.green("Claude Code session started")+p.default.dim(` (session: ${o}, port: ${s})`)),console.log(p.default.dim(` Bot: ${e.bot}`)),console.log(p.default.dim(` Room: ${e.room}`)),console.log(p.default.dim(` Project: ${n}`)),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)}}),hn=new G.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=>{f()||(console.log(p.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=(0,J.default)("Stopping Claude Code session...").start();try{e.bot&&e.room&&await F.default.post(`${q}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!1},{timeout:1e4});let s=e.sessionId;if(!s)try{let a=((await F.default.get(`${q}/claude-code/status`,{timeout:5e3})).data?.rooms||[]).find(i=>i.botId===e.bot&&i.roomId===e.room);a&&(s=a.sessionId)}catch{}s?(ot(s),o.succeed(p.default.green(`Claude Code session stopped (${s})`))):(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(s){let n=s.response?.data?.message||s.message||"Unknown error";o.fail(p.default.red(`Failed to stop Claude Code: ${n}`)),process.exit(1)}}),yn=new G.Command("status").description("Show active Claude Code sessions").action(async()=>{f()||(console.log(p.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,J.default)("Fetching Claude Code status...").start();try{let o=[];try{o=(await F.default.get(`${q}/claude-code/status`,{timeout:5e3})).data?.rooms||[]}catch{}let s=nt();if(t.stop(),o.length===0&&s.length===0){console.log(p.default.dim("No active Claude Code sessions."));return}if(o.length>0){console.log(p.default.bold(`
129
+ `)),console.log($.default.bold(" Instance")),console.log(` ID: ${de()}`),console.log(` CLI Version: ${t}`),console.log(` Plugin: ${s.pluginVersion}`),console.log(),console.log($.default.bold(" Machine")),console.log(` Hostname: ${o.hostname}`),console.log(` OS: ${o.os} / ${o.arch}`),console.log(` Uptime: ${io(o.uptimeSeconds)}`),console.log(` Free Memory: ${o.memFreeMb} MB`),console.log();let n=s.status==="running"?$.default.green:s.status==="error"?$.default.red:$.default.yellow;if(console.log($.default.bold(" Gateway")),console.log(` Status: ${n(s.status)}`),console.log(` PID: ${s.pid??"N/A"}`),console.log(` Last Restart: ${s.lastRestart??"N/A"}`),console.log(),s.bots.length===0)console.log($.default.bold(" Bots")),console.log($.default.dim(" No bots detected. Pair bots at https://badgerclaw.ai")),console.log();else{console.log($.default.bold(` Bots (${s.bots.length})`)),console.log();for(let r of s.bots){let a=r.status==="running"?$.default.green:r.status==="error"?$.default.red:$.default.yellow;if(console.log(` ${$.default.bold(r.botUsername)} ${a(`[${r.status}]`)}`),console.log(` ID: ${r.botId}`),console.log(` Uptime: ${io(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: ${$.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($.default.dim(" Rooms:"));for(let i of r.roomDetails)console.log($.default.dim(` ${i.roomName} \u2014 ${i.messagesInRoom} msgs, last: ${i.lastActivityInRoom??"N/A"}`))}console.log()}}console.log($.default.dim(` Last checked: ${new Date().toISOString()}`)),console.log()});function io(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 it=require("commander"),Q=c(require("chalk")),mo=c(require("ora"));var pn=new it.Command("restart").description("Restart the OpenClaw gateway via the plugin probe endpoint").action(async()=>{h()||(console.log(Q.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,mo.default)("Restarting gateway...").start(),o=await Y();if(o.success){t.succeed(Q.default.green(`Gateway restarted: ${o.message}`));try{await k(),console.log(Q.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(Q.default.dim(" Could not push heartbeat \u2014 daemon may not be running."))}}else t.fail(Q.default.red(`Gateway restart failed: ${o.message}`)),process.exit(1)}),uo=new it.Command("gateway").description("Manage the OpenClaw gateway").addCommand(pn);var V=require("commander"),p=c(require("chalk")),J=c(require("ora")),G=c(require("axios"));Pe();var q="http://localhost:7331",fn=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()}`,s=parseInt(e.port,10),n=e.project.replace(/^~/,process.env.HOME||""),r=(0,J.default)("Starting Claude Code session...").start();try{await G.default.post(`${q}/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:s,projectDir:n}).pid||0;await new Promise(l=>setTimeout(l,1500)),r.text="MCP server running \u2014 launching Claude Code...",et({sessionId:o,port:s,projectDir:n}),tt(o,0,i,s,n),r.succeed(p.default.green("Claude Code session started")+p.default.dim(` (session: ${o}, port: ${s})`)),console.log(p.default.dim(` Bot: ${e.bot}`)),console.log(p.default.dim(` Room: ${e.room}`)),console.log(p.default.dim(` Project: ${n}`)),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)}}),hn=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,J.default)("Stopping Claude Code session...").start();try{e.bot&&e.room&&await G.default.post(`${q}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!1},{timeout:1e4});let s=e.sessionId;if(!s)try{let a=((await G.default.get(`${q}/claude-code/status`,{timeout:5e3})).data?.rooms||[]).find(i=>i.botId===e.bot&&i.roomId===e.room);a&&(s=a.sessionId)}catch{}s?(ot(s),o.succeed(p.default.green(`Claude Code session stopped (${s})`))):(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(s){let n=s.response?.data?.message||s.message||"Unknown error";o.fail(p.default.red(`Failed to stop Claude Code: ${n}`)),process.exit(1)}}),yn=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,J.default)("Fetching Claude Code status...").start();try{let o=[];try{o=(await G.default.get(`${q}/claude-code/status`,{timeout:5e3})).data?.rooms||[]}catch{}let s=nt();if(t.stop(),o.length===0&&s.length===0){console.log(p.default.dim("No active Claude Code sessions."));return}if(o.length>0){console.log(p.default.bold(`
130
130
  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 n of o){let r=n.enabled?p.default.green("ON"):p.default.dim("OFF");console.log(` ${(n.botId||"").padEnd(30)}${(n.roomName||n.roomId||"").padEnd(30)}${(n.sessionId||"-").padEnd(20)}${r}`)}}if(s.length>0){console.log(p.default.bold(`
131
- 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 n of s)console.log(` ${n.sessionId.padEnd(25)}${String(n.port).padEnd(8)}${String(n.mcpPid).padEnd(10)}${n.projectDir.padEnd(40)}${n.startedAt}`)}console.log("")}catch(o){t.fail(p.default.red(`Failed to get status: ${o.message}`)),process.exit(1)}}),wn=new G.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,J.default)("Grouping bot+room into session...").start();try{await F.default.post(`${q}/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 s=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to group: ${s}`)),process.exit(1)}}),bn=new G.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,J.default)("Adding user to allowlist...").start();try{await F.default.post(`${q}/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 s=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to add user: ${s}`)),process.exit(1)}}),_n=new G.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,J.default)("Removing user from allowlist...").start();try{await F.default.post(`${q}/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 s=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to revoke user: ${s}`)),process.exit(1)}}),go=new G.Command("claude-code").description("Manage Claude Code sessions (relay Matrix messages to local Claude Code)").addCommand(fn).addCommand(hn).addCommand(yn).addCommand(wn).addCommand(bn).addCommand(_n);var P=new po.Command;P.name("badgerclaw").description("BadgerClaw CLI \u2014 one-click bot provisioning").version("0.2.11");P.addCommand(Lt);P.addCommand(Ut);P.addCommand(Gt);P.addCommand(Vt);P.addCommand(Ct);P.addCommand(oo);P.addCommand(ao);P.addCommand(Zt);P.addCommand(lo);P.addCommand(uo);P.addCommand(go);P.parse(process.argv);
131
+ 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 n of s)console.log(` ${n.sessionId.padEnd(25)}${String(n.port).padEnd(8)}${String(n.mcpPid).padEnd(10)}${n.projectDir.padEnd(40)}${n.startedAt}`)}console.log("")}catch(o){t.fail(p.default.red(`Failed to get status: ${o.message}`)),process.exit(1)}}),wn=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,J.default)("Grouping bot+room into session...").start();try{await G.default.post(`${q}/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 s=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to group: ${s}`)),process.exit(1)}}),bn=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,J.default)("Adding user to allowlist...").start();try{await G.default.post(`${q}/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 s=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to add user: ${s}`)),process.exit(1)}}),_n=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,J.default)("Removing user from allowlist...").start();try{await G.default.post(`${q}/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 s=o.response?.data?.message||o.message||"Unknown error";t.fail(p.default.red(`Failed to revoke user: ${s}`)),process.exit(1)}}),go=new V.Command("claude-code").description("Manage Claude Code sessions (relay Matrix messages to local Claude Code)").addCommand(fn).addCommand(hn).addCommand(yn).addCommand(wn).addCommand(bn).addCommand(_n);var P=new po.Command;P.name("badgerclaw").description("BadgerClaw CLI \u2014 one-click bot provisioning").version("0.2.13");P.addCommand(Lt);P.addCommand(Ut);P.addCommand(Gt);P.addCommand(Vt);P.addCommand(Ct);P.addCommand(oo);P.addCommand(ao);P.addCommand(Zt);P.addCommand(lo);P.addCommand(uo);P.addCommand(go);P.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badgerclaw",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "BadgerClaw CLI — one-click bot provisioning",
5
5
  "main": "dist/index.js",
6
6
  "bin": {