badgerclaw 0.2.30 → 0.2.32

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