@aicommander/agent 1.0.23 → 1.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/agent.js +1 -1
- package/dist/bin/agent.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/src/version.d.ts +1 -1
- package/package.json +16 -17
package/dist/bin/agent.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{program as x}from"commander";var O="1.0.
|
|
2
|
+
import{program as x}from"commander";var O="1.0.24";import cn from"os";function ln(e){try{let t=JSON.parse(e);return typeof t.code=="string"?t.code:null}catch{return null}}var we=class extends Error{constructor(r,s){super(`Registration failed (${r}): ${s}`);this.status=r;this.body=s;this.name="RegistrationError",this.code=ln(s)}status;body;code};async function Re(e,t,r={}){let s={hostname:cn.hostname(),platform:process.platform,arch:process.arch,agentVersion:O,...t?{deviceId:t.deviceId,deviceSecret:t.deviceSecret}:{},...r.forceNew?{forceNew:!0}:r.currentCode?{currentCode:r.currentCode}:{}},i=await fetch(`${e}/api/register`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});if(!i.ok){let o=await i.text();throw new we(i.status,o)}return i.json()}import Tn from"ws";import _n from"os";import{spawn as Ze}from"child_process";var k="https://aicommander.dev";var v="aicommander-exec";var qe="ABCDEFGHJKMNPQRSTVWXYZ0123456789";var dr=Math.floor(256/qe.length)*qe.length;var dn=/^AIC-[ABCDEFGHJKMNPQRSTVWXYZ0-9]{4}-[ABCDEFGHJKMNPQRSTVWXYZ0-9]{4}-[ABCDEFGHJKMNPQRSTVWXYZ0-9]{4}$/;function un(e){return dn.test(e.trim().toUpperCase())}function j(e){return un(e)?`AIC-${e.slice(4,8)}-***-***`:e}var Qe=process.platform==="win32";function ze(e,t,r,s){let i=Date.now(),o=Ze(e,[],{shell:!0,cwd:t??process.env.HOME,env:{...process.env,...r??{}},stdio:["ignore","pipe","pipe"],detached:!Qe}),l=!1,a=null,d=()=>{a&&(clearTimeout(a),a=null)};o.stdout?.on("data",p=>{s.onOutput(p.toString("base64"),"stdout")}),o.stderr?.on("data",p=>{s.onOutput(p.toString("base64"),"stderr")}),o.on("close",p=>{l=!0,d(),s.onDone(p??-1,Date.now()-i)}),o.on("error",p=>{l=!0,d(),s.onError(p.message)});let c=p=>{if(!(l||o.pid==null))try{Qe?Ze("taskkill",["/pid",String(o.pid),"/T","/F"],{stdio:"ignore"}):process.kill(-o.pid,p)}catch{}};return{kill:()=>{l||(c("SIGTERM"),d(),a=setTimeout(()=>{a=null,c("SIGKILL")},5e3),a.unref?.())}}}import{spawn as hn}from"node:child_process";import{readFileSync as yn}from"node:fs";import{isAbsolute as En}from"node:path";import{spawn as mn}from"node:child_process";import{createRequire as fn}from"node:module";import{constants as pn}from"node:os";var gn=fn(import.meta.url),Te="__secure-exec-drop",Sn="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";function et(){let e=!1;try{e=gn("node:sea").isSea()}catch{}return e}function tt(e){let t=process.argv[1],r=!et()&&t?[t,Te,...e]:[Te,...e];return{cmd:process.execPath,args:r}}function nt(e){let t=et()?1:2;if(e[t]!==Te)return!1;let[r,s,i,o,...l]=e.slice(t+1),a=Number(r),d=Number(s),c=process;try{if(!Number.isInteger(a)||!Number.isInteger(d)||a===0||!i||!o)throw new Error("invalid drop arguments");if(typeof c.initgroups!="function"||typeof c.setgid!="function"||typeof c.setuid!="function")throw new Error("privilege-drop syscalls unavailable on this platform");if(c.initgroups(i,d),c.setgid(d),c.setuid(a),c.getuid?.()===0||c.getgid?.()===0)throw new Error("privilege drop did not take effect");if(typeof c.getgroups=="function"){let f=c.getgroups();if(Array.isArray(f)&&f.includes(0))throw new Error("privilege drop left root's supplementary groups in place")}}catch(f){process.stderr.write(`secure-exec: privilege drop failed: ${f instanceof Error?f.message:String(f)}
|
|
3
3
|
`),process.exit(127)}let p={...process.env,PATH:Sn},m=mn(o,l,{stdio:"inherit",env:p,shell:!1}),u=!1;return m.on("error",f=>{u||(u=!0,process.stderr.write(`secure-exec: spawn failed: ${f.message}
|
|
4
4
|
`),process.exit(127))}),m.on("exit",(f,S)=>{if(!u){if(u=!0,S){let A=pn.signals[S];process.exit(128+(typeof A=="number"?A:0))}process.exit(f??0)}}),!0}function vn(){let e;try{e=yn("/etc/passwd","utf8")}catch{throw new Error("cannot read /etc/passwd to resolve the secure-exec user")}let t=e.split(`
|
|
5
5
|
`).filter(d=>d.startsWith(`${v}:`));if(t.length===0)throw new Error(`secure exec user "${v}" not found in /etc/passwd \u2014 reinstall the agent to create it`);if(t.length>1)throw new Error(`multiple /etc/passwd entries for "${v}" \u2014 refusing to guess which is the sandbox user`);let r=t[0].split(":");if(r.length!==7)throw new Error(`malformed passwd entry for ${v}`);let s=r[2],i=r[3];if(!/^\d+$/.test(s)||!/^\d+$/.test(i))throw new Error(`could not resolve uid/gid for ${v}`);let o=Number(s),l=Number(i),a=r[5]||"/tmp";if(!Number.isInteger(o)||!Number.isInteger(l))throw new Error(`could not resolve uid/gid for ${v}`);if(o===0)throw new Error("refusing to run secure exec as uid 0");if(l===0)throw new Error("refusing to run secure exec as gid 0");return{uid:o,gid:l,home:a,name:v}}var bn="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",wn=new Set(["NODE_OPTIONS","BASH_ENV","ENV","IFS","PYTHONSTARTUP","PYTHONPATH","PERL5OPT","RUBYOPT","GIT_EXTERNAL_DIFF","PATH","HOME","USER","LOGNAME"]),Rn=e=>/^LD_/.test(e)||wn.has(e);function ot(e,t){if(process.platform!=="linux")throw new Error("secure exec is only supported on Linux");if(typeof process.getuid=="function"&&process.getuid()!==0)throw new Error("secure exec requires the agent to run as root (to drop privilege)");let r=e.argv;if(!Array.isArray(r)||r.length===0||typeof r[0]!="string")throw new Error("secure exec requires a non-empty argv");let s=r[0];if(s.includes("/"))throw new Error(`command "${s}" must be a bare command name (no path separators)`);if(!e.allowedCommands.includes(s))throw new Error(`command "${s}" is not in this token's allowlist`);if(e.cwd!=null&&!En(e.cwd))throw new Error(`cwd "${e.cwd}" must be an absolute path`);let i=null;if(e.input!=null&&(i=Buffer.from(e.input,"base64"),i.length>262144))throw new Error(`stdin payload ${i.length}B exceeds limit ${262144}B`);let o=vn(),l={HOME:o.home,USER:o.name,LOGNAME:o.name,PATH:bn},a={};for(let[g,U]of Object.entries(e.env??{}))Rn(g)||(a[g]=U);let d={...a,...l},c=Date.now(),{cmd:p,args:m}=tt([String(o.uid),String(o.gid),o.name,s,...r.slice(1)]),u=hn(p,m,{cwd:e.cwd??o.home,env:d,stdio:["pipe","pipe","pipe"],detached:!0,shell:!1});i&&u.stdin?(u.stdin.on("error",()=>{}),u.stdin.end(i)):u.stdin?.end();let f=!1,S=null,A=()=>{S&&(clearTimeout(S),S=null)};u.stdout?.on("data",g=>{t.onOutput(g.toString("base64"),"stdout")}),u.stderr?.on("data",g=>{t.onOutput(g.toString("base64"),"stderr")}),u.on("close",g=>{f=!0,A(),t.onDone(g??-1,Date.now()-c)}),u.on("error",g=>{f=!0,A(),t.onError(g.message)});let T=g=>{if(!(f||u.pid==null))try{process.kill(-u.pid,g)}catch{}};return{kill:()=>{f||(T("SIGTERM"),A(),S=setTimeout(()=>{S=null,T("SIGKILL")},5e3),S.unref?.())}}}import w from"chalk";function st(e,t,r=!1){console.clear(),console.log(),console.log(w.bold.cyan(" AI Commander \u2014 Remote Agent")),console.log(),console.log(w.gray(" Session code:")),console.log(),console.log(w.bold.greenBright(` ${r?e:j(e)}`)),console.log(),r||console.log(w.gray(" Reveal the full code: sudo aicommander-agent status --reveal")),console.log(w.gray(" Then give it to your admin to connect.")),console.log(w.yellow(" \u26A0 Keep this code secret \u2014 anyone who has it can run commands as root here.")),console.log(w.gray(` Server: ${t}`)),console.log(w.gray(" Press Ctrl+C to disconnect.")),console.log(),console.log(w.yellow(" Waiting for admin connection...")),console.log()}function it(e,t){console.log(w.yellow(` Reconnecting in ${Math.round(t/1e3)}s (attempt ${e})...`))}function at(){console.log(w.green(" Connected to relay \u2014 ready for commands."))}function _e(e){console.log(w.cyan(` > ${e}`))}function xe(e,t){let r=e===0?w.green:w.red;console.log(r(` Done. Exit ${e} in ${t}ms`))}function An(){let e=process.env.AICOMMANDER_DEV;return e==="1"||e==="true"}function lt(e){let t=e.toLowerCase();return t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="[::1]"}function ct(){return new URL(k).origin}function dt(e){let t=(e??"").trim();if(!t)return k;let r;try{r=new URL(t)}catch{return console.warn(`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../bin/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import ct from"os";var U="1.0.
|
|
1
|
+
import ct from"os";var U="1.0.24";var we="device_secret_mismatch";function lt(e){try{let t=JSON.parse(e);return typeof t.code=="string"?t.code:null}catch{return null}}var O=class extends Error{constructor(r,o){super(`Registration failed (${r}): ${o}`);this.status=r;this.body=o;this.name="RegistrationError",this.code=lt(o)}status;body;code};async function J(e,t,r={}){let o={hostname:ct.hostname(),platform:process.platform,arch:process.arch,agentVersion:U,...t?{deviceId:t.deviceId,deviceSecret:t.deviceSecret}:{},...r.forceNew?{forceNew:!0}:r.currentCode?{currentCode:r.currentCode}:{}},s=await fetch(`${e}/api/register`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!s.ok){let n=await s.text();throw new O(s.status,n)}return s.json()}import vt from"ws";import At from"os";import{spawn as xe}from"child_process";var w="https://aicommander.dev";var R="aicommander-exec";var Re="ABCDEFGHJKMNPQRSTVWXYZ0123456789";var gr=Math.floor(256/Re.length)*Re.length;var Ce=process.platform==="win32";function Ie(e,t,r,o){let s=Date.now(),n=xe(e,[],{shell:!0,cwd:t??process.env.HOME,env:{...process.env,...r??{}},stdio:["ignore","pipe","pipe"],detached:!Ce}),i=!1,c=null,u=()=>{c&&(clearTimeout(c),c=null)};n.stdout?.on("data",d=>{o.onOutput(d.toString("base64"),"stdout")}),n.stderr?.on("data",d=>{o.onOutput(d.toString("base64"),"stderr")}),n.on("close",d=>{i=!0,u(),o.onDone(d??-1,Date.now()-s)}),n.on("error",d=>{i=!0,u(),o.onError(d.message)});let a=d=>{if(!(i||n.pid==null))try{Ce?xe("taskkill",["/pid",String(n.pid),"/T","/F"],{stdio:"ignore"}):process.kill(-n.pid,d)}catch{}};return{kill:()=>{i||(a("SIGTERM"),u(),c=setTimeout(()=>{c=null,a("SIGKILL")},5e3),c.unref?.())}}}import{spawn as gt}from"node:child_process";import{readFileSync as pt}from"node:fs";import{isAbsolute as ft}from"node:path";import{createRequire as ut}from"node:module";var dt=ut(import.meta.url),De="__secure-exec-drop";function mt(){let e=!1;try{e=dt("node:sea").isSea()}catch{}return e}function Oe(e){let t=process.argv[1],r=!mt()&&t?[t,De,...e]:[De,...e];return{cmd:process.execPath,args:r}}function ht(){let e;try{e=pt("/etc/passwd","utf8")}catch{throw new Error("cannot read /etc/passwd to resolve the secure-exec user")}let t=e.split(`
|
|
2
2
|
`).filter(u=>u.startsWith(`${R}:`));if(t.length===0)throw new Error(`secure exec user "${R}" not found in /etc/passwd \u2014 reinstall the agent to create it`);if(t.length>1)throw new Error(`multiple /etc/passwd entries for "${R}" \u2014 refusing to guess which is the sandbox user`);let r=t[0].split(":");if(r.length!==7)throw new Error(`malformed passwd entry for ${R}`);let o=r[2],s=r[3];if(!/^\d+$/.test(o)||!/^\d+$/.test(s))throw new Error(`could not resolve uid/gid for ${R}`);let n=Number(o),i=Number(s),c=r[5]||"/tmp";if(!Number.isInteger(n)||!Number.isInteger(i))throw new Error(`could not resolve uid/gid for ${R}`);if(n===0)throw new Error("refusing to run secure exec as uid 0");if(i===0)throw new Error("refusing to run secure exec as gid 0");return{uid:n,gid:i,home:c,name:R}}var St="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",Et=new Set(["NODE_OPTIONS","BASH_ENV","ENV","IFS","PYTHONSTARTUP","PYTHONPATH","PERL5OPT","RUBYOPT","GIT_EXTERNAL_DIFF","PATH","HOME","USER","LOGNAME"]),yt=e=>/^LD_/.test(e)||Et.has(e);function Me(e,t){if(process.platform!=="linux")throw new Error("secure exec is only supported on Linux");if(typeof process.getuid=="function"&&process.getuid()!==0)throw new Error("secure exec requires the agent to run as root (to drop privilege)");let r=e.argv;if(!Array.isArray(r)||r.length===0||typeof r[0]!="string")throw new Error("secure exec requires a non-empty argv");let o=r[0];if(o.includes("/"))throw new Error(`command "${o}" must be a bare command name (no path separators)`);if(!e.allowedCommands.includes(o))throw new Error(`command "${o}" is not in this token's allowlist`);if(e.cwd!=null&&!ft(e.cwd))throw new Error(`cwd "${e.cwd}" must be an absolute path`);let s=null;if(e.input!=null&&(s=Buffer.from(e.input,"base64"),s.length>262144))throw new Error(`stdin payload ${s.length}B exceeds limit ${262144}B`);let n=ht(),i={HOME:n.home,USER:n.name,LOGNAME:n.name,PATH:St},c={};for(let[g,C]of Object.entries(e.env??{}))yt(g)||(c[g]=C);let u={...c,...i},a=Date.now(),{cmd:d,args:m}=Oe([String(n.uid),String(n.gid),n.name,o,...r.slice(1)]),l=gt(d,m,{cwd:e.cwd??n.home,env:u,stdio:["pipe","pipe","pipe"],detached:!0,shell:!1});s&&l.stdin?(l.stdin.on("error",()=>{}),l.stdin.end(s)):l.stdin?.end();let E=!1,S=null,b=()=>{S&&(clearTimeout(S),S=null)};l.stdout?.on("data",g=>{t.onOutput(g.toString("base64"),"stdout")}),l.stderr?.on("data",g=>{t.onOutput(g.toString("base64"),"stderr")}),l.on("close",g=>{E=!0,b(),t.onDone(g??-1,Date.now()-a)}),l.on("error",g=>{E=!0,b(),t.onError(g.message)});let _=g=>{if(!(E||l.pid==null))try{process.kill(-l.pid,g)}catch{}};return{kill:()=>{E||(_("SIGTERM"),b(),S=setTimeout(()=>{S=null,_("SIGKILL")},5e3),S.unref?.())}}}import B from"chalk";function ke(e,t){console.log(B.yellow(` Reconnecting in ${Math.round(t/1e3)}s (attempt ${e})...`))}function Pe(){console.log(B.green(" Connected to relay \u2014 ready for commands."))}function ie(e){console.log(B.cyan(` > ${e}`))}function ae(e,t){let r=e===0?B.green:B.red;console.log(r(` Done. Exit ${e} in ${t}ms`))}function _t(){let e=process.env.AICOMMANDER_DEV;return e==="1"||e==="true"}function He(e){let t=e.toLowerCase();return t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="[::1]"}function Le(){return new URL(w).origin}function $e(e){let t=(e??"").trim();if(!t)return w;let r;try{r=new URL(t)}catch{return console.warn(`
|
|
3
3
|
\u26A0 Ignoring malformed AICOMMANDER_SERVER (${t}); using ${w}.
|
|
4
4
|
`),w}if(r.origin===Le())return w;let o=He(r.hostname);return!_t()&&!o?(console.warn(`
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_VERSION = "1.0.
|
|
1
|
+
export declare const AGENT_VERSION = "1.0.24";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aicommander/agent",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.24",
|
|
4
4
|
"description": "Remote-machine agent for AI Commander — runs on your server/laptop and lets your AI agent execute shell commands on it via the @aicommander/mcp server. An SSH alternative with no exposed SSH, open ports, or VPN; drive it by AIC-… session code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"remote",
|
|
@@ -40,19 +40,6 @@
|
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
|
-
"scripts": {
|
|
44
|
-
"build": "tsc && node scripts/build-npm.mjs",
|
|
45
|
-
"build:npm": "node scripts/build-npm.mjs",
|
|
46
|
-
"prepublishOnly": "tsc && node scripts/build-npm.mjs",
|
|
47
|
-
"compile": "pnpm run compile:linux-x64 && pnpm run compile:linux-arm64",
|
|
48
|
-
"compile:linux-x64": "bun build ./bin/agent.ts --compile --minify --target=bun-linux-x64 --outfile dist-bin/aicommander-agent-linux-x64",
|
|
49
|
-
"compile:linux-arm64": "bun build ./bin/agent.ts --compile --minify --target=bun-linux-arm64 --outfile dist-bin/aicommander-agent-linux-arm64",
|
|
50
|
-
"dev": "tsx bin/agent.ts",
|
|
51
|
-
"typecheck": "tsc --noEmit",
|
|
52
|
-
"start": "AICOMMANDER_SERVER=https://aicommander.dev node dist/bin/agent.js",
|
|
53
|
-
"start:root": "sudo -E AICOMMANDER_SERVER=https://aicommander.dev node dist/bin/agent.js",
|
|
54
|
-
"test": "vitest run"
|
|
55
|
-
},
|
|
56
43
|
"dependencies": {
|
|
57
44
|
"chalk": "5.6.2",
|
|
58
45
|
"commander": "12.1.0",
|
|
@@ -60,15 +47,27 @@
|
|
|
60
47
|
"ws": "8.21.0"
|
|
61
48
|
},
|
|
62
49
|
"devDependencies": {
|
|
63
|
-
"@aicommander/protocol": "workspace:*",
|
|
64
50
|
"@types/node": "22.19.21",
|
|
65
51
|
"@types/ws": "8.18.1",
|
|
66
52
|
"esbuild": "0.28.1",
|
|
67
53
|
"tsx": "^4.22.4",
|
|
68
54
|
"typescript": "5.9.3",
|
|
69
|
-
"vitest": "3.2.6"
|
|
55
|
+
"vitest": "3.2.6",
|
|
56
|
+
"@aicommander/protocol": "1.0.0"
|
|
70
57
|
},
|
|
71
58
|
"engines": {
|
|
72
59
|
"node": ">=18.0.0"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsc && node scripts/build-npm.mjs",
|
|
63
|
+
"build:npm": "node scripts/build-npm.mjs",
|
|
64
|
+
"compile": "pnpm run compile:linux-x64 && pnpm run compile:linux-arm64",
|
|
65
|
+
"compile:linux-x64": "bun build ./bin/agent.ts --compile --minify --target=bun-linux-x64 --outfile dist-bin/aicommander-agent-linux-x64",
|
|
66
|
+
"compile:linux-arm64": "bun build ./bin/agent.ts --compile --minify --target=bun-linux-arm64 --outfile dist-bin/aicommander-agent-linux-arm64",
|
|
67
|
+
"dev": "tsx bin/agent.ts",
|
|
68
|
+
"typecheck": "tsc --noEmit",
|
|
69
|
+
"start": "AICOMMANDER_SERVER=https://aicommander.dev node dist/bin/agent.js",
|
|
70
|
+
"start:root": "sudo -E AICOMMANDER_SERVER=https://aicommander.dev node dist/bin/agent.js",
|
|
71
|
+
"test": "vitest run"
|
|
73
72
|
}
|
|
74
|
-
}
|
|
73
|
+
}
|