bridge-agent 0.1.0-beta.9 → 0.1.0
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/index.js +1 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27,8 +27,7 @@ Expecting one of '${n.join("', '")}'`);let s=`${e}Help`;return this.on(s,i=>{let
|
|
|
27
27
|
`)+`\r
|
|
28
28
|
\r
|
|
29
29
|
`+t)}function X(r,e,t,n,s,i){if(r.listenerCount("wsClientError")){let o=new Error(s);Error.captureStackTrace(o,X),r.emit("wsClientError",o,t,e)}else ye(t,n,s,i)}});var Hn={};bs(Hn,{loadConfig:()=>qt,loadProjectSettings:()=>Ht,saveConfig:()=>Vt});function qt(){let r=F.default.existsSync(Ye)?Ye:Vn;F.default.existsSync(r)||(console.error("[bridge] Config not found. Run: bridge-agent auth"),process.exit(1));let e=F.default.readFileSync(r,"utf-8"),t;try{t=JSON.parse(e)}catch{console.error("[bridge] Invalid config file at",Vn),process.exit(1)}(!t||typeof t!="object")&&(console.error("[bridge] Config must be a JSON object. Run: bridge-agent auth"),process.exit(1));let n=t,s=typeof n.server=="string"?n.server:"",i=typeof n.token=="string"?n.token:"",o=typeof n.name=="string"?n.name:"bridge-agent";return(!s||!i)&&(console.error("[bridge] Config missing server or token. Run: bridge-agent auth"),process.exit(1)),{server:s,token:i,name:o}}function Vt(r){let e=be.default.dirname(Ye);F.default.existsSync(e)||F.default.mkdirSync(e,{recursive:!0}),F.default.writeFileSync(Ye,JSON.stringify(r,null,2),{mode:384})}function Ht(r){let e=be.default.join(r??process.cwd(),".jerico","settings.json");if(!F.default.existsSync(e))return{};try{let t=F.default.readFileSync(e,"utf-8"),n=JSON.parse(t);if(!n||typeof n!="object"||Array.isArray(n))return{};let s=n,i={};return typeof s.preferredAgent=="string"&&(i.preferredAgent=s.preferredAgent),s.hooks&&typeof s.hooks=="object"&&!Array.isArray(s.hooks)&&(i.hooks=Object.fromEntries(Object.entries(s.hooks).filter(([,o])=>typeof o=="string"))),s.env&&typeof s.env=="object"&&!Array.isArray(s.env)&&(i.env=Object.fromEntries(Object.entries(s.env).filter(([,o])=>typeof o=="string"))),i}catch{return console.warn("[bridge] Failed to parse .jerico/settings.json, ignoring"),{}}}var F,be,Ft,Ye,Vn,ze=ys(()=>{"use strict";F=_(require("fs")),be=_(require("path")),Ft=_(require("os")),Ye=be.default.join(Ft.default.homedir(),".jerico","settings.json"),Vn=be.default.join(Ft.default.homedir(),".bridge","config.json")});var fr=_(hr(),1),{program:ha,createCommand:fa,createArgument:pa,createOption:ga,CommanderError:ma,InvalidArgumentError:_a,InvalidOptionArgumentError:ya,Command:pr,Argument:ba,Option:Sa,Help:wa}=fr.default;var is=require("node:http"),ke=require("node:child_process"),os=require("node:fs"),Oe=require("node:os"),ee=_(require("node:path"));var Lr=_(require("node-pty"));var Pr=_(Tr()),Nr=_(require("fs")),Dr=_(require("path")),Rr=_(require("net")),Pe=r=>r+`
|
|
30
|
-
`,Ne=r=>r.replace(/[\r\n]+$/,"")+"\r",re=[{key:"sh",displayName:"Shell",binary:"sh",checkAuth:async()=>!0,formatInput:Pe},{key:"claude",displayName:"Claude Code",binary:"claude",checkAuth:async()=>bt(".claude")||te("ANTHROPIC_API_KEY"),assignSessionId:!0,spawnArgs:["--dangerously-skip-permissions"],resumeArgs:r=>["--dangerously-skip-permissions","--resume",r],supportsMcpConfig:!0,formatInput:Ne},{key:"codex",displayName:"Codex CLI",binary:"codex",checkAuth:async()=>te("OPENAI_API_KEY"),spawnArgs:["--full-auto"],supportsMcpConfig:!0,formatInput:Ne},{key:"qwen",displayName:"Qwen CLI",binary:"qwen",checkAuth:async()=>bt(".qwen"),assignSessionId:!0,spawnArgs:["--yolo"],resumeArgs:r=>["--resume",r,"--yolo"],supportsMcpConfig:!0,formatInput:Ne},{key:"gemini",displayName:"Gemini",binary:"gemini",checkAuth:async()=>te("GEMINI_API_KEY"),supportsMcpConfig:!0,formatInput:Pe},{key:"ollama",displayName:"Ollama",binary:"ollama",checkAuth:async()=>Ys(11434),formatInput:Pe},{key:"aider",displayName:"Aider",binary:"aider",checkAuth:async()=>te("OPENAI_API_KEY")||te("ANTHROPIC_API_KEY"),supportsMcpConfig:!0,formatInput:Pe},{key:"kimi",displayName:"Kimi Code",binary:"kimi",checkAuth:async()=>bt(".kimi")||te("KIMI_API_KEY"),assignSessionId:!0,spawnArgs:["--yolo"],resumeArgs:r=>["-r",r,"--yolo"],supportsMcpConfig:!0,formatInput:Ne}];async function St(){let r=[];for(let e of re)try{let t=await(0,Pr.default)(e.binary),s=await e.checkAuth()?"ok":"missing";r.push({key:e.key,displayName:e.displayName,binaryPath:t,authStatus:s})}catch
|
|
31
|
-
`)[0]})}return console.log("[daemon] agent.detect.done",{found:r.map(e=>e.key),missing:re.map(e=>e.key).filter(e=>!r.find(t=>t.key===e))}),r}function bt(r){return Nr.default.existsSync(Dr.default.join(process.env.HOME??"",r))}function te(r){return!!process.env[r]}async function Ys(r){return new Promise(e=>{let t=Rr.default.createConnection(r,"127.0.0.1");t.setTimeout(200),t.on("connect",()=>{t.destroy(),e(!0)}),t.on("error",()=>e(!1)),t.on("timeout",()=>{t.destroy(),e(!1)})})}var De=class{handles=new Map;spawn(e,t,n,s,i,o,c,a,l){this.handles.has(e)&&this.kill(e,!0);let d=Math.max(1,Math.min(500,i)),u=Math.max(1,Math.min(500,o)),h={...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"};l&&(h.BRIDGE_SERVER_URL=l.serverUrl,h.BRIDGE_TOKEN=l.token,h.BRIDGE_WORKSPACE_ID=l.workspaceId,h.BRIDGE_PROJECT_ID=l.projectId,l.projectEnv&&Object.assign(h,l.projectEnv));let g=process.env.BRIDGE_MCP_URL;g&&(h.BRIDGE_MCP_URL=g);let f;try{f=Lr.spawn(n,s,{name:"xterm-256color",cols:d,rows:u,cwd:l?.cwd,env:h})}catch(m){let v=m instanceof Error?m.message:String(m);return console.error("[daemon] pty.spawn.failed",{agentId:e,agentKey:t,error:v}),!1}let p={agentId:e,agentKey:t,process:f,pid:f.pid,killed:!1};return f.onData(m=>{c(Buffer.from(m).toString("base64"))}),f.onExit(({exitCode:m,signal:v})=>{p.killed||(this.handles.delete(e),console.log("[daemon] pty.exit",{agentId:e,exitCode:m,signal:v}),a(m??null,v?String(v):null))}),this.handles.set(e,p),console.log("[daemon] pty.spawn.success",{agentId:e,agentKey:t,args:s,cwd:l?.cwd}),!0}write(e,t,n){let s=this.handles.get(e);if(!s)return;let i=Buffer.from(t,"base64").toString(),o=re.find(a=>a.key===s.agentKey),c=n==="orchestrator"&&o?.formatInput?o.formatInput(i):i;s.process.write(c)}kill(e,t=!1){let n=this.handles.get(e);if(!n)return;n.killed=!0,this.handles.delete(e);let s=n.pid;if(t){try{process.kill(-s,"SIGTERM")}catch{n.process.kill()}setTimeout(()=>{try{process.kill(-s,"SIGKILL")}catch{}},2e3)}else try{process.kill(-s,"SIGTERM")}catch{n.process.kill()}console.log("[daemon] pty.kill",{agentId:e,force:t})}resize(e,t,n){let s=this.handles.get(e);if(!s)return;let i=Math.max(1,Math.min(500,t)),o=Math.max(1,Math.min(500,n));s.process.resize(i,o)}killAll(){for(let e of this.handles.values())try{process.kill(-e.pid,"SIGTERM")}catch{e.process.kill()}this.handles.clear()}};var go=_(Pn(),1),mo=_(Fe(),1),_o=_(ie(),1),yo=_(Pt(),1),bo=_(Rt(),1),So=_(Ut(),1),Un=_(Ge(),1),wo=_($n(),1);var O=Un.default;var Z=_(require("fs")),L=_(require("path")),ve=_(require("os")),Jt=require("node:child_process"),ts=require("node:crypto");var Wn=r=>r;var Fn=r=>r,qn=r=>r;ze();var Se=_(require("fs")),Gt=_(require("path")),Gn=_(require("os")),Eo=2e5;function xo(r){let e=Gt.default.join(Gn.default.homedir(),".claude","projects");if(Se.default.existsSync(e))try{let t=Se.default.readdirSync(e,{withFileTypes:!0}).filter(n=>n.isDirectory());for(let n of t){let s=Gt.default.join(e,n.name,`${r}.jsonl`);if(Se.default.existsSync(s))return s}}catch{}}function vo(r){try{let t=Se.default.readFileSync(r,"utf-8").trim().split(`
|
|
30
|
+
`,Ne=r=>r.replace(/[\r\n]+$/,"")+"\r",re=[{key:"sh",displayName:"Shell",binary:"sh",checkAuth:async()=>!0,formatInput:Pe},{key:"claude",displayName:"Claude Code",binary:"claude",checkAuth:async()=>bt(".claude")||te("ANTHROPIC_API_KEY"),assignSessionId:!0,spawnArgs:["--dangerously-skip-permissions"],resumeArgs:r=>["--dangerously-skip-permissions","--resume",r],supportsMcpConfig:!0,formatInput:Ne},{key:"codex",displayName:"Codex CLI",binary:"codex",checkAuth:async()=>te("OPENAI_API_KEY"),spawnArgs:["--full-auto"],supportsMcpConfig:!0,formatInput:Ne},{key:"qwen",displayName:"Qwen CLI",binary:"qwen",checkAuth:async()=>bt(".qwen"),assignSessionId:!0,spawnArgs:["--yolo"],resumeArgs:r=>["--resume",r,"--yolo"],supportsMcpConfig:!0,formatInput:Ne},{key:"gemini",displayName:"Gemini",binary:"gemini",checkAuth:async()=>te("GEMINI_API_KEY"),supportsMcpConfig:!0,formatInput:Pe},{key:"ollama",displayName:"Ollama",binary:"ollama",checkAuth:async()=>Ys(11434),formatInput:Pe},{key:"aider",displayName:"Aider",binary:"aider",checkAuth:async()=>te("OPENAI_API_KEY")||te("ANTHROPIC_API_KEY"),supportsMcpConfig:!0,formatInput:Pe},{key:"kimi",displayName:"Kimi Code",binary:"kimi",checkAuth:async()=>bt(".kimi")||te("KIMI_API_KEY"),assignSessionId:!0,spawnArgs:["--yolo"],resumeArgs:r=>["-r",r,"--yolo"],supportsMcpConfig:!0,formatInput:Ne}];async function St(){let r=[];for(let e of re)try{let t=await(0,Pr.default)(e.binary),s=await e.checkAuth()?"ok":"missing";r.push({key:e.key,displayName:e.displayName,binaryPath:t,authStatus:s})}catch{}return console.log("[daemon] agent.detect.done",{found:r.map(e=>e.key),missing:re.map(e=>e.key).filter(e=>!r.find(t=>t.key===e))}),r}function bt(r){return Nr.default.existsSync(Dr.default.join(process.env.HOME??"",r))}function te(r){return!!process.env[r]}async function Ys(r){return new Promise(e=>{let t=Rr.default.createConnection(r,"127.0.0.1");t.setTimeout(200),t.on("connect",()=>{t.destroy(),e(!0)}),t.on("error",()=>e(!1)),t.on("timeout",()=>{t.destroy(),e(!1)})})}var De=class{handles=new Map;spawn(e,t,n,s,i,o,c,a,l){this.handles.has(e)&&this.kill(e,!0);let d=Math.max(1,Math.min(500,i)),u=Math.max(1,Math.min(500,o)),h={...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"};l&&(h.BRIDGE_SERVER_URL=l.serverUrl,h.BRIDGE_TOKEN=l.token,h.BRIDGE_WORKSPACE_ID=l.workspaceId,h.BRIDGE_PROJECT_ID=l.projectId,l.projectEnv&&Object.assign(h,l.projectEnv));let g=process.env.BRIDGE_MCP_URL;g&&(h.BRIDGE_MCP_URL=g);let f;try{f=Lr.spawn(n,s,{name:"xterm-256color",cols:d,rows:u,cwd:l?.cwd,env:h})}catch(m){let v=m instanceof Error?m.message:String(m);return console.error("[daemon] pty.spawn.failed",{agentId:e,agentKey:t,error:v}),!1}let p={agentId:e,agentKey:t,process:f,pid:f.pid,killed:!1};return f.onData(m=>{c(Buffer.from(m).toString("base64"))}),f.onExit(({exitCode:m,signal:v})=>{p.killed||(this.handles.delete(e),console.log("[daemon] pty.exit",{agentId:e,exitCode:m,signal:v}),a(m??null,v?String(v):null))}),this.handles.set(e,p),console.log("[daemon] pty.spawn.success",{agentId:e,agentKey:t,args:s,cwd:l?.cwd}),!0}write(e,t,n){let s=this.handles.get(e);if(!s)return;let i=Buffer.from(t,"base64").toString(),o=re.find(a=>a.key===s.agentKey),c=n==="orchestrator"&&o?.formatInput?o.formatInput(i):i;s.process.write(c)}kill(e,t=!1){let n=this.handles.get(e);if(!n)return;n.killed=!0,this.handles.delete(e);let s=n.pid;if(t){try{process.kill(-s,"SIGTERM")}catch{n.process.kill()}setTimeout(()=>{try{process.kill(-s,"SIGKILL")}catch{}},2e3)}else try{process.kill(-s,"SIGTERM")}catch{n.process.kill()}console.log("[daemon] pty.kill",{agentId:e,force:t})}resize(e,t,n){let s=this.handles.get(e);if(!s)return;let i=Math.max(1,Math.min(500,t)),o=Math.max(1,Math.min(500,n));s.process.resize(i,o)}killAll(){for(let e of this.handles.values())try{process.kill(-e.pid,"SIGTERM")}catch{e.process.kill()}this.handles.clear()}};var go=_(Pn(),1),mo=_(Fe(),1),_o=_(ie(),1),yo=_(Pt(),1),bo=_(Rt(),1),So=_(Ut(),1),Un=_(Ge(),1),wo=_($n(),1);var O=Un.default;var Z=_(require("fs")),L=_(require("path")),ve=_(require("os")),Jt=require("node:child_process"),ts=require("node:crypto");var Wn=r=>r;var Fn=r=>r,qn=r=>r;ze();var Se=_(require("fs")),Gt=_(require("path")),Gn=_(require("os")),Eo=2e5;function xo(r){let e=Gt.default.join(Gn.default.homedir(),".claude","projects");if(Se.default.existsSync(e))try{let t=Se.default.readdirSync(e,{withFileTypes:!0}).filter(n=>n.isDirectory());for(let n of t){let s=Gt.default.join(e,n.name,`${r}.jsonl`);if(Se.default.existsSync(s))return s}}catch{}}function vo(r){try{let t=Se.default.readFileSync(r,"utf-8").trim().split(`
|
|
32
31
|
`);for(let n=t.length-1;n>=0;n--){let s=t[n]?.trim();if(s)try{let i=JSON.parse(s),o=i.message?.usage??i.usage;if(!o||typeof o!="object")continue;let c=o,a=(c.input_tokens??0)+(c.cache_creation_input_tokens??0)+(c.cache_read_input_tokens??0);if(a===0)continue;return{usedPct:Math.min(100,Math.round(a/Eo*100)),usedTokens:a}}catch{continue}}}catch{}return null}function Kt(r,e,t){let n,s=-1,i=()=>{if(n||(n=xo(e)),!n)return;let a=vo(n);a&&a.usedTokens!==s&&(s=a.usedTokens,t(r,a.usedPct,a.usedTokens))},o=setTimeout(i,2e3),c=setInterval(i,3e3);return()=>{clearTimeout(o),clearInterval(c)}}var H=_(require("fs")),we=_(require("path")),Yt=_(require("os")),Kn=300*60*1e3,Yn={free:10,pro:40,max_5x:200,max_20x:200};function ko(){let r=we.default.join(Yt.default.homedir(),".jerico","settings.json");try{if(!H.default.existsSync(r))return"pro";let t=JSON.parse(H.default.readFileSync(r,"utf-8")).claudeTier;if(typeof t=="string"&&t in Yn)return t}catch{}return"pro"}function Oo(){let r=we.default.join(Yt.default.homedir(),".claude","projects");if(!H.default.existsSync(r))return{prompts5h:0,resetAt:0};let t=Date.now()-Kn,n=1/0,s=0;try{let o=H.default.readdirSync(r,{withFileTypes:!0}).filter(c=>c.isDirectory());for(let c of o){let a=we.default.join(r,c.name),l;try{l=H.default.readdirSync(a).filter(d=>d.endsWith(".jsonl"))}catch{continue}for(let d of l){let u=we.default.join(a,d),h;try{if(H.default.statSync(u).size>20*1024*1024)continue;h=H.default.readFileSync(u,"utf-8")}catch{continue}for(let g of h.split(`
|
|
33
32
|
`)){let f=g.trim();if(f)try{let p=JSON.parse(f);if(p.type!=="user"||p.message?.role!=="user"||p.userType!==void 0&&p.userType!=="external")continue;let v=p.timestamp;if(typeof v!="string")continue;let C=Date.parse(v);if(isNaN(C)||C<t)continue;s++,C<n&&(n=C)}catch{continue}}}}}catch{}let i=isFinite(n)?n+Kn:0;return{prompts5h:s,resetAt:i}}function zn(r){let e=()=>{let n=ko(),s=Yn[n]??40,{prompts5h:i,resetAt:o}=Oo();r({prompts5h:i,limit5h:s,resetAt:o,tier:n})};try{e()}catch(n){console.warn("[quota] initial poll failed",n)}let t=setInterval(()=>{try{e()}catch{}},6e4);return()=>clearInterval(t)}var Xe=_(require("os")),Je=_(require("fs")),Xn=require("node:child_process");function Qn(){let r=0,e=0;for(let t of Xe.default.cpus())r+=t.times.idle,e+=t.times.user+t.times.nice+t.times.sys+t.times.idle+(t.times.irq??0);return{idle:r,total:e}}var zt=Qn();function Io(){let r=Qn(),e=r.idle-zt.idle,t=r.total-zt.total;return zt=r,t===0?0:Math.round((1-e/t)*100)}function Co(){let r=Xe.default.totalmem(),e=Xe.default.freemem();return{totalMb:Math.round(r/1024/1024),usedMb:Math.round((r-e)/1024/1024)}}function Ao(){try{let r=(0,Xn.spawnSync)("pmset",["-g","batt"],{encoding:"utf-8",timeout:2e3,stdio:"pipe"});if(r.status!==0||!r.stdout)return;let e=r.stdout.match(/(\d+)%;\s*(charging|discharging|charged|finishing charge)/i);if(!e)return;let t=parseInt(e[1],10),n=/charging|charged|finishing/i.test(e[2]);return{percent:t,charging:n}}catch{return}}function To(){try{let r="/sys/class/power_supply",e=Je.default.readdirSync(r).filter(o=>/^BAT/i.test(o));if(e.length===0)return;let t=`${r}/${e[0]}`,n=parseInt(Je.default.readFileSync(`${t}/capacity`,"utf-8").trim(),10),s=Je.default.readFileSync(`${t}/status`,"utf-8").trim().toLowerCase();return{percent:n,charging:s==="charging"||s==="full"}}catch{return}}function Jn(){let r=process.platform;if(r==="darwin")return Ao();if(r==="linux")return To()}var Po=1e4,No=3;function Zn(r){let e=0,t=Jn(),n=setInterval(()=>{e++,e%No===0&&(t=Jn());let s=Co();r({cpu:Io(),ramUsedMb:s.usedMb,ramTotalMb:s.totalMb,battery:t})},Po);return()=>clearInterval(n)}var Q=new Map,Do=r=>r.replace(/[\r\n]+$/,"")+"\r",Xt=null,Ro=zn(r=>{Xt=r}),Lo=3e4,Mo=5e3,jo=400;function Bo(r){return r.replace(/\x1b\[[0-9;?]*[A-Za-z]/g,"")}function $o(r,e=jo){return r.length<=e?r:`${r.slice(0,e)}...`}function Uo(r){return r.replace(/^wss?:/,e=>e==="wss:"?"https:":"http:").replace(/\/ws(\/.*)?$/,"")}function Ze(){let r=Z.default.realpathSync(process.argv[1]??""),e=L.default.dirname(r);return[L.default.resolve(e,"../../mcp-server/dist/index.cjs"),L.default.resolve(e,"bridge-mcp.cjs"),L.default.resolve(process.cwd(),"node_modules/.bin/bridge-mcp")].find(n=>Z.default.existsSync(n))??"bridge-mcp"}function Wo(r){try{let e=process.env.BRIDGE_MCP_URL,t=e?{mcpServers:{bridge:{type:"http",url:`${e}/mcp/${r.workspaceId}/${r.projectId}`,headers:{Authorization:`Bearer ${r.token}`,"x-panel-id":r.agentId??""}}}}:{mcpServers:{bridge:{command:Ze(),args:[],env:{BRIDGE_SERVER_URL:r.serverUrl,BRIDGE_TOKEN:r.token,BRIDGE_WORKSPACE_ID:r.workspaceId,BRIDGE_PROJECT_ID:r.projectId,BRIDGE_PANEL_ID:r.agentId??"",HTTP_MODE:"false"}}}},n=L.default.join(ve.default.tmpdir(),`bridge-mcp-${r.agentId??r.projectId}.json`);return Z.default.writeFileSync(n,JSON.stringify(t,null,2)+`
|
|
34
33
|
`,"utf-8"),console.log("[daemon] mcp.config.written",{tmpPath:n,transport:e?"http":"stdio"}),["--mcp-config",n]}catch(e){return console.warn("[daemon] mcp.config.build.failed",{error:String(e)}),[]}}var Fo={bridge_get_project:"Project metadata: name, cwd, machineId",bridge_get_plan:"Read project spec/description",bridge_update_plan:"Update project spec/description",bridge_get_project_history:"Past run history and failure patterns",bridge_get_execution_status:"Run history with todo completion counts",bridge_get_todos:"List todos + session state for this project",bridge_add_todo:"Create a new todo (title, todoType, dependsOn)",bridge_update_todo:"Update a todo title or status",bridge_cancel_run:"Cancel active run (use before restarting a stale plan)",bridge_list_agents:"All agents: role, status, inRun flag",bridge_get_agent_status:"Single agent status check",bridge_spawn_worker:"Spawn a new worker agent (agentKey, role)",bridge_kill_agent:"Terminate a stuck or dead agent",bridge_get_agent_output:"Read terminal output of any agent",bridge_send_input:"Send text input to an agent PTY",bridge_get_my_task:"Get the task assigned to this agent",bridge_complete_task:"Signal task completion",bridge_fail_task:"Signal task failure with a specific reason",bridge_get_todo_context:"Read todo output/error for a specific todo",bridge_assign_task:"Assign a pending todo to a specific agent"};function Ee(...r){return`
|