badgerclaw 0.2.68 → 0.2.69

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 +21 -21
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Vs=Object.create;var Rt=Object.defineProperty;var qs=Object.getOwnPropertyDescriptor;var Ks=Object.getOwnPropertyNames;var Js=Object.getPrototypeOf,Ys=Object.prototype.hasOwnProperty;var F=(e,t)=>()=>(e&&(t=e(e=0)),t);var zs=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),wo=(e,t)=>{for(var o in t)Rt(e,o,{get:t[o],enumerable:!0})},$n=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Ks(t))!Ys.call(e,r)&&r!==o&&Rt(e,r,{get:()=>t[r],enumerable:!(n=qs(t,r))||n.enumerable});return e};var d=(e,t,o)=>(o=e!=null?Vs(Js(e)):{},$n(t||!e||!e.__esModule?Rt(o,"default",{value:e,enumerable:!0}):o,e)),Cn=e=>$n(Rt({},"__esModule",{value:!0}),e);function h(){try{let e=st.default.readFileSync(_o,"utf-8");return JSON.parse(e)}catch{return null}}function Me(e){st.default.mkdirSync(An,{recursive:!0}),st.default.writeFileSync(_o,JSON.stringify(e,null,2),{mode:384})}function it(){try{st.default.unlinkSync(_o)}catch{}}function At(){let e=h();return e?new Date(e.expires_at)>new Date:!1}function Et(e){let t=e.match(/^@?([^:]+)/);return t?t[1]:e}var st,bo,Rn,An,_o,j=F(()=>{"use strict";st=d(require("fs")),bo=d(require("path")),Rn=d(require("os")),An=bo.default.join(Rn.default.homedir(),".badgerclaw"),_o=bo.default.join(An,"auth.json")});function at(){return En.default.createHash("sha256").update(`${Q.default.hostname()}-${Q.default.platform()}-${Q.default.arch()}`).digest("hex").slice(0,16)}function ee(){let e=h();if(e?.instance_id)return e.instance_id;let t=at();return`openclaw-${Q.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${t}`}function Pt(){return{hostname:Q.default.hostname(),os:Q.default.platform(),arch:Q.default.arch(),uptimeSeconds:Math.floor(Q.default.uptime()),memFreeMb:Math.floor(Q.default.freemem()/1024/1024)}}var Q,En,xe=F(()=>{"use strict";Q=d(require("os")),En=d(require("crypto"));j()});var Pn,U,On,fe=F(()=>{"use strict";Pn=process.env.BADGERCLAW_ENV==="local",U=process.env.BADGERCLAW_API_URL??(Pn?"http://localhost:8000":"https://api.badger.signout.io"),On=process.env.BADGERCLAW_AUTH_URL??(Pn?"http://localhost:5500":"https://badgerclaw.ai")});function Nn(){return ct}function Xs(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),r=JSON.parse(Buffer.from(n,"base64").toString("utf8"));return(typeof r?.sub=="string"?r.sub:null)||null}catch{return null}}async function ko(){let e=h();if(!e?.refresh_token||!e?.email)return ct=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=Xs(e.access_token);try{let o=await lt.default.post(`${Dt}/api/v1/user/token/refresh`,{refresh_token:e.refresh_token,email:e.email,...t?{cognito_username:t}:{}}),n=o.data?.result??o.data,r=n?.access_token;if(!r)return ct="server returned no access_token",null;let s=n.expires_in||3600,i=new Date(Date.now()+s*1e3).toISOString();return Me({...e,access_token:r,expires_at:i}),ct=null,r}catch(o){let n=o?.response?.status,r=o?.response?.data?.errors?.[0]||o?.response?.data?.detail||o?.message||"unknown error";ct=n?`HTTP ${n}: ${r}`:`network error: ${r}`;let s=o?.response?.data?.errors?.[0]||o?.response?.data?.detail||o?.message||"";if(n===403&&Dn.test(s))throw it(),new He(s);return null}}function So(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 Tn(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(Dn.test(n))return it(),Promise.reject(new He(n))}return Promise.reject(t)}),e}function jn(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,Ot||(Ot=ko().finally(()=>{Ot=null}));let n=await Ot;return n?(o.headers.Authorization=`Bearer ${n}`,e.request(o)):Promise.reject(t)}),e}function O(){let e=h(),t={"Content-Type":"application/json"};e&&(t.Authorization=`Bearer ${e.access_token}`);let o=lt.default.create({baseURL:Dt,headers:t});return So(o),jn(o),Tn(o),o}function Bn(){return So(lt.default.create({baseURL:Dt,headers:{"Content-Type":"application/json"}}))}function te(e){let t=lt.default.create({baseURL:Dt,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`}});return So(t),jn(t),Tn(t),t}var lt,Dt,He,Dn,Ot,ct,oe=F(()=>{"use strict";lt=d(require("axios"));j();fe();Dt=U,He=class extends Error{constructor(o){super(o);this.code="DEACTIVATED";this.name="DeactivatedError"}},Dn=/account\s+has\s+been\s+(deleted|deactivated)/i,Ot=null,ct=null});function Fn(){try{let e=he.default.statSync(Re);return Date.now()-e.mtimeMs>Mn}catch{return!0}}function vo(){try{return he.default.mkdirSync($o.default.dirname(Re),{recursive:!0}),he.default.writeFileSync(Re,String(process.pid),{flag:"wx"}),!0}catch{if(Fn())try{return he.default.unlinkSync(Re),he.default.writeFileSync(Re,String(process.pid),{flag:"wx"}),!0}catch{return!1}return!1}}function Un(){try{he.default.unlinkSync(Re)}catch{}}async function Gn(e){let t=!1;for(let o=0;o<Zs;o++){if(vo()){t=!0;break}await new Promise(n=>setTimeout(n,Hn))}t||console.warn("[config-lock] Could not acquire lock after timeout \u2014 proceeding without lock");try{return await e()}finally{t&&Un()}}function Ae(e){let t=vo();if(!t&&Fn()){try{he.default.unlinkSync(Re)}catch{}t=vo()}try{return e()}finally{t&&Un()}}var he,Ln,$o,Re,Mn,Hn,Zs,dt=F(()=>{"use strict";he=d(require("fs")),Ln=d(require("os")),$o=d(require("path")),Re=$o.default.join(Ln.default.homedir(),".openclaw","openclaw.json.lock"),Mn=1e4,Hn=50,Zs=Math.ceil(Mn/Hn)});var we=zs((Bc,Qs)=>{Qs.exports={name:"badgerclaw",version:"0.2.68",engines:{node:">=18"},description:"BadgerClaw CLI \u2014 one-click bot provisioning",main:"dist/index.js",bin:{badgerclaw:"./dist/index.js"},files:["dist/","scripts/","assets/","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",preuninstall:"node scripts/preuninstall.cjs",test:"tsx --test 'tests/**/*.test.ts'"},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",tsx:"^4.22.0",typescript:"^5.3.0"}}});function Tt(e=ri){try{return Io.default.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()&&t.name.startsWith("badgerclaw-connect-")).map(t=>le.default.join(e,t.name))}catch{return[]}}function si(){return[...Tt().map(t=>le.default.join(t,"node_modules/@badgerclaw/connect/package.json")),le.default.join(ni,"package.json"),le.default.join(Wn,"node_modules/@badgerclaw/connect/package.json"),le.default.join(Wn,"package.json")]}function xo(){return"0.2.68"}function jt(){for(let e of si())try{let t=Io.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 ii(e){let t=e.trim(),o=t.match(/\d+(?:\.\d+){1,3}/);return o?o[0]:t}function J(){if((0,Co.spawnSync)("which",["openclaw"],{encoding:"utf-8"}).status!==0)return null;let t=(0,Co.spawnSync)("openclaw",["--version"],{encoding:"utf-8",timeout:3e3});return t.status!==0||!t.stdout?null:ii(t.stdout)||null}async function ai(){let e=new AbortController,t=setTimeout(()=>e.abort(),ti);try{let o=await fetch(ei,{signal:e.signal});if(!o.ok)return null;let n=await o.json(),r=n.result&&typeof n.result=="object"?n.result:n;return{cli:r.cli??"unknown",plugin:r.plugin??"unknown",supported_openclaw:r.supported_openclaw??"unknown"}}catch{return null}finally{clearTimeout(t)}}function ci(e){let t=[];if(e.cli&&e.cli!=="unknown"){let n=xo();n!==e.cli&&t.push({component:"cli",current:n,approved:e.cli})}if(!(J()!==null))return t;if(e.plugin&&e.plugin!=="unknown"){let n=jt();(n===null||n!==e.plugin)&&t.push({component:"plugin",current:n??"not installed",approved:e.plugin})}if(e.supported_openclaw&&e.supported_openclaw!=="unknown"){let n=J();(n===null||n!==e.supported_openclaw)&&t.push({component:"openclaw",current:n??"not installed",approved:e.supported_openclaw})}return t}function li(e){return e[2]}function di(e){return!e||e.startsWith("-")?!0:oi.has(e)}function ui(e){let t=[];t.push(""),t.push(ye.default.red.bold("\u2717 Unsupported versions detected")),t.push("");for(let o of e){let n=o.component.padEnd(8);t.push(` ${n} ${ye.default.yellow(o.current)} \u2192 ${ye.default.green(o.approved)} ${ye.default.dim("(supported)")}`)}return t.push(""),t.push("This command is blocked until your installation matches the supported versions."),t.push(""),t.push(ye.default.green(" To fix, run:")),t.push(ye.default.green.bold(" badgerclaw setup")),t.push(""),t.push(ye.default.dim(" (bypass temporarily: BADGERCLAW_NO_VERSION_CHECK=1 badgerclaw <cmd>)")),t.push(""),t.join(`
3
- `)}async function Vn(e){if(process.env.BADGERCLAW_NO_VERSION_CHECK)return;let t=li(e);if(di(t))return;let o=await ai();if(!o)return;let n=ci(o);n.length!==0&&(process.stderr.write(ui(n)),process.exit(1))}var Io,Nt,le,Co,ye,ei,ti,oi,Wn,ni,ri,Fe=F(()=>{"use strict";Io=d(require("fs")),Nt=d(require("os")),le=d(require("path")),Co=require("child_process"),ye=d(require("chalk"));fe();ei=`${U}/api/v1/dashboard/versions/latest`,ti=2500,oi=new Set(["setup","logout","help","--version","-V","--help","-h","heartbeat","watch","autopair"]),Wn=le.default.join(Nt.default.homedir(),".openclaw/extensions/badgerclaw"),ni=le.default.join(Nt.default.homedir(),".openclaw/npm/node_modules/@badgerclaw/connect"),ri=le.default.join(Nt.default.homedir(),".openclaw/npm/projects")});var zn={};wo(zn,{HERMES_IMAGE_DEFAULT:()=>Ue,detectCapabilities:()=>be,detectDiskFreeGb:()=>Yn,detectDocker:()=>Bt,detectHermes:()=>Lt,detectOpenClaw:()=>Jn});function Bt(){if((0,ut.spawnSync)("which",["docker"],{encoding:"utf-8"}).status!==0)return{installed:!1};let t=(0,ut.spawnSync)("docker",["version","--format","{{.Server.Version}}"],{encoding:"utf-8",timeout:3e3});return t.status!==0||!t.stdout.trim()?{installed:!1}:{installed:!0,version:t.stdout.trim()}}function Jn(){let e=J();return e?{installed:!0,version:e}:{installed:!1}}function Lt(e){if(!e.installed)return{installed:!1};let t=process.env.HERMES_IMAGE||Ue;return(0,ut.spawnSync)("docker",["image","inspect","--format","{{.RepoDigests}}",t],{encoding:"utf-8",timeout:3e3}).status!==0?{installed:!1}:{installed:!0,image:t}}function Yn(){let e=Kn.default.join(Ro.default.homedir(),".badgerclaw"),t=qn.default.existsSync(e)?e:Ro.default.homedir();if(process.platform==="win32")return null;let o=(0,ut.spawnSync)("df",["-Pk",t],{encoding:"utf-8",timeout:3e3});if(o.status!==0||!o.stdout)return null;let n=o.stdout.trim().split(`
2
+ "use strict";var Vs=Object.create;var Rt=Object.defineProperty;var qs=Object.getOwnPropertyDescriptor;var Ks=Object.getOwnPropertyNames;var Js=Object.getPrototypeOf,Ys=Object.prototype.hasOwnProperty;var F=(e,t)=>()=>(e&&(t=e(e=0)),t);var zs=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),wo=(e,t)=>{for(var o in t)Rt(e,o,{get:t[o],enumerable:!0})},$n=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Ks(t))!Ys.call(e,r)&&r!==o&&Rt(e,r,{get:()=>t[r],enumerable:!(n=qs(t,r))||n.enumerable});return e};var d=(e,t,o)=>(o=e!=null?Vs(Js(e)):{},$n(t||!e||!e.__esModule?Rt(o,"default",{value:e,enumerable:!0}):o,e)),Cn=e=>$n(Rt({},"__esModule",{value:!0}),e);function h(){try{let e=st.default.readFileSync(_o,"utf-8");return JSON.parse(e)}catch{return null}}function Me(e){st.default.mkdirSync(An,{recursive:!0}),st.default.writeFileSync(_o,JSON.stringify(e,null,2),{mode:384})}function it(){try{st.default.unlinkSync(_o)}catch{}}function At(){let e=h();return e?new Date(e.expires_at)>new Date:!1}function Et(e){let t=e.match(/^@?([^:]+)/);return t?t[1]:e}var st,bo,Rn,An,_o,j=F(()=>{"use strict";st=d(require("fs")),bo=d(require("path")),Rn=d(require("os")),An=bo.default.join(Rn.default.homedir(),".badgerclaw"),_o=bo.default.join(An,"auth.json")});function at(){return En.default.createHash("sha256").update(`${ee.default.hostname()}-${ee.default.platform()}-${ee.default.arch()}`).digest("hex").slice(0,16)}function te(){let e=h();if(e?.instance_id)return e.instance_id;let t=at();return`openclaw-${ee.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${t}`}function Pt(){return{hostname:ee.default.hostname(),os:ee.default.platform(),arch:ee.default.arch(),uptimeSeconds:Math.floor(ee.default.uptime()),memFreeMb:Math.floor(ee.default.freemem()/1024/1024)}}var ee,En,xe=F(()=>{"use strict";ee=d(require("os")),En=d(require("crypto"));j()});var Pn,U,On,fe=F(()=>{"use strict";Pn=process.env.BADGERCLAW_ENV==="local",U=process.env.BADGERCLAW_API_URL??(Pn?"http://localhost:8000":"https://api.badger.signout.io"),On=process.env.BADGERCLAW_AUTH_URL??(Pn?"http://localhost:5500":"https://badgerclaw.ai")});function Nn(){return ct}function Xs(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),r=JSON.parse(Buffer.from(n,"base64").toString("utf8"));return(typeof r?.sub=="string"?r.sub:null)||null}catch{return null}}async function ko(){let e=h();if(!e?.refresh_token||!e?.email)return ct=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=Xs(e.access_token);try{let o=await lt.default.post(`${Dt}/api/v1/user/token/refresh`,{refresh_token:e.refresh_token,email:e.email,...t?{cognito_username:t}:{}}),n=o.data?.result??o.data,r=n?.access_token;if(!r)return ct="server returned no access_token",null;let s=n.expires_in||3600,i=new Date(Date.now()+s*1e3).toISOString();return Me({...e,access_token:r,expires_at:i}),ct=null,r}catch(o){let n=o?.response?.status,r=o?.response?.data?.errors?.[0]||o?.response?.data?.detail||o?.message||"unknown error";ct=n?`HTTP ${n}: ${r}`:`network error: ${r}`;let s=o?.response?.data?.errors?.[0]||o?.response?.data?.detail||o?.message||"";if(n===403&&Dn.test(s))throw it(),new He(s);return null}}function So(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 Tn(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(Dn.test(n))return it(),Promise.reject(new He(n))}return Promise.reject(t)}),e}function jn(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,Ot||(Ot=ko().finally(()=>{Ot=null}));let n=await Ot;return n?(o.headers.Authorization=`Bearer ${n}`,e.request(o)):Promise.reject(t)}),e}function O(){let e=h(),t={"Content-Type":"application/json"};e&&(t.Authorization=`Bearer ${e.access_token}`);let o=lt.default.create({baseURL:Dt,headers:t});return So(o),jn(o),Tn(o),o}function Bn(){return So(lt.default.create({baseURL:Dt,headers:{"Content-Type":"application/json"}}))}function J(e){let t=lt.default.create({baseURL:Dt,headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`}});return So(t),jn(t),Tn(t),t}var lt,Dt,He,Dn,Ot,ct,oe=F(()=>{"use strict";lt=d(require("axios"));j();fe();Dt=U,He=class extends Error{constructor(o){super(o);this.code="DEACTIVATED";this.name="DeactivatedError"}},Dn=/account\s+has\s+been\s+(deleted|deactivated)/i,Ot=null,ct=null});function Fn(){try{let e=he.default.statSync(Re);return Date.now()-e.mtimeMs>Mn}catch{return!0}}function vo(){try{return he.default.mkdirSync($o.default.dirname(Re),{recursive:!0}),he.default.writeFileSync(Re,String(process.pid),{flag:"wx"}),!0}catch{if(Fn())try{return he.default.unlinkSync(Re),he.default.writeFileSync(Re,String(process.pid),{flag:"wx"}),!0}catch{return!1}return!1}}function Un(){try{he.default.unlinkSync(Re)}catch{}}async function Gn(e){let t=!1;for(let o=0;o<Zs;o++){if(vo()){t=!0;break}await new Promise(n=>setTimeout(n,Hn))}t||console.warn("[config-lock] Could not acquire lock after timeout \u2014 proceeding without lock");try{return await e()}finally{t&&Un()}}function Ae(e){let t=vo();if(!t&&Fn()){try{he.default.unlinkSync(Re)}catch{}t=vo()}try{return e()}finally{t&&Un()}}var he,Ln,$o,Re,Mn,Hn,Zs,dt=F(()=>{"use strict";he=d(require("fs")),Ln=d(require("os")),$o=d(require("path")),Re=$o.default.join(Ln.default.homedir(),".openclaw","openclaw.json.lock"),Mn=1e4,Hn=50,Zs=Math.ceil(Mn/Hn)});var we=zs((Lc,Qs)=>{Qs.exports={name:"badgerclaw",version:"0.2.69",engines:{node:">=18"},description:"BadgerClaw CLI \u2014 one-click bot provisioning",main:"dist/index.js",bin:{badgerclaw:"./dist/index.js"},files:["dist/","scripts/","assets/","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",preuninstall:"node scripts/preuninstall.cjs",test:"tsx --test 'tests/**/*.test.ts'"},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",tsx:"^4.22.0",typescript:"^5.3.0"}}});function Tt(e=ri){try{return Io.default.readdirSync(e,{withFileTypes:!0}).filter(t=>t.isDirectory()&&t.name.startsWith("badgerclaw-connect-")).map(t=>le.default.join(e,t.name))}catch{return[]}}function si(){return[...Tt().map(t=>le.default.join(t,"node_modules/@badgerclaw/connect/package.json")),le.default.join(ni,"package.json"),le.default.join(Wn,"node_modules/@badgerclaw/connect/package.json"),le.default.join(Wn,"package.json")]}function xo(){return"0.2.69"}function jt(){for(let e of si())try{let t=Io.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 ii(e){let t=e.trim(),o=t.match(/\d+(?:\.\d+){1,3}/);return o?o[0]:t}function Y(){if((0,Co.spawnSync)("which",["openclaw"],{encoding:"utf-8"}).status!==0)return null;let t=(0,Co.spawnSync)("openclaw",["--version"],{encoding:"utf-8",timeout:3e3});return t.status!==0||!t.stdout?null:ii(t.stdout)||null}async function ai(){let e=new AbortController,t=setTimeout(()=>e.abort(),ti);try{let o=await fetch(ei,{signal:e.signal});if(!o.ok)return null;let n=await o.json(),r=n.result&&typeof n.result=="object"?n.result:n;return{cli:r.cli??"unknown",plugin:r.plugin??"unknown",supported_openclaw:r.supported_openclaw??"unknown"}}catch{return null}finally{clearTimeout(t)}}function ci(e){let t=[];if(e.cli&&e.cli!=="unknown"){let n=xo();n!==e.cli&&t.push({component:"cli",current:n,approved:e.cli})}if(!(Y()!==null))return t;if(e.plugin&&e.plugin!=="unknown"){let n=jt();(n===null||n!==e.plugin)&&t.push({component:"plugin",current:n??"not installed",approved:e.plugin})}if(e.supported_openclaw&&e.supported_openclaw!=="unknown"){let n=Y();(n===null||n!==e.supported_openclaw)&&t.push({component:"openclaw",current:n??"not installed",approved:e.supported_openclaw})}return t}function li(e){return e[2]}function di(e){return!e||e.startsWith("-")?!0:oi.has(e)}function ui(e){let t=[];t.push(""),t.push(ye.default.red.bold("\u2717 Unsupported versions detected")),t.push("");for(let o of e){let n=o.component.padEnd(8);t.push(` ${n} ${ye.default.yellow(o.current)} \u2192 ${ye.default.green(o.approved)} ${ye.default.dim("(supported)")}`)}return t.push(""),t.push("This command is blocked until your installation matches the supported versions."),t.push(""),t.push(ye.default.green(" To fix, run:")),t.push(ye.default.green.bold(" badgerclaw setup")),t.push(""),t.push(ye.default.dim(" (bypass temporarily: BADGERCLAW_NO_VERSION_CHECK=1 badgerclaw <cmd>)")),t.push(""),t.join(`
3
+ `)}async function Vn(e){if(process.env.BADGERCLAW_NO_VERSION_CHECK)return;let t=li(e);if(di(t))return;let o=await ai();if(!o)return;let n=ci(o);n.length!==0&&(process.stderr.write(ui(n)),process.exit(1))}var Io,Nt,le,Co,ye,ei,ti,oi,Wn,ni,ri,Fe=F(()=>{"use strict";Io=d(require("fs")),Nt=d(require("os")),le=d(require("path")),Co=require("child_process"),ye=d(require("chalk"));fe();ei=`${U}/api/v1/dashboard/versions/latest`,ti=2500,oi=new Set(["setup","logout","help","--version","-V","--help","-h","heartbeat","watch","autopair"]),Wn=le.default.join(Nt.default.homedir(),".openclaw/extensions/badgerclaw"),ni=le.default.join(Nt.default.homedir(),".openclaw/npm/node_modules/@badgerclaw/connect"),ri=le.default.join(Nt.default.homedir(),".openclaw/npm/projects")});var zn={};wo(zn,{HERMES_IMAGE_DEFAULT:()=>Ue,detectCapabilities:()=>be,detectDiskFreeGb:()=>Yn,detectDocker:()=>Bt,detectHermes:()=>Lt,detectOpenClaw:()=>Jn});function Bt(){if((0,ut.spawnSync)("which",["docker"],{encoding:"utf-8"}).status!==0)return{installed:!1};let t=(0,ut.spawnSync)("docker",["version","--format","{{.Server.Version}}"],{encoding:"utf-8",timeout:3e3});return t.status!==0||!t.stdout.trim()?{installed:!1}:{installed:!0,version:t.stdout.trim()}}function Jn(){let e=Y();return e?{installed:!0,version:e}:{installed:!1}}function Lt(e){if(!e.installed)return{installed:!1};let t=process.env.HERMES_IMAGE||Ue;return(0,ut.spawnSync)("docker",["image","inspect","--format","{{.RepoDigests}}",t],{encoding:"utf-8",timeout:3e3}).status!==0?{installed:!1}:{installed:!0,image:t}}function Yn(){let e=Kn.default.join(Ro.default.homedir(),".badgerclaw"),t=qn.default.existsSync(e)?e:Ro.default.homedir();if(process.platform==="win32")return null;let o=(0,ut.spawnSync)("df",["-Pk",t],{encoding:"utf-8",timeout:3e3});if(o.status!==0||!o.stdout)return null;let n=o.stdout.trim().split(`
4
4
  `);if(n.length<2)return null;let r=n[1].split(/\s+/),s=parseInt(r[3]||"",10);return Number.isFinite(s)?Math.floor(s/1024/1024):null}function be(){let e=Bt();return{openclaw:Jn(),hermes:Lt(e),docker:e,disk_free_gb:Yn(),ports_in_use:[]}}var ut,qn,Ro,Kn,Ue,Ee=F(()=>{"use strict";ut=require("child_process"),qn=d(require("fs")),Ro=d(require("os")),Kn=d(require("path"));Fe();Ue="hermes-agent-bc:bundled"});function Ht(e){return ne.default.join(mi,`bot-${e}`)}function Eo(e){return`badgerclaw-hermes-bot-${e}`}function Po(){if(!B.default.existsSync(Ao))return{hermes_bots:{}};try{let e=B.default.readFileSync(Ao,"utf-8"),t=JSON.parse(e);return{hermes_bots:t.hermes_bots&&typeof t.hermes_bots=="object"?t.hermes_bots:{}}}catch{return{hermes_bots:{}}}}function gi(e){B.default.existsSync(Mt)||B.default.mkdirSync(Mt,{recursive:!0,mode:448}),B.default.writeFileSync(Ao,JSON.stringify(e,null,2)+`
5
5
  `,{mode:384})}function fi(e,t=pi){let o=new Set(Object.values(e.hermes_bots).map(r=>r.port)),n=t;for(;o.has(n)||!hi(n);)if(n+=1,n-t>1e3)throw new Error(`Could not find a free port near ${t} after 1000 tries \u2014 host is unusually busy`);return n}function hi(e){let t=Qn.default.createServer(),o=!1;try{t.listen(e,"127.0.0.1"),o=!0}catch{o=!1}finally{try{t.close()}catch{}}return o}function tr(e=process.env){let t=e.BADGERCLAW_LLM_PROVIDER?.toLowerCase(),o=e.BADGERCLAW_LLM_API_KEY;if(t&&o){if(t!=="gemini"&&t!=="anthropic"&&t!=="openrouter")throw new Error(`BADGERCLAW_LLM_PROVIDER must be one of: gemini, anthropic, openrouter. Got '${t}'.`);return{provider:t,apiKey:o}}let n=e.GOOGLE_API_KEY||e.GEMINI_API_KEY;if(n)return{provider:"gemini",apiKey:n};if(e.ANTHROPIC_API_KEY)return{provider:"anthropic",apiKey:e.ANTHROPIC_API_KEY};if(e.OPENROUTER_API_KEY)return{provider:"openrouter",apiKey:e.OPENROUTER_API_KEY}}function wi(e){switch(e){case"gemini":return"gemini-2.5-flash";case"anthropic":return"claude-sonnet-4-6";case"openrouter":return"anthropic/claude-sonnet-4-6"}}function yi(e){switch(e){case"gemini":return"GOOGLE_API_KEY";case"anthropic":return"ANTHROPIC_API_KEY";case"openrouter":return"OPENROUTER_API_KEY"}}function bi(e,t){let o=[`# Generated by badgerclaw CLI for bot ${e.botId}.`,"# Edit at your own risk; subsequent pair operations may overwrite.","",`MATRIX_HOMESERVER=${e.matrixHomeserver}`,`MATRIX_ACCESS_TOKEN=${e.matrixAccessToken}`,`MATRIX_USER_ID=${e.matrixUserId}`,`MATRIX_DEVICE_ID=${e.matrixDeviceId}`,"MATRIX_ENCRYPTION=true",`MATRIX_ALLOWED_USERS=${e.ownerMatrixUserId}`];return e.homeRoomId&&o.push(`MATRIX_HOME_ROOM=${e.homeRoomId}`),e.llm&&(o.push(""),o.push("# LLM provider \u2014 set by the operator's environment at pair time."),o.push("# Hermes reads this directly; model selection lives in config.yaml."),o.push(`${yi(e.llm.provider)}=${e.llm.apiKey}`)),o.push("","# OpenAI-compatible API surface \u2014 localhost only by default so the","# CLI's daemon can health-check the container without exposing it","# beyond the host loopback.","API_SERVER_ENABLED=true","API_SERVER_HOST=127.0.0.1",`API_SERVER_PORT=${t}`,`API_SERVER_KEY=${(0,Zn.randomBytes)(24).toString("hex")}`),o.join(`
6
6
  `)+`
@@ -12,9 +12,9 @@ ${i.stderr}`,c=Ci(a);if(!c)return r;if(r.recoveryKey=c,n.api)try{let u=await n.a
12
12
  # Hermes re-uses this on restart to re-sign the device after
13
13
  # Synapse rotates server keys.
14
14
  MATRIX_RECOVERY_KEY=${c}
15
- `),r.envUpdated=!0)),r}async function rr(e={}){let t=Po(),o=[];for(let[n,r]of Object.entries(t.hermes_bots)){let s=ne.default.join(r.data_dir,".env"),i=!1;try{B.default.existsSync(s)&&(i=B.default.readFileSync(s,"utf-8").includes("MATRIX_RECOVERY_KEY="))}catch{}if(i){o.push({bot_id:n,attempted:!1,recoveryKeyFound:!0,posted:!1,envUpdated:!1});continue}if(n.startsWith("@")){o.push({bot_id:n,attempted:!1,recoveryKeyFound:!1,posted:!1,envUpdated:!1});continue}try{let a=await Do({botId:n,backendBotId:n},r.container_name,r.image,{docker:e.docker,api:e.api,envPath:s});o.push({bot_id:n,attempted:!0,recoveryKeyFound:a.recoveryKey!==null,posted:a.posted,envUpdated:a.envUpdated})}catch(a){console.warn(`[hermes] recovery-key retry failed for ${n}: ${a.message}`),o.push({bot_id:n,attempted:!0,recoveryKeyFound:!1,posted:!1,envUpdated:!1})}}return o}var Xn,Zn,B,Qn,er,ne,Mt,mi,Ao,pi,Ft,$i,Gt=F(()=>{"use strict";Xn=require("child_process"),Zn=require("crypto"),B=d(require("fs")),Qn=d(require("net")),er=d(require("os")),ne=d(require("path"));Ee();Mt=ne.default.join(er.default.homedir(),".badgerclaw"),mi=ne.default.join(Mt,"hermes"),Ao=ne.default.join(Mt,"state.json"),pi=8642,Ft={run:e=>{let t=(0,Xn.spawnSync)("docker",e,{encoding:"utf-8"});return{status:t.status,stdout:t.stdout||"",stderr:t.stderr||""}}};$i=/SAVE THIS RECOVERY KEY[\s\S]*?key rotation:\s+((?:[A-Za-z0-9]{4}\s+){7,}[A-Za-z0-9]{4})/});function Wt(e){return`'${e.replace(/'/g,"'\\''")}'`}function Ii(){if(_e!==null)return _e;let e=["/opt/homebrew/lib/node_modules/openclaw/openclaw.mjs","/usr/local/lib/node_modules/openclaw/openclaw.mjs","/usr/lib/node_modules/openclaw/openclaw.mjs"];for(let t of e)if(mt.default.existsSync(t))return _e=`${Wt(process.execPath)} ${Wt(t)}`,_e;try{let{execSync:t}=require("child_process"),o=t("npm root -g",{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]}).toString().trim();if(o){let n=jo.default.join(o,"openclaw","openclaw.mjs");if(mt.default.existsSync(n))return _e=`${Wt(process.execPath)} ${Wt(n)}`,_e}}catch{}return _e="openclaw",_e}function No(e,t,o){t?t.fail(Y.default.red(o)):e&&console.error(`[autopair] ${o}`)}async function xi(e){if(!e.owner_matrix_user_id)throw new Error("Hermes redeem response missing owner_matrix_user_id. Update the API or fall back to OpenClaw runtime for this bot.");let t=e.user_id.replace(/[^a-zA-Z0-9_.-]/g,"_"),o={botId:e.bot_id??t,backendBotId:e.bot_id??void 0,matrixHomeserver:e.homeserver,matrixAccessToken:e.access_token,matrixUserId:e.user_id,matrixDeviceId:e.device_id,ownerMatrixUserId:e.owner_matrix_user_id,botName:e.bot_name,llm:tr()},n=or(o);if(o.backendBotId){let r=h();if(r){let s=te(r.access_token);try{await Do(o,Eo(o.botId),n.image,{api:{post:async(i,a)=>{let c=await s.post(i,a);return{status:c.status,data:c.data}}}})}catch(i){console.warn(`[hermes] recovery key capture failed for ${o.botId}: ${i.message}. Daemon will retry next beat.`)}}}}async function pt(e,t,o,n){let r=h();if(!r)return;let s=n?null:(0,To.default)(`Pairing bot: ${t}...`).start();try{let i=await fetch(`${U}/api/v1/pairing/redeem`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:e,instance_id:ee()})});if(!i.ok){if(i.status===410){s?.info(Y.default.dim(`${t} already paired (race-loss; another channel redeemed first).`));return}let u=await i.json().catch(()=>({errors:[i.statusText]}));No(n,s,`Failed to redeem ${t}: ${u.errors?.[0]||i.status}`);return}let a=await i.json(),c=a.result??a;if((c.runtime??"openclaw")==="hermes"){try{await xi(c),s?.succeed(Y.default.green(`\u2705 ${c.bot_name} (${c.user_id}) running on Hermes \u2014 bot is live!`))}catch(u){No(n,s,`Failed to start Hermes container for ${t}: ${u.message}`)}return}await Gn(async()=>{let u=c.user_id.split(":")[0].replace("@","").replace(/_bot$/,""),p;try{p=JSON.parse(mt.default.readFileSync(sr,"utf-8"))}catch{p={}}p.channels||(p.channels={}),p.channels.badgerclaw||(p.channels.badgerclaw={}),p.channels.badgerclaw.accounts||(p.channels.badgerclaw.accounts={});let A={userId:c.user_id,accessToken:c.access_token,homeserver:c.homeserver,encryption:!0,groupPolicy:"open",allowlistOnly:!1,dm:{policy:"open"}};c.device_id&&(A.deviceId=c.device_id),p.channels.badgerclaw.accounts[u]=A,mt.default.writeFileSync(sr,JSON.stringify(p,null,2),{mode:384})}),await fetch(`${U}/api/v1/openclaw/pending-pairs/${e}/claim`,{method:"POST",headers:{Authorization:`Bearer ${r.access_token}`}}).catch(()=>{}),s?.succeed(Y.default.green(`\u2705 ${c.bot_name} (${c.user_id}) paired \u2014 bot is live!`))}catch(i){No(n,s,`Failed to pair ${t}: ${i.message}`)}}async function gt(e=!1){let t=h();if(!t)return 0;let o=te(t.access_token);try{let{data:n}=await o.get("/api/v1/openclaw/pending-pairs");if(!n||n.length===0)return 0;let r=new Map;for(let i of n)r.set(i.bot_user_id,i);for(let i of n)r.get(i.bot_user_id)!==i&&await o.post(`/api/v1/openclaw/pending-pairs/${i.pair_code}/claim`).catch(()=>{});let s=0;for(let i of r.values()){let a=e?null:(0,To.default)(`Pairing bot: ${i.bot_name} (${i.bot_user_id})`).start();try{await pt(i.pair_code,i.bot_name,i.bot_user_id,e),await o.post(`/api/v1/openclaw/pending-pairs/${i.pair_code}/claim`).catch(()=>{}),s++}catch(c){a?.fail(Y.default.red(`Error pairing ${i.bot_name}: ${c}`))}}if(s>0)try{let{execSync:i}=await import("child_process");i(`${Ii()} gateway restart`,{stdio:"ignore"}),e||console.log(Y.default.green(`
16
- \u26A1 ${s} bot(s) paired \u2014 gateway restarted, bots are live!`))}catch(i){e?console.error(`[autopair] gateway restart after pair failed: ${i?.message||i}`):console.log(Y.default.yellow(`
17
- \u26A1 ${s} bot(s) paired. Run: openclaw gateway restart`))}return s}catch{return 0}}var ir,Y,To,ar,jo,mt,sr,_e,cr,ft=F(()=>{"use strict";ir=require("commander"),Y=d(require("chalk")),To=d(require("ora")),ar=d(require("os")),jo=d(require("path")),mt=d(require("fs"));j();oe();fe();xe();dt();Gt();sr=jo.default.join(ar.default.homedir(),".openclaw","openclaw.json");_e=null;cr=new ir.Command("autopair").description("Check for pending bot pairs and connect them to OpenClaw automatically").action(async()=>{if(!h()){console.log(Y.default.yellow("Not logged in. Run `badgerclaw login` first."));return}console.log(Y.default.dim("Checking for pending bot pairs...")),await gt(!1)===0&&console.log(Y.default.dim("No pending pairs found."))})});async function Go(){try{return await Jt.default.get(qi,{timeout:2e3,validateStatus:()=>!0}),!0}catch{return!1}}async function bt(){try{let t=(await Jt.default.get(`${_r}/health`,{timeout:5e3})).data;return t.pluginVersion&&t.pluginVersion!=="unknown"&&(Uo=t.pluginVersion),t}catch{return{status:await Go()?"running":"stopped",pid:null,lastRestart:null,pluginVersion:Uo,bots:[]}}}function Wo(e){e&&e!=="unknown"&&(Uo=e)}async function Je(){try{return{success:!0,message:(await Jt.default.post(`${_r}/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 Jt,Wi,_r,Vi,qi,Uo,ke=F(()=>{"use strict";Jt=d(require("axios")),Wi=7331,_r=`http://localhost:${Wi}`,Vi=parseInt(process.env.OPENCLAW_GATEWAY_PORT||"",10)||18789,qi=`http://127.0.0.1:${Vi}`,Uo="unknown"});var on={};wo(on,{getActiveSessions:()=>tn,launchClaudeCode:()=>Zo,launchMCPServer:()=>Xo,recordSession:()=>Qo,stopSession:()=>en});function Ko(){try{if(M.default.existsSync(qo))return JSON.parse(M.default.readFileSync(qo,"utf-8"))}catch{}return[]}function Jo(e){M.default.mkdirSync(De,{recursive:!0}),M.default.writeFileSync(qo,JSON.stringify(e,null,2))}function Zt(e){try{return process.kill(e,0),!0}catch{return!1}}function zi(){if(process.env.TMUX)return"tmux";try{if((0,de.execSync)(`osascript -e 'tell application "System Events" to (name of processes) contains "iTerm2"'`,{stdio:"pipe",timeout:3e3}),M.default.existsSync("/Applications/iTerm.app"))return"iterm2"}catch{}return process.platform==="darwin"?"terminal":"direct"}function Yo(e,t){let o=q.default.join(De,`claude-launcher-${t}.exp`),n=q.default.join(De,`pending-input-${t}.txt`);M.default.writeFileSync(n,"","utf-8");let r=`#!/usr/bin/expect -f
15
+ `),r.envUpdated=!0)),r}async function rr(e={}){let t=Po(),o=[];for(let[n,r]of Object.entries(t.hermes_bots)){let s=ne.default.join(r.data_dir,".env"),i=!1;try{B.default.existsSync(s)&&(i=B.default.readFileSync(s,"utf-8").includes("MATRIX_RECOVERY_KEY="))}catch{}if(i){o.push({bot_id:n,attempted:!1,recoveryKeyFound:!0,posted:!1,envUpdated:!1});continue}if(n.startsWith("@")){o.push({bot_id:n,attempted:!1,recoveryKeyFound:!1,posted:!1,envUpdated:!1});continue}try{let a=await Do({botId:n,backendBotId:n},r.container_name,r.image,{docker:e.docker,api:e.api,envPath:s});o.push({bot_id:n,attempted:!0,recoveryKeyFound:a.recoveryKey!==null,posted:a.posted,envUpdated:a.envUpdated})}catch(a){console.warn(`[hermes] recovery-key retry failed for ${n}: ${a.message}`),o.push({bot_id:n,attempted:!0,recoveryKeyFound:!1,posted:!1,envUpdated:!1})}}return o}var Xn,Zn,B,Qn,er,ne,Mt,mi,Ao,pi,Ft,$i,Gt=F(()=>{"use strict";Xn=require("child_process"),Zn=require("crypto"),B=d(require("fs")),Qn=d(require("net")),er=d(require("os")),ne=d(require("path"));Ee();Mt=ne.default.join(er.default.homedir(),".badgerclaw"),mi=ne.default.join(Mt,"hermes"),Ao=ne.default.join(Mt,"state.json"),pi=8642,Ft={run:e=>{let t=(0,Xn.spawnSync)("docker",e,{encoding:"utf-8"});return{status:t.status,stdout:t.stdout||"",stderr:t.stderr||""}}};$i=/SAVE THIS RECOVERY KEY[\s\S]*?key rotation:\s+((?:[A-Za-z0-9]{4}\s+){7,}[A-Za-z0-9]{4})/});function Wt(e){return`'${e.replace(/'/g,"'\\''")}'`}function Ii(){if(_e!==null)return _e;let e=["/opt/homebrew/lib/node_modules/openclaw/openclaw.mjs","/usr/local/lib/node_modules/openclaw/openclaw.mjs","/usr/lib/node_modules/openclaw/openclaw.mjs"];for(let t of e)if(mt.default.existsSync(t))return _e=`${Wt(process.execPath)} ${Wt(t)}`,_e;try{let{execSync:t}=require("child_process"),o=t("npm root -g",{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]}).toString().trim();if(o){let n=jo.default.join(o,"openclaw","openclaw.mjs");if(mt.default.existsSync(n))return _e=`${Wt(process.execPath)} ${Wt(n)}`,_e}}catch{}return _e="openclaw",_e}function No(e,t,o){t?t.fail(z.default.red(o)):e&&console.error(`[autopair] ${o}`)}async function xi(e){if(!e.owner_matrix_user_id)throw new Error("Hermes redeem response missing owner_matrix_user_id. Update the API or fall back to OpenClaw runtime for this bot.");let t=e.user_id.replace(/[^a-zA-Z0-9_.-]/g,"_"),o={botId:e.bot_id??t,backendBotId:e.bot_id??void 0,matrixHomeserver:e.homeserver,matrixAccessToken:e.access_token,matrixUserId:e.user_id,matrixDeviceId:e.device_id,ownerMatrixUserId:e.owner_matrix_user_id,botName:e.bot_name,llm:tr()},n=or(o);if(o.backendBotId){let r=h();if(r){let s=J(r.access_token);try{await Do(o,Eo(o.botId),n.image,{api:{post:async(i,a)=>{let c=await s.post(i,a);return{status:c.status,data:c.data}}}})}catch(i){console.warn(`[hermes] recovery key capture failed for ${o.botId}: ${i.message}. Daemon will retry next beat.`)}}}}async function pt(e,t,o,n){let r=h();if(!r)return;let s=n?null:(0,To.default)(`Pairing bot: ${t}...`).start();try{let i=await fetch(`${U}/api/v1/pairing/redeem`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:e,instance_id:te()})});if(!i.ok){if(i.status===410){s?.info(z.default.dim(`${t} already paired (race-loss; another channel redeemed first).`));return}let u=await i.json().catch(()=>({errors:[i.statusText]}));No(n,s,`Failed to redeem ${t}: ${u.errors?.[0]||i.status}`);return}let a=await i.json(),c=a.result??a;if((c.runtime??"openclaw")==="hermes"){try{await xi(c),s?.succeed(z.default.green(`\u2705 ${c.bot_name} (${c.user_id}) running on Hermes \u2014 bot is live!`))}catch(u){No(n,s,`Failed to start Hermes container for ${t}: ${u.message}`)}return}await Gn(async()=>{let u=c.user_id.split(":")[0].replace("@","").replace(/_bot$/,""),p;try{p=JSON.parse(mt.default.readFileSync(sr,"utf-8"))}catch{p={}}p.channels||(p.channels={}),p.channels.badgerclaw||(p.channels.badgerclaw={}),p.channels.badgerclaw.accounts||(p.channels.badgerclaw.accounts={});let A={userId:c.user_id,accessToken:c.access_token,homeserver:c.homeserver,encryption:!0,groupPolicy:"open",allowlistOnly:!1,dm:{policy:"open"}};c.device_id&&(A.deviceId=c.device_id),p.channels.badgerclaw.accounts[u]=A,mt.default.writeFileSync(sr,JSON.stringify(p,null,2),{mode:384})}),await fetch(`${U}/api/v1/openclaw/pending-pairs/${e}/claim`,{method:"POST",headers:{Authorization:`Bearer ${r.access_token}`}}).catch(()=>{}),s?.succeed(z.default.green(`\u2705 ${c.bot_name} (${c.user_id}) paired \u2014 bot is live!`))}catch(i){No(n,s,`Failed to pair ${t}: ${i.message}`)}}async function gt(e=!1){let t=h();if(!t)return 0;let o=J(t.access_token);try{let{data:n}=await o.get("/api/v1/openclaw/pending-pairs");if(!n||n.length===0)return 0;let r=new Map;for(let i of n)r.set(i.bot_user_id,i);for(let i of n)r.get(i.bot_user_id)!==i&&await o.post(`/api/v1/openclaw/pending-pairs/${i.pair_code}/claim`).catch(()=>{});let s=0;for(let i of r.values()){let a=e?null:(0,To.default)(`Pairing bot: ${i.bot_name} (${i.bot_user_id})`).start();try{await pt(i.pair_code,i.bot_name,i.bot_user_id,e),await o.post(`/api/v1/openclaw/pending-pairs/${i.pair_code}/claim`).catch(()=>{}),s++}catch(c){a?.fail(z.default.red(`Error pairing ${i.bot_name}: ${c}`))}}if(s>0)try{let{execSync:i}=await import("child_process");i(`${Ii()} gateway restart`,{stdio:"ignore"}),e||console.log(z.default.green(`
16
+ \u26A1 ${s} bot(s) paired \u2014 gateway restarted, bots are live!`))}catch(i){e?console.error(`[autopair] gateway restart after pair failed: ${i?.message||i}`):console.log(z.default.yellow(`
17
+ \u26A1 ${s} bot(s) paired. Run: openclaw gateway restart`))}return s}catch{return 0}}var ir,z,To,ar,jo,mt,sr,_e,cr,ft=F(()=>{"use strict";ir=require("commander"),z=d(require("chalk")),To=d(require("ora")),ar=d(require("os")),jo=d(require("path")),mt=d(require("fs"));j();oe();fe();xe();dt();Gt();sr=jo.default.join(ar.default.homedir(),".openclaw","openclaw.json");_e=null;cr=new ir.Command("autopair").description("Check for pending bot pairs and connect them to OpenClaw automatically").action(async()=>{if(!h()){console.log(z.default.yellow("Not logged in. Run `badgerclaw login` first."));return}console.log(z.default.dim("Checking for pending bot pairs...")),await gt(!1)===0&&console.log(z.default.dim("No pending pairs found."))})});async function Go(){try{return await Jt.default.get(qi,{timeout:2e3,validateStatus:()=>!0}),!0}catch{return!1}}async function bt(){try{let t=(await Jt.default.get(`${_r}/health`,{timeout:5e3})).data;return t.pluginVersion&&t.pluginVersion!=="unknown"&&(Uo=t.pluginVersion),t}catch{return{status:await Go()?"running":"stopped",pid:null,lastRestart:null,pluginVersion:Uo,bots:[]}}}function Wo(e){e&&e!=="unknown"&&(Uo=e)}async function Je(){try{return{success:!0,message:(await Jt.default.post(`${_r}/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 Jt,Wi,_r,Vi,qi,Uo,ke=F(()=>{"use strict";Jt=d(require("axios")),Wi=7331,_r=`http://localhost:${Wi}`,Vi=parseInt(process.env.OPENCLAW_GATEWAY_PORT||"",10)||18789,qi=`http://127.0.0.1:${Vi}`,Uo="unknown"});var on={};wo(on,{getActiveSessions:()=>tn,launchClaudeCode:()=>Zo,launchMCPServer:()=>Xo,recordSession:()=>Qo,stopSession:()=>en});function Ko(){try{if(M.default.existsSync(qo))return JSON.parse(M.default.readFileSync(qo,"utf-8"))}catch{}return[]}function Jo(e){M.default.mkdirSync(De,{recursive:!0}),M.default.writeFileSync(qo,JSON.stringify(e,null,2))}function Zt(e){try{return process.kill(e,0),!0}catch{return!1}}function zi(){if(process.env.TMUX)return"tmux";try{if((0,de.execSync)(`osascript -e 'tell application "System Events" to (name of processes) contains "iTerm2"'`,{stdio:"pipe",timeout:3e3}),M.default.existsSync("/Applications/iTerm.app"))return"iterm2"}catch{}return process.platform==="darwin"?"terminal":"direct"}function Yo(e,t){let o=q.default.join(De,`claude-launcher-${t}.exp`),n=q.default.join(De,`pending-input-${t}.txt`);M.default.writeFileSync(n,"","utf-8");let r=`#!/usr/bin/expect -f
18
18
  set timeout -1
19
19
  set msgfile "${n}"
20
20
 
@@ -74,9 +74,9 @@ Reply using the reply tool with botId="..." and roomId="..."
74
74
  ALWAYS use the \`reply\` MCP tool to send your response back to the chat room.
75
75
  Use the exact botId and roomId provided in the message \u2014 do not modify them.
76
76
  Keep responses concise and helpful.
77
- `),e}function ia(){try{y.default.mkdirSync(I.default.dirname(to),{recursive:!0});try{let e=y.default.statSync(to);if(Date.now()-e.mtimeMs<6e4)return!1;y.default.unlinkSync(to)}catch{}return y.default.writeFileSync(to,String(process.pid),{flag:"wx"}),!0}catch{return!1}}async function aa(e){if(!e?.bot_id)return{success:!1,message:"Missing bot_id in payload"};if(!ia())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 _t(e.bot_id),{launchClaudeCode:o,recordSession:n,getActiveSessions:r,stopSession:s}=(eo(),Cn(on)),i=new Set;try{let A=(await H.default.get("http://localhost:7331/claude-code/status",{timeout:5e3})).data?.bots||[];for(let g of A)if(g.botId!==t&&g.enabled!==!1){let w=g.port;typeof w=="number"&&w>=7332&&i.add(w)}}catch{}for(let p=7332;p<=7340;p++)try{(0,N.execSync)(`lsof -ti :${p} >/dev/null 2>&1`,{stdio:"pipe",timeout:2e3}),i.add(p)}catch{}let a=7332;for(;i.has(a);)a++;let c=r();for(let p of c)p.port===a&&(console.log(`[command-executor] Stopping existing session ${p.sessionId} on port ${a}`),s(p.sessionId));try{(0,N.execSync)(`lsof -ti :${a} | xargs kill -9 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let l=e.session_id||`session-${Date.now()}`;await H.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!0,sessionId:l,port:a},{timeout:1e4});let u=sa();return o({sessionId:l,port:a,projectDir:u}),n(l,0,0,a,u),{success:!0,message:`Claude Code started globally for bot ${t} (session: ${l}, port: ${a})`}}catch(t){return{success:!1,message:`Failed to start Claude Code: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function _t(e){if(e.startsWith("@"))return e;try{let o=(await H.default.get("http://localhost:7331/health",{timeout:1e4})).data?.bots||[],n=I.default.join(Ne.default.homedir(),".badgerclaw","bot-mapping.json");if(y.default.existsSync(n)){let r=JSON.parse(y.default.readFileSync(n,"utf-8"));if(r[e])return r[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 ca(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 _t(e.bot_id),o=e.session_id;if(!o)try{let n=await H.default.get("http://localhost:7331/claude-code/status",{timeout:5e3}),s=(n.data?.bots||n.data?.rooms||[]).find(i=>i.botId===t);s&&(o=s.sessionId)}catch{}if(await H.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!1},{timeout:1e4}),o){let{stopSession:n}=(eo(),Cn(on));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 la(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 _t(t));let n=e?.session_id||`cc-${Date.now()}`;return await H.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 da(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 _t(t)),await H.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 ua(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 _t(t)),await H.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 ma(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 H.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 pa(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 H.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 ga(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 H.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 fa(e){let t=e?.bot_user_id||e?.bot_id;if(!t)return{success:!1,message:"Missing bot_id in bot_refresh payload"};let o=t;t.startsWith("@")&&(o=t.split(":")[0].replace("@","").replace(/_bot$/,""));let n=I.default.join(Ne.default.homedir(),".openclaw","badgerclaw","quarantine",`${o}.json`);try{y.default.rmSync(n,{force:!0})}catch{}try{return(0,N.execSync)("openclaw gateway restart",{stdio:"pipe",timeout:15e3}),{success:!0,message:`Bot ${o} quarantine cleared, gateway restarted`}}catch{return{success:!1,message:`Quarantine cleared for ${o} but gateway restart failed`}}}async function ha(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 H.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 N,y,I,Ne,H,to,rn=F(()=>{"use strict";N=require("child_process"),y=d(require("fs")),I=d(require("path")),Ne=d(require("os")),H=d(require("axios"));ke();to=I.default.join(Ne.default.homedir(),".badgerclaw","claude-code.lock")});var an={};wo(an,{heartbeatCommand:()=>sn,pushHeartbeat:()=>L});function no(e,t){if(e!=="start_claude_code"&&e!=="stop_claude_code")return!1;let o=`${e}:${t||"unknown"}`,n=Date.now();for(let[r,s]of oo)n-s>ka&&oo.delete(r);return oo.has(o)?!0:(oo.set(o,n),!1)}function Pr(e,t){let o=Pt();return{instance_id:ee(),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,capabilities:be(),hermes_containers:nr(),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(r=>({roomId:r.roomId,roomName:r.roomName,workspaceName:r.workspaceName||null,messagesInRoom:r.messagesInRoom,lastActivityInRoom:r.lastActivityInRoom})),claude_code_enabled:n.claudeCodeEnabled??!1,claude_code_session_id:n.claudeCodeSessionId??null,quarantined:n.quarantined??!1}))}}async function L(){let{version:e}=we(),t=await bt(),o=Pr(t,e);await O().post(Er,o)}function Sa(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 r=o.get(n.botId);if(!r||r.status!==n.status||r.errors!==n.errors)return!0}return e.bots.length!==t.bots.length}async function xr(){try{let o=(await O().get(ba)).data?.shares||[],n={shares:o.map(r=>({botUserId:r.bot_user_id,sharedWithUserId:r.shared_with_user_id,expiresAt:r.expires_at||null,shareId:r.share_id}))};await Ar.default.post("http://localhost:7331/bot-share/sync",n,{timeout:1e4}),console.log(f.default.dim(` [${x()}] Share sync: ${o.length} active share(s) pushed to plugin`))}catch(e){console.log(f.default.dim(` [${x()}] Share sync failed (non-fatal): ${e.message}`))}}async function va(){if(!Ir){Ir=!0;try{await O().post(ya,{instance_id:ee()},{timeout:_a}),console.log(f.default.dim(` [${new Date().toISOString()}] Posted disconnect \u2014 dashboard will mark machine offline immediately.`))}catch(e){console.log(f.default.dim(` [${new Date().toISOString()}] Disconnect post failed (non-fatal): ${e?.message||e}`))}}}async function Or(){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(f.default.dim(` [${x()}] Token expires soon \u2014 refreshing proactively...`)),await ko())console.log(f.default.green(` [${x()}] Token refreshed successfully`));else{let s=Nn()||"unknown reason";console.log(f.default.yellow(` [${x()}] Token refresh failed: ${s}`))}}function Ca(e,t){let o=3e3,n=3e4,r=null;async function s(){try{await Or();let a=h()?.access_token||e,c=require("eventsource"),l=new c(`${U}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${a}`}});l.onopen=()=>{o=3e3,console.log(f.default.dim(` [${x()}] SSE connected \u2014 listening for real-time events`)),r&&clearTimeout(r),r=setTimeout(()=>{console.log(f.default.dim(` [${x()}] SSE proactive reconnect \u2014 refreshing token before expiry`)),l.close(),s()},$a)},l.onmessage=async u=>{try{let p=JSON.parse(u.data);await Ia(p)}catch{}},l.onerror=async()=>{l.close(),r&&(clearTimeout(r),r=null),console.log(f.default.dim(` [${x()}] SSE disconnected \u2014 reconnecting in ${o/1e3}s...`)),setTimeout(s,o),o=Math.min(o*1.5,n)}}catch(i){console.log(f.default.dim(` [${x()}] SSE connection failed: ${i.message}`)),setTimeout(s,o),o=Math.min(o*1.5,n)}}s()}function x(){return new Date().toISOString()}async function Ia(e){if(e.type==="pair"){console.log(f.default.cyan(` [${x()}] Pair event: ${e.bot_name}`)),await pt(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(f.default.green(` [${x()}] Gateway restarted \u2014 ${e.bot_name} is live`))}catch{}try{await L()}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(f.default.yellow(` [${x()}] Bot deleted: ${t}`));try{let n=await import("fs"),r=await import("path"),s=await import("os"),i=r.join(s.homedir(),".openclaw","openclaw.json");if(Ae(()=>{let c=JSON.parse(n.readFileSync(i,"utf-8")),l=!1;if(c.channels?.badgerclaw?.accounts?.[o]&&(delete c.channels.badgerclaw.accounts[o],l=!0),c.agents?.list){let u=c.agents.list.length;c.agents.list=c.agents.list.filter(p=>p.id!==o),c.agents.list.length!==u&&(l=!0)}return l&&n.writeFileSync(i,JSON.stringify(c,null,2)),l})){console.log(f.default.green(` [${x()}] Removed "${o}" from openclaw.json`));let{execSync:c}=await import("child_process");try{c("openclaw gateway restart",{stdio:"ignore"}),console.log(f.default.green(` [${x()}] Gateway restarted`))}catch{}}}catch(n){console.log(f.default.red(` [${x()}] Failed to clean up bot: ${n}`))}try{await L()}catch{}}else if(e.type==="gateway-restart"){console.log(f.default.cyan(` [${x()}] Remote gateway-restart received`));let t=await Je();console.log(t.success?f.default.green(` [${x()}] Gateway restarted`):f.default.red(` [${x()}] Gateway restart failed: ${t.message}`));try{await L()}catch{}}else if(e.type==="claude_code.start"&&e.bot_id){if(console.log(f.default.cyan(` [${x()}] Claude Code START: bot=${e.bot_id}`)),no("start_claude_code",e.bot_id)){console.log(f.default.dim(` [${x()}] Skipping duplicate start_claude_code (already processed)`));return}try{let t=await ue({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 O().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await L()}catch{}}else if(e.type==="claude_code.stop"&&e.bot_id){if(console.log(f.default.cyan(` [${x()}] Claude Code STOP: bot=${e.bot_id}`)),no("stop_claude_code",e.bot_id)){console.log(f.default.dim(` [${x()}] Skipping duplicate stop_claude_code (already processed)`));return}try{let t=await ue({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 O().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await L()}catch{}}else if(e.type==="command.execute"&&e.command_id){if(console.log(f.default.cyan(` [${x()}] Command: ${e.command_type} (${e.command_id})`)),no(e.command_type,e.payload?.bot_id)){console.log(f.default.dim(` [${x()}] Skipping duplicate ${e.command_type} (already processed)`));return}try{let t=O();await t.post(`/api/v1/dashboard/commands/${e.command_id}/ack`);let o=await ue({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(f.default.cyan(` [${x()}] CLI updated \u2014 restarting in 2s...`)),setTimeout(()=>process.exit(0),2e3))}catch{}try{await L()}catch{}}}var Rr,f,Ar,Cr,wa,Er,ya,ba,_a,Ir,oo,ka,sn,$a,Ye=F(()=>{"use strict";Rr=require("commander"),f=d(require("chalk")),Ar=d(require("axios"));j();oe();xe();Ee();Gt();ke();rn();fe();ft();ke();dt();Fe();Cr=3e4,wa=15e4,Er="/api/v1/dashboard/heartbeat",ya="/api/v1/dashboard/disconnect",ba="/api/v1/me/active-shares",_a=3e3,Ir=!1,oo=new Map,ka=3e4;sn=new Rr.Command("heartbeat").description("Run heartbeat daemon \u2014 reports telemetry to the BadgerClaw dashboard every 30s").action(async()=>{let e=h();e||(console.log(f.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=we();console.log(f.default.green(`Heartbeat daemon started (v${t})`)),console.log(f.default.dim(` Instance: ${ee()}`)),console.log(f.default.dim(` Interval: ${Cr/1e3}s`)),console.log(f.default.dim(` Press Ctrl+C to stop.
78
- `));let o=null,n=10,r=0,s=async()=>{try{await Or();let c=await bt(),l=Pr(c,t);Sa(o,c)&&o!==null&&console.log(f.default.cyan(` [${new Date().toISOString()}] State change detected \u2014 pushing immediately`));let p=O(),A=await p.post(Er,l);r=0;let g=c.bots.length,w=c.bots.filter(R=>R.status==="running").length;console.log(f.default.dim(` [${new Date().toISOString()}] gateway=${c.status} bots=${w}/${g} running mem=${l.mem_free_mb}MB free`)),o=c;try{let $=await rr({api:{post:async(V,P)=>{let ce=await p.post(V,P);return{status:ce.status,data:ce.data}}}});for(let V of $)V.attempted&&(V.posted||V.envUpdated)&&console.log(f.default.cyan(` [${new Date().toISOString()}] Hermes recovery key captured for ${V.bot_id} (posted=${V.posted}, env_updated=${V.envUpdated})`))}catch(R){console.log(f.default.dim(` [${new Date().toISOString()}] Hermes recovery-key retry skipped: ${R.message}`))}let C=A.data?.pending_commands||[],k=!1;for(let R of C)try{if(console.log(f.default.cyan(` [${new Date().toISOString()}] Received command: ${R.command_type} (${R.id})`)),await p.post(`/api/v1/dashboard/commands/${R.id}/ack`),no(R.command_type,R.payload?.bot_id)){console.log(f.default.dim(` [${new Date().toISOString()}] Skipping duplicate ${R.command_type}`));continue}let $=await ue(R);console.log($.success?f.default.green(` [${new Date().toISOString()}] ${$.message}`):f.default.red(` [${new Date().toISOString()}] ${$.message}`)),await p.post(`/api/v1/dashboard/commands/${R.id}/result`,{status:$.success?"success":"failed",result:$.message,new_version:$.newVersion||null}),R.command_type==="update_cli"&&$.success&&(k=!0)}catch($){console.log(f.default.dim(` [${new Date().toISOString()}] Command ${R.id} error: ${$.message}`))}if(k){console.log(f.default.cyan(` [${new Date().toISOString()}] CLI updated \u2014 restarting in 2s...`));try{await L()}catch{}setTimeout(()=>process.exit(0),2e3);return}}catch(c){c instanceof He&&(console.log(f.default.yellow(` [${new Date().toISOString()}] Account deactivated \u2014 signed out. Exiting daemon.`)),process.exit(0)),r+=1,console.log(f.default.dim(` [${new Date().toISOString()}] Heartbeat failed (${r}/${n}): ${c.message}`)),r>=n&&(console.log(f.default.red(` [${new Date().toISOString()}] ${n} consecutive heartbeat failures \u2014 exiting so launchctl/systemd can restart the daemon.`)),process.exit(1))}};await s();let i=J()!==null;i?await xr():console.log(f.default.dim(` [${x()}] Hermes-only host \u2014 share-sync disabled (no plugin to push to).`)),setInterval(s,Cr),i&&setInterval(xr,wa),Ca(e.access_token,t);let a=c=>{console.log(f.default.yellow(`
79
- [${new Date().toISOString()}] Received ${c} \u2014 posting disconnect and exiting.`)),va().finally(()=>{process.exit(0)})};process.on("SIGTERM",a),process.on("SIGINT",a),await new Promise(()=>{})});$a=2700*1e3});var Ws=require("commander");var Dr=require("commander"),K=d(require("chalk")),Nr=d(require("ora")),Tr=d(require("open")),cn=d(require("os"));var yo=d(require("crypto"));function In(){return yo.default.randomBytes(32).toString("base64url")}function xn(e){return yo.default.createHash("sha256").update(e).digest("base64url")}j();xe();oe();fe();ft();var qt=d(require("os")),X=d(require("fs")),Kt=d(require("path")),Oe=require("child_process");var Ge=d(require("fs")),Pe=d(require("path")),Ve=d(require("os")),qe=require("child_process"),lr="ai.badgerclaw.watch",dr=Pe.default.join(Ve.default.homedir(),"Library","LaunchAgents"),We=Pe.default.join(dr,`${lr}.plist`);function Ri(){try{return(0,qe.execSync)("which badgerclaw",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/badgerclaw"}}function Ai(){try{return(0,qe.execSync)("which node",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/node"}}function Ei(e){let t=Pe.default.join(Ve.default.homedir(),".badgerclaw"),o=Ai(),n=Pe.default.dirname(o),r=Pe.default.dirname(e),s=[n,r,"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"],i=new Set,a=s.filter(c=>!c||i.has(c)?!1:(i.add(c),!0)).join(":");return`<?xml version="1.0" encoding="UTF-8"?>
77
+ `),e}function ia(){try{y.default.mkdirSync(I.default.dirname(to),{recursive:!0});try{let e=y.default.statSync(to);if(Date.now()-e.mtimeMs<6e4)return!1;y.default.unlinkSync(to)}catch{}return y.default.writeFileSync(to,String(process.pid),{flag:"wx"}),!0}catch{return!1}}async function aa(e){if(!e?.bot_id)return{success:!1,message:"Missing bot_id in payload"};if(!ia())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 _t(e.bot_id),{launchClaudeCode:o,recordSession:n,getActiveSessions:r,stopSession:s}=(eo(),Cn(on)),i=new Set;try{let A=(await H.default.get("http://localhost:7331/claude-code/status",{timeout:5e3})).data?.bots||[];for(let g of A)if(g.botId!==t&&g.enabled!==!1){let w=g.port;typeof w=="number"&&w>=7332&&i.add(w)}}catch{}for(let p=7332;p<=7340;p++)try{(0,N.execSync)(`lsof -ti :${p} >/dev/null 2>&1`,{stdio:"pipe",timeout:2e3}),i.add(p)}catch{}let a=7332;for(;i.has(a);)a++;let c=r();for(let p of c)p.port===a&&(console.log(`[command-executor] Stopping existing session ${p.sessionId} on port ${a}`),s(p.sessionId));try{(0,N.execSync)(`lsof -ti :${a} | xargs kill -9 2>/dev/null`,{stdio:"pipe",timeout:3e3})}catch{}let l=e.session_id||`session-${Date.now()}`;await H.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!0,sessionId:l,port:a},{timeout:1e4});let u=sa();return o({sessionId:l,port:a,projectDir:u}),n(l,0,0,a,u),{success:!0,message:`Claude Code started globally for bot ${t} (session: ${l}, port: ${a})`}}catch(t){return{success:!1,message:`Failed to start Claude Code: ${t.response?.data?.message||t.message||"Unknown error"}`}}}async function _t(e){if(e.startsWith("@"))return e;try{let o=(await H.default.get("http://localhost:7331/health",{timeout:1e4})).data?.bots||[],n=I.default.join(Ne.default.homedir(),".badgerclaw","bot-mapping.json");if(y.default.existsSync(n)){let r=JSON.parse(y.default.readFileSync(n,"utf-8"));if(r[e])return r[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 ca(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 _t(e.bot_id),o=e.session_id;if(!o)try{let n=await H.default.get("http://localhost:7331/claude-code/status",{timeout:5e3}),s=(n.data?.bots||n.data?.rooms||[]).find(i=>i.botId===t);s&&(o=s.sessionId)}catch{}if(await H.default.post("http://localhost:7331/claude-code/toggle",{botId:t,enabled:!1},{timeout:1e4}),o){let{stopSession:n}=(eo(),Cn(on));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 la(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 _t(t));let n=e?.session_id||`cc-${Date.now()}`;return await H.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 da(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 _t(t)),await H.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 ua(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 _t(t)),await H.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 ma(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 H.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 pa(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 H.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 ga(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 H.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 fa(e){let t=e?.bot_user_id||e?.bot_id;if(!t)return{success:!1,message:"Missing bot_id in bot_refresh payload"};let o=t;t.startsWith("@")&&(o=t.split(":")[0].replace("@","").replace(/_bot$/,""));let n=I.default.join(Ne.default.homedir(),".openclaw","badgerclaw","quarantine",`${o}.json`);try{y.default.rmSync(n,{force:!0})}catch{}try{return(0,N.execSync)("openclaw gateway restart",{stdio:"pipe",timeout:15e3}),{success:!0,message:`Bot ${o} quarantine cleared, gateway restarted`}}catch{return{success:!1,message:`Quarantine cleared for ${o} but gateway restart failed`}}}async function ha(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 H.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 N,y,I,Ne,H,to,rn=F(()=>{"use strict";N=require("child_process"),y=d(require("fs")),I=d(require("path")),Ne=d(require("os")),H=d(require("axios"));ke();to=I.default.join(Ne.default.homedir(),".badgerclaw","claude-code.lock")});var an={};wo(an,{heartbeatCommand:()=>sn,pushHeartbeat:()=>L});function no(e,t){if(e!=="start_claude_code"&&e!=="stop_claude_code")return!1;let o=`${e}:${t||"unknown"}`,n=Date.now();for(let[r,s]of oo)n-s>ka&&oo.delete(r);return oo.has(o)?!0:(oo.set(o,n),!1)}function Pr(e,t){let o=Pt();return{instance_id:te(),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,capabilities:be(),hermes_containers:nr(),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(r=>({roomId:r.roomId,roomName:r.roomName,workspaceName:r.workspaceName||null,messagesInRoom:r.messagesInRoom,lastActivityInRoom:r.lastActivityInRoom})),claude_code_enabled:n.claudeCodeEnabled??!1,claude_code_session_id:n.claudeCodeSessionId??null,quarantined:n.quarantined??!1}))}}async function L(){let{version:e}=we(),t=await bt(),o=Pr(t,e);await O().post(Er,o)}function Sa(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 r=o.get(n.botId);if(!r||r.status!==n.status||r.errors!==n.errors)return!0}return e.bots.length!==t.bots.length}async function xr(){try{let o=(await O().get(ba)).data?.shares||[],n={shares:o.map(r=>({botUserId:r.bot_user_id,sharedWithUserId:r.shared_with_user_id,expiresAt:r.expires_at||null,shareId:r.share_id}))};await Ar.default.post("http://localhost:7331/bot-share/sync",n,{timeout:1e4}),console.log(f.default.dim(` [${x()}] Share sync: ${o.length} active share(s) pushed to plugin`))}catch(e){console.log(f.default.dim(` [${x()}] Share sync failed (non-fatal): ${e.message}`))}}async function va(){if(!Ir){Ir=!0;try{await O().post(ya,{instance_id:te()},{timeout:_a}),console.log(f.default.dim(` [${new Date().toISOString()}] Posted disconnect \u2014 dashboard will mark machine offline immediately.`))}catch(e){console.log(f.default.dim(` [${new Date().toISOString()}] Disconnect post failed (non-fatal): ${e?.message||e}`))}}}async function Or(){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(f.default.dim(` [${x()}] Token expires soon \u2014 refreshing proactively...`)),await ko())console.log(f.default.green(` [${x()}] Token refreshed successfully`));else{let s=Nn()||"unknown reason";console.log(f.default.yellow(` [${x()}] Token refresh failed: ${s}`))}}function Ca(e,t){let o=3e3,n=3e4,r=null;async function s(){try{await Or();let a=h()?.access_token||e,c=require("eventsource"),l=new c(`${U}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${a}`}});l.onopen=()=>{o=3e3,console.log(f.default.dim(` [${x()}] SSE connected \u2014 listening for real-time events`)),r&&clearTimeout(r),r=setTimeout(()=>{console.log(f.default.dim(` [${x()}] SSE proactive reconnect \u2014 refreshing token before expiry`)),l.close(),s()},$a)},l.onmessage=async u=>{try{let p=JSON.parse(u.data);await Ia(p)}catch{}},l.onerror=async()=>{l.close(),r&&(clearTimeout(r),r=null),console.log(f.default.dim(` [${x()}] SSE disconnected \u2014 reconnecting in ${o/1e3}s...`)),setTimeout(s,o),o=Math.min(o*1.5,n)}}catch(i){console.log(f.default.dim(` [${x()}] SSE connection failed: ${i.message}`)),setTimeout(s,o),o=Math.min(o*1.5,n)}}s()}function x(){return new Date().toISOString()}async function Ia(e){if(e.type==="pair"){console.log(f.default.cyan(` [${x()}] Pair event: ${e.bot_name}`)),await pt(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(f.default.green(` [${x()}] Gateway restarted \u2014 ${e.bot_name} is live`))}catch{}try{await L()}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(f.default.yellow(` [${x()}] Bot deleted: ${t}`));try{let n=await import("fs"),r=await import("path"),s=await import("os"),i=r.join(s.homedir(),".openclaw","openclaw.json");if(Ae(()=>{let c=JSON.parse(n.readFileSync(i,"utf-8")),l=!1;if(c.channels?.badgerclaw?.accounts?.[o]&&(delete c.channels.badgerclaw.accounts[o],l=!0),c.agents?.list){let u=c.agents.list.length;c.agents.list=c.agents.list.filter(p=>p.id!==o),c.agents.list.length!==u&&(l=!0)}return l&&n.writeFileSync(i,JSON.stringify(c,null,2)),l})){console.log(f.default.green(` [${x()}] Removed "${o}" from openclaw.json`));let{execSync:c}=await import("child_process");try{c("openclaw gateway restart",{stdio:"ignore"}),console.log(f.default.green(` [${x()}] Gateway restarted`))}catch{}}}catch(n){console.log(f.default.red(` [${x()}] Failed to clean up bot: ${n}`))}try{await L()}catch{}}else if(e.type==="gateway-restart"){console.log(f.default.cyan(` [${x()}] Remote gateway-restart received`));let t=await Je();console.log(t.success?f.default.green(` [${x()}] Gateway restarted`):f.default.red(` [${x()}] Gateway restart failed: ${t.message}`));try{await L()}catch{}}else if(e.type==="claude_code.start"&&e.bot_id){if(console.log(f.default.cyan(` [${x()}] Claude Code START: bot=${e.bot_id}`)),no("start_claude_code",e.bot_id)){console.log(f.default.dim(` [${x()}] Skipping duplicate start_claude_code (already processed)`));return}try{let t=await ue({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 O().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await L()}catch{}}else if(e.type==="claude_code.stop"&&e.bot_id){if(console.log(f.default.cyan(` [${x()}] Claude Code STOP: bot=${e.bot_id}`)),no("stop_claude_code",e.bot_id)){console.log(f.default.dim(` [${x()}] Skipping duplicate stop_claude_code (already processed)`));return}try{let t=await ue({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 O().post(`/api/v1/dashboard/commands/${e.command_id}/result`,{status:t.success?"success":"failed",result:t.message}).catch(()=>{})}catch{}try{await L()}catch{}}else if(e.type==="command.execute"&&e.command_id){if(console.log(f.default.cyan(` [${x()}] Command: ${e.command_type} (${e.command_id})`)),no(e.command_type,e.payload?.bot_id)){console.log(f.default.dim(` [${x()}] Skipping duplicate ${e.command_type} (already processed)`));return}try{let t=O();await t.post(`/api/v1/dashboard/commands/${e.command_id}/ack`);let o=await ue({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(f.default.cyan(` [${x()}] CLI updated \u2014 restarting in 2s...`)),setTimeout(()=>process.exit(0),2e3))}catch{}try{await L()}catch{}}}var Rr,f,Ar,Cr,wa,Er,ya,ba,_a,Ir,oo,ka,sn,$a,Ye=F(()=>{"use strict";Rr=require("commander"),f=d(require("chalk")),Ar=d(require("axios"));j();oe();xe();Ee();Gt();ke();rn();fe();ft();ke();dt();Fe();Cr=3e4,wa=15e4,Er="/api/v1/dashboard/heartbeat",ya="/api/v1/dashboard/disconnect",ba="/api/v1/me/active-shares",_a=3e3,Ir=!1,oo=new Map,ka=3e4;sn=new Rr.Command("heartbeat").description("Run heartbeat daemon \u2014 reports telemetry to the BadgerClaw dashboard every 30s").action(async()=>{let e=h();e||(console.log(f.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=we();console.log(f.default.green(`Heartbeat daemon started (v${t})`)),console.log(f.default.dim(` Instance: ${te()}`)),console.log(f.default.dim(` Interval: ${Cr/1e3}s`)),console.log(f.default.dim(` Press Ctrl+C to stop.
78
+ `));let o=null,n=10,r=0,s=async()=>{try{await Or();let c=await bt(),l=Pr(c,t);Sa(o,c)&&o!==null&&console.log(f.default.cyan(` [${new Date().toISOString()}] State change detected \u2014 pushing immediately`));let p=O(),A=await p.post(Er,l);r=0;let g=c.bots.length,w=c.bots.filter(R=>R.status==="running").length;console.log(f.default.dim(` [${new Date().toISOString()}] gateway=${c.status} bots=${w}/${g} running mem=${l.mem_free_mb}MB free`)),o=c;try{let $=await rr({api:{post:async(V,P)=>{let ce=await p.post(V,P);return{status:ce.status,data:ce.data}}}});for(let V of $)V.attempted&&(V.posted||V.envUpdated)&&console.log(f.default.cyan(` [${new Date().toISOString()}] Hermes recovery key captured for ${V.bot_id} (posted=${V.posted}, env_updated=${V.envUpdated})`))}catch(R){console.log(f.default.dim(` [${new Date().toISOString()}] Hermes recovery-key retry skipped: ${R.message}`))}let C=A.data?.pending_commands||[],k=!1;for(let R of C)try{if(console.log(f.default.cyan(` [${new Date().toISOString()}] Received command: ${R.command_type} (${R.id})`)),await p.post(`/api/v1/dashboard/commands/${R.id}/ack`),no(R.command_type,R.payload?.bot_id)){console.log(f.default.dim(` [${new Date().toISOString()}] Skipping duplicate ${R.command_type}`));continue}let $=await ue(R);console.log($.success?f.default.green(` [${new Date().toISOString()}] ${$.message}`):f.default.red(` [${new Date().toISOString()}] ${$.message}`)),await p.post(`/api/v1/dashboard/commands/${R.id}/result`,{status:$.success?"success":"failed",result:$.message,new_version:$.newVersion||null}),R.command_type==="update_cli"&&$.success&&(k=!0)}catch($){console.log(f.default.dim(` [${new Date().toISOString()}] Command ${R.id} error: ${$.message}`))}if(k){console.log(f.default.cyan(` [${new Date().toISOString()}] CLI updated \u2014 restarting in 2s...`));try{await L()}catch{}setTimeout(()=>process.exit(0),2e3);return}}catch(c){c instanceof He&&(console.log(f.default.yellow(` [${new Date().toISOString()}] Account deactivated \u2014 signed out. Exiting daemon.`)),process.exit(0)),r+=1,console.log(f.default.dim(` [${new Date().toISOString()}] Heartbeat failed (${r}/${n}): ${c.message}`)),r>=n&&(console.log(f.default.red(` [${new Date().toISOString()}] ${n} consecutive heartbeat failures \u2014 exiting so launchctl/systemd can restart the daemon.`)),process.exit(1))}};await s();let i=Y()!==null;i?await xr():console.log(f.default.dim(` [${x()}] Hermes-only host \u2014 share-sync disabled (no plugin to push to).`)),setInterval(s,Cr),i&&setInterval(xr,wa),Ca(e.access_token,t);let a=c=>{console.log(f.default.yellow(`
79
+ [${new Date().toISOString()}] Received ${c} \u2014 posting disconnect and exiting.`)),va().finally(()=>{process.exit(0)})};process.on("SIGTERM",a),process.on("SIGINT",a),await new Promise(()=>{})});$a=2700*1e3});var Ws=require("commander");var Dr=require("commander"),K=d(require("chalk")),Nr=d(require("ora")),Tr=d(require("open")),cn=d(require("os"));var yo=d(require("crypto"));function In(){return yo.default.randomBytes(32).toString("base64url")}function xn(e){return yo.default.createHash("sha256").update(e).digest("base64url")}j();xe();oe();fe();ft();var qt=d(require("os")),Z=d(require("fs")),Kt=d(require("path")),Oe=require("child_process");var Ge=d(require("fs")),Pe=d(require("path")),Ve=d(require("os")),qe=require("child_process"),lr="ai.badgerclaw.watch",dr=Pe.default.join(Ve.default.homedir(),"Library","LaunchAgents"),We=Pe.default.join(dr,`${lr}.plist`);function Ri(){try{return(0,qe.execSync)("which badgerclaw",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/badgerclaw"}}function Ai(){try{return(0,qe.execSync)("which node",{encoding:"utf-8"}).trim()}catch{return"/opt/homebrew/bin/node"}}function Ei(e){let t=Pe.default.join(Ve.default.homedir(),".badgerclaw"),o=Ai(),n=Pe.default.dirname(o),r=Pe.default.dirname(e),s=[n,r,"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"],i=new Set,a=s.filter(c=>!c||i.has(c)?!1:(i.add(c),!0)).join(":");return`<?xml version="1.0" encoding="UTF-8"?>
80
80
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
81
81
  <plist version="1.0">
82
82
  <dict>
@@ -104,7 +104,7 @@ Keep responses concise and helpful.
104
104
  <key>ThrottleInterval</key>
105
105
  <integer>30</integer>
106
106
  </dict>
107
- </plist>`}function ur(){if(Ve.default.platform()==="darwin")try{let e=Ri();Ge.default.mkdirSync(dr,{recursive:!0}),Ge.default.mkdirSync(Pe.default.join(Ve.default.homedir(),".badgerclaw"),{recursive:!0}),Ge.default.writeFileSync(We,Ei(e));try{(0,qe.execSync)(`launchctl unload "${We}" 2>/dev/null`)}catch{}(0,qe.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")}}function mr(){if(Ve.default.platform()==="darwin")try{(0,qe.execSync)(`launchctl unload "${We}" 2>/dev/null`),Ge.default.existsSync(We)&&Ge.default.unlinkSync(We)}catch{}}var Ke=d(require("fs")),wt=d(require("path")),ht=d(require("os")),z=require("child_process"),Vt="badgerclaw-watch.service",pr=wt.default.join(ht.default.homedir(),".config","systemd","user"),Bo=wt.default.join(pr,Vt);function Pi(){try{return(0,z.execSync)("which badgerclaw",{encoding:"utf-8"}).trim()}catch{return"/usr/local/bin/badgerclaw"}}function Oi(){try{return(0,z.execSync)("which node",{encoding:"utf-8"}).trim()}catch{return"/usr/bin/node"}}function Di(e){let t=Oi(),o=wt.default.dirname(t);return`[Unit]
107
+ </plist>`}function ur(){if(Ve.default.platform()==="darwin")try{let e=Ri();Ge.default.mkdirSync(dr,{recursive:!0}),Ge.default.mkdirSync(Pe.default.join(Ve.default.homedir(),".badgerclaw"),{recursive:!0}),Ge.default.writeFileSync(We,Ei(e));try{(0,qe.execSync)(`launchctl unload "${We}" 2>/dev/null`)}catch{}(0,qe.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")}}function mr(){if(Ve.default.platform()==="darwin")try{(0,qe.execSync)(`launchctl unload "${We}" 2>/dev/null`),Ge.default.existsSync(We)&&Ge.default.unlinkSync(We)}catch{}}var Ke=d(require("fs")),wt=d(require("path")),ht=d(require("os")),X=require("child_process"),Vt="badgerclaw-watch.service",pr=wt.default.join(ht.default.homedir(),".config","systemd","user"),Bo=wt.default.join(pr,Vt);function Pi(){try{return(0,X.execSync)("which badgerclaw",{encoding:"utf-8"}).trim()}catch{return"/usr/local/bin/badgerclaw"}}function Oi(){try{return(0,X.execSync)("which node",{encoding:"utf-8"}).trim()}catch{return"/usr/bin/node"}}function Di(e){let t=Oi(),o=wt.default.dirname(t);return`[Unit]
108
108
  Description=BadgerClaw background watcher (heartbeat + pair events)
109
109
  After=network-online.target
110
110
  Wants=network-online.target
@@ -120,17 +120,17 @@ StandardError=append:%h/.badgerclaw/heartbeat.log
120
120
 
121
121
  [Install]
122
122
  WantedBy=default.target
123
- `}function gr(){try{return(0,z.execSync)("systemctl --user --version",{stdio:"ignore"}),!0}catch{return!1}}function fr(){if(ht.default.platform()!=="linux"||!gr())return!1;try{let e=Pi();Ke.default.mkdirSync(pr,{recursive:!0}),Ke.default.mkdirSync(wt.default.join(ht.default.homedir(),".badgerclaw"),{recursive:!0}),Ke.default.writeFileSync(Bo,Di(e)),(0,z.execSync)("systemctl --user daemon-reload",{stdio:"ignore"});try{(0,z.execSync)(`systemctl --user restart ${Vt}`,{stdio:"ignore"})}catch{}(0,z.execSync)(`systemctl --user enable --now ${Vt}`,{stdio:"ignore"});try{let t=(0,z.execSync)("whoami",{encoding:"utf-8"}).trim();(0,z.execSync)(`loginctl enable-linger ${t}`,{stdio:"ignore"})}catch{}return console.log("\x1B[2mHeartbeat daemon registered as systemd user service (auto-starts on login).\x1B[0m"),!0}catch{return!1}}function hr(){if(ht.default.platform()==="linux"&&gr()){try{(0,z.execSync)(`systemctl --user disable --now ${Vt}`,{stdio:"ignore"})}catch{}try{Ke.default.existsSync(Bo)&&Ke.default.unlinkSync(Bo),(0,z.execSync)("systemctl --user daemon-reload",{stdio:"ignore"})}catch{}}}var Lo=Kt.default.join(qt.default.homedir(),".badgerclaw"),yt=Kt.default.join(Lo,"heartbeat.pid"),Ni=Kt.default.join(Lo,"heartbeat.log");function Ti(e){if(!e||e.length===0)return!1;let t=s=>/(^|[\\/])node(\.exe)?$/i.test(s||""),o=t(e[0])||t(e[1]),n=e.includes("heartbeat"),r=e.some(s=>/(^|[\\/])badgerclaw($|[\\/. ])/i.test(s)||/[\\/]dist[\\/]index\.js$/.test(s));return o&&n&&r}function ji(e){try{if(process.platform==="linux")return X.default.readFileSync(`/proc/${e}/cmdline`).toString("utf-8").split("\0").filter(Boolean);let t=(0,Oe.execSync)(`ps -o args= -p ${e}`,{encoding:"utf-8"}).trim();return t.length?t.split(/\s+/).filter(Boolean):null}catch{return null}}function Mo(e){if(!Number.isFinite(e)||e<=0||e===process.pid||e===process.ppid)return!1;let t=ji(e);return t?Ti(t):!1}function Ho(){let e="";try{e=(0,Oe.execSync)("pgrep -f heartbeat",{encoding:"utf-8"})}catch{return[]}return e.split(/\s+/).map(t=>parseInt(t,10)).filter(t=>Number.isFinite(t)&&t>0).filter(t=>Mo(t))}function Bi(e){try{Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,Math.max(0,e))}catch{}}function Li(e){try{if(process.platform==="linux"){let r=X.default.readFileSync(`/proc/${e}/status`,"utf-8").match(/^PPid:\s*(\d+)/m),s=r?parseInt(r[1],10):NaN;if(!Number.isFinite(s))return null;let i="";try{i=X.default.readFileSync(`/proc/${s}/comm`,"utf-8").trim()}catch{}return{ppid:s,comm:i}}let t=parseInt((0,Oe.execSync)(`ps -o ppid= -p ${e}`,{encoding:"utf-8"}).trim(),10);if(!Number.isFinite(t))return null;let o="";try{o=(0,Oe.execSync)(`ps -o comm= -p ${t}`,{encoding:"utf-8"}).trim()}catch{}return{ppid:t,comm:o}}catch{return null}}var Mi=/(systemd|supervisord|launchd|runsv|runit|s6-supervise|openrc)/i;function Hi(){for(let e of Ho()){let t=Li(e);if(t&&Mi.test(t.comm))return e}return null}function Fi(){try{let e=parseInt(X.default.readFileSync(yt,"utf-8").trim(),10);if(Number.isFinite(e)&&e>0&&Mo(e))return!0}catch{}return yr(),Ho().length>0}function yr(){try{let e=parseInt(X.default.readFileSync(yt,"utf-8").trim(),10);if(Number.isFinite(e)&&e>0&&Mo(e))return}catch{}try{X.default.rmSync(yt,{force:!0})}catch{}}function Ui(e="SIGTERM"){let t=Ho(),o=0;for(let i of t)try{process.kill(i,e),o++}catch{}if(o===0)return 0;let n=i=>{try{return process.kill(i,0),!0}catch{return!1}},r=Date.now()+4e3,s=t.filter(n);for(;s.length>0&&Date.now()<r;)Bi(120),s=s.filter(n);for(let i of s)try{process.kill(i,"SIGKILL")}catch{}return o}function wr(){if(Fi())return console.log("\x1B[2mHeartbeat already running.\x1B[0m"),!0;try{X.default.mkdirSync(Lo,{recursive:!0});let e=X.default.openSync(Ni,"a"),t=(0,Oe.spawn)(process.execPath,[process.argv[1],"heartbeat"],{detached:!0,stdio:["ignore",e,e]});if(t.pid==null)return console.log("\x1B[2mNote: could not start the heartbeat. Run `badgerclaw heartbeat` manually.\x1B[0m"),!1;try{X.default.writeFileSync(yt,String(t.pid))}catch{}return t.unref(),console.log("\x1B[2mHeartbeat started in the background (no service manager on this host; it will not auto-restart after a reboot \u2014 re-run `badgerclaw setup --hermes` or `badgerclaw heartbeat` if the host restarts).\x1B[0m"),!0}catch{return console.log("\x1B[2mNote: could not start the heartbeat. Run `badgerclaw heartbeat` manually.\x1B[0m"),!1}}function Fo(){let e=qt.default.platform();if(e==="darwin"){ur();return}if(e==="linux"){if(fr())return;wr();return}wr()}function Gi(){let e=qt.default.platform();e==="darwin"?mr():e==="linux"&&hr(),Ui();try{X.default.rmSync(yt,{force:!0})}catch{}}function br(e){let t=e.log||(()=>{}),o=Hi();if(o!==null){yr(),t(`heartbeat already supervised (pid ${o}) \u2014 left in place; cleared any stale pid file.`);return}Gi(),t("removed stale heartbeat hooks from previous installs."),e.loggedIn?(Fo(),t("reinstalled a fresh heartbeat daemon for this host.")):t("run `badgerclaw login` to start the heartbeat for this host.")}var Se=d(require("fs")),Vo=d(require("os")),Yt=d(require("path")),re=require("child_process"),G=d(require("chalk"));dt();ke();var kr=Yt.default.join(Vo.default.homedir(),".openclaw","openclaw.json");function Ki(){return process.platform!=="linux"?!1:!!(Se.default.existsSync("/.dockerenv")||(0,re.spawnSync)("which",["systemctl"],{encoding:"utf-8"}).status!==0)}function Sr(e=!1){let t=null;try{Se.default.existsSync(kr)&&(t=JSON.parse(Se.default.readFileSync(kr,"utf-8"))?.gateway?.mode??null)}catch{}if(typeof t=="string"&&t.length>0)return!0;e||console.log(G.default.dim(" Setting gateway.mode=local..."));try{return Ae(()=>((0,re.execSync)("openclaw config set gateway.mode local",{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),!0))}catch(o){return e||(console.log(G.default.yellow(` \u26A0\uFE0F Could not set gateway.mode automatically: ${o.message}`)),console.log(G.default.yellow(" Run `openclaw config set gateway.mode local` manually."))),!1}}async function zt(e={}){let t=e.verbose!==!1,o=a=>{t&&console.log(a)};if(Ki())return Yi(t);o(G.default.dim(" Installing OpenClaw gateway service (if not present)...")),(0,re.spawnSync)("openclaw",["gateway","install"],{stdio:t?"inherit":"pipe",shell:!0}).status!==0&&o(G.default.yellow(" \u26A0\uFE0F `openclaw gateway install` returned non-zero \u2014 continuing.")),Sr(!t),o(G.default.dim(" Starting OpenClaw gateway..."));let r=(0,re.spawnSync)("openclaw",["gateway","start"],{stdio:t?"inherit":"pipe",shell:!0}),s="started";if(r.status!==0&&(r=(0,re.spawnSync)("openclaw",["gateway","restart"],{stdio:t?"inherit":"pipe",shell:!0}),s="restarted"),r.status!==0)return{ok:!1,error:"gateway start/restart returned non-zero exit"};o(G.default.dim(" Waiting for the gateway to start answering..."));let i=await Ji(2e4);return i||o(G.default.yellow(" \u26A0\uFE0F Gateway start issued but it is not answering yet \u2014 it may still be booting.")),{ok:!0,state:s,ready:i}}async function Ji(e,t=Go,o=500){let n=Date.now()+e;for(;;){if(await t())return!0;if(Date.now()>=n)return!1;await new Promise(r=>setTimeout(r,o))}}async function Yi(e){let t=l=>{e&&console.log(l)};t(G.default.dim(" Container mode (no systemd) \u2014 running gateway in foreground via nohup.")),Sr(!e);let o=Yt.default.join(Vo.default.homedir(),".openclaw","logs");try{Se.default.mkdirSync(o,{recursive:!0})}catch{}let n=Yt.default.join(o,"gateway-foreground.log"),r,s;try{r=Se.default.openSync(n,"a"),s=Se.default.openSync(n,"a")}catch(l){return{ok:!1,error:`cannot open gateway log at ${n}: ${l.message}`}}let i=(0,re.spawn)("openclaw",["gateway"],{detached:!0,stdio:["ignore",r,s]});if(i.pid==null)return{ok:!1,error:"failed to spawn `openclaw gateway`"};i.unref(),t(G.default.dim(` Gateway PID: ${i.pid}, log: ${n}`));let a=Date.now()+2e4,c=!1;for(;Date.now()<a;){try{let l=Se.default.readFileSync(n,"utf-8");if(l.includes("[gateway] ready")){c=!0;break}if(/EADDRINUSE|FATAL|Error:|gateway start blocked/.test(l))return{ok:!1,error:`gateway aborted on startup \u2014 see ${n}`}}catch{}await new Promise(l=>setTimeout(l,200))}return c?{ok:!0,state:"started",ready:!0}:{ok:!1,error:`gateway did not report ready within 20s \u2014 see ${n}`}}function Xt(){if(process.platform!=="linux"||process.getuid?.()!==0)return;let e=(0,re.spawnSync)("loginctl",["show-user","root","--property=Linger"],{encoding:"utf-8"});e.status===0&&/Linger=no/.test(e.stdout||"")&&(console.log(G.default.yellow(`
124
- \u26A0\uFE0F systemd lingering is OFF for root. The gateway will stop on SSH disconnect.`)),console.log(G.default.dim(" Enable persistence: loginctl enable-linger root")))}Fe();var xa=2e3,Ra=12e4,jr=new Dr.Command("login").description("Log in to BadgerClaw via browser").action(async()=>{let e=In(),t=xn(e),o=`${On}/cli-auth?code=${t}`;console.log(K.default.yellow("Opening browser for authentication...")),console.log(K.default.dim(`If the browser doesn't open, visit: ${o}`)),await(0,Tr.default)(o);let n=(0,Nr.default)("Waiting for authentication...").start(),r=Bn(),s=Date.now();for(;Date.now()-s<Ra;){try{let i=await r.post(`/api/v1/openclaw/cli/auth/poll/${t}`,{code_verifier:e,code_challenge:t});if(i.status===429){await new Promise(a=>setTimeout(a,5e3));continue}if(i.data?.access_token){let{access_token:a,user_id:c,expires_at:l,refresh_token:u,email:p}=i.data,A=at(),g=`openclaw-${cn.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${A}`,w=g;try{let{version:k}=we(),R=await r.post("/api/v1/openclaw/register",{instance_id:g,label:cn.default.hostname(),version:k,machine_fingerprint:A},{headers:{Authorization:`Bearer ${a}`}}),$=R.data?.result||R.data;$&&typeof $.instance_id=="string"&&$.instance_id.length>0&&(w=$.instance_id)}catch(k){let R=k?.response?.status;if(R===403||R===409){let $=k?.response?.data,V=Array.isArray($?.errors)&&typeof $.errors[0]=="string"?$.errors[0]:null,P=$?.detail,ce=typeof P=="string"?P:P?.error==="downgrade_selection_required"?"Your account has an unresolved plan-change request. Open the BadgerClaw app to finish the downgrade selection, then try again.":null,ge=V||ce||`Login refused (status ${R}). Open the BadgerClaw app to check your subscription state.`;n.fail(K.default.red(ge)),process.exit(1)}}if(Me({access_token:a,user_id:c,instance_id:w,expires_at:l,refresh_token:u,email:p}),n.succeed(K.default.green(`Logged in as ${Et(c)}`)),J()!==null){let k=await zt({verbose:!0});k.ok?k.ready===!1&&console.log(K.default.dim(" Gateway is still coming up \u2014 it should be online shortly.")):console.log(K.default.yellow("\n \u26A0\uFE0F Logged in, but gateway failed to start. Re-run `badgerclaw setup` to repair."))}else console.log(K.default.dim(" Hermes-only host \u2014 skipping OpenClaw gateway bring-up."));let C=await gt(!0);C>0&&console.log(K.default.green(`\u2705 ${C} bot(s) automatically paired to OpenClaw.`)),Fo(),Xt();try{let{pushHeartbeat:k}=await Promise.resolve().then(()=>(Ye(),an));await k(),console.log(K.default.dim(" Capabilities pushed \u2014 the machine should show online shortly."))}catch(k){console.log(K.default.dim(` Capability push will retry via the heartbeat (${k?.message||k}).`))}return}}catch{}await new Promise(i=>setTimeout(i,xa))}n.fail(K.default.red("Authentication timed out. Please try again.")),process.exit(1)});var Lr=require("commander"),kt=d(require("chalk")),ro=d(require("fs")),ze=d(require("os")),vt=d(require("path")),St=require("child_process");j();oe();function Aa(){let e=process.platform;if(e==="darwin"){let t=vt.default.join(ze.default.homedir(),"Library","LaunchAgents","ai.badgerclaw.watch.plist");(0,St.spawnSync)("launchctl",["unload",t],{stdio:"ignore"});try{ro.default.unlinkSync(t)}catch{}}else if(e==="linux"){(0,St.spawnSync)("systemctl",["--user","disable","--now","badgerclaw-watch.service"],{stdio:"ignore"});let t=vt.default.join(ze.default.homedir(),".config","systemd","user","badgerclaw-watch.service");try{ro.default.unlinkSync(t)}catch{}(0,St.spawnSync)("systemctl",["--user","daemon-reload"],{stdio:"ignore"})}(0,St.spawnSync)("pkill",["-f","badgerclaw heartbeat"],{stdio:"ignore"})}function Br(e){try{return ro.default.rmSync(e,{recursive:!0,force:!0}),!0}catch{return!1}}var Mr=new Lr.Command("logout").description("Disconnect this machine, log out of BadgerClaw, and wipe local state").option("--keep-state","Only clear auth.json (legacy behaviour); preserve bot-mapping, claude-sessions, heartbeat logs, and plugin quarantine ledger").action(async e=>{let t=h();if(t)try{let i=te(t.access_token),{version:a}=we();await i.post("/api/v1/openclaw/register",{instance_id:t.instance_id,label:ze.default.hostname(),version:a,online:!1})}catch{}if(Aa(),e.keepState){it(),console.log(kt.default.green("Logged out \u2014 auth cleared. (state preserved with --keep-state)"));return}let o=vt.default.join(ze.default.homedir(),".badgerclaw"),n=Br(o),r=vt.default.join(ze.default.homedir(),".openclaw","badgerclaw"),s=Br(r);n||s?(console.log(kt.default.green("Logged out \u2014 local state cleared.")),console.log(kt.default.dim(` Removed: ${o}${s?`, ${r}`:""}`))):console.log(kt.default.green("Logged out."))});var Hr=require("commander"),ln=d(require("chalk"));j();var Fr=new Hr.Command("status").description("Show connected instance info").action(async()=>{let e=h();(!e||!At())&&(console.log(ln.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1)),console.log(ln.default.green("Authenticated")),console.log(` User: ${Et(e.user_id)}`),console.log(` Instance: ${e.instance_id}`),console.log(` Expires: ${new Date(e.expires_at).toLocaleDateString()}`)});var Ze=require("commander"),S=d(require("chalk")),co=d(require("ora")),ao=d(require("fs")),Kr=d(require("os")),Jr=d(require("path")),Yr=require("child_process");j();oe();var Xe=d(require("fs")),Ur=d(require("os")),Gr=d(require("path")),Wr=require("child_process");dt();function so(e){let t=e.split(":")[0].replace(/^@/,"").replace(/_bot$/,""),o=Gr.join(Ur.homedir(),".openclaw","openclaw.json");return Xe.existsSync(o)?{changed:Ae(()=>{let r=JSON.parse(Xe.readFileSync(o,"utf-8")),s=!1;if(r.channels?.badgerclaw?.accounts?.[t]&&(delete r.channels.badgerclaw.accounts[t],s=!0),r.agents?.list){let i=r.agents.list.length;r.agents.list=r.agents.list.filter(a=>a.id!==t),r.agents.list.length!==i&&(s=!0)}return s&&Xe.writeFileSync(o,JSON.stringify(r,null,2)),s})}:{changed:!1}}function io(){try{return(0,Wr.execSync)("openclaw gateway restart",{stdio:"ignore"}),!0}catch{return!1}}Ee();function Vr(e){return e.hermes?"hermes":"openclaw"}function qr(e){return e.openclaw.installed?"openclaw":e.hermes.installed?"hermes":"openclaw"}function un(){At()||(console.log(S.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1))}function Ea(e){return/^[a-z0-9_]{4,20}$/.test(e)}function zr(e){return e.replace(/_bot$/,"")}var dn=["openclaw","hermes"],Pa=new Ze.Command("create").description("Create a new bot").argument("<name>","Bot name (4-20 chars, lowercase alphanumeric + underscores)").option("-r, --runtime <runtime>",`Bot runtime: ${dn.join(" | ")}. Default is selected from this host's capabilities (Hermes preferred when available, OpenClaw otherwise \u2014 see \`badgerclaw setup\` output). Hermes requires HERMES_RUNTIME_ENABLED on the backend and a host that advertises Hermes capability via badgerclaw setup. Operator-side LLM credentials (BADGERCLAW_LLM_API_KEY or GOOGLE_API_KEY etc.) must be set at pair time, not at create time.`).action(async(e,t)=>{un(),Ea(e)||(console.log(S.default.red("Invalid bot name. Must be 4-20 characters, lowercase alphanumeric and underscores only.")),process.exit(1));let o=t.runtime??qr(be());dn.includes(o)||(console.log(S.default.red(`Invalid --runtime "${t.runtime}". Must be one of: ${dn.join(", ")}.`)),process.exit(1));let n=(0,co.default)(`Creating ${o} bot "${e}"...`).start();try{let r=O();o==="hermes"?await r.post("/api/v1/bots",{bot_name:e,bot_username:e,runtime:"hermes"}):await r.post("/api/v1/openclaw/bots",{username:e}),n.succeed(S.default.green(`Bot "${e}" (${o}) created successfully!`)),o==="hermes"&&console.log(S.default.dim(" Next: generate a pair code from Adminweb (or POST /api/v1/pairing/create),\n then run `badgerclaw autopair` on a Hermes-capable host."))}catch(r){let s=r.response?.data?.errors?.[0]||r.message;n.fail(S.default.red(`Failed to create bot: ${s}`)),process.exit(1)}}),Oa=new Ze.Command("list").description("List your bots").action(async()=>{un();let e=(0,co.default)("Fetching bots...").start();try{let n=(await O().get("/api/v1/openclaw/bots")).data?.bots||[];if(e.stop(),n.length===0){console.log(S.default.yellow("No bots found. Create one with `badgerclaw bot create <name>`."));return}console.log(S.default.green(`Your bots (${n.length}):
123
+ `}function gr(){try{return(0,X.execSync)("systemctl --user --version",{stdio:"ignore"}),!0}catch{return!1}}function fr(){if(ht.default.platform()!=="linux"||!gr())return!1;try{let e=Pi();Ke.default.mkdirSync(pr,{recursive:!0}),Ke.default.mkdirSync(wt.default.join(ht.default.homedir(),".badgerclaw"),{recursive:!0}),Ke.default.writeFileSync(Bo,Di(e)),(0,X.execSync)("systemctl --user daemon-reload",{stdio:"ignore"});try{(0,X.execSync)(`systemctl --user restart ${Vt}`,{stdio:"ignore"})}catch{}(0,X.execSync)(`systemctl --user enable --now ${Vt}`,{stdio:"ignore"});try{let t=(0,X.execSync)("whoami",{encoding:"utf-8"}).trim();(0,X.execSync)(`loginctl enable-linger ${t}`,{stdio:"ignore"})}catch{}return console.log("\x1B[2mHeartbeat daemon registered as systemd user service (auto-starts on login).\x1B[0m"),!0}catch{return!1}}function hr(){if(ht.default.platform()==="linux"&&gr()){try{(0,X.execSync)(`systemctl --user disable --now ${Vt}`,{stdio:"ignore"})}catch{}try{Ke.default.existsSync(Bo)&&Ke.default.unlinkSync(Bo),(0,X.execSync)("systemctl --user daemon-reload",{stdio:"ignore"})}catch{}}}var Lo=Kt.default.join(qt.default.homedir(),".badgerclaw"),yt=Kt.default.join(Lo,"heartbeat.pid"),Ni=Kt.default.join(Lo,"heartbeat.log");function Ti(e){if(!e||e.length===0)return!1;let t=s=>/(^|[\\/])node(\.exe)?$/i.test(s||""),o=t(e[0])||t(e[1]),n=e.includes("heartbeat"),r=e.some(s=>/(^|[\\/])badgerclaw($|[\\/. ])/i.test(s)||/[\\/]dist[\\/]index\.js$/.test(s));return o&&n&&r}function ji(e){try{if(process.platform==="linux")return Z.default.readFileSync(`/proc/${e}/cmdline`).toString("utf-8").split("\0").filter(Boolean);let t=(0,Oe.execSync)(`ps -o args= -p ${e}`,{encoding:"utf-8"}).trim();return t.length?t.split(/\s+/).filter(Boolean):null}catch{return null}}function Mo(e){if(!Number.isFinite(e)||e<=0||e===process.pid||e===process.ppid)return!1;let t=ji(e);return t?Ti(t):!1}function Ho(){let e="";try{e=(0,Oe.execSync)("pgrep -f heartbeat",{encoding:"utf-8"})}catch{return[]}return e.split(/\s+/).map(t=>parseInt(t,10)).filter(t=>Number.isFinite(t)&&t>0).filter(t=>Mo(t))}function Bi(e){try{Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,Math.max(0,e))}catch{}}function Li(e){try{if(process.platform==="linux"){let r=Z.default.readFileSync(`/proc/${e}/status`,"utf-8").match(/^PPid:\s*(\d+)/m),s=r?parseInt(r[1],10):NaN;if(!Number.isFinite(s))return null;let i="";try{i=Z.default.readFileSync(`/proc/${s}/comm`,"utf-8").trim()}catch{}return{ppid:s,comm:i}}let t=parseInt((0,Oe.execSync)(`ps -o ppid= -p ${e}`,{encoding:"utf-8"}).trim(),10);if(!Number.isFinite(t))return null;let o="";try{o=(0,Oe.execSync)(`ps -o comm= -p ${t}`,{encoding:"utf-8"}).trim()}catch{}return{ppid:t,comm:o}}catch{return null}}var Mi=/(systemd|supervisord|launchd|runsv|runit|s6-supervise|openrc)/i;function Hi(){for(let e of Ho()){let t=Li(e);if(t&&Mi.test(t.comm))return e}return null}function Fi(){try{let e=parseInt(Z.default.readFileSync(yt,"utf-8").trim(),10);if(Number.isFinite(e)&&e>0&&Mo(e))return!0}catch{}return yr(),Ho().length>0}function yr(){try{let e=parseInt(Z.default.readFileSync(yt,"utf-8").trim(),10);if(Number.isFinite(e)&&e>0&&Mo(e))return}catch{}try{Z.default.rmSync(yt,{force:!0})}catch{}}function Ui(e="SIGTERM"){let t=Ho(),o=0;for(let i of t)try{process.kill(i,e),o++}catch{}if(o===0)return 0;let n=i=>{try{return process.kill(i,0),!0}catch{return!1}},r=Date.now()+4e3,s=t.filter(n);for(;s.length>0&&Date.now()<r;)Bi(120),s=s.filter(n);for(let i of s)try{process.kill(i,"SIGKILL")}catch{}return o}function wr(){if(Fi())return console.log("\x1B[2mHeartbeat already running.\x1B[0m"),!0;try{Z.default.mkdirSync(Lo,{recursive:!0});let e=Z.default.openSync(Ni,"a"),t=(0,Oe.spawn)(process.execPath,[process.argv[1],"heartbeat"],{detached:!0,stdio:["ignore",e,e]});if(t.pid==null)return console.log("\x1B[2mNote: could not start the heartbeat. Run `badgerclaw heartbeat` manually.\x1B[0m"),!1;try{Z.default.writeFileSync(yt,String(t.pid))}catch{}return t.unref(),console.log("\x1B[2mHeartbeat started in the background (no service manager on this host; it will not auto-restart after a reboot \u2014 re-run `badgerclaw setup --hermes` or `badgerclaw heartbeat` if the host restarts).\x1B[0m"),!0}catch{return console.log("\x1B[2mNote: could not start the heartbeat. Run `badgerclaw heartbeat` manually.\x1B[0m"),!1}}function Fo(){let e=qt.default.platform();if(e==="darwin"){ur();return}if(e==="linux"){if(fr())return;wr();return}wr()}function Gi(){let e=qt.default.platform();e==="darwin"?mr():e==="linux"&&hr(),Ui();try{Z.default.rmSync(yt,{force:!0})}catch{}}function br(e){let t=e.log||(()=>{}),o=Hi();if(o!==null){yr(),t(`heartbeat already supervised (pid ${o}) \u2014 left in place; cleared any stale pid file.`);return}Gi(),t("removed stale heartbeat hooks from previous installs."),e.loggedIn?(Fo(),t("reinstalled a fresh heartbeat daemon for this host.")):t("run `badgerclaw login` to start the heartbeat for this host.")}var Se=d(require("fs")),Vo=d(require("os")),Yt=d(require("path")),re=require("child_process"),G=d(require("chalk"));dt();ke();var kr=Yt.default.join(Vo.default.homedir(),".openclaw","openclaw.json");function Ki(){return process.platform!=="linux"?!1:!!(Se.default.existsSync("/.dockerenv")||(0,re.spawnSync)("which",["systemctl"],{encoding:"utf-8"}).status!==0)}function Sr(e=!1){let t=null;try{Se.default.existsSync(kr)&&(t=JSON.parse(Se.default.readFileSync(kr,"utf-8"))?.gateway?.mode??null)}catch{}if(typeof t=="string"&&t.length>0)return!0;e||console.log(G.default.dim(" Setting gateway.mode=local..."));try{return Ae(()=>((0,re.execSync)("openclaw config set gateway.mode local",{encoding:"utf-8",timeout:1e4,stdio:"pipe"}),!0))}catch(o){return e||(console.log(G.default.yellow(` \u26A0\uFE0F Could not set gateway.mode automatically: ${o.message}`)),console.log(G.default.yellow(" Run `openclaw config set gateway.mode local` manually."))),!1}}async function zt(e={}){let t=e.verbose!==!1,o=a=>{t&&console.log(a)};if(Ki())return Yi(t);o(G.default.dim(" Installing OpenClaw gateway service (if not present)...")),(0,re.spawnSync)("openclaw",["gateway","install"],{stdio:t?"inherit":"pipe",shell:!0}).status!==0&&o(G.default.yellow(" \u26A0\uFE0F `openclaw gateway install` returned non-zero \u2014 continuing.")),Sr(!t),o(G.default.dim(" Starting OpenClaw gateway..."));let r=(0,re.spawnSync)("openclaw",["gateway","start"],{stdio:t?"inherit":"pipe",shell:!0}),s="started";if(r.status!==0&&(r=(0,re.spawnSync)("openclaw",["gateway","restart"],{stdio:t?"inherit":"pipe",shell:!0}),s="restarted"),r.status!==0)return{ok:!1,error:"gateway start/restart returned non-zero exit"};o(G.default.dim(" Waiting for the gateway to start answering..."));let i=await Ji(2e4);return i||o(G.default.yellow(" \u26A0\uFE0F Gateway start issued but it is not answering yet \u2014 it may still be booting.")),{ok:!0,state:s,ready:i}}async function Ji(e,t=Go,o=500){let n=Date.now()+e;for(;;){if(await t())return!0;if(Date.now()>=n)return!1;await new Promise(r=>setTimeout(r,o))}}async function Yi(e){let t=l=>{e&&console.log(l)};t(G.default.dim(" Container mode (no systemd) \u2014 running gateway in foreground via nohup.")),Sr(!e);let o=Yt.default.join(Vo.default.homedir(),".openclaw","logs");try{Se.default.mkdirSync(o,{recursive:!0})}catch{}let n=Yt.default.join(o,"gateway-foreground.log"),r,s;try{r=Se.default.openSync(n,"a"),s=Se.default.openSync(n,"a")}catch(l){return{ok:!1,error:`cannot open gateway log at ${n}: ${l.message}`}}let i=(0,re.spawn)("openclaw",["gateway"],{detached:!0,stdio:["ignore",r,s]});if(i.pid==null)return{ok:!1,error:"failed to spawn `openclaw gateway`"};i.unref(),t(G.default.dim(` Gateway PID: ${i.pid}, log: ${n}`));let a=Date.now()+2e4,c=!1;for(;Date.now()<a;){try{let l=Se.default.readFileSync(n,"utf-8");if(l.includes("[gateway] ready")){c=!0;break}if(/EADDRINUSE|FATAL|Error:|gateway start blocked/.test(l))return{ok:!1,error:`gateway aborted on startup \u2014 see ${n}`}}catch{}await new Promise(l=>setTimeout(l,200))}return c?{ok:!0,state:"started",ready:!0}:{ok:!1,error:`gateway did not report ready within 20s \u2014 see ${n}`}}function Xt(){if(process.platform!=="linux"||process.getuid?.()!==0)return;let e=(0,re.spawnSync)("loginctl",["show-user","root","--property=Linger"],{encoding:"utf-8"});e.status===0&&/Linger=no/.test(e.stdout||"")&&(console.log(G.default.yellow(`
124
+ \u26A0\uFE0F systemd lingering is OFF for root. The gateway will stop on SSH disconnect.`)),console.log(G.default.dim(" Enable persistence: loginctl enable-linger root")))}Fe();var xa=2e3,Ra=12e4,jr=new Dr.Command("login").description("Log in to BadgerClaw via browser").action(async()=>{let e=In(),t=xn(e),o=`${On}/cli-auth?code=${t}`;console.log(K.default.yellow("Opening browser for authentication...")),console.log(K.default.dim(`If the browser doesn't open, visit: ${o}`)),await(0,Tr.default)(o);let n=(0,Nr.default)("Waiting for authentication...").start(),r=Bn(),s=Date.now();for(;Date.now()-s<Ra;){try{let i=await r.post(`/api/v1/openclaw/cli/auth/poll/${t}`,{code_verifier:e,code_challenge:t});if(i.status===429){await new Promise(a=>setTimeout(a,5e3));continue}if(i.data?.access_token){let{access_token:a,user_id:c,expires_at:l,refresh_token:u,email:p}=i.data,A=at(),g=`openclaw-${cn.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${A}`,w=g;try{let{version:k}=we(),R=await r.post("/api/v1/openclaw/register",{instance_id:g,label:cn.default.hostname(),version:k,machine_fingerprint:A},{headers:{Authorization:`Bearer ${a}`}}),$=R.data?.result||R.data;$&&typeof $.instance_id=="string"&&$.instance_id.length>0&&(w=$.instance_id)}catch(k){let R=k?.response?.status;if(R===403||R===409){let $=k?.response?.data,V=Array.isArray($?.errors)&&typeof $.errors[0]=="string"?$.errors[0]:null,P=$?.detail,ce=typeof P=="string"?P:P?.error==="downgrade_selection_required"?"Your account has an unresolved plan-change request. Open the BadgerClaw app to finish the downgrade selection, then try again.":null,ge=V||ce||`Login refused (status ${R}). Open the BadgerClaw app to check your subscription state.`;n.fail(K.default.red(ge)),process.exit(1)}}if(Me({access_token:a,user_id:c,instance_id:w,expires_at:l,refresh_token:u,email:p}),n.succeed(K.default.green(`Logged in as ${Et(c)}`)),Y()!==null){let k=await zt({verbose:!0});k.ok?k.ready===!1&&console.log(K.default.dim(" Gateway is still coming up \u2014 it should be online shortly.")):console.log(K.default.yellow("\n \u26A0\uFE0F Logged in, but gateway failed to start. Re-run `badgerclaw setup` to repair."))}else console.log(K.default.dim(" Hermes-only host \u2014 skipping OpenClaw gateway bring-up."));let C=await gt(!0);C>0&&console.log(K.default.green(`\u2705 ${C} bot(s) automatically paired to OpenClaw.`)),Fo(),Xt();try{let{pushHeartbeat:k}=await Promise.resolve().then(()=>(Ye(),an));await k(),console.log(K.default.dim(" Capabilities pushed \u2014 the machine should show online shortly."))}catch(k){console.log(K.default.dim(` Capability push will retry via the heartbeat (${k?.message||k}).`))}return}}catch{}await new Promise(i=>setTimeout(i,xa))}n.fail(K.default.red("Authentication timed out. Please try again.")),process.exit(1)});var Lr=require("commander"),kt=d(require("chalk")),ro=d(require("fs")),ze=d(require("os")),vt=d(require("path")),St=require("child_process");j();oe();function Aa(){let e=process.platform;if(e==="darwin"){let t=vt.default.join(ze.default.homedir(),"Library","LaunchAgents","ai.badgerclaw.watch.plist");(0,St.spawnSync)("launchctl",["unload",t],{stdio:"ignore"});try{ro.default.unlinkSync(t)}catch{}}else if(e==="linux"){(0,St.spawnSync)("systemctl",["--user","disable","--now","badgerclaw-watch.service"],{stdio:"ignore"});let t=vt.default.join(ze.default.homedir(),".config","systemd","user","badgerclaw-watch.service");try{ro.default.unlinkSync(t)}catch{}(0,St.spawnSync)("systemctl",["--user","daemon-reload"],{stdio:"ignore"})}(0,St.spawnSync)("pkill",["-f","badgerclaw heartbeat"],{stdio:"ignore"})}function Br(e){try{return ro.default.rmSync(e,{recursive:!0,force:!0}),!0}catch{return!1}}var Mr=new Lr.Command("logout").description("Disconnect this machine, log out of BadgerClaw, and wipe local state").option("--keep-state","Only clear auth.json (legacy behaviour); preserve bot-mapping, claude-sessions, heartbeat logs, and plugin quarantine ledger").action(async e=>{let t=h();if(t)try{let i=J(t.access_token),{version:a}=we();await i.post("/api/v1/openclaw/register",{instance_id:t.instance_id,label:ze.default.hostname(),version:a,online:!1})}catch{}if(Aa(),e.keepState){it(),console.log(kt.default.green("Logged out \u2014 auth cleared. (state preserved with --keep-state)"));return}let o=vt.default.join(ze.default.homedir(),".badgerclaw"),n=Br(o),r=vt.default.join(ze.default.homedir(),".openclaw","badgerclaw"),s=Br(r);n||s?(console.log(kt.default.green("Logged out \u2014 local state cleared.")),console.log(kt.default.dim(` Removed: ${o}${s?`, ${r}`:""}`))):console.log(kt.default.green("Logged out."))});var Hr=require("commander"),ln=d(require("chalk"));j();var Fr=new Hr.Command("status").description("Show connected instance info").action(async()=>{let e=h();(!e||!At())&&(console.log(ln.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1)),console.log(ln.default.green("Authenticated")),console.log(` User: ${Et(e.user_id)}`),console.log(` Instance: ${e.instance_id}`),console.log(` Expires: ${new Date(e.expires_at).toLocaleDateString()}`)});var Ze=require("commander"),S=d(require("chalk")),co=d(require("ora")),ao=d(require("fs")),Kr=d(require("os")),Jr=d(require("path")),Yr=require("child_process");j();oe();var Xe=d(require("fs")),Ur=d(require("os")),Gr=d(require("path")),Wr=require("child_process");dt();function so(e){let t=e.split(":")[0].replace(/^@/,"").replace(/_bot$/,""),o=Gr.join(Ur.homedir(),".openclaw","openclaw.json");return Xe.existsSync(o)?{changed:Ae(()=>{let r=JSON.parse(Xe.readFileSync(o,"utf-8")),s=!1;if(r.channels?.badgerclaw?.accounts?.[t]&&(delete r.channels.badgerclaw.accounts[t],s=!0),r.agents?.list){let i=r.agents.list.length;r.agents.list=r.agents.list.filter(a=>a.id!==t),r.agents.list.length!==i&&(s=!0)}return s&&Xe.writeFileSync(o,JSON.stringify(r,null,2)),s})}:{changed:!1}}function io(){try{return(0,Wr.execSync)("openclaw gateway restart",{stdio:"ignore"}),!0}catch{return!1}}Ee();function Vr(e){return e.hermes?"hermes":"openclaw"}function qr(e){return e.openclaw.installed?"openclaw":e.hermes.installed?"hermes":"openclaw"}function un(){At()||(console.log(S.default.red("Not logged in. Run `badgerclaw login` to authenticate.")),process.exit(1))}function Ea(e){return/^[a-z0-9_]{4,20}$/.test(e)}function zr(e){return e.replace(/_bot$/,"")}var dn=["openclaw","hermes"],Pa=new Ze.Command("create").description("Create a new bot").argument("<name>","Bot name (4-20 chars, lowercase alphanumeric + underscores)").option("-r, --runtime <runtime>",`Bot runtime: ${dn.join(" | ")}. Default is selected from this host's capabilities (Hermes preferred when available, OpenClaw otherwise \u2014 see \`badgerclaw setup\` output). Hermes requires HERMES_RUNTIME_ENABLED on the backend and a host that advertises Hermes capability via badgerclaw setup. Operator-side LLM credentials (BADGERCLAW_LLM_API_KEY or GOOGLE_API_KEY etc.) must be set at pair time, not at create time.`).action(async(e,t)=>{un(),Ea(e)||(console.log(S.default.red("Invalid bot name. Must be 4-20 characters, lowercase alphanumeric and underscores only.")),process.exit(1));let o=t.runtime??qr(be());dn.includes(o)||(console.log(S.default.red(`Invalid --runtime "${t.runtime}". Must be one of: ${dn.join(", ")}.`)),process.exit(1));let n=(0,co.default)(`Creating ${o} bot "${e}"...`).start();try{let r=O();o==="hermes"?await r.post("/api/v1/bots",{bot_name:e,bot_username:e,runtime:"hermes"}):await r.post("/api/v1/openclaw/bots",{username:e}),n.succeed(S.default.green(`Bot "${e}" (${o}) created successfully!`)),o==="hermes"&&console.log(S.default.dim(" Next: generate a pair code from Adminweb (or POST /api/v1/pairing/create),\n then run `badgerclaw autopair` on a Hermes-capable host."))}catch(r){let s=r.response?.data?.errors?.[0]||r.message;n.fail(S.default.red(`Failed to create bot: ${s}`)),process.exit(1)}}),Oa=new Ze.Command("list").description("List your bots").action(async()=>{un();let e=(0,co.default)("Fetching bots...").start();try{let n=(await O().get("/api/v1/openclaw/bots")).data?.bots||[];if(e.stop(),n.length===0){console.log(S.default.yellow("No bots found. Create one with `badgerclaw bot create <name>`."));return}console.log(S.default.green(`Your bots (${n.length}):
125
125
  `));for(let r of n){let s=zr(r.username||r.name),i=r.active===!1?S.default.dim("deactivated"):r.openclaw_connected?S.default.green("connected"):S.default.gray("disconnected");console.log(` ${S.default.bold(s)} ${i}`)}}catch(t){let o=t.response?.data?.errors?.[0]||t.message;e.fail(S.default.red(`Failed to list bots: ${o}`)),process.exit(1)}}),Da=new Ze.Command("delete").description("Deactivate a bot").argument("<name>","Bot name to deactivate").action(async e=>{un();let t=(0,co.default)(`Deactivating bot "${e}"...`).start();try{await O().delete(`/api/v1/openclaw/bots/${e}`),t.succeed(S.default.green(`Bot "${e}" deactivated.`));let{changed:n}=so(e);n&&(console.log(S.default.dim(" Removed from openclaw.json")),io()&&console.log(S.default.dim(" Gateway restarted")))}catch(o){let n=o.response?.data?.errors?.[0]||o.message;t.fail(S.default.red(`Failed to deactivate bot: ${n}`)),process.exit(1)}});function Na(e){let t=e.trim();return t.startsWith("@")&&(t=t.slice(1)),t.includes(":")&&(t=t.split(":")[0]),zr(t)}function Ta(e){let t=e.replace(/[^a-zA-Z0-9_.-]/g,"_")||"default";return Jr.default.join(Kr.default.homedir(),".openclaw","badgerclaw","quarantine",`${t}.json`)}var ja=new Ze.Command("refresh").description("Recover a bot stuck in quarantine \u2014 clears the quarantine ledger and restarts the gateway so the plugin's refresh chain runs from scratch").argument("<name>",'Bot name (e.g. "claude", "claude_bot", or full Matrix ID)').action(async e=>{let t=Na(e);t||(console.log(S.default.red(`Couldn't parse bot name "${e}".`)),process.exit(1));let o=Ta(t),n=!1;if(ao.default.existsSync(o))try{let r=JSON.parse(ao.default.readFileSync(o,"utf-8")),s=r.failureCount??"?",i=r.quarantinedAt??"?";console.log(S.default.dim(` Quarantine for "${t}" \u2014 ${s} failures, since ${i}`)),ao.default.unlinkSync(o),n=!0}catch(r){console.log(S.default.red(`Failed to clear quarantine ledger at ${o}: ${r.message}`)),process.exit(1)}console.log(n?S.default.green(`\u2705 Cleared quarantine for "${t}"`):S.default.dim(` No quarantine file for "${t}" \u2014 already healthy or never quarantined.`)),console.log(S.default.dim(" Restarting OpenClaw gateway so the refresh chain runs..."));try{(0,Yr.execSync)("openclaw gateway restart",{stdio:"inherit"})}catch(r){console.log(S.default.yellow(` Gateway restart command failed: ${r.message}`)),console.log(S.default.yellow(" Run `openclaw gateway restart` manually.")),process.exit(1)}console.log(S.default.green(`
126
- \u2705 Refresh triggered. Watch the gateway logs for token refresh progress:`)),console.log(S.default.dim(" tail -f ~/.openclaw/logs/*.log")),console.log(S.default.dim(" If the bot fails to recover, the plugin's 4 refresh strategies all hit")),console.log(S.default.dim(" dead ends. Verify SYNAPSE_REGISTRATION_SHARED_SECRET is set on this gateway,")),console.log(S.default.dim(" or re-pair the bot from the BadgerClaw iOS app."))}),Xr=new Ze.Command("bot").description("Manage bots").addCommand(Pa).addCommand(Oa).addCommand(Da).addCommand(ja);ft();var Qr=require("commander"),b=d(require("chalk"));j();fe();ft();ke();Ye();rn();oe();xe();var Zr=3e3,Ba=6e4,La=2700*1e3,es=new Qr.Command("watch").description("Watch for bot pair events in real-time (no polling)").action(async()=>{h()||(console.log(b.default.yellow("Not logged in.")),process.exit(1)),await gt(!1),console.log(b.default.green("\u{1F534} Listening for pair events... (Ctrl+C to stop)"));let t=require("eventsource"),o=Zr,n=null,r=null,s=()=>{let i=h();i||(console.log(b.default.red(" Auth missing \u2014 run `badgerclaw login` and re-start `badgerclaw watch`.")),process.exit(1));let a=new t(`${U}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${i.access_token}`}});r=a,a.onopen=()=>{o=Zr,console.log(b.default.dim(" SSE connected \u2014 listening for events")),n&&clearTimeout(n),n=setTimeout(()=>{console.log(b.default.dim(" SSE proactive reconnect \u2014 refreshing token before expiry")),a.close(),s()},La)},a.onerror=()=>{a.close(),n&&(clearTimeout(n),n=null),console.log(b.default.dim(` SSE disconnected \u2014 reconnecting in ${Math.floor(o/1e3)}s...`)),setTimeout(s,o),o=Math.min(o*1.5,Ba)},a.onmessage=async c=>{try{let l=JSON.parse(c.data);if(l.type==="pair"){let u=l.target_instance_id;if(u&&u!==ee()){console.log(b.default.dim(`
126
+ \u2705 Refresh triggered. Watch the gateway logs for token refresh progress:`)),console.log(S.default.dim(" tail -f ~/.openclaw/logs/*.log")),console.log(S.default.dim(" If the bot fails to recover, the plugin's 4 refresh strategies all hit")),console.log(S.default.dim(" dead ends. Verify SYNAPSE_REGISTRATION_SHARED_SECRET is set on this gateway,")),console.log(S.default.dim(" or re-pair the bot from the BadgerClaw iOS app."))}),Xr=new Ze.Command("bot").description("Manage bots").addCommand(Pa).addCommand(Oa).addCommand(Da).addCommand(ja);ft();var Qr=require("commander"),b=d(require("chalk"));j();fe();ft();ke();Ye();rn();oe();xe();var Zr=3e3,Ba=6e4,La=2700*1e3,es=new Qr.Command("watch").description("Watch for bot pair events in real-time (no polling)").action(async()=>{h()||(console.log(b.default.yellow("Not logged in.")),process.exit(1)),await gt(!1),console.log(b.default.green("\u{1F534} Listening for pair events... (Ctrl+C to stop)"));let t=require("eventsource"),o=Zr,n=null,r=null,s=()=>{let i=h();i||(console.log(b.default.red(" Auth missing \u2014 run `badgerclaw login` and re-start `badgerclaw watch`.")),process.exit(1));let a=new t(`${U}/api/v1/openclaw/events`,{headers:{Authorization:`Bearer ${i.access_token}`}});r=a,a.onopen=()=>{o=Zr,console.log(b.default.dim(" SSE connected \u2014 listening for events")),n&&clearTimeout(n),n=setTimeout(()=>{console.log(b.default.dim(" SSE proactive reconnect \u2014 refreshing token before expiry")),a.close(),s()},La)},a.onerror=()=>{a.close(),n&&(clearTimeout(n),n=null),console.log(b.default.dim(` SSE disconnected \u2014 reconnecting in ${Math.floor(o/1e3)}s...`)),setTimeout(s,o),o=Math.min(o*1.5,Ba)},a.onmessage=async c=>{try{let l=JSON.parse(c.data);if(l.type==="pair"){let u=l.target_instance_id;if(u&&u!==te()){console.log(b.default.dim(`
127
127
  \u{1F4F1} Pair event for ${l.bot_name} targets ${u} \u2014 not us, skipping`));return}console.log(b.default.cyan(`
128
128
  \u{1F4F1} Pair event received: ${l.bot_name}`)),await pt(l.pair_code,l.bot_name,l.bot_user_id,!1);try{let{execSync:p}=await import("child_process");p("openclaw gateway restart",{stdio:"ignore"}),console.log(b.default.green(" \u2705 Gateway restarted \u2014 bot is live!"))}catch{console.log(b.default.dim(" Gateway restart failed \u2014 run: openclaw gateway restart"))}}else if(l.type==="gateway-restart"){console.log(b.default.cyan(`
129
129
  \u{1F504} Remote gateway-restart command received`));let u=await Je();u.success?console.log(b.default.green(` \u2705 Gateway restarted: ${u.message}`)):console.log(b.default.red(` \u274C Gateway restart failed: ${u.message}`));try{await L(),console.log(b.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(b.default.dim(" Could not push heartbeat."))}}else if((l.type==="bot.delete"||l.type==="bot.disconnect")&&l.bot_user_id){let u=l.bot_user_id,p=l.type==="bot.delete"?"deleted":"disconnected",A=l.type==="bot.delete"?"\u{1F5D1}\uFE0F ":"\u{1F50C}";console.log(b.default.yellow(`
130
130
  ${A} Bot ${p}: ${u} \u2014 removing from OpenClaw config...`));try{let{changed:g}=so(u);g?(console.log(b.default.green(" \u2705 Removed from openclaw.json")),io()?console.log(b.default.green(" \u2705 Gateway restarted")):console.log(b.default.dim(" Gateway restart failed \u2014 restart manually"))):console.log(b.default.dim(" Account not found in openclaw.json \u2014 nothing to remove"))}catch(g){console.log(b.default.red(` Failed to update openclaw.json: ${g}`))}}else if(l.type==="claude_code.start"&&l.bot_id&&l.room_id){console.log(b.default.cyan(`
131
131
  \u{1F916} Claude Code START received: bot=${l.bot_id} room=${l.room_id}`));try{let u=await ue({id:l.command_id||`cc-start-${Date.now()}`,command_type:"start_claude_code",payload:{bot_id:l.bot_id,room_id:l.room_id,session_id:l.session_id}});if(console.log(u.success?b.default.green(` \u2705 ${u.message}`):b.default.red(` \u274C ${u.message}`)),l.command_id)try{await O().post(`/api/v1/dashboard/commands/${l.command_id}/result`,{status:u.success?"success":"failed",result:u.message})}catch{}try{await L()}catch{}}catch(u){console.log(b.default.red(` Claude Code start error: ${u.message}`))}}else if(l.type==="claude_code.stop"&&l.bot_id&&l.room_id){console.log(b.default.cyan(`
132
132
  \u{1F916} Claude Code STOP received: bot=${l.bot_id} room=${l.room_id}`));try{let u=await ue({id:l.command_id||`cc-stop-${Date.now()}`,command_type:"stop_claude_code",payload:{bot_id:l.bot_id,room_id:l.room_id,session_id:l.session_id}});if(console.log(u.success?b.default.green(` \u2705 ${u.message}`):b.default.red(` \u274C ${u.message}`)),l.command_id)try{await O().post(`/api/v1/dashboard/commands/${l.command_id}/result`,{status:u.success?"success":"failed",result:u.message})}catch{}try{await L()}catch{}}catch(u){console.log(b.default.red(` Claude Code stop error: ${u.message}`))}}else if(l.type==="command.execute"&&l.command_id){console.log(b.default.cyan(`
133
- \u26A1 SSE command received: ${l.command_type} (${l.command_id})`));try{let u=O();await u.post(`/api/v1/dashboard/commands/${l.command_id}/ack`);let p=await ue({id:l.command_id,command_type:l.command_type,payload:l.payload});console.log(p.success?b.default.green(` \u2705 ${p.message}`):b.default.red(` \u274C ${p.message}`)),await u.post(`/api/v1/dashboard/commands/${l.command_id}/result`,{status:p.success?"success":"failed",result:p.message,new_version:p.newVersion||null});try{await L()}catch{}l.command_type==="update_cli"&&p.success&&(console.log(b.default.cyan(" CLI updated \u2014 restarting in 2s...")),setTimeout(()=>process.exit(0),2e3))}catch(u){console.log(b.default.red(` Command ${l.command_id} error: ${u.message}`))}}}catch{}}};s(),await new Promise(()=>{})});var ps=require("commander"),m=d(require("chalk")),se=require("child_process"),E=d(require("fs")),Ct=d(require("os")),me=d(require("path"));fe();Fe();Ee();var et=require("child_process"),os=d(require("fs")),T=d(require("chalk")),W={alreadyUp:!1,install:null,start:null,requiresRoot:!1,networkHostRequired:!1,guidance:null},ts='On this distro the bare "docker" package is the podman shim (no dockerd). Install Docker Engine from the official docker-ce repository (https://docs.docker.com/engine/install/), then re-run `badgerclaw setup --hermes`.';function Ma(e){return e.daemonUp?{...W,alreadyUp:!0}:e.host==="darwin"?e.hasDockerApp?{...W,start:"docker-app"}:e.hasColima?{...W,start:"colima"}:e.binaryPresent?{...W,guidance:"A `docker` CLI is present but no engine we can start (Docker.app / colima) was found and the daemon is not answering. Start your Docker daemon (or `colima start`), then re-run `badgerclaw setup --hermes`."}:e.hasBrew?{...W,install:{tool:"colima",via:"brew"},start:"colima"}:{...W,guidance:"No container engine found and Homebrew is absent. Install Docker Desktop (https://www.docker.com/products/docker-desktop) or Homebrew (https://brew.sh) then colima, and re-run `badgerclaw setup --hermes`."}:e.host==="linux-systemd"?e.binaryPresent?{...W,start:"systemctl",requiresRoot:!0}:e.pkgManager==="apt"?{...W,install:{tool:"docker",via:"apt"},start:"systemctl",requiresRoot:!0}:{...W,guidance:e.pkgManager?ts:"Docker is not installed and no supported package manager (apt) was found. Install Docker, then re-run."}:e.host==="linux-nosystemd"?e.binaryPresent?{...W,start:"dockerd-restricted",requiresRoot:!0,networkHostRequired:!0}:e.pkgManager==="apt"?{...W,install:{tool:"docker",via:"apt"},start:"dockerd-restricted",requiresRoot:!0,networkHostRequired:!0}:{...W,guidance:e.pkgManager?ts:"Docker is not installed and no supported package manager (apt) was found. Install Docker (e.g. `apt-get install -y docker.io`), then re-run."}:{...W,guidance:`Automatic Docker setup isn't supported on this platform (${process.platform}). Install + start Docker manually, then re-run.`}}function ns(e,t,o=8e3){return(0,et.spawnSync)(e,t,{encoding:"utf-8",timeout:o})}function mn(){let e=ns("docker",["version","--format","{{.Server.Version}}"],4e3);return e.status===0&&!!(e.stdout||"").trim()}function Ha(){return ns("docker",["--version"],4e3).status===0}function Qe(e){return(0,et.spawnSync)("sh",["-c",`command -v ${e}`],{encoding:"utf-8"}).status===0}function Fa(){return Qe("apt-get")?"apt":Qe("dnf")?"dnf":Qe("yum")?"yum":null}function Ua(){let e=(0,et.spawnSync)("systemctl",["is-system-running"],{encoding:"utf-8",timeout:4e3});if(e.error)return!1;let t=`${e.stdout||""}${e.stderr||""}`.toLowerCase();return!/failed to connect to bus|not been booted with systemd|no such file/.test(t)}function Ga(){return process.platform==="darwin"?"darwin":process.platform==="linux"?Ua()?"linux-systemd":"linux-nosystemd":"unsupported"}function Wa(){return typeof process.getuid=="function"?process.getuid()===0:!1}function ve(e,t){return t(T.default.dim(` $ ${e}`)),(0,et.spawnSync)("sh",["-c",e],{stdio:"inherit"}).status===0}function Va(e,t,o){let n=t?"sudo ":"";switch(e.via){case"brew":return o(T.default.dim(" Installing colima + docker CLI via Homebrew...")),ve("brew install colima docker",o);case"apt":return o(T.default.dim(" Installing Docker via apt...")),ve(`${n}apt-get update`,o),ve(`${n}apt-get install -y docker.io`,o);default:return!1}}function qa(e,t,o){let n=t?"sudo ":"";switch(e){case"docker-app":return ve("open -a Docker",o);case"colima":return ve("colima start",o);case"systemctl":return ve(`${n}systemctl enable --now docker`,o);case"dockerd-restricted":{if(!Qe("dockerd"))return o(T.default.red(" \u274C `dockerd` is not installed (the docker CLI alone is not enough on a no-systemd host).")),!1;if(t&&!ve("sudo -v",o))return o(T.default.red(" \u274C root is required to start dockerd here, but sudo is unavailable.")),!1;ve(`${n}sh -c 'mount -t cgroup2 none /sys/fs/cgroup 2>/dev/null || true'`,o);let r="/tmp/badgerclaw-dockerd.log";o(T.default.dim(` Starting dockerd (restricted: --bridge=none --iptables=false) \u2192 ${r}`));let s=`nohup dockerd --storage-driver=overlay2 --iptables=false --bridge=none > ${r} 2>&1 &`,i=t?`sudo sh -c ${JSON.stringify(s)}`:`sh -c ${JSON.stringify(s)}`;return(0,et.spawnSync)("sh",["-c",i],{stdio:"ignore"}).status===0}}}async function Ka(e,t,o){let n=Date.now()+t;for(;;){if(e())return!0;if(Date.now()>=n)return!1;await new Promise(r=>setTimeout(r,o))}}async function rs(e={}){let t=e.log??(i=>console.log(i));if(process.env.BADGERCLAW_NO_AUTO_DEPS==="1"){let i=mn();return i||(t(T.default.yellow(" BADGERCLAW_NO_AUTO_DEPS=1 \u2014 skipping automatic Docker setup.")),t(T.default.dim(" Start the Docker daemon yourself, then re-run `badgerclaw setup --hermes`."))),{ok:i,daemonUp:i,networkHostRequired:!1}}let o={daemonUp:mn(),binaryPresent:Ha(),host:Ga(),hasBrew:Qe("brew"),hasDockerApp:os.default.existsSync("/Applications/Docker.app"),hasColima:Qe("colima"),pkgManager:Fa(),isRoot:Wa()},n=Ma(o);if(n.alreadyUp)return{ok:!0,daemonUp:!0,networkHostRequired:!1};if(n.guidance)return t(T.default.red(` \u274C ${n.guidance}`)),{ok:!1,daemonUp:!1,networkHostRequired:n.networkHostRequired};let r=n.requiresRoot&&!o.isRoot;return r&&t(T.default.dim(" (some steps need root \u2014 using sudo; you may be prompted for your password)")),n.install&&!Va(n.install,r,t)?(t(T.default.red(" \u274C Docker install failed (see output above). Install it manually, then re-run.")),{ok:!1,daemonUp:!1,networkHostRequired:n.networkHostRequired}):qa(n.start,r,t)?(t(T.default.dim(" Waiting for the Docker daemon to answer...")),await Ka(mn,12e4,1500)?(t(T.default.green(" \u2705 Docker daemon is up.")),{ok:!0,daemonUp:!0,networkHostRequired:n.networkHostRequired}):(t(T.default.red(" \u274C Docker did not become ready in time.")),n.start==="dockerd-restricted"?t(T.default.dim(" Check /tmp/badgerclaw-dockerd.log for the daemon output.")):n.start==="docker-app"&&t(T.default.dim(" Docker Desktop can take a minute to boot \u2014 re-run once its menu-bar icon is steady.")),{ok:!1,daemonUp:!1,networkHostRequired:n.networkHostRequired})):(t(T.default.red(" \u274C Could not start Docker (see output above). Resolve it, then re-run.")),{ok:!1,daemonUp:!1,networkHostRequired:n.networkHostRequired})}function ss(e){let t=e.minMajor??18;if(!Number.isFinite(e.nodeMajor)||e.nodeMajor<t){let o=Number.isFinite(e.nodeMajor)?`Node v${e.nodeMajor}`:"an unknown Node version";return`badgerclaw requires Node.js >= ${t} (this is ${o}). Upgrade Node \u2014 nodesource (https://github.com/nodesource/distributions) or nvm (\`nvm install ${t}\`) \u2014 then re-run \`badgerclaw setup --hermes\`.`}return e.npmPresent?null:`npm was not found on PATH. badgerclaw is installed and updated via npm \u2014 install Node.js ${t}+ (which bundles npm) and re-run \`badgerclaw setup --hermes\`.`}function is(e=process.versions.node){return parseInt(String(e).split(".")[0],10)}var pn=require("child_process"),lo=d(require("fs")),as=d(require("os")),uo=d(require("path"));Ee();Gt();function Ja(){let e=cs();for(let t of e)if(lo.default.existsSync(t))return t;return null}function cs(){return[uo.default.resolve(__dirname,"..","assets","hermes-agent-bc.Dockerfile"),uo.default.resolve(__dirname,"..","..","assets","hermes-agent-bc.Dockerfile")]}var Ya="nousresearch/hermes-agent";function za(e){let t=(process.env.HERMES_UPSTREAM||e?.upstream||"").trim();if(!t)return;if(t.includes("/"))return t;let o=t.includes(":")?t.split(":").pop():t;return`${Ya}:${o}`}var Xa={run:e=>{let t=(0,pn.spawnSync)("docker",e,{encoding:"utf-8"});return{status:t.status,stdout:t.stdout||"",stderr:t.stderr||""}}};function Za(e){return["build",...e.hostNetwork?["--network","host"]:[],...e.upstreamRef?["--build-arg",`UPSTREAM=${e.upstreamRef}`]:[],"-t",e.image,"-f",e.dockerfile,e.ctxDir]}function ls(e){let t=Bt();if(!t.installed)return{status:"no-docker"};let o=process.env.HERMES_IMAGE||Ue;if(Lt(t).installed)return{status:"already-present",image:o};let r=Ja();if(!r)return{status:"no-dockerfile",expectedPaths:cs()};let s=za(e),i=Oo({bridgeUsable:()=>Ut(Xa)}),a=lo.default.mkdtempSync(uo.default.join(as.default.tmpdir(),"bc-hermes-build-"));try{let c=(0,pn.spawnSync)("docker",Za({hostNetwork:i,upstreamRef:s,image:o,dockerfile:r,ctxDir:a}),{stdio:"inherit",timeout:6e5});return c.status===0?{status:"built",image:o}:{status:"build-failed",image:o,stderr:`docker build exited ${c.status??"<no-status>"}`}}finally{try{lo.default.rmSync(a,{recursive:!0,force:!0})}catch{}}}j();var Z=me.default.join(Ct.default.homedir(),".openclaw","openclaw.json"),$t=Z+".badgerclaw-stash",gs=me.default.join(Ct.default.homedir(),".openclaw","npm"),Qa=me.default.join(gs,"package.json");async function ds(){try{let e=await fetch(`${U}/api/v1/dashboard/versions/latest`,{headers:{Accept:"application/json"}});if(!e.ok)return{cli:null,plugin:null,openclaw:null,hermes:null};let t=await e.json(),o=t.result&&typeof t.result=="object"?t.result:t,n=r=>typeof r!="string"||!r||r==="unknown"?null:r;return{cli:n(o.cli),plugin:n(o.plugin),openclaw:n(o.supported_openclaw),hermes:n(o.supported_hermes)}}catch{return{cli:null,plugin:null,openclaw:null,hermes:null}}}function ec(){if(!E.default.existsSync(Z))return null;try{let e=JSON.parse(E.default.readFileSync(Z,"utf-8")),t=e.channels?.badgerclaw;return t?(delete e.channels.badgerclaw,e.plugins?.entries?.badgerclaw&&delete e.plugins.entries.badgerclaw,E.default.writeFileSync(Z,JSON.stringify(e,null,2)),E.default.writeFileSync($t,JSON.stringify(t,null,2)),t):null}catch{return null}}function tc(){if(!E.default.existsSync(Z))return null;try{let e=JSON.parse(E.default.readFileSync(Z,"utf-8"));return!e.gateway||typeof e.gateway!="object"?null:JSON.parse(JSON.stringify(e.gateway))}catch{return null}}function oc(e){if(e&&E.default.existsSync(Z))try{let t=JSON.parse(E.default.readFileSync(Z,"utf-8"));t.gateway={...e,...t.gateway||{}},E.default.writeFileSync(Z,JSON.stringify(t,null,2))}catch(t){console.log(m.default.yellow(` \u26A0\uFE0F Could not restore gateway block: ${t.message}`)),console.log(m.default.yellow(" Run `openclaw config set gateway.mode local` manually if the gateway fails to start."))}}function nc(){if(E.default.existsSync($t))try{let e=JSON.parse(E.default.readFileSync($t,"utf-8")),t=JSON.parse(E.default.readFileSync(Z,"utf-8"));t.channels=t.channels||{},t.channels.badgerclaw=e,E.default.writeFileSync(Z,JSON.stringify(t,null,2)),E.default.unlinkSync($t)}catch(e){console.log(m.default.yellow(` \u26A0\uFE0F Could not restore config: ${e.message}`)),console.log(m.default.yellow(` Your bot credentials are backed up at: ${$t}`))}}async function us(e){return new Promise(t=>{let o=(0,se.spawn)("openclaw",["plugins","install",e,"--force","--dangerously-force-unsafe-install"],{stdio:["ignore","pipe","pipe"],shell:!0}),n="",r=!1,s=!1,i=/Installed plugin:|Restart the gateway to load plugins/,a=()=>{r||s||(r=!0,setTimeout(()=>{if(!s){try{o.kill("SIGTERM")}catch{}setTimeout(()=>{if(!s)try{o.kill("SIGKILL")}catch{}},1e3)}},3e3))},c=(l,u)=>{u.write(l),n+=l.toString("utf-8"),i.test(n)&&a()};o.stdout.on("data",l=>c(l,process.stdout)),o.stderr.on("data",l=>c(l,process.stderr)),o.on("exit",l=>{s=!0,t({status:r?0:l??1})}),o.on("error",l=>{s||(s=!0,console.error(m.default.red(` openclaw spawn error: ${l.message}`)),t({status:1}))})})}function ms(e){if(!E.default.existsSync(e))return!1;let t;try{t=JSON.parse(E.default.readFileSync(e,"utf-8"))}catch{return!1}let o=!1;return t.overrides&&typeof t.overrides=="object"&&"uuid"in t.overrides&&(delete t.overrides.uuid,o=!0),t.openclaw&&Array.isArray(t.openclaw.managedOverrides)&&t.openclaw.managedOverrides.includes("uuid")&&(t.openclaw.managedOverrides=t.openclaw.managedOverrides.filter(n=>n!=="uuid"),o=!0),o?(E.default.writeFileSync(e,JSON.stringify(t,null,2)+`
133
+ \u26A1 SSE command received: ${l.command_type} (${l.command_id})`));try{let u=O();await u.post(`/api/v1/dashboard/commands/${l.command_id}/ack`);let p=await ue({id:l.command_id,command_type:l.command_type,payload:l.payload});console.log(p.success?b.default.green(` \u2705 ${p.message}`):b.default.red(` \u274C ${p.message}`)),await u.post(`/api/v1/dashboard/commands/${l.command_id}/result`,{status:p.success?"success":"failed",result:p.message,new_version:p.newVersion||null});try{await L()}catch{}l.command_type==="update_cli"&&p.success&&(console.log(b.default.cyan(" CLI updated \u2014 restarting in 2s...")),setTimeout(()=>process.exit(0),2e3))}catch(u){console.log(b.default.red(` Command ${l.command_id} error: ${u.message}`))}}}catch{}}};s(),await new Promise(()=>{})});var ps=require("commander"),m=d(require("chalk")),se=require("child_process"),E=d(require("fs")),Ct=d(require("os")),me=d(require("path"));fe();Fe();Ee();var et=require("child_process"),os=d(require("fs")),T=d(require("chalk")),W={alreadyUp:!1,install:null,start:null,requiresRoot:!1,networkHostRequired:!1,guidance:null},ts='On this distro the bare "docker" package is the podman shim (no dockerd). Install Docker Engine from the official docker-ce repository (https://docs.docker.com/engine/install/), then re-run `badgerclaw setup --hermes`.';function Ma(e){return e.daemonUp?{...W,alreadyUp:!0}:e.host==="darwin"?e.hasDockerApp?{...W,start:"docker-app"}:e.hasColima?{...W,start:"colima"}:e.binaryPresent?{...W,guidance:"A `docker` CLI is present but no engine we can start (Docker.app / colima) was found and the daemon is not answering. Start your Docker daemon (or `colima start`), then re-run `badgerclaw setup --hermes`."}:e.hasBrew?{...W,install:{tool:"colima",via:"brew"},start:"colima"}:{...W,guidance:"No container engine found and Homebrew is absent. Install Docker Desktop (https://www.docker.com/products/docker-desktop) or Homebrew (https://brew.sh) then colima, and re-run `badgerclaw setup --hermes`."}:e.host==="linux-systemd"?e.binaryPresent?{...W,start:"systemctl",requiresRoot:!0}:e.pkgManager==="apt"?{...W,install:{tool:"docker",via:"apt"},start:"systemctl",requiresRoot:!0}:{...W,guidance:e.pkgManager?ts:"Docker is not installed and no supported package manager (apt) was found. Install Docker, then re-run."}:e.host==="linux-nosystemd"?e.binaryPresent?{...W,start:"dockerd-restricted",requiresRoot:!0,networkHostRequired:!0}:e.pkgManager==="apt"?{...W,install:{tool:"docker",via:"apt"},start:"dockerd-restricted",requiresRoot:!0,networkHostRequired:!0}:{...W,guidance:e.pkgManager?ts:"Docker is not installed and no supported package manager (apt) was found. Install Docker (e.g. `apt-get install -y docker.io`), then re-run."}:{...W,guidance:`Automatic Docker setup isn't supported on this platform (${process.platform}). Install + start Docker manually, then re-run.`}}function ns(e,t,o=8e3){return(0,et.spawnSync)(e,t,{encoding:"utf-8",timeout:o})}function mn(){let e=ns("docker",["version","--format","{{.Server.Version}}"],4e3);return e.status===0&&!!(e.stdout||"").trim()}function Ha(){return ns("docker",["--version"],4e3).status===0}function Qe(e){return(0,et.spawnSync)("sh",["-c",`command -v ${e}`],{encoding:"utf-8"}).status===0}function Fa(){return Qe("apt-get")?"apt":Qe("dnf")?"dnf":Qe("yum")?"yum":null}function Ua(){let e=(0,et.spawnSync)("systemctl",["is-system-running"],{encoding:"utf-8",timeout:4e3});if(e.error)return!1;let t=`${e.stdout||""}${e.stderr||""}`.toLowerCase();return!/failed to connect to bus|not been booted with systemd|no such file/.test(t)}function Ga(){return process.platform==="darwin"?"darwin":process.platform==="linux"?Ua()?"linux-systemd":"linux-nosystemd":"unsupported"}function Wa(){return typeof process.getuid=="function"?process.getuid()===0:!1}function ve(e,t){return t(T.default.dim(` $ ${e}`)),(0,et.spawnSync)("sh",["-c",e],{stdio:"inherit"}).status===0}function Va(e,t,o){let n=t?"sudo ":"";switch(e.via){case"brew":return o(T.default.dim(" Installing colima + docker CLI via Homebrew...")),ve("brew install colima docker",o);case"apt":return o(T.default.dim(" Installing Docker via apt...")),ve(`${n}apt-get update`,o),ve(`${n}apt-get install -y docker.io`,o);default:return!1}}function qa(e,t,o){let n=t?"sudo ":"";switch(e){case"docker-app":return ve("open -a Docker",o);case"colima":return ve("colima start",o);case"systemctl":return ve(`${n}systemctl enable --now docker`,o);case"dockerd-restricted":{if(!Qe("dockerd"))return o(T.default.red(" \u274C `dockerd` is not installed (the docker CLI alone is not enough on a no-systemd host).")),!1;if(t&&!ve("sudo -v",o))return o(T.default.red(" \u274C root is required to start dockerd here, but sudo is unavailable.")),!1;ve(`${n}sh -c 'mount -t cgroup2 none /sys/fs/cgroup 2>/dev/null || true'`,o);let r="/tmp/badgerclaw-dockerd.log";o(T.default.dim(` Starting dockerd (restricted: --bridge=none --iptables=false) \u2192 ${r}`));let s=`nohup dockerd --storage-driver=overlay2 --iptables=false --bridge=none > ${r} 2>&1 &`,i=t?`sudo sh -c ${JSON.stringify(s)}`:`sh -c ${JSON.stringify(s)}`;return(0,et.spawnSync)("sh",["-c",i],{stdio:"ignore"}).status===0}}}async function Ka(e,t,o){let n=Date.now()+t;for(;;){if(e())return!0;if(Date.now()>=n)return!1;await new Promise(r=>setTimeout(r,o))}}async function rs(e={}){let t=e.log??(i=>console.log(i));if(process.env.BADGERCLAW_NO_AUTO_DEPS==="1"){let i=mn();return i||(t(T.default.yellow(" BADGERCLAW_NO_AUTO_DEPS=1 \u2014 skipping automatic Docker setup.")),t(T.default.dim(" Start the Docker daemon yourself, then re-run `badgerclaw setup --hermes`."))),{ok:i,daemonUp:i,networkHostRequired:!1}}let o={daemonUp:mn(),binaryPresent:Ha(),host:Ga(),hasBrew:Qe("brew"),hasDockerApp:os.default.existsSync("/Applications/Docker.app"),hasColima:Qe("colima"),pkgManager:Fa(),isRoot:Wa()},n=Ma(o);if(n.alreadyUp)return{ok:!0,daemonUp:!0,networkHostRequired:!1};if(n.guidance)return t(T.default.red(` \u274C ${n.guidance}`)),{ok:!1,daemonUp:!1,networkHostRequired:n.networkHostRequired};let r=n.requiresRoot&&!o.isRoot;return r&&t(T.default.dim(" (some steps need root \u2014 using sudo; you may be prompted for your password)")),n.install&&!Va(n.install,r,t)?(t(T.default.red(" \u274C Docker install failed (see output above). Install it manually, then re-run.")),{ok:!1,daemonUp:!1,networkHostRequired:n.networkHostRequired}):qa(n.start,r,t)?(t(T.default.dim(" Waiting for the Docker daemon to answer...")),await Ka(mn,12e4,1500)?(t(T.default.green(" \u2705 Docker daemon is up.")),{ok:!0,daemonUp:!0,networkHostRequired:n.networkHostRequired}):(t(T.default.red(" \u274C Docker did not become ready in time.")),n.start==="dockerd-restricted"?t(T.default.dim(" Check /tmp/badgerclaw-dockerd.log for the daemon output.")):n.start==="docker-app"&&t(T.default.dim(" Docker Desktop can take a minute to boot \u2014 re-run once its menu-bar icon is steady.")),{ok:!1,daemonUp:!1,networkHostRequired:n.networkHostRequired})):(t(T.default.red(" \u274C Could not start Docker (see output above). Resolve it, then re-run.")),{ok:!1,daemonUp:!1,networkHostRequired:n.networkHostRequired})}function ss(e){let t=e.minMajor??18;if(!Number.isFinite(e.nodeMajor)||e.nodeMajor<t){let o=Number.isFinite(e.nodeMajor)?`Node v${e.nodeMajor}`:"an unknown Node version";return`badgerclaw requires Node.js >= ${t} (this is ${o}). Upgrade Node \u2014 nodesource (https://github.com/nodesource/distributions) or nvm (\`nvm install ${t}\`) \u2014 then re-run \`badgerclaw setup --hermes\`.`}return e.npmPresent?null:`npm was not found on PATH. badgerclaw is installed and updated via npm \u2014 install Node.js ${t}+ (which bundles npm) and re-run \`badgerclaw setup --hermes\`.`}function is(e=process.versions.node){return parseInt(String(e).split(".")[0],10)}var pn=require("child_process"),lo=d(require("fs")),as=d(require("os")),uo=d(require("path"));Ee();Gt();function Ja(){let e=cs();for(let t of e)if(lo.default.existsSync(t))return t;return null}function cs(){return[uo.default.resolve(__dirname,"..","assets","hermes-agent-bc.Dockerfile"),uo.default.resolve(__dirname,"..","..","assets","hermes-agent-bc.Dockerfile")]}var Ya="nousresearch/hermes-agent";function za(e){let t=(process.env.HERMES_UPSTREAM||e?.upstream||"").trim();if(!t)return;if(t.includes("/"))return t;let o=t.includes(":")?t.split(":").pop():t;return`${Ya}:${o}`}var Xa={run:e=>{let t=(0,pn.spawnSync)("docker",e,{encoding:"utf-8"});return{status:t.status,stdout:t.stdout||"",stderr:t.stderr||""}}};function Za(e){return["build",...e.hostNetwork?["--network","host"]:[],...e.upstreamRef?["--build-arg",`UPSTREAM=${e.upstreamRef}`]:[],"-t",e.image,"-f",e.dockerfile,e.ctxDir]}function ls(e){let t=Bt();if(!t.installed)return{status:"no-docker"};let o=process.env.HERMES_IMAGE||Ue;if(Lt(t).installed)return{status:"already-present",image:o};let r=Ja();if(!r)return{status:"no-dockerfile",expectedPaths:cs()};let s=za(e),i=Oo({bridgeUsable:()=>Ut(Xa)}),a=lo.default.mkdtempSync(uo.default.join(as.default.tmpdir(),"bc-hermes-build-"));try{let c=(0,pn.spawnSync)("docker",Za({hostNetwork:i,upstreamRef:s,image:o,dockerfile:r,ctxDir:a}),{stdio:"inherit",timeout:6e5});return c.status===0?{status:"built",image:o}:{status:"build-failed",image:o,stderr:`docker build exited ${c.status??"<no-status>"}`}}finally{try{lo.default.rmSync(a,{recursive:!0,force:!0})}catch{}}}j();var Q=me.default.join(Ct.default.homedir(),".openclaw","openclaw.json"),$t=Q+".badgerclaw-stash",gs=me.default.join(Ct.default.homedir(),".openclaw","npm"),Qa=me.default.join(gs,"package.json");async function ds(){try{let e=await fetch(`${U}/api/v1/dashboard/versions/latest`,{headers:{Accept:"application/json"}});if(!e.ok)return{cli:null,plugin:null,openclaw:null,hermes:null};let t=await e.json(),o=t.result&&typeof t.result=="object"?t.result:t,n=r=>typeof r!="string"||!r||r==="unknown"?null:r;return{cli:n(o.cli),plugin:n(o.plugin),openclaw:n(o.supported_openclaw),hermes:n(o.supported_hermes)}}catch{return{cli:null,plugin:null,openclaw:null,hermes:null}}}function ec(){if(!E.default.existsSync(Q))return null;try{let e=JSON.parse(E.default.readFileSync(Q,"utf-8")),t=e.channels?.badgerclaw;return t?(delete e.channels.badgerclaw,e.plugins?.entries?.badgerclaw&&delete e.plugins.entries.badgerclaw,E.default.writeFileSync(Q,JSON.stringify(e,null,2)),E.default.writeFileSync($t,JSON.stringify(t,null,2)),t):null}catch{return null}}function tc(){if(!E.default.existsSync(Q))return null;try{let e=JSON.parse(E.default.readFileSync(Q,"utf-8"));return!e.gateway||typeof e.gateway!="object"?null:JSON.parse(JSON.stringify(e.gateway))}catch{return null}}function oc(e){if(e&&E.default.existsSync(Q))try{let t=JSON.parse(E.default.readFileSync(Q,"utf-8"));t.gateway={...e,...t.gateway||{}},E.default.writeFileSync(Q,JSON.stringify(t,null,2))}catch(t){console.log(m.default.yellow(` \u26A0\uFE0F Could not restore gateway block: ${t.message}`)),console.log(m.default.yellow(" Run `openclaw config set gateway.mode local` manually if the gateway fails to start."))}}function nc(){if(E.default.existsSync($t))try{let e=JSON.parse(E.default.readFileSync($t,"utf-8")),t=JSON.parse(E.default.readFileSync(Q,"utf-8"));t.channels=t.channels||{},t.channels.badgerclaw=e,E.default.writeFileSync(Q,JSON.stringify(t,null,2)),E.default.unlinkSync($t)}catch(e){console.log(m.default.yellow(` \u26A0\uFE0F Could not restore config: ${e.message}`)),console.log(m.default.yellow(` Your bot credentials are backed up at: ${$t}`))}}async function us(e){return new Promise(t=>{let o=(0,se.spawn)("openclaw",["plugins","install",e,"--force","--dangerously-force-unsafe-install"],{stdio:["ignore","pipe","pipe"],shell:!0}),n="",r=!1,s=!1,i=/Installed plugin:|Restart the gateway to load plugins/,a=()=>{r||s||(r=!0,setTimeout(()=>{if(!s){try{o.kill("SIGTERM")}catch{}setTimeout(()=>{if(!s)try{o.kill("SIGKILL")}catch{}},1e3)}},3e3))},c=(l,u)=>{u.write(l),n+=l.toString("utf-8"),i.test(n)&&a()};o.stdout.on("data",l=>c(l,process.stdout)),o.stderr.on("data",l=>c(l,process.stderr)),o.on("exit",l=>{s=!0,t({status:r?0:l??1})}),o.on("error",l=>{s||(s=!0,console.error(m.default.red(` openclaw spawn error: ${l.message}`)),t({status:1}))})})}function ms(e){if(!E.default.existsSync(e))return!1;let t;try{t=JSON.parse(E.default.readFileSync(e,"utf-8"))}catch{return!1}let o=!1;return t.overrides&&typeof t.overrides=="object"&&"uuid"in t.overrides&&(delete t.overrides.uuid,o=!0),t.openclaw&&Array.isArray(t.openclaw.managedOverrides)&&t.openclaw.managedOverrides.includes("uuid")&&(t.openclaw.managedOverrides=t.openclaw.managedOverrides.filter(n=>n!=="uuid"),o=!0),o?(E.default.writeFileSync(e,JSON.stringify(t,null,2)+`
134
134
  `),!0):!1}function rc(){let e=[];ms(Qa)&&e.push(gs);for(let t of Tt())ms(me.default.join(t,"package.json"))&&e.push(t);return e}async function sc(){let{detectCapabilities:e}=await Promise.resolve().then(()=>(Ee(),zn)),{pushHeartbeat:t}=await Promise.resolve().then(()=>(Ye(),an));console.log(m.default.green(`
135
135
  \u{1F9A1} BadgerClaw \u2014 capability refresh
136
136
  `));let o=e();console.log(m.default.dim(" Detected on this host:")),console.log(m.default.dim(` OpenClaw : ${gn(o.openclaw)}`)),console.log(m.default.dim(` Hermes : ${gn(o.hermes)}`)),console.log(m.default.dim(` Docker : ${gn(o.docker)}`)),o.disk_free_gb!==null&&console.log(m.default.dim(` Disk free: ${o.disk_free_gb} GB`));try{await t(),console.log(m.default.green(`
@@ -148,31 +148,31 @@ ${A} Bot ${p}: ${u} \u2014 removing from OpenClaw config...`));try{let{changed:g
148
148
  Cleaning up heartbeat hooks from previous installs...`)),br({loggedIn:h()!==null,log:C=>console.log(m.default.dim(` ${C}`))}),console.log(m.default.dim(`
149
149
  Hermes-only mode \u2014 skipping OpenClaw plugin + gateway install.
150
150
  To enable OC bots later, drop the --hermes flag: \`badgerclaw setup\`.
151
- `)),console.log(m.default.green("\u2705 Setup complete (Hermes-only host).")),console.log(m.default.dim("\nNext steps:\n 1. `badgerclaw login` \u2014 authenticate this CLI to the backend.\n 2. `badgerclaw setup --refresh` \u2014 push the Hermes capability so\n the backend (and the iOS app) knows this host can serve\n Hermes bots.\n 3. `badgerclaw bot create <name>` \u2014 defaults to Hermes on this host."));return}let o=await ds();if(o.cli){let g=xo();g!==o.cli?(console.log(m.default.dim(` Updating CLI: ${g} \u2192 ${o.cli} (supported)...`)),(0,se.spawnSync)("npm",["install","-g",`badgerclaw@${o.cli}`],{stdio:"inherit",shell:!0}).status!==0&&(console.log(m.default.red("\n\u274C CLI update failed. Fix the npm error above, then re-run `badgerclaw setup`.")),process.exit(1)),console.log(m.default.green(` \u2705 CLI updated to ${o.cli}`))):console.log(m.default.dim(` CLI already at approved version ${g}.`))}if(o.openclaw){let g=J();g!==o.openclaw?(console.log(g===null?m.default.dim(` Installing OpenClaw ${o.openclaw} (supported)...`):m.default.dim(` Updating OpenClaw: ${g} \u2192 ${o.openclaw} (supported)...`)),(0,se.spawnSync)("npm",["install","-g",`openclaw@${o.openclaw}`],{stdio:"inherit",shell:!0}).status!==0&&(console.log(m.default.red("\n\u274C OpenClaw install/update failed. Fix the npm error above, then re-run `badgerclaw setup`.")),process.exit(1)),console.log(m.default.green(` \u2705 OpenClaw at ${o.openclaw}`))):console.log(m.default.dim(` OpenClaw already at approved version ${g}.`))}else J()===null&&(console.log(m.default.yellow(" \u26A0\uFE0F No approved OpenClaw version and none installed \u2014 installing latest from npm.")),(0,se.spawnSync)("npm",["install","-g","openclaw"],{stdio:"inherit",shell:!0}).status!==0&&(console.log(m.default.red(`
151
+ `)),console.log(m.default.green("\u2705 Setup complete (Hermes-only host).")),console.log(m.default.dim("\nNext steps:\n 1. `badgerclaw login` \u2014 authenticate this CLI to the backend.\n 2. `badgerclaw setup --refresh` \u2014 push the Hermes capability so\n the backend (and the iOS app) knows this host can serve\n Hermes bots.\n 3. `badgerclaw bot create <name>` \u2014 defaults to Hermes on this host."));return}let o=await ds();if(o.cli){let g=xo();g!==o.cli?(console.log(m.default.dim(` Updating CLI: ${g} \u2192 ${o.cli} (supported)...`)),(0,se.spawnSync)("npm",["install","-g",`badgerclaw@${o.cli}`],{stdio:"inherit",shell:!0}).status!==0&&(console.log(m.default.red("\n\u274C CLI update failed. Fix the npm error above, then re-run `badgerclaw setup`.")),process.exit(1)),console.log(m.default.green(` \u2705 CLI updated to ${o.cli}`))):console.log(m.default.dim(` CLI already at approved version ${g}.`))}if(o.openclaw){let g=Y();g!==o.openclaw?(console.log(g===null?m.default.dim(` Installing OpenClaw ${o.openclaw} (supported)...`):m.default.dim(` Updating OpenClaw: ${g} \u2192 ${o.openclaw} (supported)...`)),(0,se.spawnSync)("npm",["install","-g",`openclaw@${o.openclaw}`],{stdio:"inherit",shell:!0}).status!==0&&(console.log(m.default.red("\n\u274C OpenClaw install/update failed. Fix the npm error above, then re-run `badgerclaw setup`.")),process.exit(1)),console.log(m.default.green(` \u2705 OpenClaw at ${o.openclaw}`))):console.log(m.default.dim(` OpenClaw already at approved version ${g}.`))}else Y()===null&&(console.log(m.default.yellow(" \u26A0\uFE0F No approved OpenClaw version and none installed \u2014 installing latest from npm.")),(0,se.spawnSync)("npm",["install","-g","openclaw"],{stdio:"inherit",shell:!0}).status!==0&&(console.log(m.default.red(`
152
152
  \u274C OpenClaw install failed.`)),process.exit(1)));let n=ec();n&&console.log(m.default.dim(" Existing bot config stashed temporarily..."));let r=tc();(0,se.spawnSync)("openclaw",["gateway","stop"],{stdio:"pipe",shell:!0,timeout:1e4});let s=[me.default.join(Ct.default.homedir(),".openclaw","extensions","badgerclaw"),me.default.join(Ct.default.homedir(),".openclaw","npm","node_modules","@badgerclaw","connect"),...Tt()],i=[],a=[],c=g=>{let w=`${g}.bc-setup-stash-${Date.now()}-${Math.floor(Math.random()*1e6)}`,C=(0,se.spawnSync)("mv",["-f",g,w],{encoding:"utf-8"});return C.status===0?{ok:!0,stash:w}:{ok:!1,error:(C.stderr||"").trim()||`exit ${C.status}`}};for(let g of s)if(E.default.existsSync(g))try{E.default.rmSync(g,{recursive:!0,force:!0}),i.push(g)}catch(w){let C=c(g);C.ok?(a.push(`${g} \u2192 ${C.stash}`),console.log(m.default.yellow(` \u26A0\uFE0F Could not delete ${g} (${w.message}); renamed it aside instead.`))):(console.log(m.default.red(` \u274C Could not delete ${g} (${w.message})`)),console.log(m.default.red(` Could not rename ${g} aside either (${C.error}). Plugin install will likely fail.`)))}i.length>0&&console.log(m.default.dim(` Cleared existing plugin director${i.length>1?"ies":"y"}.`)),a.length>0&&console.log(m.default.dim(` Renamed busy install${a.length>1?"s":""} aside: ${a.join(", ")}`));let l=o.plugin?`@badgerclaw/connect@${o.plugin}`:"@badgerclaw/connect";o.plugin?console.log(m.default.dim(` Installing ${l} (supported)...`)):console.log(m.default.yellow(" \u26A0\uFE0F Allow-list unavailable \u2014 installing @badgerclaw/connect unpinned."));let u=await us(l);if(u.status===0&&o.plugin&&o.plugin!=="unknown"){for(let w=1;w<=2&&!(jt()===o.plugin||(console.log(m.default.yellow(` Plugin landed as a hook-pack-only install (not yet visible to \`badgerclaw login\`) \u2014 re-running plugin install (attempt ${w}/2)...`)),u=await us(l),u.status!==0));w++);u.status===0&&jt()!==o.plugin&&console.log(m.default.yellow(" \u26A0\uFE0F Plugin still not detected at the npm install path after 2 attempt(s). If `badgerclaw login` reports it as not installed, re-run `badgerclaw setup`."))}n&&(nc(),console.log(m.default.dim(" Bot config restored."))),r&&(oc(r),console.log(m.default.dim(" Gateway config restored."))),u.status!==0&&(console.log(m.default.red(`
153
153
  \u274C Plugin install failed. Your bot config has been restored.`)),process.exit(1)),console.log(m.default.green(`
154
154
  \u2705 BadgerClaw plugin installed successfully!`));let p=rc();for(let g of p){console.log(m.default.dim(` Stripping OpenClaw uuid:14 override in ${g} (breaks request@2.88 in matrix-bot-sdk)...`));try{E.default.rmSync(me.default.join(g,"node_modules","uuid"),{recursive:!0,force:!0})}catch{}try{E.default.rmSync(me.default.join(g,"package-lock.json"),{force:!0})}catch{}(0,se.spawnSync)("npm",["install"],{cwd:g,stdio:"inherit",shell:!0}).status!==0&&(console.log(m.default.red(`
155
155
  \u274C npm install failed after removing uuid override. Bot will not reply correctly until this is resolved.`)),process.exit(1))}p.length>0&&console.log(m.default.green(" \u2705 uuid override stripped + npm tree re-resolved.")),console.log("");let A=await zt({verbose:!0});A.ok||(console.log(m.default.red(`
156
156
  \u274C Gateway failed to start. Diagnose with:`)),console.log(m.default.dim(" systemctl --user status openclaw-gateway.service # Linux")),console.log(m.default.dim(" launchctl list | grep openclaw # macOS")),console.log(m.default.dim(" openclaw config get gateway.mode")),console.log(m.default.dim(" Then re-run `badgerclaw setup` after fixing the underlying issue.")),process.exit(1)),A.ready===!1?console.log(m.default.yellow(" \u23F3 Gateway started but not answering yet \u2014 it may still be coming up.")):console.log(m.default.green(" \u2705 Gateway is running.")),console.log(m.default.dim("\nNext: run `badgerclaw login` to authenticate.")),Xt()});Ye();var ws=require("commander"),D=d(require("chalk"));j();xe();ke();var ys=new ws.Command("dashboard").description("Show local diagnostic dashboard \u2014 machine health, gateway status, bot telemetry").action(async()=>{h()||(console.log(D.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let{version:t}=we(),o=Pt(),n=await bt();console.log(D.default.bold.green(`
157
157
  BadgerClaw Dashboard
158
- `)),console.log(D.default.bold(" Instance")),console.log(` ID: ${ee()}`),console.log(` CLI Version: ${t}`),console.log(` Plugin: ${n.pluginVersion}`),console.log(),console.log(D.default.bold(" Machine")),console.log(` Hostname: ${o.hostname}`),console.log(` OS: ${o.os} / ${o.arch}`),console.log(` Uptime: ${hs(o.uptimeSeconds)}`),console.log(` Free Memory: ${o.memFreeMb} MB`),console.log();let r=n.status==="running"?D.default.green:n.status==="error"?D.default.red:D.default.yellow;if(console.log(D.default.bold(" Gateway")),console.log(` Status: ${r(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(D.default.bold(" Bots")),console.log(D.default.dim(" No bots detected. Pair bots at https://badgerclaw.ai")),console.log();else{console.log(D.default.bold(` Bots (${n.bots.length})`)),console.log();for(let s of n.bots){let i=s.status==="running"?D.default.green:s.status==="error"?D.default.red:D.default.yellow;if(console.log(` ${D.default.bold(s.botUsername)} ${i(`[${s.status}]`)}`),console.log(` ID: ${s.botId}`),console.log(` Uptime: ${hs(s.uptimeSeconds)}`),console.log(` Messages: ${s.messagesReceived} in / ${s.messagesSent} out`),s.chunkedMessages>0&&console.log(` Chunked: ${s.chunkedMessages} messages, ${s.totalChunksSent} chunks`),console.log(` Rooms: ${s.roomsActive} active`),console.log(` Errors: ${s.errors}`),s.lastError&&(console.log(` Last Error: ${D.default.red(s.lastError)}`),console.log(` Error At: ${s.lastErrorAt}`)),console.log(` Last Active: ${s.lastActivity??"N/A"}`),s.roomDetails&&s.roomDetails.length>0){console.log(D.default.dim(" Rooms:"));for(let a of s.roomDetails)console.log(D.default.dim(` ${a.roomName} \u2014 ${a.messagesInRoom} msgs, last: ${a.lastActivityInRoom??"N/A"}`))}console.log()}}console.log(D.default.dim(` Last checked: ${new Date().toISOString()}`)),console.log()});function hs(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 fn=require("commander"),tt=d(require("chalk")),bs=d(require("ora"));j();ke();Ye();var ic=new fn.Command("restart").description("Restart the OpenClaw gateway via the plugin probe endpoint").action(async()=>{h()||(console.log(tt.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,bs.default)("Restarting gateway...").start(),o=await Je();if(o.success){t.succeed(tt.default.green(`Gateway restarted: ${o.message}`));try{await L(),console.log(tt.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(tt.default.dim(" Could not push heartbeat \u2014 daemon may not be running."))}}else t.fail(tt.default.red(`Gateway restart failed: ${o.message}`)),process.exit(1)}),_s=new fn.Command("gateway").description("Manage the OpenClaw gateway").addCommand(ic);var Ce=require("commander"),v=d(require("chalk")),je=d(require("ora")),$e=d(require("axios"));eo();j();var Te="http://localhost:7331",ac=new Ce.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(v.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=e.sessionId||`session-${Date.now()}`,n=parseInt(e.port,10),r=e.project.replace(/^~/,process.env.HOME||""),s=(0,je.default)("Starting Claude Code session...").start();try{await $e.default.post(`${Te}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!0,sessionId:o},{timeout:1e4}),s.text="Gateway toggled \u2014 launching MCP server...";let a=Xo({sessionId:o,port:n,projectDir:r}).pid||0;await new Promise(c=>setTimeout(c,1500)),s.text="MCP server running \u2014 launching Claude Code...",Zo({sessionId:o,port:n,projectDir:r}),Qo(o,0,a,n,r),s.succeed(v.default.green("Claude Code session started")+v.default.dim(` (session: ${o}, port: ${n})`)),console.log(v.default.dim(` Bot: ${e.bot}`)),console.log(v.default.dim(` Room: ${e.room}`)),console.log(v.default.dim(` Project: ${r}`)),console.log(v.default.dim(" Claude Code should open in a new terminal window."))}catch(i){let a=i.response?.data?.message||i.message||"Unknown error";s.fail(v.default.red(`Failed to start Claude Code: ${a}`)),process.exit(1)}}),cc=new Ce.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(v.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=(0,je.default)("Stopping Claude Code session...").start();try{e.bot&&e.room&&await $e.default.post(`${Te}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!1},{timeout:1e4});let n=e.sessionId;if(!n)try{let i=((await $e.default.get(`${Te}/claude-code/status`,{timeout:5e3})).data?.rooms||[]).find(a=>a.botId===e.bot&&a.roomId===e.room);i&&(n=i.sessionId)}catch{}n?(en(n),o.succeed(v.default.green(`Claude Code session stopped (${n})`))):(o.succeed(v.default.green("Claude Code toggled off at gateway")),console.log(v.default.dim(" No local session found to kill \u2014 may need to close Claude Code manually.")))}catch(n){let r=n.response?.data?.message||n.message||"Unknown error";o.fail(v.default.red(`Failed to stop Claude Code: ${r}`)),process.exit(1)}}),lc=new Ce.Command("status").description("Show active Claude Code sessions").action(async()=>{h()||(console.log(v.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,je.default)("Fetching Claude Code status...").start();try{let o=[];try{o=(await $e.default.get(`${Te}/claude-code/status`,{timeout:5e3})).data?.rooms||[]}catch{}let n=tn();if(t.stop(),o.length===0&&n.length===0){console.log(v.default.dim("No active Claude Code sessions."));return}if(o.length>0){console.log(v.default.bold(`
158
+ `)),console.log(D.default.bold(" Instance")),console.log(` ID: ${te()}`),console.log(` CLI Version: ${t}`),console.log(` Plugin: ${n.pluginVersion}`),console.log(),console.log(D.default.bold(" Machine")),console.log(` Hostname: ${o.hostname}`),console.log(` OS: ${o.os} / ${o.arch}`),console.log(` Uptime: ${hs(o.uptimeSeconds)}`),console.log(` Free Memory: ${o.memFreeMb} MB`),console.log();let r=n.status==="running"?D.default.green:n.status==="error"?D.default.red:D.default.yellow;if(console.log(D.default.bold(" Gateway")),console.log(` Status: ${r(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(D.default.bold(" Bots")),console.log(D.default.dim(" No bots detected. Pair bots at https://badgerclaw.ai")),console.log();else{console.log(D.default.bold(` Bots (${n.bots.length})`)),console.log();for(let s of n.bots){let i=s.status==="running"?D.default.green:s.status==="error"?D.default.red:D.default.yellow;if(console.log(` ${D.default.bold(s.botUsername)} ${i(`[${s.status}]`)}`),console.log(` ID: ${s.botId}`),console.log(` Uptime: ${hs(s.uptimeSeconds)}`),console.log(` Messages: ${s.messagesReceived} in / ${s.messagesSent} out`),s.chunkedMessages>0&&console.log(` Chunked: ${s.chunkedMessages} messages, ${s.totalChunksSent} chunks`),console.log(` Rooms: ${s.roomsActive} active`),console.log(` Errors: ${s.errors}`),s.lastError&&(console.log(` Last Error: ${D.default.red(s.lastError)}`),console.log(` Error At: ${s.lastErrorAt}`)),console.log(` Last Active: ${s.lastActivity??"N/A"}`),s.roomDetails&&s.roomDetails.length>0){console.log(D.default.dim(" Rooms:"));for(let a of s.roomDetails)console.log(D.default.dim(` ${a.roomName} \u2014 ${a.messagesInRoom} msgs, last: ${a.lastActivityInRoom??"N/A"}`))}console.log()}}console.log(D.default.dim(` Last checked: ${new Date().toISOString()}`)),console.log()});function hs(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 fn=require("commander"),tt=d(require("chalk")),bs=d(require("ora"));j();ke();Ye();var ic=new fn.Command("restart").description("Restart the OpenClaw gateway via the plugin probe endpoint").action(async()=>{h()||(console.log(tt.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,bs.default)("Restarting gateway...").start(),o=await Je();if(o.success){t.succeed(tt.default.green(`Gateway restarted: ${o.message}`));try{await L(),console.log(tt.default.dim(" Heartbeat pushed with updated status."))}catch{console.log(tt.default.dim(" Could not push heartbeat \u2014 daemon may not be running."))}}else t.fail(tt.default.red(`Gateway restart failed: ${o.message}`)),process.exit(1)}),_s=new fn.Command("gateway").description("Manage the OpenClaw gateway").addCommand(ic);var Ce=require("commander"),v=d(require("chalk")),je=d(require("ora")),$e=d(require("axios"));eo();j();var Te="http://localhost:7331",ac=new Ce.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(v.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=e.sessionId||`session-${Date.now()}`,n=parseInt(e.port,10),r=e.project.replace(/^~/,process.env.HOME||""),s=(0,je.default)("Starting Claude Code session...").start();try{await $e.default.post(`${Te}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!0,sessionId:o},{timeout:1e4}),s.text="Gateway toggled \u2014 launching MCP server...";let a=Xo({sessionId:o,port:n,projectDir:r}).pid||0;await new Promise(c=>setTimeout(c,1500)),s.text="MCP server running \u2014 launching Claude Code...",Zo({sessionId:o,port:n,projectDir:r}),Qo(o,0,a,n,r),s.succeed(v.default.green("Claude Code session started")+v.default.dim(` (session: ${o}, port: ${n})`)),console.log(v.default.dim(` Bot: ${e.bot}`)),console.log(v.default.dim(` Room: ${e.room}`)),console.log(v.default.dim(` Project: ${r}`)),console.log(v.default.dim(" Claude Code should open in a new terminal window."))}catch(i){let a=i.response?.data?.message||i.message||"Unknown error";s.fail(v.default.red(`Failed to start Claude Code: ${a}`)),process.exit(1)}}),cc=new Ce.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(v.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let o=(0,je.default)("Stopping Claude Code session...").start();try{e.bot&&e.room&&await $e.default.post(`${Te}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!1},{timeout:1e4});let n=e.sessionId;if(!n)try{let i=((await $e.default.get(`${Te}/claude-code/status`,{timeout:5e3})).data?.rooms||[]).find(a=>a.botId===e.bot&&a.roomId===e.room);i&&(n=i.sessionId)}catch{}n?(en(n),o.succeed(v.default.green(`Claude Code session stopped (${n})`))):(o.succeed(v.default.green("Claude Code toggled off at gateway")),console.log(v.default.dim(" No local session found to kill \u2014 may need to close Claude Code manually.")))}catch(n){let r=n.response?.data?.message||n.message||"Unknown error";o.fail(v.default.red(`Failed to stop Claude Code: ${r}`)),process.exit(1)}}),lc=new Ce.Command("status").description("Show active Claude Code sessions").action(async()=>{h()||(console.log(v.default.yellow("Not logged in. Run `badgerclaw login` first.")),process.exit(1));let t=(0,je.default)("Fetching Claude Code status...").start();try{let o=[];try{o=(await $e.default.get(`${Te}/claude-code/status`,{timeout:5e3})).data?.rooms||[]}catch{}let n=tn();if(t.stop(),o.length===0&&n.length===0){console.log(v.default.dim("No active Claude Code sessions."));return}if(o.length>0){console.log(v.default.bold(`
159
159
  Gateway Claude Code Rooms:`)),console.log(v.default.dim(" Bot".padEnd(30)+"Room".padEnd(30)+"Session".padEnd(20)+"Enabled")),console.log(v.default.dim(" "+"-".repeat(88)));for(let r of o){let s=r.enabled?v.default.green("ON"):v.default.dim("OFF");console.log(` ${(r.botId||"").padEnd(30)}${(r.roomName||r.roomId||"").padEnd(30)}${(r.sessionId||"-").padEnd(20)}${s}`)}}if(n.length>0){console.log(v.default.bold(`
160
- Local Sessions:`)),console.log(v.default.dim(" Session".padEnd(25)+"Port".padEnd(8)+"MCP PID".padEnd(10)+"Project".padEnd(40)+"Started")),console.log(v.default.dim(" "+"-".repeat(90)));for(let r of n)console.log(` ${r.sessionId.padEnd(25)}${String(r.port).padEnd(8)}${String(r.mcpPid).padEnd(10)}${r.projectDir.padEnd(40)}${r.startedAt}`)}console.log("")}catch(o){t.fail(v.default.red(`Failed to get status: ${o.message}`)),process.exit(1)}}),dc=new Ce.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,je.default)("Grouping bot+room into session...").start();try{await $e.default.post(`${Te}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!0,sessionId:e.session},{timeout:1e4}),t.succeed(v.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(v.default.red(`Failed to group: ${n}`)),process.exit(1)}}),uc=new Ce.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,je.default)("Adding user to allowlist...").start();try{await $e.default.post(`${Te}/claude-code/allow`,{botId:e.bot,roomId:e.room,userId:e.user},{timeout:1e4}),t.succeed(v.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(v.default.red(`Failed to add user: ${n}`)),process.exit(1)}}),mc=new Ce.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,je.default)("Removing user from allowlist...").start();try{await $e.default.post(`${Te}/claude-code/revoke`,{botId:e.bot,roomId:e.room,userId:e.user},{timeout:1e4}),t.succeed(v.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(v.default.red(`Failed to revoke user: ${n}`)),process.exit(1)}}),ks=new Ce.Command("claude-code").description("Manage Claude Code sessions (relay Matrix messages to local Claude Code)").addCommand(ac).addCommand(cc).addCommand(lc).addCommand(dc).addCommand(uc).addCommand(mc);var Ms=require("commander"),_=d(require("chalk"));var vs=d(require("fs")),pc=process.env.ORGO_API_BASE||"https://www.orgo.ai/api",Ss=e=>new Promise(t=>setTimeout(t,e)),ie=class extends Error{constructor(t,o){super(t),this.name="OrgoError",this.status=o}};function $s(e){if(e.keyFile){let o;try{o=vs.default.readFileSync(e.keyFile,"utf-8").trim()}catch(r){throw new ie(`could not read key file ${e.keyFile}: ${r?.message||r}`)}let n=o.includes("=")&&!o.startsWith("sk")?o.split("=",2)[1].trim().replace(/^["']|["']$/g,""):o;if(!n)throw new ie(`key file ${e.keyFile} is empty`);return n}let t=process.env.ORGO_API_KEY;if(t&&t.trim())return t.trim();throw new ie("No orgo API key found. Pass --key-file <path> (a chmod-600 file containing the key) or set ORGO_API_KEY. Do NOT pass the key as a command-line argument \u2014 it is visible in `ps`.")}var mo=class{constructor(t,o=pc){this.key=t,this.base=o.replace(/\/$/,"")}async req(t,o,n,r={}){let s=Math.max(0,r.retries??0);for(let i=0;;i++){let a;try{a=await fetch(`${this.base}${o}`,{method:t,headers:{Authorization:`Bearer ${this.key}`,...n!==void 0?{"Content-Type":"application/json"}:{}},body:n!==void 0?JSON.stringify(n):void 0})}catch(l){if(i<s){await Ss(500*(i+1));continue}let u=l?.cause?.code||l?.cause?.message||(l?.cause?String(l.cause):"");throw new ie(`network error calling orgo ${t} ${o}: ${l?.message||l}${u?` (${u})`:""}`)}let c=await a.text();if(!a.ok)throw new ie(`orgo ${t} ${o} \u2192 HTTP ${a.status}: ${c.slice(0,300)}`,a.status);return c?JSON.parse(c):{}}}async listWorkspaces(){let t=await this.req("GET","/workspaces",void 0,{retries:2});return Array.isArray(t)?t:t?.projects||t?.workspaces||t?.data||[]}getWorkspace(t){return this.req("GET",`/workspaces/${t}`,void 0,{retries:2})}async listComputers(t){let o=await this.getWorkspace(t);return(Array.isArray(o.desktops)?o.desktops:[]).map(r=>({id:String(r.id),status:r.status,name:r.name??r.instance_details?.name,fly_instance_id:r.fly_instance_id}))}async createComputer(t){let o={os:"linux",ram:4,cpu:1,...t};try{return await this.req("POST","/computers",o)}catch(n){if(n instanceof ie&&n.status)throw n;await Ss(2500);try{let r=(await this.listComputers(t.workspace_id)).find(s=>s.name===t.name);if(r)return r}catch{}return await this.req("POST","/computers",o)}}getComputer(t){return this.req("GET",`/computers/${t}`,void 0,{retries:2})}bash(t,o){return this.req("POST",`/computers/${t}/bash`,{command:o})}stopComputer(t){return this.req("POST",`/computers/${t}/stop`,void 0,{retries:1})}deleteComputer(t){return this.req("DELETE",`/computers/${t}`,void 0,{retries:1})}};var xs=d(require("crypto"));var gc=e=>new Promise(t=>setTimeout(t,e));function fc(e){return e.replace(/[^a-zA-Z0-9_.-]/g,"_").slice(0,40)||"step"}async function Ie(e,t,o,n={}){let r=await e.bash(t,o);if(!n.allowNonZero&&r.exit_code!==0){let s=(r.output||r.error||"").slice(0,400);throw new Error(`remote command failed (exit ${r.exit_code}): ${o.slice(0,80)}
160
+ Local Sessions:`)),console.log(v.default.dim(" Session".padEnd(25)+"Port".padEnd(8)+"MCP PID".padEnd(10)+"Project".padEnd(40)+"Started")),console.log(v.default.dim(" "+"-".repeat(90)));for(let r of n)console.log(` ${r.sessionId.padEnd(25)}${String(r.port).padEnd(8)}${String(r.mcpPid).padEnd(10)}${r.projectDir.padEnd(40)}${r.startedAt}`)}console.log("")}catch(o){t.fail(v.default.red(`Failed to get status: ${o.message}`)),process.exit(1)}}),dc=new Ce.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,je.default)("Grouping bot+room into session...").start();try{await $e.default.post(`${Te}/claude-code/toggle`,{botId:e.bot,roomId:e.room,enabled:!0,sessionId:e.session},{timeout:1e4}),t.succeed(v.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(v.default.red(`Failed to group: ${n}`)),process.exit(1)}}),uc=new Ce.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,je.default)("Adding user to allowlist...").start();try{await $e.default.post(`${Te}/claude-code/allow`,{botId:e.bot,roomId:e.room,userId:e.user},{timeout:1e4}),t.succeed(v.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(v.default.red(`Failed to add user: ${n}`)),process.exit(1)}}),mc=new Ce.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,je.default)("Removing user from allowlist...").start();try{await $e.default.post(`${Te}/claude-code/revoke`,{botId:e.bot,roomId:e.room,userId:e.user},{timeout:1e4}),t.succeed(v.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(v.default.red(`Failed to revoke user: ${n}`)),process.exit(1)}}),ks=new Ce.Command("claude-code").description("Manage Claude Code sessions (relay Matrix messages to local Claude Code)").addCommand(ac).addCommand(cc).addCommand(lc).addCommand(dc).addCommand(uc).addCommand(mc);var Ms=require("commander"),_=d(require("chalk"));var vs=d(require("fs")),pc=process.env.ORGO_API_BASE||"https://www.orgo.ai/api",Ss=e=>new Promise(t=>setTimeout(t,e)),ie=class extends Error{constructor(t,o){super(t),this.name="OrgoError",this.status=o}};function $s(e){if(e.keyFile){let o;try{o=vs.default.readFileSync(e.keyFile,"utf-8").trim()}catch(r){throw new ie(`could not read key file ${e.keyFile}: ${r?.message||r}`)}let n=o.includes("=")&&!o.startsWith("sk")?o.split("=",2)[1].trim().replace(/^["']|["']$/g,""):o;if(!n)throw new ie(`key file ${e.keyFile} is empty`);return n}let t=process.env.ORGO_API_KEY;if(t&&t.trim())return t.trim();throw new ie("No orgo API key found. Pass --key-file <path> (a chmod-600 file containing the key) or set ORGO_API_KEY. Do NOT pass the key as a command-line argument \u2014 it is visible in `ps`.")}var mo=class{constructor(t,o=pc){this.key=t,this.base=o.replace(/\/$/,"")}async req(t,o,n,r={}){let s=Math.max(0,r.retries??0);for(let i=0;;i++){let a;try{a=await fetch(`${this.base}${o}`,{method:t,headers:{Authorization:`Bearer ${this.key}`,...n!==void 0?{"Content-Type":"application/json"}:{}},body:n!==void 0?JSON.stringify(n):void 0})}catch(l){if(i<s){await Ss(500*(i+1));continue}let u=l?.cause?.code||l?.cause?.message||(l?.cause?String(l.cause):"");throw new ie(`network error calling orgo ${t} ${o}: ${l?.message||l}${u?` (${u})`:""}`)}let c=await a.text();if(!a.ok)throw new ie(`orgo ${t} ${o} \u2192 HTTP ${a.status}: ${c.slice(0,300)}`,a.status);return c?JSON.parse(c):{}}}async listWorkspaces(){let t=await this.req("GET","/workspaces",void 0,{retries:2});return Array.isArray(t)?t:t?.projects||t?.workspaces||t?.data||[]}getWorkspace(t){return this.req("GET",`/workspaces/${t}`,void 0,{retries:2})}async listComputers(t){let o=await this.getWorkspace(t);return(Array.isArray(o.desktops)?o.desktops:[]).map(r=>({id:String(r.id),status:r.status,name:r.name??r.instance_details?.name,fly_instance_id:r.fly_instance_id}))}async createComputer(t){let o={os:"linux",ram:4,cpu:1,...t};try{return await this.req("POST","/computers",o)}catch(n){if(n instanceof ie&&n.status)throw n;await Ss(2500);try{let r=(await this.listComputers(t.workspace_id)).find(s=>s.name===t.name);if(r)return r}catch{}return await this.req("POST","/computers",o)}}getComputer(t){return this.req("GET",`/computers/${t}`,void 0,{retries:2})}bash(t,o){return this.req("POST",`/computers/${t}/bash`,{command:o})}restartComputer(t){return this.req("POST",`/computers/${t}/restart`,void 0,{retries:1})}deleteComputer(t){return this.req("DELETE",`/computers/${t}`,void 0,{retries:1})}};var xs=d(require("crypto"));var gc=e=>new Promise(t=>setTimeout(t,e));function fc(e){return e.replace(/[^a-zA-Z0-9_.-]/g,"_").slice(0,40)||"step"}async function Ie(e,t,o,n={}){let r=await e.bash(t,o);if(!n.allowNonZero&&r.exit_code!==0){let s=(r.output||r.error||"").slice(0,400);throw new Error(`remote command failed (exit ${r.exit_code}): ${o.slice(0,80)}
161
161
  ${s}`)}return r}async function hn(e,t,o,n){let r=fc(n.tag),s=`/tmp/bc-${r}.log`,i=`/tmp/bc-${r}.done`,a=`/tmp/bc-${r}.sh`,c=Buffer.from(o,"utf-8").toString("base64"),l=`rm -f ${s} ${i} ${a}; echo ${c} | base64 -d > ${a}; setsid sh -c 'sh ${a} >${s} 2>&1; echo __EXIT_$?__ >>${s}; touch ${i}' >/dev/null 2>&1 & echo launched`;await Ie(e,t,l);let u=n.pollMs??5e3,p=Date.now()+(n.timeoutMs??900*1e3);for(;Date.now()<p;){await gc(u);let g;try{g=await e.bash(t,`if [ -f ${i} ]; then echo __DONE__; fi; tail -n 3 ${s} 2>/dev/null`)}catch{continue}let w=g.output||"";if(n.onTick&&n.onTick(w.replace("__DONE__","").trim()),w.includes("__DONE__")){let C=await e.bash(t,`cat ${s} 2>/dev/null`),k=(C.output||"").match(/__EXIT_(\d+)__/);return{exitCode:k?parseInt(k[1],10):null,log:C.output||"",timedOut:!1}}}return{exitCode:null,log:(await e.bash(t,`cat ${s} 2>/dev/null`)).output||"",timedOut:!0}}async function Cs(e,t,o={}){let n=o.timeoutMs??1e4,r=`sed -n 's/.*"instance_id"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p' /root/.badgerclaw/auth.json 2>/dev/null`,s,i=new Promise(a=>{s=setTimeout(()=>a(null),n)});try{let a=await Promise.race([e.bash(t,r).catch(()=>null),i]);return a&&(a.output||"").split(`
162
162
  `).map(l=>l.trim()).find(l=>/^openclaw-\S+$/.test(l))||null}finally{s&&clearTimeout(s)}}async function wn(e,t,o,n,r="600"){let s=Buffer.from(n,"utf-8").toString("base64"),i=o.replace(/\/[^/]*$/,"")||"/",a=await e.bash(t,`mkdir -p ${i} && echo ${s} | base64 -d > ${o} && chmod ${r} ${o} && echo ok`);if(a.exit_code!==0||!/ok/.test(a.output||""))throw new Error(`failed to write ${o} on the VM (exit ${a.exit_code})`)}j();oe();var hc=e=>new Promise(t=>setTimeout(t,e)),po=e=>(e||"").trim().split(`
163
163
  `).filter(Boolean).pop()||"",Is=(e,t=14)=>(e||"").trim().split(`
164
164
  `).slice(-t).join(`
165
- `);async function wc(e){let t=h();if(!t)throw new Error("Not signed in on this machine \u2014 sign in to Clawdy Express (or run `badgerclaw login`) first so a machine token can be minted.");let o=te(t.access_token),n=`orgo-${e}-${Date.now().toString(36)}`.replace(/[^a-zA-Z0-9_.-]/g,"-").slice(0,60);try{let r=await o.post("/api/v1/user/cli-tokens",{name:n,expires_in:"1y"}),s=r.data?.result??r.data,i=s?.token;if(!i||typeof i!="string")throw new Error("mint response did not include a token");return{token:i,expires_at:s?.expires_at}}catch(r){let s=r?.response?.status,i=r?.response?.data?.errors?.[0]||r?.response?.data?.detail||r?.message||"unknown error";throw new Error(`could not mint a machine token (HTTP ${s??"?"}): ${i}`)}}async function yc(e,t,o){let n=Date.now()+3e5;for(;Date.now()<n;){let r="?";try{let s=await e.getComputer(t);r=String(s.status??"?")}catch{}try{if(((await e.bash(t,"echo __ready__")).output||"").includes("__ready__")){o(` VM is up (status=${r}).`);return}}catch{}o(` \u2026booting (status=${r})`),await hc(5e3)}throw new Error("VM did not become ready within 5 minutes")}async function bc(e,t,o){let n=await Ie(e,t,'command -v badgerclaw || echo /usr/local/bin/badgerclaw; dirname "$(command -v node)" 2>/dev/null || echo /usr/bin; (command -v supervisord >/dev/null 2>&1 && echo HAVE_SUP || echo NO_SUP)',{allowNonZero:!0}),r=(n.output||"").trim().split(`
165
+ `);async function wc(e){let t=h();if(!t)throw new Error("Not signed in on this machine \u2014 sign in to Clawdy Express (or run `badgerclaw login`) first so a machine token can be minted.");let o=J(t.access_token),n=`orgo-${e}-${Date.now().toString(36)}`.replace(/[^a-zA-Z0-9_.-]/g,"-").slice(0,60);try{let r=await o.post("/api/v1/user/cli-tokens",{name:n,expires_in:"1y"}),s=r.data?.result??r.data,i=s?.token;if(!i||typeof i!="string")throw new Error("mint response did not include a token");return{token:i,expires_at:s?.expires_at}}catch(r){let s=r?.response?.status,i=r?.response?.data?.errors?.[0]||r?.response?.data?.detail||r?.message||"unknown error";throw new Error(`could not mint a machine token (HTTP ${s??"?"}): ${i}`)}}async function yc(){let e=h();if(!e)return;let t;try{let r=await J(e.access_token).get("/api/v1/me/capabilities");t=r.data?.result??r.data??{}}catch{return}let o=t.multiple_openclaw_instances===!0,n=typeof t.openclaw_instance_count=="number"?t.openclaw_instance_count:0;if(!o&&n>=1)throw new Error(`Your current plan allows a single machine and you already have ${n}. Upgrade to Ultimate to run multiple machines (cloud or local), or remove an existing one first. No orgo VM was created.`)}async function bc(e,t,o){let n=Date.now()+3e5;for(;Date.now()<n;){let r="?";try{let s=await e.getComputer(t);r=String(s.status??"?")}catch{}try{if(((await e.bash(t,"echo __ready__")).output||"").includes("__ready__")){o(` VM is up (status=${r}).`);return}}catch{}o(` \u2026booting (status=${r})`),await hc(5e3)}throw new Error("VM did not become ready within 5 minutes")}async function _c(e,t,o){let n=await Ie(e,t,'command -v badgerclaw || echo /usr/local/bin/badgerclaw; dirname "$(command -v node)" 2>/dev/null || echo /usr/bin; (command -v supervisord >/dev/null 2>&1 && echo HAVE_SUP || echo NO_SUP)',{allowNonZero:!0}),r=(n.output||"").trim().split(`
166
166
  `).map(u=>u.trim()).filter(Boolean),s=r[0]||"/usr/local/bin/badgerclaw",i=r[1]||"/usr/bin",a=/HAVE_SUP/.test(n.output||"");if(await Ie(e,t,"mkdir -p /root/.badgerclaw",{allowNonZero:!0}),!a){o(" \u26A0\uFE0F no supervisord on this host \u2014 using a detached heartbeat (NOT reboot-proof)."),await Ie(e,t,`setsid sh -c '${s} heartbeat >>/root/.badgerclaw/heartbeat.log 2>&1' >/dev/null 2>&1 & echo started`,{allowNonZero:!0});return}let c=["[program:badgerclaw-heartbeat]",`command=${s} heartbeat`,"directory=/root","autostart=true","autorestart=true","startsecs=5","startretries=100","stopsignal=TERM","stopwaitsecs=20","stdout_logfile=/root/.badgerclaw/heartbeat.log","stdout_logfile_maxbytes=10MB","stderr_logfile=/root/.badgerclaw/heartbeat.log",`environment=HOME="/root",PATH="${i}:/usr/local/bin:/usr/bin:/bin"`,"user=root",""].join(`
167
- `);await wn(e,t,"/etc/supervisor/conf.d/badgerclaw-heartbeat.conf",c,"644");let l=await Ie(e,t,"(pgrep -x supervisord >/dev/null 2>&1 || supervisord -c /etc/supervisor/supervisord.conf >/dev/null 2>&1 || true); supervisorctl reread; supervisorctl update; supervisorctl status badgerclaw-heartbeat",{allowNonZero:!0});o(` heartbeat supervised \u2192 ${po(l.output)}`)}async function Rs(e){let{client:t,log:o}=e;if(!h())throw new Error("Not signed in on this machine \u2014 sign in to Clawdy Express (or run `badgerclaw login`) first.");o("Creating the orgo VM\u2026");let n=await t.createComputer({workspace_id:e.workspaceId,name:e.name,cpu:e.cpu,ram:e.ram,disk_size_gb:e.disk}),r=String(n.id);e.onVmCreated?.(r),o(` Created VM ${r} (status=${n.status??"?"}).`),await yc(t,r,o),o("Installing Node + the badgerclaw CLI\u2026");let s=await hn(t,r,'export DEBIAN_FRONTEND=noninteractive; NODEMAJ=$(node -v 2>/dev/null | sed "s/v\\([0-9]*\\).*/\\1/"); if ! command -v npm >/dev/null 2>&1 || [ "${NODEMAJ:-0}" -lt 18 ]; then apt-get update -y || true; apt-get install -y nodejs npm; fi; npm install -g badgerclaw && badgerclaw --version',{tag:"install",timeoutMs:600*1e3,onTick:P=>P&&o(` ${po(P)}`)});if(s.exitCode!==0)throw new Error(`Node/CLI install failed (exit ${s.exitCode}).
167
+ `);await wn(e,t,"/etc/supervisor/conf.d/badgerclaw-heartbeat.conf",c,"644");let l=await Ie(e,t,"(pgrep -x supervisord >/dev/null 2>&1 || supervisord -c /etc/supervisor/supervisord.conf >/dev/null 2>&1 || true); supervisorctl reread; supervisorctl update; supervisorctl status badgerclaw-heartbeat",{allowNonZero:!0});o(` heartbeat supervised \u2192 ${po(l.output)}`)}async function Rs(e){let{client:t,log:o}=e;if(!h())throw new Error("Not signed in on this machine \u2014 sign in to Clawdy Express (or run `badgerclaw login`) first.");await yc(),o("Creating the orgo VM\u2026");let n=await t.createComputer({workspace_id:e.workspaceId,name:e.name,cpu:e.cpu,ram:e.ram,disk_size_gb:e.disk}),r=String(n.id);e.onVmCreated?.(r),o(` Created VM ${r} (status=${n.status??"?"}).`),await bc(t,r,o),o("Installing Node + the badgerclaw CLI\u2026");let s=await hn(t,r,'export DEBIAN_FRONTEND=noninteractive; NODEMAJ=$(node -v 2>/dev/null | sed "s/v\\([0-9]*\\).*/\\1/"); if ! command -v npm >/dev/null 2>&1 || [ "${NODEMAJ:-0}" -lt 18 ]; then apt-get update -y || true; apt-get install -y nodejs npm; fi; npm install -g badgerclaw && badgerclaw --version',{tag:"install",timeoutMs:600*1e3,onTick:P=>P&&o(` ${po(P)}`)});if(s.exitCode!==0)throw new Error(`Node/CLI install failed (exit ${s.exitCode}).
168
168
  ${Is(s.log)}`);o("Building the Hermes image (setup --hermes \u2014 one-time, ~minutes)\u2026");let i=await hn(t,r,"badgerclaw setup --hermes",{tag:"setup",timeoutMs:1200*1e3,onTick:P=>P&&o(` ${po(P)}`)});if(i.exitCode!==0)throw new Error(`setup --hermes failed (exit ${i.exitCode}).
169
169
  ${Is(i.log)}`);o("Minting a machine token (browser-free login)\u2026");let a=h(),{token:c,expires_at:l}=await wc(e.name);o("Registering the machine with the backend\u2026");let u=await Ie(t,r,`node -e 'const o=require("os");console.log(JSON.stringify([o.hostname(),o.platform(),o.arch()]))'`),p="orgo",A="linux",g="x64";try{let P=JSON.parse((u.output||"").trim().split(`
170
- `).pop()||"[]");Array.isArray(P)&&P.length===3&&([p,A,g]=P.map(String))}catch{}let w=xs.default.createHash("sha256").update(`${p}-${A}-${g}`).digest("hex").slice(0,16),C=`openclaw-${p.toLowerCase().replace(/[^a-z0-9]/g,"-")}-${w}`,k=await Ie(t,r,"badgerclaw --version 2>/dev/null || echo 0.0.0",{allowNonZero:!0}),R=po(k.output)||"0.0.0",$=C;try{let ce=await te(c).post("/api/v1/openclaw/register",{instance_id:C,label:p,version:R,machine_fingerprint:w,provider:"orgo",orgo_workspace_id:e.workspaceId,...e.workspaceName?{orgo_workspace_name:e.workspaceName}:{},orgo_computer_id:r}),ge=ce.data?.result??ce.data;ge&&typeof ge.instance_id=="string"&&ge.instance_id.length>0&&($=ge.instance_id),o(` Registered as ${$}.`)}catch(P){let ce=P?.response?.status,ge=P?.response?.data?.errors?.[0]||P?.response?.data?.detail||P?.message||"register failed";throw new Error(`register failed (HTTP ${ce??"?"}): ${ge}`)}o("Writing credentials onto the VM\u2026");let V=JSON.stringify({access_token:c,user_id:a.user_id,instance_id:$,expires_at:l||new Date(Date.now()+365*864e5).toISOString(),email:a.email},null,2);return await wn(t,r,"/root/.badgerclaw/auth.json",V,"600"),o("Making the heartbeat reboot-proof (supervisord)\u2026"),await bc(t,r,o),o(`\u2713 Provisioned: orgo VM ${r}${$?`, instance ${$}`:""}.`),{computerId:r,instanceId:$}}var ot=d(require("fs")),As=d(require("os")),yn=d(require("path"));function Es(){return yn.default.join(As.default.homedir(),".badgerclaw")}function It(){return yn.default.join(Es(),"orgo.json")}function Ps(){return It()}function Be(){try{return JSON.parse(ot.default.readFileSync(It(),"utf-8"))}catch{return{}}}function xt(e){let t={...Be(),...e};ot.default.mkdirSync(Es(),{recursive:!0}),ot.default.writeFileSync(It(),JSON.stringify(t,null,2),{mode:384});try{ot.default.chmodSync(It(),384)}catch{}return t}function Os(){try{ot.default.rmSync(It(),{force:!0})}catch{}}var Ds=d(require("readline"));function nt(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function Ns(e){return new Promise((t,o)=>{let n=process.stdin,r=process.stdout;if(!n.isTTY){o(new Error("not a TTY \u2014 cannot prompt for a hidden value"));return}r.write(e),n.setRawMode(!0),n.resume(),n.setEncoding("utf8");let s="",i=a=>{for(let c of a){if(c==="\r"||c===`
170
+ `).pop()||"[]");Array.isArray(P)&&P.length===3&&([p,A,g]=P.map(String))}catch{}let w=xs.default.createHash("sha256").update(`${p}-${A}-${g}`).digest("hex").slice(0,16),C=`openclaw-${p.toLowerCase().replace(/[^a-z0-9]/g,"-")}-${w}`,k=await Ie(t,r,"badgerclaw --version 2>/dev/null || echo 0.0.0",{allowNonZero:!0}),R=po(k.output)||"0.0.0",$=C;try{let ce=await J(c).post("/api/v1/openclaw/register",{instance_id:C,label:p,version:R,machine_fingerprint:w,provider:"orgo",orgo_workspace_id:e.workspaceId,...e.workspaceName?{orgo_workspace_name:e.workspaceName}:{},orgo_computer_id:r}),ge=ce.data?.result??ce.data;ge&&typeof ge.instance_id=="string"&&ge.instance_id.length>0&&($=ge.instance_id),o(` Registered as ${$}.`)}catch(P){let ce=P?.response?.status,ge=P?.response?.data?.errors?.[0]||P?.response?.data?.detail||P?.message||"register failed";throw new Error(`register failed (HTTP ${ce??"?"}): ${ge}`)}o("Writing credentials onto the VM\u2026");let V=JSON.stringify({access_token:c,user_id:a.user_id,instance_id:$,expires_at:l||new Date(Date.now()+365*864e5).toISOString(),email:a.email},null,2);return await wn(t,r,"/root/.badgerclaw/auth.json",V,"600"),o("Making the heartbeat reboot-proof (supervisord)\u2026"),await _c(t,r,o),o(`\u2713 Provisioned: orgo VM ${r}${$?`, instance ${$}`:""}.`),{computerId:r,instanceId:$}}var ot=d(require("fs")),As=d(require("os")),yn=d(require("path"));function Es(){return yn.default.join(As.default.homedir(),".badgerclaw")}function It(){return yn.default.join(Es(),"orgo.json")}function Ps(){return It()}function Be(){try{return JSON.parse(ot.default.readFileSync(It(),"utf-8"))}catch{return{}}}function xt(e){let t={...Be(),...e};ot.default.mkdirSync(Es(),{recursive:!0}),ot.default.writeFileSync(It(),JSON.stringify(t,null,2),{mode:384});try{ot.default.chmodSync(It(),384)}catch{}return t}function Os(){try{ot.default.rmSync(It(),{force:!0})}catch{}}var Ds=d(require("readline"));function nt(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function Ns(e){return new Promise((t,o)=>{let n=process.stdin,r=process.stdout;if(!n.isTTY){o(new Error("not a TTY \u2014 cannot prompt for a hidden value"));return}r.write(e),n.setRawMode(!0),n.resume(),n.setEncoding("utf8");let s="",i=a=>{for(let c of a){if(c==="\r"||c===`
171
171
  `||c===""){n.setRawMode(!1),n.pause(),n.removeListener("data",i),r.write(`
172
172
  `),t(s);return}c===""&&(n.setRawMode(!1),r.write(`
173
173
  `),process.exit(130)),c==="\x7F"||c==="\b"?s=s.slice(0,-1):c>=" "&&(s+=c)}};n.on("data",i)})}function bn(e){return new Promise(t=>{let o=Ds.default.createInterface({input:process.stdin,output:process.stdout});o.question(e,n=>{o.close(),t(n.trim())})})}async function go(e,t,o){if(t.length===0)throw new Error("no items to choose from");for(process.stdout.write(e+`
174
174
  `),t.forEach((n,r)=>process.stdout.write(` ${r+1}) ${o(n)}
175
175
  `));;){let n=await bn(`Enter a number (1-${t.length}): `),r=parseInt(n,10);if(Number.isInteger(r)&&r>=1&&r<=t.length)return r-1;process.stdout.write(` Please enter a valid number.
176
- `)}}oe();j();var _c=new Set(["stopped","stopping","terminated","terminating","off","paused","suspended","destroyed"]);function Ts(e){return _c.has((e||"").toLowerCase().trim())}function js(e){if(!e||typeof e!="object")return"";let t=["hermes","docker","openclaw"],o=r=>{let s=e[r];return s&&typeof s=="object"?s.installed===!0:s===!0};return[...t.filter(o),...Object.keys(e).filter(r=>!t.includes(r)&&o(r))].join(", ")}function Bs(e){return e.stopped?{state:"vm_stopped"}:e.instanceId?e.instance?{state:e.instance.online?"online":"offline",instanceId:e.instanceId,version:e.instance.version,capabilities:e.instance.capabilities}:{state:"not_registered",instanceId:e.instanceId}:{state:"no_auth"}}function Ls(e){return e==="online"?!0:e==="offline"||e==="vm_stopped"?!1:null}var pe=new Ms.Command("orgo").description("Provision and manage BadgerClaw Hermes machines on orgo (orgo.ai) cloud VMs");function ae(e){console.error(_.default.red(`\u2717 ${e}`)),process.exit(1)}function fo(e){return e instanceof ie&&e.status===401?"orgo rejected the key (HTTP 401) \u2014 check that it is a valid sk_live_\u2026 key.":e instanceof Error?e.message:String(e)}function rt(e){ae(fo(e))}var kn=e=>`${e.name?String(e.name):"(unnamed)"} ${_.default.dim(String(e.id))}`;async function kc(e,t){try{return{key:$s({keyFile:e.keyFile}),fromPrompt:!1}}catch(n){e.keyFile&&rt(n)}let o=Be().api_key;if(o)return{key:o,fromPrompt:!1};if(t&&nt()){console.log(_.default.dim(" Don't have an orgo API key yet? Create one at https://www.orgo.ai/start")),console.log(_.default.dim(" Paste it below \u2014 it stays on this machine (chmod 600) and is never shown."));let n=(await Ns("Enter your orgo API key (sk_live_\u2026, hidden): ")).trim();return n||ae("No key entered."),{key:n,fromPrompt:!0}}ae("No orgo API key. Run `badgerclaw orgo connect`, pass --key-file <path>, or set ORGO_API_KEY.")}async function Le(e,t){let{key:o,fromPrompt:n}=await kc(e,t);return{client:new mo(o),key:o,fromPrompt:n}}async function Hs(e,t,o){if(t.workspace)return t.workspace;let n=Be();if(n.workspace_id)return o&&console.log(_.default.dim(` Using workspace: ${n.workspace_name||n.workspace_id} (change it with \`badgerclaw orgo workspace\`).`)),n.workspace_id;if(o&&nt()){let s=await e.listWorkspaces();s.length===0&&ae("No orgo workspaces found. Create one at https://www.orgo.ai/workspaces.");let i=await _n(),a=i?s.findIndex(u=>String(u.id)===i.workspace_id):-1,c;a>=0?(c=a,console.log(_.default.dim(` Using your account's default orgo workspace: ${s[c].name||s[c].id} (change it with \`badgerclaw orgo workspace\`).`))):c=s.length===1?0:await go("Choose a workspace:",s,kn);let l=s[c];return xt({workspace_id:String(l.id),workspace_name:l.name?String(l.name):""}),await Sn(String(l.id),l.name?String(l.name):void 0),console.log(_.default.dim(` Using workspace: ${l.name||l.id}`)),String(l.id)}let r=await _n();if(r)return r.workspace_id;ae("No workspace selected. Run `badgerclaw orgo connect` (or `orgo workspace`), or pass --workspace <id>.")}async function Fs(e,t,o,n){let r;try{let s=await Rs({client:e,workspaceId:t,workspaceName:n.workspaceName,name:o,cpu:n.cpu,ram:n.ram,disk:n.disk,log:i=>{n.json||console.log(_.default.dim(i))},onVmCreated:i=>{r=i}});n.json?console.log(JSON.stringify({ok:!0,...s})):console.log(_.default.green(`
176
+ `)}}oe();j();var kc=new Set(["stopped","stopping","terminated","terminating","off","paused","suspended","destroyed"]);function Ts(e){return kc.has((e||"").toLowerCase().trim())}function js(e){if(!e||typeof e!="object")return"";let t=["hermes","docker","openclaw"],o=r=>{let s=e[r];return s&&typeof s=="object"?s.installed===!0:s===!0};return[...t.filter(o),...Object.keys(e).filter(r=>!t.includes(r)&&o(r))].join(", ")}function Bs(e){return e.stopped?{state:"vm_stopped"}:e.instanceId?e.instance?{state:e.instance.online?"online":"offline",instanceId:e.instanceId,version:e.instance.version,capabilities:e.instance.capabilities}:{state:"not_registered",instanceId:e.instanceId}:{state:"no_auth"}}function Ls(e){return e==="online"?!0:e==="offline"||e==="vm_stopped"?!1:null}var pe=new Ms.Command("orgo").description("Provision and manage BadgerClaw Hermes machines on orgo (orgo.ai) cloud VMs");function ae(e){console.error(_.default.red(`\u2717 ${e}`)),process.exit(1)}function fo(e){return e instanceof ie&&e.status===401?"orgo rejected the key (HTTP 401) \u2014 check that it is a valid sk_live_\u2026 key.":e instanceof Error?e.message:String(e)}function rt(e){ae(fo(e))}var kn=e=>`${e.name?String(e.name):"(unnamed)"} ${_.default.dim(String(e.id))}`;async function Sc(e,t){try{return{key:$s({keyFile:e.keyFile}),fromPrompt:!1}}catch(n){e.keyFile&&rt(n)}let o=Be().api_key;if(o)return{key:o,fromPrompt:!1};if(t&&nt()){console.log(_.default.dim(" Don't have an orgo API key yet? Create one at https://www.orgo.ai/start")),console.log(_.default.dim(" Paste it below \u2014 it stays on this machine (chmod 600) and is never shown."));let n=(await Ns("Enter your orgo API key (sk_live_\u2026, hidden): ")).trim();return n||ae("No key entered."),{key:n,fromPrompt:!0}}ae("No orgo API key. Run `badgerclaw orgo connect`, pass --key-file <path>, or set ORGO_API_KEY.")}async function Le(e,t){let{key:o,fromPrompt:n}=await Sc(e,t);return{client:new mo(o),key:o,fromPrompt:n}}async function Hs(e,t,o){if(t.workspace)return t.workspace;let n=Be();if(n.workspace_id)return o&&console.log(_.default.dim(` Using workspace: ${n.workspace_name||n.workspace_id} (change it with \`badgerclaw orgo workspace\`).`)),n.workspace_id;if(o&&nt()){let s=await e.listWorkspaces();s.length===0&&ae("No orgo workspaces found. Create one at https://www.orgo.ai/workspaces.");let i=await _n(),a=i?s.findIndex(u=>String(u.id)===i.workspace_id):-1,c;a>=0?(c=a,console.log(_.default.dim(` Using your account's default orgo workspace: ${s[c].name||s[c].id} (change it with \`badgerclaw orgo workspace\`).`))):c=s.length===1?0:await go("Choose a workspace:",s,kn);let l=s[c];return xt({workspace_id:String(l.id),workspace_name:l.name?String(l.name):""}),await Sn(String(l.id),l.name?String(l.name):void 0),console.log(_.default.dim(` Using workspace: ${l.name||l.id}`)),String(l.id)}let r=await _n();if(r)return r.workspace_id;ae("No workspace selected. Run `badgerclaw orgo connect` (or `orgo workspace`), or pass --workspace <id>.")}async function Fs(e,t,o,n){let r;try{let s=await Rs({client:e,workspaceId:t,workspaceName:n.workspaceName,name:o,cpu:n.cpu,ram:n.ram,disk:n.disk,log:i=>{n.json||console.log(_.default.dim(i))},onVmCreated:i=>{r=i}});n.json?console.log(JSON.stringify({ok:!0,...s})):console.log(_.default.green(`
177
177
  \u2713 "${o}" provisioned \u2014 it should appear online shortly (orgo ${s.computerId}).`))}catch(s){let i=s instanceof Error?s.message:String(s);if(r&&!n.keepOnFailure)try{await e.deleteComputer(r),n.json||console.error(_.default.dim(` (auto-destroyed VM ${r} \u2014 pass --keep-on-failure to keep it for debugging)`))}catch{}n.json?console.log(JSON.stringify({ok:!1,error:i,computerId:r})):console.error(_.default.red(`
178
- \u2717 Provisioning failed: ${i}`)),process.exit(1)}}pe.command("connect").alias("link").description("Connect orgo: enter your API key (hidden), pick a workspace, and remember both").option("--key-file <path>","read the key from a file instead of prompting").option("--workspace <id>","preselect a workspace (skip the picker)").option("--reconfigure","pick the workspace again even if one is already remembered").option("--json","validate + list workspaces as JSON (no prompt, no store)").action(async e=>{if(e.json){let{client:i}=await Le(e,!1);try{let a=await i.listWorkspaces();console.log(JSON.stringify({ok:!0,workspaces:a}))}catch(a){console.log(JSON.stringify({ok:!1,error:fo(a)})),process.exit(1)}return}let{client:t,key:o}=await Le(e,!0),n;try{n=await t.listWorkspaces()}catch(i){rt(i)}n.length===0&&ae("No orgo workspaces found. Create one at https://www.orgo.ai/workspaces."),console.log(_.default.green(`\u2713 orgo key valid \u2014 ${n.length} workspace(s).`));let r;if(e.workspace)r=n.findIndex(i=>String(i.id)===e.workspace),r<0&&ae(`Workspace ${e.workspace} is not available for this key.`);else{let i=Be().workspace_id,a=i?n.findIndex(c=>String(c.id)===i):-1;if(a>=0&&!e.reconfigure)r=a,console.log(_.default.dim(` Using remembered workspace: ${n[r].name||n[r].id} (change it with \`badgerclaw orgo workspace\`, or re-run with --reconfigure).`));else{let c=e.reconfigure?null:await _n(),l=c?n.findIndex(u=>String(u.id)===c.workspace_id):-1;l>=0?(r=l,console.log(_.default.dim(` Using your account's default orgo workspace: ${n[r].name||n[r].id} (re-run with --reconfigure to choose another).`))):n.length>1&&nt()?r=await go("Choose a workspace:",n,kn):r=0}}let s=n[r];if(xt({api_key:o,workspace_id:String(s.id),workspace_name:s.name?String(s.name):""}),await Sn(String(s.id),s.name?String(s.name):void 0),console.log(_.default.green(`\u2713 Connected to orgo \u2014 workspace: ${s.name||s.id}`)),console.log(_.default.dim(` Saved to ${Ps()} (chmod 600).`)),nt()){let i=await bn("Create a machine now? Enter a name (or press Enter to skip): ");if(i){console.log(""),await Fs(t,String(s.id),i,{cpu:1,ram:4,workspaceName:s.name?String(s.name):void 0});return}}console.log(_.default.dim(" Next: `badgerclaw orgo create <name>`."))});pe.command("workspace").description("Show or change the remembered orgo workspace").option("--key-file <path>","path to a file containing the orgo API key").option("--set <id>","set the workspace to this id (skip the picker)").option("--list","list available workspaces and exit").action(async e=>{let t=Be();if(!e.list&&!e.set&&!nt()){t.workspace_id?console.log(`${t.workspace_id} ${t.workspace_name||""}`.trim()):ae("No workspace set. Run `badgerclaw orgo connect`.");return}let{client:o}=await Le(e,!0),n;try{n=await o.listWorkspaces()}catch(i){rt(i)}if(e.list){for(let i of n){let a=String(i.id)===t.workspace_id?_.default.green(" \u2190 current"):"";console.log(` ${i.id} ${_.default.dim(i.name?String(i.name):"")}${a}`)}return}let r;e.set?(r=n.findIndex(i=>String(i.id)===e.set),r<0&&ae(`Workspace ${e.set} is not available for this key.`)):r=await go("Choose a workspace:",n,kn);let s=n[r];xt({workspace_id:String(s.id),workspace_name:s.name?String(s.name):""}),await Sn(String(s.id),s.name?String(s.name):void 0),console.log(_.default.green(`\u2713 Workspace set: ${s.name||s.id}`))});pe.command("disconnect").description("Forget the stored orgo key + workspace").action(()=>{Os(),console.log(_.default.green("\u2713 Disconnected \u2014 cleared the stored orgo key + workspace."))});async function Sc(){if(!h())return{instances:null,note:"sign in with `badgerclaw login` to show bot-online status"};try{let e=await O().get("/api/v1/openclaw/status");return{instances:Array.isArray(e.data)?e.data:e.data?.result??[],note:""}}catch(e){return{instances:null,note:`bot status unavailable (${fo(e)})`}}}async function Sn(e,t){if(h())try{await O().put("/api/v1/openclaw/orgo/workspace",{workspace_id:e,...t?{workspace_name:t}:{}})}catch{}}async function _n(){if(!h())return null;try{let e=await O().get("/api/v1/openclaw/orgo/workspace"),t=e.data&&typeof e.data=="object"&&"result"in e.data?e.data.result:e.data;return t&&typeof t.workspace_id=="string"&&t.workspace_id?{workspace_id:t.workspace_id,workspace_name:typeof t.workspace_name=="string"?t.workspace_name:void 0}:null}catch{return null}}function vc(e){if(!e)return"";switch(e.state){case"online":{let t=js(e.capabilities),o=[e.version?`v${e.version}`:"",t].filter(Boolean).join(", ");return _.default.green("\u25CF bot online")+(o?_.default.dim(` (${o})`):"")}case"offline":return _.default.yellow("\u25CB bot offline");case"vm_stopped":return _.default.dim("\u25CB bot offline (vm stopped)");case"not_registered":return _.default.dim("\xB7 not registered with BadgerClaw");case"no_auth":return _.default.dim("\xB7 not a BadgerClaw machine");default:return""}}pe.command("list").alias("ls").description("List the orgo computers in the (remembered) workspace, their infra status, and each one's BadgerClaw bot-online state").option("--workspace <id>","workspace id (defaults to the remembered one)").option("--key-file <path>","path to a file containing the orgo API key").option("--no-bot-status","skip the BadgerClaw bot-online lookup (faster; infra status only)").option("--json","emit machine-readable JSON").action(async e=>{let{client:t}=await Le(e,!e.json),o=await Hs(t,e,!e.json);try{let n=await t.listComputers(o),r=n.map(()=>{}),s="";if(e.botStatus!==!1&&n.length>0){let i=await Sc();if(s=i.note,i.instances){let a=new Map(i.instances.map(c=>[c.instance_id,c]));await Promise.all(n.map(async(c,l)=>{let u=Ts(c.status),p=u?null:await Cs(t,c.id);r[l]=Bs({stopped:u,instanceId:p,instance:p?a.get(p):void 0})}))}}if(e.json){let i=n.map((a,c)=>({id:a.id,status:a.status??null,name:a.name??null,fly_instance_id:a.fly_instance_id??null,bot:r[c]?{state:r[c].state,online:Ls(r[c].state),instance_id:r[c].instanceId??null,version:r[c].version??null,capabilities:r[c].capabilities??null}:null}));console.log(JSON.stringify({ok:!0,computers:i,...s?{note:s}:{}}));return}if(n.length===0){console.log(_.default.dim("No computers in this workspace."));return}console.log(_.default.green(`${n.length} computer(s):`));for(let i=0;i<n.length;i++){let a=n[i],c=_.default.dim((a.status||"?").padEnd(9)),l=(a.name?String(a.name):"").padEnd(16);console.log(` ${a.id} ${c}${l}${vc(r[i])}`)}s&&console.log(_.default.dim(` (${s})`))}catch(n){e.json&&(console.log(JSON.stringify({ok:!1,error:fo(n)})),process.exit(1)),rt(n)}});pe.command("create").description("Provision an orgo VM and bring up a BadgerClaw Hermes host on it (one-command setup)").argument("<name>","a name for the machine").option("--workspace <id>","workspace id (defaults to the remembered one; prompts the first time)").option("--key-file <path>","path to a file containing the orgo API key (else prompts/uses stored)").option("--cpu <n>","vCPUs (1,2,4,8,16)","1").option("--ram <gb>","RAM in GB (4,8,16,32,64)","4").option("--disk <gb>","disk in GB").option("--keep-on-failure","leave the VM running if provisioning fails (default: auto-destroy it)").option("--json","machine-readable result").action(async(e,t)=>{let o=!t.json,{client:n,key:r,fromPrompt:s}=await Le(t,o),i=await Hs(n,t,o);s&&xt({api_key:r});let a=Be(),c=a.workspace_id===i?a.workspace_name:void 0;await Fs(n,i,e,{workspaceName:c,cpu:parseInt(t.cpu,10)||1,ram:parseInt(t.ram,10)||4,disk:t.disk?parseInt(t.disk,10):void 0,keepOnFailure:t.keepOnFailure,json:t.json})});pe.command("stop").description("Stop an orgo computer (it can be restarted later)").argument("<computer-id>","orgo computer id").option("--key-file <path>","path to a file containing the orgo API key").action(async(e,t)=>{let{client:o}=await Le(t,!0);try{await o.stopComputer(e),console.log(_.default.green(`\u2713 stop requested for ${e}`))}catch(n){rt(n)}});pe.command("destroy").description("Terminate an orgo computer (stops billing). Requires --yes.").argument("<computer-id>","orgo computer id").option("--key-file <path>","path to a file containing the orgo API key").option("--yes","confirm termination (this is destructive)").action(async(e,t)=>{t.yes||ae(`Refusing to terminate ${e} without --yes (this is destructive).`);let{client:o}=await Le(t,!0);try{await o.deleteComputer(e),console.log(_.default.green(`\u2713 terminated ${e} (billing stops).`))}catch(n){rt(n)}});var Us=require("commander"),ho=d(require("chalk")),vn=d(require("os"));j();xe();oe();var Gs=new Us.Command("register").description("Register this machine as a BadgerClaw instance using the existing auth.json (idempotent)").option("--json","machine-readable output").action(async e=>{let t=h();if(!t){let i="Not logged in (no auth.json) \u2014 nothing to register.";e.json?console.log(JSON.stringify({ok:!1,error:i})):console.error(ho.default.red(`\u2717 ${i}`)),process.exit(1)}let o=at(),n=`openclaw-${vn.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${o}`,r=te(t.access_token),s=n;try{let{version:i}=we(),a=await r.post("/api/v1/openclaw/register",{instance_id:n,label:vn.default.hostname(),version:i,machine_fingerprint:o}),c=a.data?.result??a.data;c&&typeof c.instance_id=="string"&&c.instance_id.length>0&&(s=c.instance_id)}catch(i){let a=i?.response?.status,c=i?.response?.data?.errors?.[0]||i?.response?.data?.detail||i?.message||"register failed";e.json?console.log(JSON.stringify({ok:!1,error:`${a??"?"}: ${c}`})):console.error(ho.default.red(`\u2717 register failed (${a??"?"}): ${c}`)),process.exit(1)}s!==t.instance_id&&Me({...t,instance_id:s}),e.json?console.log(JSON.stringify({ok:!0,instance_id:s})):console.log(ho.default.green(`\u2713 registered: ${s}`))});Fe();async function $c(){await Vn(process.argv);let e=new Ws.Command;e.name("badgerclaw").description("BadgerClaw CLI \u2014 one-click bot provisioning").version("0.2.68"),e.addCommand(jr),e.addCommand(Mr),e.addCommand(Fr),e.addCommand(Xr),e.addCommand(cr),e.addCommand(es),e.addCommand(fs),e.addCommand(sn),e.addCommand(ys),e.addCommand(_s),e.addCommand(ks),e.addCommand(pe),e.addCommand(Gs),e.parse(process.argv)}$c().catch(e=>{console.error(e),process.exit(1)});
178
+ \u2717 Provisioning failed: ${i}`)),process.exit(1)}}pe.command("connect").alias("link").description("Connect orgo: enter your API key (hidden), pick a workspace, and remember both").option("--key-file <path>","read the key from a file instead of prompting").option("--workspace <id>","preselect a workspace (skip the picker)").option("--reconfigure","pick the workspace again even if one is already remembered").option("--json","validate + list workspaces as JSON (no prompt, no store)").action(async e=>{if(e.json){let{client:i}=await Le(e,!1);try{let a=await i.listWorkspaces();console.log(JSON.stringify({ok:!0,workspaces:a}))}catch(a){console.log(JSON.stringify({ok:!1,error:fo(a)})),process.exit(1)}return}let{client:t,key:o}=await Le(e,!0),n;try{n=await t.listWorkspaces()}catch(i){rt(i)}n.length===0&&ae("No orgo workspaces found. Create one at https://www.orgo.ai/workspaces."),console.log(_.default.green(`\u2713 orgo key valid \u2014 ${n.length} workspace(s).`));let r;if(e.workspace)r=n.findIndex(i=>String(i.id)===e.workspace),r<0&&ae(`Workspace ${e.workspace} is not available for this key.`);else{let i=Be().workspace_id,a=i?n.findIndex(c=>String(c.id)===i):-1;if(a>=0&&!e.reconfigure)r=a,console.log(_.default.dim(` Using remembered workspace: ${n[r].name||n[r].id} (change it with \`badgerclaw orgo workspace\`, or re-run with --reconfigure).`));else{let c=e.reconfigure?null:await _n(),l=c?n.findIndex(u=>String(u.id)===c.workspace_id):-1;l>=0?(r=l,console.log(_.default.dim(` Using your account's default orgo workspace: ${n[r].name||n[r].id} (re-run with --reconfigure to choose another).`))):n.length>1&&nt()?r=await go("Choose a workspace:",n,kn):r=0}}let s=n[r];if(xt({api_key:o,workspace_id:String(s.id),workspace_name:s.name?String(s.name):""}),await Sn(String(s.id),s.name?String(s.name):void 0),console.log(_.default.green(`\u2713 Connected to orgo \u2014 workspace: ${s.name||s.id}`)),console.log(_.default.dim(` Saved to ${Ps()} (chmod 600).`)),nt()){let i=await bn("Create a machine now? Enter a name (or press Enter to skip): ");if(i){console.log(""),await Fs(t,String(s.id),i,{cpu:1,ram:4,workspaceName:s.name?String(s.name):void 0});return}}console.log(_.default.dim(" Next: `badgerclaw orgo create <name>`."))});pe.command("workspace").description("Show or change the remembered orgo workspace").option("--key-file <path>","path to a file containing the orgo API key").option("--set <id>","set the workspace to this id (skip the picker)").option("--list","list available workspaces and exit").action(async e=>{let t=Be();if(!e.list&&!e.set&&!nt()){t.workspace_id?console.log(`${t.workspace_id} ${t.workspace_name||""}`.trim()):ae("No workspace set. Run `badgerclaw orgo connect`.");return}let{client:o}=await Le(e,!0),n;try{n=await o.listWorkspaces()}catch(i){rt(i)}if(e.list){for(let i of n){let a=String(i.id)===t.workspace_id?_.default.green(" \u2190 current"):"";console.log(` ${i.id} ${_.default.dim(i.name?String(i.name):"")}${a}`)}return}let r;e.set?(r=n.findIndex(i=>String(i.id)===e.set),r<0&&ae(`Workspace ${e.set} is not available for this key.`)):r=await go("Choose a workspace:",n,kn);let s=n[r];xt({workspace_id:String(s.id),workspace_name:s.name?String(s.name):""}),await Sn(String(s.id),s.name?String(s.name):void 0),console.log(_.default.green(`\u2713 Workspace set: ${s.name||s.id}`))});pe.command("disconnect").description("Forget the stored orgo key + workspace").action(()=>{Os(),console.log(_.default.green("\u2713 Disconnected \u2014 cleared the stored orgo key + workspace."))});async function vc(){if(!h())return{instances:null,note:"sign in with `badgerclaw login` to show bot-online status"};try{let e=await O().get("/api/v1/openclaw/status");return{instances:Array.isArray(e.data)?e.data:e.data?.result??[],note:""}}catch(e){return{instances:null,note:`bot status unavailable (${fo(e)})`}}}async function Sn(e,t){if(h())try{await O().put("/api/v1/openclaw/orgo/workspace",{workspace_id:e,...t?{workspace_name:t}:{}})}catch{}}async function _n(){if(!h())return null;try{let e=await O().get("/api/v1/openclaw/orgo/workspace"),t=e.data&&typeof e.data=="object"&&"result"in e.data?e.data.result:e.data;return t&&typeof t.workspace_id=="string"&&t.workspace_id?{workspace_id:t.workspace_id,workspace_name:typeof t.workspace_name=="string"?t.workspace_name:void 0}:null}catch{return null}}function $c(e){if(!e)return"";switch(e.state){case"online":{let t=js(e.capabilities),o=[e.version?`v${e.version}`:"",t].filter(Boolean).join(", ");return _.default.green("\u25CF bot online")+(o?_.default.dim(` (${o})`):"")}case"offline":return _.default.yellow("\u25CB bot offline");case"vm_stopped":return _.default.dim("\u25CB bot offline (vm stopped)");case"not_registered":return _.default.dim("\xB7 not registered with BadgerClaw");case"no_auth":return _.default.dim("\xB7 not a BadgerClaw machine");default:return""}}pe.command("list").alias("ls").description("List the orgo computers in the (remembered) workspace, their infra status, and each one's BadgerClaw bot-online state").option("--workspace <id>","workspace id (defaults to the remembered one)").option("--key-file <path>","path to a file containing the orgo API key").option("--no-bot-status","skip the BadgerClaw bot-online lookup (faster; infra status only)").option("--json","emit machine-readable JSON").action(async e=>{let{client:t}=await Le(e,!e.json),o=await Hs(t,e,!e.json);try{let n=await t.listComputers(o),r=n.map(()=>{}),s="";if(e.botStatus!==!1&&n.length>0){let i=await vc();if(s=i.note,i.instances){let a=new Map(i.instances.map(c=>[c.instance_id,c]));await Promise.all(n.map(async(c,l)=>{let u=Ts(c.status),p=u?null:await Cs(t,c.id);r[l]=Bs({stopped:u,instanceId:p,instance:p?a.get(p):void 0})}))}}if(e.json){let i=n.map((a,c)=>({id:a.id,status:a.status??null,name:a.name??null,fly_instance_id:a.fly_instance_id??null,bot:r[c]?{state:r[c].state,online:Ls(r[c].state),instance_id:r[c].instanceId??null,version:r[c].version??null,capabilities:r[c].capabilities??null}:null}));console.log(JSON.stringify({ok:!0,computers:i,...s?{note:s}:{}}));return}if(n.length===0){console.log(_.default.dim("No computers in this workspace."));return}console.log(_.default.green(`${n.length} computer(s):`));for(let i=0;i<n.length;i++){let a=n[i],c=_.default.dim((a.status||"?").padEnd(9)),l=(a.name?String(a.name):"").padEnd(16);console.log(` ${a.id} ${c}${l}${$c(r[i])}`)}s&&console.log(_.default.dim(` (${s})`))}catch(n){e.json&&(console.log(JSON.stringify({ok:!1,error:fo(n)})),process.exit(1)),rt(n)}});pe.command("create").description("Provision an orgo VM and bring up a BadgerClaw Hermes host on it (one-command setup)").argument("<name>","a name for the machine").option("--workspace <id>","workspace id (defaults to the remembered one; prompts the first time)").option("--key-file <path>","path to a file containing the orgo API key (else prompts/uses stored)").option("--cpu <n>","vCPUs (1,2,4,8,16)","1").option("--ram <gb>","RAM in GB (4,8,16,32,64)","4").option("--disk <gb>","disk in GB").option("--keep-on-failure","leave the VM running if provisioning fails (default: auto-destroy it)").option("--json","machine-readable result").action(async(e,t)=>{let o=!t.json,{client:n,key:r,fromPrompt:s}=await Le(t,o),i=await Hs(n,t,o);s&&xt({api_key:r});let a=Be(),c=a.workspace_id===i?a.workspace_name:void 0;await Fs(n,i,e,{workspaceName:c,cpu:parseInt(t.cpu,10)||1,ram:parseInt(t.ram,10)||4,disk:t.disk?parseInt(t.disk,10):void 0,keepOnFailure:t.keepOnFailure,json:t.json})});pe.command("restart").description("Restart an orgo computer").argument("<computer-id>","orgo computer id").option("--key-file <path>","path to a file containing the orgo API key").action(async(e,t)=>{let{client:o}=await Le(t,!0);try{await o.restartComputer(e),console.log(_.default.green(`\u2713 restart requested for ${e}`))}catch(n){rt(n)}});pe.command("destroy").description("Terminate an orgo computer (stops billing). Requires --yes.").argument("<computer-id>","orgo computer id").option("--key-file <path>","path to a file containing the orgo API key").option("--yes","confirm termination (this is destructive)").action(async(e,t)=>{t.yes||ae(`Refusing to terminate ${e} without --yes (this is destructive).`);let{client:o}=await Le(t,!0);try{await o.deleteComputer(e),console.log(_.default.green(`\u2713 terminated ${e} (billing stops).`))}catch(n){rt(n)}});var Us=require("commander"),ho=d(require("chalk")),vn=d(require("os"));j();xe();oe();var Gs=new Us.Command("register").description("Register this machine as a BadgerClaw instance using the existing auth.json (idempotent)").option("--json","machine-readable output").action(async e=>{let t=h();if(!t){let i="Not logged in (no auth.json) \u2014 nothing to register.";e.json?console.log(JSON.stringify({ok:!1,error:i})):console.error(ho.default.red(`\u2717 ${i}`)),process.exit(1)}let o=at(),n=`openclaw-${vn.default.hostname().toLowerCase().replace(/[^a-z0-9]/g,"-")}-${o}`,r=J(t.access_token),s=n;try{let{version:i}=we(),a=await r.post("/api/v1/openclaw/register",{instance_id:n,label:vn.default.hostname(),version:i,machine_fingerprint:o}),c=a.data?.result??a.data;c&&typeof c.instance_id=="string"&&c.instance_id.length>0&&(s=c.instance_id)}catch(i){let a=i?.response?.status,c=i?.response?.data?.errors?.[0]||i?.response?.data?.detail||i?.message||"register failed";e.json?console.log(JSON.stringify({ok:!1,error:`${a??"?"}: ${c}`})):console.error(ho.default.red(`\u2717 register failed (${a??"?"}): ${c}`)),process.exit(1)}s!==t.instance_id&&Me({...t,instance_id:s}),e.json?console.log(JSON.stringify({ok:!0,instance_id:s})):console.log(ho.default.green(`\u2713 registered: ${s}`))});Fe();async function Cc(){await Vn(process.argv);let e=new Ws.Command;e.name("badgerclaw").description("BadgerClaw CLI \u2014 one-click bot provisioning").version("0.2.69"),e.addCommand(jr),e.addCommand(Mr),e.addCommand(Fr),e.addCommand(Xr),e.addCommand(cr),e.addCommand(es),e.addCommand(fs),e.addCommand(sn),e.addCommand(ys),e.addCommand(_s),e.addCommand(ks),e.addCommand(pe),e.addCommand(Gs),e.parse(process.argv)}Cc().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.68",
3
+ "version": "0.2.69",
4
4
  "engines": {
5
5
  "node": ">=18"
6
6
  },