@engineeros/connector 1.56.9 → 1.56.11
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.
|
@@ -1005,7 +1005,7 @@ It is checked with the provider and stored in this machine's protected vault
|
|
|
1005
1005
|
(Windows Data Protection, the macOS Keychain or the Linux Secret Service).
|
|
1006
1006
|
EngineerOS never receives it; the running connector uses it when EngineerOS asks.`;function JB(e,{input:t=process.stdin,output:n=process.stdout}={}){return t.isTTY?new Promise((r,o)=>{n.write(e);let s="";t.setRawMode(!0),t.resume(),t.setEncoding("utf8");let i=c=>{t.setRawMode(!1),t.pause(),t.removeListener("data",a),n.write(`
|
|
1007
1007
|
`),c?o(c):r(s.trim())},a=c=>{for(let l of c){if(l==="\r"||l===`
|
|
1008
|
-
`)return i();if(l==="")return i(new Error("Cancelled."));l==="\x7F"||l==="\b"?s=s.slice(0,-1):s+=l}};t.on("data",a)}):new Promise((r,o)=>{let s="";t.setEncoding("utf8"),t.on("data",i=>s+=i),t.on("end",()=>r(s.trim())),t.on("error",o)})}var tk=Symbol("missing");function KB(e,t){return new Promise(n=>{let r=VB(e,t,{stdio:"inherit",shell:!1});r.once("error",o=>n(o?.code==="ENOENT"?tk:o.message)),r.once("close",o=>n(o===0?null:`${e} exited with code ${o}.`))})}function ek(e,t){for(let n of pi){let r=t[n],o=r.connected?`connected${r.account?` as ${r.account}`:""}`:"not connected";e(`${n.padEnd(8)} ${o}`),r.connected||e(` ${r.detail?`${r.detail} `:""}Connect: ${r.connect_command}`)}}async function nk(e,t,n,{vault:r=sf(),run:o=qc,fetchImpl:s=fetch,secret:i=JB,interactive:a=KB,install:c=Wc,log:l=console.log,error:u=console.error}={}){if(n.help||e!=="integrations"&&!t[0])return l(XB),n.help?0:2;if(e==="integrations")return ek(l,(await Jc({run:o,vault:r})).providers),0;let d=t[0];if(!pi.includes(d))return u(`Unknown provider ${d}. Choose one of: ${pi.join(", ")}.`),2;if(d==="github"||d==="gitlab"){let f=ro[d];if(e==="disconnect")return l(`${d} uses this machine's ${f} sign-in. Run \`${f} auth logout\` to sign out everywhere on this machine.`),0;let h=await a(f,["auth","login"]);if(h===tk){let g=await Go(f);if(!g){l(`Installing the ${li[f].label} ${li[f].version} for the connector...`);try{g=(await c(f)).path}catch(y){return u(y.message),1}}h=await a(g,["auth","login"])}return h?(u(`${h} ${Xc[d]} is how this machine signs in to ${d}.`),1):(ek(l,{[d]:(await Jc({run:o,vault:r})).providers[d]}),0)}let p=Et[d];if(e==="disconnect")return await r.delete("",d),l(`Removed the ${p.label} ${p.tokenName} from this machine.`),0;try{await af(r);let f=await i(`${p.label} ${p.tokenName} (create one at ${p.tokenUrl}): `),h=await cf(r,d,{token:f,site:n.site,email:n.email},s);return l(`Connected ${p.label}${h.account?` as ${h.account}`:""}. The token stays on this machine.`),0}catch(f){return u(f.message),1}}import{spawn as YB}from"node:child_process";async function rk({root:e,bundled:t,argv:n,workspace:r,spawnImpl:o=YB,log:s=console.log}){let i=n,a=!1;for(;;){let c=t;try{c=hr(await It(e),t)}catch(d){s(`${d.message} Starting the installed connector ${t.version}.`)}let{code:l,signal:u}=await ZB(o,c.entry,i,t);if(l===is){i=["start","--workspace",r],a=!1,s("Restarting the connector process on the activated update. Goal runs continue in their own processes.");continue}if(l!==0&&!u&&!a){let d=await It(e).catch(()=>null);if(d&&!d.confirmed&&d.active?.version===c.version)try{let p=await Nl(e,{version:c.version,entry:c.entry,bundled:t},{automatic:!0,reason:`${c.version} exited with code ${l} before connecting to EngineerOS.`});a=!0,s(`Connector ${c.version} stopped before connecting; rolled back to ${p.version}.`);continue}catch(p){s(`Automatic rollback failed: ${p.message}`)}}return l??1}}function ZB(e,t,n,r){return new Promise((o,s)=>{let i=e(process.execPath,[...process.execArgv,t,...n],{stdio:"inherit",env:{...process.env,[co]:"1",[Rl]:r.entry,[Cl]:r.version}}),a=process.platform==="win32"?[]:["SIGINT","SIGTERM","SIGHUP"],c=u=>i.kill(u);for(let u of a)process.on(u,c);let l=()=>{for(let u of a)process.off(u,c)};i.once("error",u=>{l(),s(u)}),i.once("exit",(u,d)=>{l(),o({code:u,signal:d})})})}var Nr="1.56.
|
|
1008
|
+
`)return i();if(l==="")return i(new Error("Cancelled."));l==="\x7F"||l==="\b"?s=s.slice(0,-1):s+=l}};t.on("data",a)}):new Promise((r,o)=>{let s="";t.setEncoding("utf8"),t.on("data",i=>s+=i),t.on("end",()=>r(s.trim())),t.on("error",o)})}var tk=Symbol("missing");function KB(e,t){return new Promise(n=>{let r=VB(e,t,{stdio:"inherit",shell:!1});r.once("error",o=>n(o?.code==="ENOENT"?tk:o.message)),r.once("close",o=>n(o===0?null:`${e} exited with code ${o}.`))})}function ek(e,t){for(let n of pi){let r=t[n],o=r.connected?`connected${r.account?` as ${r.account}`:""}`:"not connected";e(`${n.padEnd(8)} ${o}`),r.connected||e(` ${r.detail?`${r.detail} `:""}Connect: ${r.connect_command}`)}}async function nk(e,t,n,{vault:r=sf(),run:o=qc,fetchImpl:s=fetch,secret:i=JB,interactive:a=KB,install:c=Wc,log:l=console.log,error:u=console.error}={}){if(n.help||e!=="integrations"&&!t[0])return l(XB),n.help?0:2;if(e==="integrations")return ek(l,(await Jc({run:o,vault:r})).providers),0;let d=t[0];if(!pi.includes(d))return u(`Unknown provider ${d}. Choose one of: ${pi.join(", ")}.`),2;if(d==="github"||d==="gitlab"){let f=ro[d];if(e==="disconnect")return l(`${d} uses this machine's ${f} sign-in. Run \`${f} auth logout\` to sign out everywhere on this machine.`),0;let h=await a(f,["auth","login"]);if(h===tk){let g=await Go(f);if(!g){l(`Installing the ${li[f].label} ${li[f].version} for the connector...`);try{g=(await c(f)).path}catch(y){return u(y.message),1}}h=await a(g,["auth","login"])}return h?(u(`${h} ${Xc[d]} is how this machine signs in to ${d}.`),1):(ek(l,{[d]:(await Jc({run:o,vault:r})).providers[d]}),0)}let p=Et[d];if(e==="disconnect")return await r.delete("",d),l(`Removed the ${p.label} ${p.tokenName} from this machine.`),0;try{await af(r);let f=await i(`${p.label} ${p.tokenName} (create one at ${p.tokenUrl}): `),h=await cf(r,d,{token:f,site:n.site,email:n.email},s);return l(`Connected ${p.label}${h.account?` as ${h.account}`:""}. The token stays on this machine.`),0}catch(f){return u(f.message),1}}import{spawn as YB}from"node:child_process";async function rk({root:e,bundled:t,argv:n,workspace:r,spawnImpl:o=YB,log:s=console.log}){let i=n,a=!1;for(;;){let c=t;try{c=hr(await It(e),t)}catch(d){s(`${d.message} Starting the installed connector ${t.version}.`)}let{code:l,signal:u}=await ZB(o,c.entry,i,t);if(l===is){i=["start","--workspace",r],a=!1,s("Restarting the connector process on the activated update. Goal runs continue in their own processes.");continue}if(l!==0&&!u&&!a){let d=await It(e).catch(()=>null);if(d&&!d.confirmed&&d.active?.version===c.version)try{let p=await Nl(e,{version:c.version,entry:c.entry,bundled:t},{automatic:!0,reason:`${c.version} exited with code ${l} before connecting to EngineerOS.`});a=!0,s(`Connector ${c.version} stopped before connecting; rolled back to ${p.version}.`);continue}catch(p){s(`Automatic rollback failed: ${p.message}`)}}return l??1}}function ZB(e,t,n,r){return new Promise((o,s)=>{let i=e(process.execPath,[...process.execArgv,t,...n],{stdio:"inherit",env:{...process.env,[co]:"1",[Rl]:r.entry,[Cl]:r.version}}),a=process.platform==="win32"?[]:["SIGINT","SIGTERM","SIGHUP"],c=u=>i.kill(u);for(let u of a)process.on(u,c);let l=()=>{for(let u of a)process.off(u,c)};i.once("error",u=>{l(),s(u)}),i.once("exit",(u,d)=>{l(),o({code:u,signal:d})})})}var Nr="1.56.11",rl="1.56.11",nH=3e5,ol=["queued","running","reporting"],rH=5e3,lf={id:"design_sync",title:"Design artifact sync",remedy:"Fix the reported problem in this workspace. The connector retries on its own; it does not need restarting."},uf={id:"opportunity_scan",title:"Workspace opportunity scan",remedy:"EngineerOS asked this workspace what to deliver next and the scan failed. Check that the coding agent still answers here, or turn autonomy off in Project steering."},oH=6e4,sH=3e4,iH=60*6e4,df={id:"tool_inventory",title:"Tool inventory refresh",remedy:"Run `engineeros-connector tools list` in this workspace for the full registry state."},pf={id:"runner_setup_reporting",title:"Goal runner setup reporting",remedy:"Restore the connection to EngineerOS; saved setup reports will retry automatically."},{command:st,positional:xt,flags:_e}=iS(process.argv.slice(2));st==="version"&&(console.log(Nr),process.exit(0));var dr=null,$t=!1,On=null,gk=!1,wk=null,Ef=null,ft=null,bi=null,vf,ok,sk,mi,qo,yk=Uc({getWorkspace:()=>C.workspace,onRecorded:e=>lE(C,e).then(()=>console.log(`Recorded the ${e.role} sign-in for Bug Hunter; it is kept on this machine.`)).catch(t=>console.error(`The recorded ${e.role} sign-in was not reported to EngineerOS: ${t.message}`))}),aH=ZE({getWorkspace:()=>C.workspace,huntSignIns:yk}),gi=uS();st==="results"&&(xt[0]!=="upload"&&(console.log(Nc),process.exit(_e.help||!xt[0]?0:2)),process.exit(await WS(_e)));(st==="connect"||st==="disconnect"||st==="integrations")&&process.exit(await nk(st,xt,_e,{fetchImpl:JE}));if(st==="runner"){let e=Rt.resolve(_e.workspace||process.cwd()),t=xt[0]||"status";try{if(t==="serve"||t==="worker"){let n=t==="worker"?Rt.join(Rt.dirname(Qe(e,_e["run-id"])),"worker.log"):Rt.join(e,".engineeros","runner","service.log");eH(Rt.dirname(n),{recursive:!0});let r=(...s)=>Xs(n,`${tH(...s)}
|
|
1009
1009
|
`),o=(s,i,a)=>(Xs(n,s),(typeof i=="function"?i:a)?.(),!0);process.stdout.write=process.stderr.write=o,console.log=console.error=console.warn=r}if(t==="install"){if(_e["keep-awake"]!==void 0){if(!["on","off"].includes(_e["keep-awake"]))throw new Error("Use --keep-awake on or off.");let n=await _t(e);if(!n)throw new Error("Pair this workspace before changing its runner keep-awake setting.");await vn({...n,runner_keep_awake:_e["keep-awake"]==="on"})}console.log(`Installed Goal runner service: ${await Ec(e)}`),process.platform==="darwin"&&console.log("macOS may show a Background Items Added notice. Manage the runner in System Settings > General > Login Items.")}else t==="uninstall"?(await xb(e),console.log("Goal runner service removed. Saved and queued jobs are kept.")):t==="start"?await Fo(e,{enable:!0}):t==="status"?console.log(JSON.stringify(await $r(e),null,2)):t==="serve"?await Cb(e):t==="worker"?await Ob(e,_e["run-id"]):Be("Usage: engineeros-connector runner [install|start|status|uninstall] --workspace PATH [--keep-awake on|off]");process.exit(0)}catch(n){Be(wp(n,e).message)}}_e["assessment-workers"]!==void 0&&Be("--assessment-workers is no longer supported. Select 3 to 8 parallel agents in EngineerOS before starting the assessment.");if(st==="tools"){try{let e=Pb(_e),t=xt[0]||"list";if(["sign-in","auth-status","sign-out"].includes(t)){let r=xt[1];r||Be(`Usage: engineeros-connector tools ${t} PROVIDER_ID [--workspace PATH | --project PROJECT_UUID]`);let o=await pd(e,{type:"tools.auth",command_id:"00000000-0000-4000-8000-000000000001",action:{"sign-in":"sign_in","auth-status":"status","sign-out":"sign_out"}[t],provider_id:r,confirmed:t==="sign-out"});o.completion&&await o.completion}else["setup","upgrade","rollback"].includes(t)?await Ns(e,{type:"tools.update",command_id:"00000000-0000-4000-8000-000000000002",action:t,provider_id:xt[1],confirmed:!0},void 0,{confirmLocal:async()=>!0}):t!=="list"&&await ld(e,t,xt[1]);let n=await Yt(e);console.log(JSON.stringify(n,null,2)),process.exitCode=n.error?1:0}catch(e){Be(e.message)}process.exit(process.exitCode||0)}if(st==="agents"){let e;try{e=await Td()}catch(n){Be(n instanceof Error?n.message:String(n))}let t=await Promise.all(e.map(async n=>{try{return await Ps(n.id),`${n.id}: ready (${n.name} ${n.version}, ${n.distribution_type})`}catch(r){let o=r instanceof Error?r.message:String(r);return`${n.id}: setup needed (${n.name} ${n.version}, ${n.distribution_type}) - ${o}`}}));for(let n of t)console.log(n);process.exit(0)}if(st==="agent"){let e=xt[0],t=xt[1]||"check";(!e||!["check","install"].includes(t))&&Be("Usage: engineeros-connector agent AGENT_ID [check|install]");try{let n=t==="install"?await Ls(e):await Ps(e);console.log(`${n.name} is ready (${n.version}, ${n.distribution}).`)}catch(n){Be(n instanceof Error?n.message:String(n))}process.exit(0)}if(st==="mcp"){let e=_e.workspace||process.env.ENGINEEROS_MCP_WORKSPACE||process.cwd(),t=_e["run-id"]||xt[0]||process.env.ENGINEEROS_MCP_RUN_ID||null,n=await _t(e);await kS({config:n,runId:t,version:Nr,input:process.stdin,output:process.stdout}),process.exit(0)}if(st==="context-mcp"){let e=_e["config-workspace"]||_e.workspace||process.env.ENGINEEROS_MCP_WORKSPACE||process.cwd(),t=await _t(e);t||Be("This workspace is not paired with EngineerOS."),await MS({config:t,workspace:_e.workspace||process.env.ENGINEEROS_CONTEXT_WORKSPACE||t.workspace,version:Nr,input:process.stdin,output:process.stdout}),process.exit(0)}if(st==="status"){let e=await _t(_e.workspace||process.cwd());console.log(e?`Paired as ${e.name} (${e.connector_id}) for ${e.workspace}`:"Not paired"),process.exit(e?0:1)}if(st==="doctor"){let e=Rt.resolve(_e.workspace||process.cwd()),t=await _t(e),n=await _S(e),r=await Yo(t||{workspace:e},e,jp(n));console.log(Op(r)),process.exit(r.status==="failed"?1:0)}if(st==="update"){let e=xt[0]||"status";try{let t=Il(process.argv[1],rl),n=await Ml(Wn(),t,{action:e,policy:xt[1]??null});console.log(cs(Pl(n,t,{supervised:!0})))}catch(t){Be(`${t.message}
|
|
1010
1010
|
Usage: engineeros-connector update [status|check|apply|rollback|policy manual|approve|auto-patch|auto-minor]`)}process.exit(0)}var Vo=st==="hunt-host";if(Vo)try{_e.workspace=Mb(xt,_e)}catch(e){Be(e.message)}if((st==="start"||st==="pair"||Vo)&&process.env[co]!=="1"&&it(rl))try{process.exit(await rk({root:Wn(),bundled:{version:rl,entry:Rt.resolve(process.argv[1])},argv:process.argv.slice(2),workspace:Rt.resolve(_e.workspace||process.cwd())}))}catch(e){Be(`The connector process could not be started: ${e.message}`)}if(Vo){try{await Lb(_e.workspace,xt[0]?_e.agent:null)}catch(e){Be(e.message)}st=xt[0]?"pair":"start"}var C,so,wi;if(st==="pair"){let e=xt[0];e||Be("Usage: engineeros-connector pair CODE --url URL [--agent AGENT_ID | --agent-protocol forge] [--name NAME] [--workspace PATH] [--skip-git-repo-check]");let t=_e.url;t||Be("Pairing requires --url with the EngineerOS backend address."),_e.agent&&_e["agent-command"]&&Be("Use either --agent or --agent-command, not both.");let n=_e["agent-protocol"]||(_e["agent-command"]?"acp":"codex");["codex","acp","forge"].includes(n)||Be(`Unknown --agent-protocol '${n}'. Use codex, acp, or forge.`),n==="forge"&&(_e.agent||_e["agent-command"])&&Be("Forge runs its own agents. Drop --agent and --agent-command when pairing with --agent-protocol forge.");let r={};try{_e.agent&&(await Ps(_e.agent),r=await Rd(_e.agent))}catch(o){Be(o instanceof Error?o.message:String(o))}C={server_url:Ul(t),workspace:Rt.resolve(_e.workspace||process.cwd()),onboard:_e.onboard===!0,onboarding_pending:_e.onboard===!0,hunt_host:Vo,agent_protocol:n,agent_command:_e["agent-command"]||null,agent_args:TH(_e["agent-args"]),agent_name:_e["agent-name"]||null,...r,skip_git_repo_check:Vo||_e["skip-git-repo-check"]===!0,name:_e.name||`${QB.hostname()} - ${Rt.basename(Rt.resolve(_e.workspace||process.cwd()))}`},wi=await _t(C.workspace),so={type:"pair",pairing_code:e,name:C.name,capabilities:{},...Nh(wi,C.server_url)}}else st==="start"?(C=await _t(_e.workspace||process.cwd()),C||Be("This connector is not paired. Create a pairing command in EngineerOS first."),Vo&&!C.hunt_host&&Be("This folder is not a paired hunt host. Generate a new hunt-host command in EngineerOS."),C.token||Be("This connector's token is no longer in this machine's credential store. Create a new pairing command in EngineerOS and pair again."),so={type:"authenticate",connector_id:C.connector_id,token:C.token}):Be("Use `engineeros-connector pair`, `start`, `status`, `doctor`, `agents`, `agent`, `tools`, or `mcp`.");var _k=Ib(C,{reportError:e=>console.error(e)}),jr=0,sl=!1,yi=null,At=new Map,ff=0,hf=new Set,Xo=[],kt=new Map,mt,bf,Qc,zn=null,el=!1,vk=0,mf=null,gf=[],tl,bk,fi=1e3,Jo,ik=0,wf=!1,cr=!1,dn,Ho=!1,il=!1,Sf=0;function Kc(e){return Sf+=1,e.finally(()=>{Sf-=1})}var Wo,oo=0;function _i({exitCode:e=0}={}){if(oo=Math.max(oo,e),Wo)return Wo;let t=setTimeout(()=>{console.error("Connector shutdown exceeded 15 seconds; inspect the retained agent logs before restarting."),process.exit(1)},15e3);return t.unref(),Wo=cH().finally(()=>clearTimeout(t)),Wo}async function cH(){if($t=!0,bi?.stop(),dr?.stop(),Ef?.stop(),wk?.stop(),clearInterval(vf),ft?.stop(),bk?.(),clearTimeout(tl),clearInterval(bf),clearInterval(Qc),await Promise.all([...[...At.values()].map(e=>Mt(e.child))]),await Promise.all([...kt.values()].map(xf)),await mi?.cancelAll(),await qo?.abortAll(),await Ms(),await jf().catch(e=>{oo=Math.max(oo,1),console.error(`${e.message}. Stop those processes before restarting the connector.`)}),mt?.close(),oo&&oo!==is){let e;await Promise.race([(async()=>{await dr?.drain(),await Yo(C,C.workspace)})().catch(()=>{}),new Promise(t=>{e=setTimeout(t,1e4)})]).finally(()=>clearTimeout(e))}process.exit(oo)}for(let e of["SIGINT","SIGTERM","SIGHUP"])process.on(e,()=>{_i()});var ak=!1;for(let e of["uncaughtException","unhandledRejection"])process.on(e,async t=>{ak||(ak=!0,console.error(`Connector stopping after an unhandled failure: ${t instanceof Error?t.stack||t.message:String(t)}`),await _i({exitCode:1}))});ft=Uf();process.on("exit",()=>{bi?.stop(),ft.stop()});ft.banner(`EngineerOS connector ${Nr}`,[C.workspace,C.server_url]);dr=lS({actions:{refresh_tool_inventory:async()=>{Ee.tool_inventory=await Yt(C.workspace),Ht()},restart_goal_runner:()=>Fo(C.workspace)},onNotify:()=>Yo(C,C.workspace),explain:async e=>{if(!await vi())return null;let{reading:t}=await nb(C,e);return t},onUpdate:e=>yS(C.workspace,e)});wk=bS({render:(e,t)=>ft.write(e,t),onRecord:e=>dr.observe(e)});Ef=SS({workspace:C.workspace,onRecord:e=>{dr.observe(e),ft.line(e.channel,e.level,e.message)}});dr.start();C.hunt_host||Ef.start();ft.live&&!C.hunt_host&&(vf=setInterval(()=>{lH().catch(()=>{})},rH),vf.unref?.());var yf=new Set;async function lH(){if(C.hunt_host)return;ok??=hp(C.workspace);let{jobs:e}=await ok(),t=new Set,n=e.filter(r=>r.status!=="queued"&&ol.includes(r.status)).length;for(let r of e){if(!ol.includes(r.status))continue;t.add(r.runId),yf.add(r.runId);let o=r.status==="queued"&&n>0?`queued behind running Goals (running: ${n})`:r.activity?.phase||r.status;ft.status(`goal:${r.runId}`,o,uH(r),{agent:r.status!=="queued",link:yi&&`${yi}/goals`}),ft.step(`goal:${r.runId}`,r.activity?.message)}for(let r of yf)t.has(r)||(yf.delete(r),ft.clearStatus(`goal:${r}`))}function uH(e){let t=e.startedAt??Date.parse(e.updatedAt??"");return Number.isFinite(t)?t:Date.now()}async function vi({ignoreBugHunt:e=!1}={}){if($t||At.size>0||kt.size>0||jr>0||(mi?.active??0)>0||!e&&(qo?.active??0)>0)return!1;try{let{jobs:t}=await $r(C.workspace);return!$t&&!t.some(n=>ol.includes(n.status))}catch{return!1}}try{let e=C.hunt_host?{}:await io(C.workspace);e.committed&&(C.onboarding_pending=!0,C.connector_id&&await vn(C),console.log(`Local project repository ready at ${e.revision.slice(0,8)}. Source and design artifacts are committed locally.`))}catch(e){await $k(e)}var Sk=await It(Wn()).then(e=>e.policy!=="manual",()=>!1),Fe;try{Fe=await qs(C,C.workspace)}catch(e){await $k(e)}console.log(`Using ${Fe.name} through ${Fe.protocol} (${Fe.version}).`);var Ee=Cc(C,Fe,await Yt(C.workspace)),ur=bh({running:Il(process.argv[1],rl),supervised:process.env[co]==="1",isIdle:async()=>!$t&&At.size===0&&Xo.length===0&&kt.size===0&&jr===0&&Sf===0&&!Ho&&!il&&!el,restart:()=>_i({exitCode:is}),onChange:e=>{Ee.runtime_update=e,mt?.readyState===WebSocket.OPEN&&Ht()}});try{await ur.refresh()}catch(e){console.error(`Connector updates are unavailable: ${e.message}`)}C={...C,execution_profiles:Fe.executionProfiles??null};st==="pair"&&wi?.connector_id||await vn(C);Ee.agent_session={...Ee.agent_session,status:"checking",message:`Checking that ${Fe.name} can answer.`};Ee.bug_hunt_browser=!1;so.capabilities=Ee;console.log(nr(C.worker_limit)===null?`Workers: automatic, ${Io()} ${Fe.name} workers side by side for this machine's CPU and memory; change it with /workers.`:`Workers: ${nr(C.worker_limit)} ${Fe.name} workers side by side, set with /workers.`);var Ko=e=>rr(C,e),ck=_c(Ko,{signature:db});async function dH(){let e=await $r(C.workspace).catch(()=>({service:null,jobs:[]}));return{version:Nr,now:Date.now(),workspace:C.workspace,config_path:en(C.workspace),config:C,agent:Fe,automatic_worker_limit:Io(),worker_limit:nr(C.worker_limit),connection:{state:pH(),server_url:C.server_url,last_error:dn||null},work:{assessments:[...At.values()].map(t=>({stage:t.stage,message:t.lastMessage,started_at:t.startedAt})),prompts:[...kt.values()].map(t=>({id:String(t.runId).slice(0,8),purpose:t.purpose,started_at:t.startedAt})),integrations:jr},runner:e,runtime_update:ur.report(),health:dr?.health()??null,activity:gi.snapshot()}}function pH(){return $t||cr?"stopped":mt?.readyState===WebSocket.OPEN?"connected":"connecting"}var fH={async cancelPrompt(e){let t=[...kt.values()].find(n=>n.runId.startsWith(e));return t?(t.stoppedHere=!0,t.cancellation.abort(),await t.controller?.completed.catch(()=>{}),`Stopping prompt ${e} (${t.purpose}); EngineerOS will be told it was cancelled here.`):`Prompt ${e} finished before it could be stopped.`},setWorkers:e=>kk(e),setVerbose(e){return e===sl?`Detailed agent activity is already ${e?"on":"off"}.`:(kf(e),"This lasts until EngineerOS sends its own setting again: when the connector reconnects, or when it is changed there.")},async runtimeUpdate(e){return e.action==="apply"?(ur.command(e).catch(t=>console.error(`Connector update: ${t.message}`)),"Preparing the latest connector release beside this one; it switches over once this connector is idle."):(await ur.command(e),cs(await ur.refresh()))}};bi=hS({ui:ft,snapshot:dH,actions:fH});bi&&console.log(fS());await Ek();var lk=new Set;async function Ek(){if($t||cr)return;console.log(`Connecting ${C.name} to ${C.server_url}`),cr=!1,dn=void 0;let e=new WebSocket(C.server_url);mt=e;let t=xw(e,C.server_url,{onTimeout:r=>{mt===e&&(dn=r,console.error(r),_f())}});bk=t,e.addEventListener("open",()=>{if(mt!==e){e.close();return}try{if(vw(mt,e,so))return;throw new Error("The WebSocket was not open when authentication started.")}catch(r){dn=jt(r),console.error(`Could not authenticate the WebSocket connection: ${dn}`);try{e.close()}catch{}_f()}}),e.addEventListener("message",r=>{if(mt!==e)return;let o;try{o=JSON.parse(String(r.data))}catch{console.error("Ignored a malformed EngineerOS message frame (invalid JSON).");return}n(o).catch(s=>{console.error(`EngineerOS ${String(o?.type||"unknown").slice(0,80)} message failed: ${jt(s)}`)})});let n=async r=>{if(r.type==="authenticated"&&r.connector?.capabilities?.http_updates!==!0){$t=!0,cr=!0,t(),console.error("Update the EngineerOS backend to support connector HTTP updates before reconnecting."),e.close();return}if(r.type==="paired"){t();let s=wi?.connector_id===r.connector.id;if(C=Mh(C,wi,r.connector.id,r.token),await vn(C),r.connector?.capabilities?.http_updates!==!0){$t=!0,cr=!0,console.error("Pairing saved. Update the EngineerOS backend for HTTP updates, then start this connector again."),e.close();return}so={type:"authenticate",connector_id:C.connector_id,token:C.token,capabilities:Ee},console.log(s?`Reconnected existing workspace connector ${C.connector_id}; assessment history is preserved.`:`Paired. Connector ${C.connector_id} is online.`),dk(r);return}if(r.type==="authenticated"){t();let s=C.hunt_host?"Bug Hunter sessions":"EngineerOS runs";console.log(Jo?`Reconnected after ${Ie(Date.now()-Jo)} offline; waiting for ${s}.`:`Connected and waiting for ${s}.`),Jo=void 0,dk(r);return}if(r.type==="provider.login"||r.type==="provider.logout"){il||mH(r);return}if(r.type==="workspace.refresh"){al();return}if(r.type==="workers.update"){try{console.log(`EngineerOS changed the workers. ${await kk(r.worker_limit??"auto")}`)}catch(s){console.error(`Workers were not changed: ${s.message}`)}return}if(r.type==="logging.update"){kf(r.activity_log_enabled===!0);return}if(r.type==="tools.update"){let s=r.provider_id==="playwright"&&["setup","upgrade","rollback"].includes(r.action);s&&(lr=!1,Ee.bug_hunt_browser=!1,Ht());try{Ee.tool_inventory=await Ns(C.workspace,r,void 0,{confirmLocal:i=>bi?.confirm(i)??!1,log:nl}),s&&(lr=!0),Ee.bug_hunt_browser=no(Ee.tool_inventory)&&lr,e.send(JSON.stringify({type:"tools.updated",command_id:r.command_id,inventory:Ee.tool_inventory})),Ht(),console.log(`Tool registry updated: ${r.action} ${r.provider_id}.`)}catch(i){let a=i instanceof Error?i.message.slice(0,300):"The local connector rejected the tool registry update.";e.send(JSON.stringify({type:"tools.updated",command_id:r.command_id,error:a})),console.error(`Tool registry update rejected: ${a}`)}return}if(r.type==="tools.auth"){try{let s=await pd(C.workspace,r,{onStatus:async()=>{Ee.tool_inventory=await Yt(C.workspace),Ht()}});Ee.tool_inventory=s.inventory,s.completion&&s.completion.catch(i=>console.error(`Tool authentication status: ${i instanceof Error?i.message.slice(0,300):"Local status update failed."}`)),e.send(JSON.stringify({type:"tools.updated",command_id:r.command_id,inventory:Ee.tool_inventory})),Ht(),console.log(`Tool authentication updated: ${r.action} ${r.provider_id}.`)}catch(s){let i=s instanceof Error?s.message.slice(0,300):"The local connector rejected the tool authentication request.";e.send(JSON.stringify({type:"tools.updated",command_id:r.command_id,error:i})),console.error(`Tool authentication rejected: ${i}`)}return}if(r.type==="test_environment.health_check"){wo(r).then(s=>{e.send(JSON.stringify({type:"test_environment.health_result",command_id:r.command_id,result:s})),console.log(`Test environment health: ${s.status}${s.message?` (${s.message})`:""}.`)}).catch(s=>console.error(`Test environment health was not reported: ${s.message}`));return}if(r.type===YE){Kc(aH(r).then(s=>(s.error&&console.error(`${r.provider} ${r.operation} failed: ${s.error}`),QE(C,s))).catch(s=>console.error(`An integration answer was not delivered: ${s.message}`)));return}if(r.type==="workspace.assessment"){let s=`${r.assessment_id}:${r.stage}`;rp(Xo,At.get(s),r)==="deferred"&&console.log(`Assessment stage ${r.stage} is already running here; EngineerOS will be answered when it finishes.`),Si();return}if(r.type==="prompt.execute"){let s=kt.get(r.prompt_id);s?Ck(r)>s.executionRevision&&await kH(s,r):Rk(r);return}if(r.type==="prompt.cancel"){let s=kt.get(r.prompt_id);s&&await xf(s);return}if(r.type==="agent.warm"){wH(r);return}if(r.type==="run.available"){if(C.hunt_host){console.error("A hunt host cannot run Goals. Use Connect your code to pair a repository connector.");return}try{let s=await _k.dispatch(r);s.blocked?console.error(s.message):console.log(`Goal ${r.run_id} queued for the independent runner. Logs: ${Rt.join(C.workspace,".engineeros","runs",r.run_id,"activity.log")}`)}catch(s){console.error(`Goal dispatch failed: ${jt(s)}`)}return}if(r.type==="goal.cleanup"){try{await Rb(C.workspace),await Fo(C.workspace)}catch(s){console.error(`Goal cleanup is pending: ${s.message}`)}return}if(r.type==="run.accepted"){AH(r);return}if(r.type==="run.cancelled"){await fp(C.workspace,r.run_id);return}if(r.type===ey){mi??=py({getConfig:()=>C,onTestsCommitted:()=>al()}),Kc(mi.handle(r));return}if(r.type===ty){await mi?.cancel(r);return}if(r.type===_E){qo??=kE({getConfig:()=>C,isIdle:()=>vi({ignoreBugHunt:!0}),recordedSignIns:yk,activity:{status:ft.status,step:$f,agents:ft.agents,finish:ft.finish}}),Kc(qo.handle(r));return}if(r.type===vE){qo?.stop(r);return}if(r.type===qS){sk??=VS({getConfig:()=>C}),Kc(sk.handle(r));return}if(r.type==="connector.update"){hH(e,r);return}if(r.type==="connector.disconnect"){console.log(r.message),await _i();return}if(r.type==="connector.revoked"){$t=!0,console.error("This connector was revoked in EngineerOS."),e.close();return}if(r.type==="run.error"){console.error(`EngineerOS: ${r.message}`),r.run_id||(Ho=!1);return}if(r.type==="connection.error"){cr=!0,console.error(`EngineerOS: ${r.message}`);return}let o=String(r.type??"(missing)").replace(/[^a-zA-Z0-9_.-]/g,"_").slice(0,120);lk.has(o)||(lk.add(o),console.warn(`Unknown EngineerOS message type ${o}; connector ${Nr}. Update the connector and backend to compatible versions.`))};e.addEventListener("close",r=>{if(t(),mt!==e||Wo)return;let o=bw(r);if(!o.retry||cr||$t){console.error(o.message),o.retry&&cr&&console.error("Connection rejected. Create a new pairing command in EngineerOS if this connector was revoked."),_i();return}dn=dn?`${o.message} ${dn}`:o.message,_f()}),e.addEventListener("error",r=>{mt===e&&(dn=_w(r),console.error(`WebSocket connection to ${C.server_url} failed: ${dn}`))})}async function hH(e,t){let n=r=>e.send(JSON.stringify({type:"connector.updated",command_id:t.command_id,...r}));try{let r={action:t.action,policy:t.policy??null},o=ur.command(r);r.action==="apply"?(o.catch(s=>console.error(`Connector update: ${s.message}`)),await Promise.race([o,new Promise(s=>setTimeout(s,3e3).unref())])):await o,n({report:await ur.refresh()}),console.log(`EngineerOS asked for connector update ${r.action}.`)}catch(r){let o=(r instanceof Error?r.message:String(r)).slice(0,300)||"The connector rejected the update request.";n({error:o}),console.error(`Connector update ${t.action} rejected: ${o}`)}}async function mH(e){let t=e.request_id,n=e.type==="provider.logout"?"logout":"login";il=!0,console.log(`Starting interactive ${Fe.name} provider ${n}.`);try{await(n==="logout"?$w:kw)(Fe,C.workspace),Fe=await qs(C,C.workspace),Ee=Cc(C,Fe,Ee.tool_inventory),so.capabilities=Ee,mt.readyState===WebSocket.OPEN&&(mt.send(JSON.stringify({type:`provider.${n}.completed`,request_id:t,session:Ee.agent_session})),mt.close(1e3,`Provider ${n} completed`)),console.log(`${Fe.name} provider ${n} completed.`)}catch(r){let o=jt(r).slice(0,500);mt.readyState===WebSocket.OPEN&&mt.send(JSON.stringify({type:`provider.${n}.failed`,request_id:t,message:o})),console.error(`Provider ${n} failed: ${o}`)}finally{il=!1}}function _f(){if($t||cr||tl)return;let e=dn?` Last error: ${dn}`:"",t=Jo?` Offline for ${Ie(Date.now()-Jo)}.`:"";Jo??=Date.now(),console.error(`Connection unavailable.${e}${t} Retrying in ${Math.round(fi/1e3)}s.`),tl=setTimeout(()=>{tl=void 0,Ek()},fi),fi=Math.min(3e4,fi*2)}async function al(){if(!C.hunt_host&&!(Ho||mt.readyState!==WebSocket.OPEN)){Ho=!0,console.log("Inspecting the workspace without executing its code.");try{let e=await sb(C.workspace),t=await ob(C.workspace,C.last_snapshot_head,e.head_revision).catch(()=>null);t&&(e.changed_since=t);let n=await fetch(lo(C.server_url,C.connector_id),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${C.token}`},body:JSON.stringify(e)});if(!n.ok)throw new Error(await ba(n,"the workspace"));let r=await n.json();C={...C,onboarding_pending:!1,last_snapshot_head:e.head_revision??C.last_snapshot_head},await vn(C),console.log(`Inventoried ${e.total_file_count.toLocaleString()} safe file(s).`),console.log(`Uploaded ${e.evidence_file_count.toLocaleString()} prioritized source file(s).`),console.log(`Excluded ${e.excluded_file_count.toLocaleString()} sensitive or generated file(s).`),e.omitted_evidence_file_count>0&&console.log(`${e.omitted_evidence_file_count.toLocaleString()} additional file(s) remain available to the connected Agent locally.`),console.log(`Workspace inventory registered as ${r.workspace_kind}. Start the baseline assessment in EngineerOS to continue.`);try{let o=await na(C.workspace,C.connector_id);console.log(`Built the local context index: ${o.total_files.toLocaleString()} file(s) ready for assignment context.`)}catch(o){console.error(`Local context index build failed: ${o.message}`)}Ho=!1}catch(e){Ho=!1,console.error(`Workspace assessment failed: ${jt(e)}`)}}}var gH=6e4,uk=0;async function wH(e){if(C.hunt_host)return;let t=typeof e.session_key=="string"?e.session_key.trim():"",n=t?C.sessions?.[t]:void 0,r=[];Date.now()-uk>gH&&(uk=Date.now(),r.push(na(C.workspace,C.connector_id).catch(o=>console.error(`Context index refresh ahead of a conversation failed: ${o.message}`)))),C.agent_protocol==="acp"&&r.push(N_(C.workspace,C,{sessionKey:n?t:null,previousSessionId:n,sandbox:e.sandbox_mode==="workspace-write"?"workspace-write":"read-only",profile:e.execution_profile&&typeof e.execution_profile=="object"?e.execution_profile:{}}).catch(o=>console.error(`${Fe?.name||"The agent"} could not be started ahead of the conversation: ${o.message}`))),await Promise.all(r)}function Ht(){let e=q0(At);ck.update({type:"assessment.workers",assessment_workers:e,tool_inventory:Ee.tool_inventory,runtime_update:Ee.runtime_update,agent_session:Ee.agent_session,bug_hunt_browser:Ee.bug_hunt_browser,...hc(C.worker_limit)}),ck.flush().catch(t=>console.error(`Assessment status: ${t.message}`))}async function kk(e){let t=nr(e);return t===nr(C.worker_limit)?t===null?"Workers are already automatic.":`Workers are already set to ${t}.`:(C={...C,worker_limit:t},await vn(C),Si(),Ht(),t===null?`Workers are automatic again: up to ${Io()} side by side for this machine's CPU and memory, for ${oi} (an assessment may ask for fewer). A Goal that uses your working folder still runs alone.`:`Up to ${t} worker${t===1?"":"s"} now run side by side: ${oi}. A Goal that uses your working folder still runs alone. Running work finishes; waiting work starts as workers free up.`)}function kf(e){if(e!==sl){if(sl=e,!e)for(let t of At.values())t.lastDetail=null;console.log(e?"Detailed agent activity is on: every agent action is printed here and shown in EngineerOS.":"Detailed agent activity is off: prompts and stages show only their latest steps."),Ht()}}function $f(e,t,n=null){ft.step(e,t,n)&&sl&&console.log(`[${e}] ${n?`${n}: `:""}${t}`)}function yH(){clearInterval(Qc);let e=!1,t=()=>{e||At.size>0||kt.size>0||(e=!0,Yo(C,C.workspace).finally(()=>{e=!1}))};t(),Qc=setInterval(t,nH),Qc.unref?.()}async function Yo(e,t,n=dr?.healthChecks()??[]){let r=await oS({config:e,workspace:t,version:Nr,insights:n,agentSession:On,probes:{inspectAgent:(o,s)=>$t?Fe:qs(o,s),inspectTools:o=>$t?Ee.tool_inventory:Yt(o),runnerStatus:$r}});try{gk=(await sS(e,r,rr))?.autonomy_scan===!0}catch(o){console.error(`EngineerOS did not accept the connector self-check: ${o instanceof Error?o.message:String(o)}`)}return r}async function $k(e){if($t)return Wo;let t=e instanceof Error?e.message:String(e),n=await Yo(C,C.workspace).catch(()=>null);n&&console.error(Op(n)),Be(t)}function dk(e){kf(e.connector?.activity_log_enabled===!0),yi=e.project_url??null,fi=1e3,vH(),Ak(),ur.confirm().catch(t=>console.error(`Connector update state: ${t.message}`)),bH(),C.onboarding_pending&&al()}var hi=null,lr=!1,xk=0,_H=Date.now();async function vH(){return hi||(hi=(async()=>{Sk&&await g_(C.workspace,{log:t=>console.log(`[tools] ${t}`)}).catch(t=>console.error(`[tools] Tool updates were skipped: ${t.message}`));let e=Date.now();try{nl("Preparing Bug Hunter's browser: Playwright, then a check that a browser starts. The first setup can take a few minutes."),await Db(C.workspace,{log:nl}),lr=!0,Ee.tool_inventory=await Yt(C.workspace),Ee.bug_hunt_browser=no(Ee.tool_inventory)&&lr,nl(`Bug Hunter's browser is ready (${Ie(Date.now()-e)}).`)}catch(t){console.error(`[browser] Bug Hunter's browser setup failed after ${Ie(Date.now()-e)}: ${t.message}`),Ee.bug_hunt_browser=!1}Ht()})(),hi)}function nl(e){console.log(`[browser] ${e}`)}async function Ak(){if(On?.state!=="checking"){xk=Date.now(),Ee.agent_session={...Ee.agent_session,status:"checking",message:`Checking that ${Fe.name} can answer.`},Ht(),On={state:"checking",detail:`Asking ${Fe.name} one question to confirm its session.`},console.log(`Checking that ${Fe.name} can answer before accepting work.`);try{await Y0(C,Fe.name),On={state:"ready",detail:`${Fe.name} answered; its session is usable.`},Ee.agent_session={...Ee.agent_session,status:"authenticated",message:On.detail},console.log(On.detail)}catch(e){On={state:"failed",detail:e instanceof Error?e.message:String(e),remedy:C.hunt_host?Ub(C.agent_id||C.agent_protocol):To(C.agent_id||C.agent_protocol)},Ee.agent_session={...Ee.agent_session,status:"logged_out",message:On.remedy},console.error(`${On.detail}
|
|
1011
1011
|
${On.remedy}`)}Ht(),await Yo(C,C.workspace).catch(()=>null)}}function bH(){clearInterval(bf);let e=!1,t=0,n=0,r=!1,o=()=>{ur.tick(),SH(),C.hunt_host&&hi&&Date.now()-xk>=Fb(_H)&&kt.size===0&&At.size===0&&!(qo?.active>0)&&Ak(),!C.hunt_host&&!r&&ni(pf.id)&&(r=!0,_k.flush().then(()=>Zc(pf)).catch(s=>Yc(pf,s)).finally(()=>{r=!1})),At.size>0&&Ht(),!C.hunt_host&&!zn&&Date.now()-t>=oH&&ni(lf.id)&&(t=Date.now(),Tk().then(()=>Zc(lf)).catch(s=>Yc(lf,s))),!C.hunt_host&&gk&&!el&&ni(uf.id)&&Date.now()-vk>=Ty&&(el=!0,EH().then(()=>Zc(uf)).catch(s=>Yc(uf,s)).finally(()=>{el=!1})),!e&&Date.now()-n>=sH&&ni(df.id)&&(e=!0,n=Date.now(),Yt(C.workspace).then(async s=>{if(Ee.tool_inventory=s,!lr&&no(s))try{await(await Mr(await Ar(C.workspace))).close(),lr=!0}catch{lr=!1}Ee.bug_hunt_browser=no(s)&&lr,Ht(),Zc(df)}).catch(s=>Yc(df,s)).finally(()=>{e=!1}))};o(),bf=setInterval(o,1e4),yH()}async function SH(){if(!(!Sk||C.agent_protocol!=="acp"||!C.agent_id||wf||On?.state==="checking"||Date.now()-ik<iH)){wf=!0;try{if(!await vi())return;ik=Date.now();let e,t=await G_(C,{verify:async r=>{e=await qs(r,C.workspace)},log:r=>console.log(`[agent] ${r}`)});if(t===C||$t)return;C={...t,execution_profiles:e.executionProfiles??null},await vn(C),Fe=e;let n=Cc(C,Fe,Ee.tool_inventory);if(Object.assign(Ee,{agent_name:n.agent_name,agent_version:n.agent_version,execution_profiles:n.execution_profiles}),so.capabilities=Ee,!await vi())return;await Ms(),mt?.readyState===WebSocket.OPEN&&mt.close(1e3,"Coding agent updated")}catch(e){console.error(`[agent] The agent update check failed: ${e.message}`)}finally{wf=!1}}}function Yc(e,t){let n=Zb(e.id,e.title,t,{remedy:e.remedy});console.error(`${e.title} failed ${n.failures} time(s); retrying in ${Math.round(n.retryInMs/1e3)}s: ${n.message}`)}function Zc(e){Qb(e.id)&&console.log(`${e.title} recovered.`)}async function EH(){if(C.hunt_host||!await vi())return;vk=Date.now();let{jobs:e}=await $r(C.workspace).catch(()=>({jobs:[]})),t=await Ry(C.workspace,{jobs:e});if(!Cy(t))return;let n=`${t.fingerprint}:${gf.join(",")}`,r=mf?.key===n,o=r?mf.candidates:await rb(C,t,gf);mf={key:n,candidates:o};let s=await Ko(jy(t,o,{version:Nr}));Array.isArray(s?.refused)&&(gf=s.refused.map(String));let i=r?"unchanged since the last scan":"scanned";console.log(o.length?`Workspace ${i}; reported ${o.length} delivery candidate(s) to EngineerOS: ${o.map(a=>a.capability_name).join(", ")}.`:`Workspace ${i}; nothing worth starting.`)}var Ir=null,pk=null;async function Tk(){if(!C.hunt_host){if(zn)return zn;zn=(async()=>{let e=await vy(C,{knownRevision:Ir?.revision??null});if(e.unchanged||(Ir=e),pk===Ir.revision)return Ir;let{jobs:t}=await $r(C.workspace);return!t.some(r=>ol.includes(r.status))&&jr===0&&At.size===0&&(await Pa(C.workspace,Ir),pk=Ir.revision),Ir})();try{return await zn}finally{zn=null,Si()}}}function fk(e,t){if(!t)return;let n={type:"prompt.event",prompt_id:e,kind:t.kind};t.message&&(n.message=String(t.message).slice(0,500)),t.delta&&(n.delta=String(t.delta).slice(0,5e4)),t.status&&(n.status=String(t.status).slice(0,100)),kt.get(e)?.events.push(n)}var hk=null;function Si(){let e=mt.readyState===WebSocket.OPEN,t=At.values().next().value,n=nr(C.worker_limit)??Math.min(Io(),op(t?.workerLimit??Xo[0]?.worker_limit)),r=e&&!zn&&jr===0?L0(Xo,At.size,n):[];for(let s of r){let i=`${s.assessment_id}:${s.stage}`,a={kind:"assessment",key:i,runId:s.assessment_id,stage:s.stage,child:null,controller:null,resumeAssignment:null,phase:"starting",progressPercent:5,lastMessage:`Starting ${s.stage} assessment stage`,startedAt:Date.now(),workerLimit:op(s.worker_limit),lastActivityAt:Date.now(),eventCount:0,lastDetail:null};At.set(i,a),xH(s,a)}r.length>0&&Ht();let o=D0({queued:Xo,running:At.size,workerLimit:n,connected:e,designSync:!!zn,integrations:jr});o&&o!==hk&&console.log(o),hk=o}function cl(e){let t=sp(e);return t?`${Fe.name} on ${t}`:Fe.name}async function Rk(e){let t=e.prompt_id,n=`prompt:${String(t).slice(0,8)}`,r=e.purpose||"project",o=Date.now(),s={runId:t,purpose:r,startedAt:o,child:null,controller:null,cancelled:!1,stoppedHere:!1,cancellation:new AbortController,events:hb(Ko),executionRevision:Ck(e),sessionKey:mc(e),sessionId:null,replacement:null};kt.set(t,s);let i,a=g=>{let y=g?JSON.stringify(g):null;!y||y===i||kt.get(t)!==s||(i=y,fk(t,g))},c=`${r} \xB7 ${cl(e)}`,l=K0(e,Fe.name);fk(t,{kind:"status",message:l});let u=Number(e.answer_within_seconds),d=u>0?o+u*1e3:void 0;console.log([`[${n}] ${l} for ${r}.`,`${Fe.name} can reason for several minutes without reporting a step.`,...d?[hl(d,o)]:[]].join(" ")),ft.status(n,c,o,{link:yi,answerBy:d});let p=g=>{let y=N0(g),w=Jr(g);kt.get(t)===s&&$f(n,w??y?.message);let S=g.type==="forge.output"?null:w;a(y??(S?{kind:"status",message:S}:null))},f="failed",h=[r];try{gc(e)||(p({type:"connector.step",message:"Syncing the design context from EngineerOS"}),e={...e,design_context:await $y(Tk,{pinned:!!e.local_design_context,last:Ir,onFallback:(S,v)=>p({type:"connector.step",message:`Design context not refreshed (${S.message}); continuing with ${v?"the copy synced earlier":"none"}`})})});let g=await T0(e,C,{onProcess:S=>{kt.get(t)===s&&(s.child=S)},onController:S=>{kt.get(t)===s&&(s.controller=S)},onSession:S=>{s.sessionId=S},onEvent:p},{signal:s.cancellation.signal});if(s.stoppedHere)throw new Error(mk);let y=g.singleTurn?Ph(C.sessions,g.sessionKey):zl(C.sessions,g.sessionKey,g.sessionId);if(JSON.stringify(y)!==JSON.stringify(C.sessions||{})&&(C={...C,sessions:y},await vn(C)),s.cancelled)return;await s.events.close().catch(S=>{console.error(`[${n}] Prompt progress delivery: ${S.message} The agent has finished; submitting its complete response separately.`)});let w=await yc(Ko,{type:"prompt.completed",prompt_id:t,execution_revision:s.executionRevision,content:g.content,model:g.model,session_id:g.sessionId,usage:g.usage});w||console.error(`[${n}] ${lp}`),gi.record("prompt","completed",{durationMs:Date.now()-o,usage:g.usage}),f=w?"finished":"undelivered",h=[xi(g.usage),r]}catch(g){let y=s.stoppedHere?mk:jt(g);if(gi.record("prompt","failed",{durationMs:Date.now()-o}),s.stoppedHere&&(f="cancelled"),!s.cancelled){try{await yc(Ko,{type:"prompt.failed",prompt_id:t,execution_revision:s.executionRevision,message:y})||console.error(`[${n}] ${lp}`)}catch(w){console.error(`[${n}] Prompt failure delivery: ${w.message}`)}console.error(y)}}finally{s.events.stop();let g=s.replacement;g?(f="replaced",h=[`continuing on ${cl(g)}`,r]):s.cancelled&&(f="cancelled"),ft.finish(n,f,h),kt.get(t)===s&&kt.delete(t),g&&$H(s,g)}}var mk="Cancelled from the connector terminal by the person running it.";async function xf(e){e.cancelled=!0,e.cancellation.abort(),await e.controller?.completed.catch(()=>{})}function Ck(e){return Number(e.execution_revision)||1}async function kH(e,t){let n=e.replacement!==null;e.replacement=t,!n&&(console.log(`[prompt:${String(e.runId).slice(0,8)}] The model was changed in EngineerOS; stopping this turn to continue it on ${cl(t)}.`),await xf(e))}function $H(e,t){e.sessionId&&(C={...C,sessions:zl(C.sessions,e.sessionKey,e.sessionId)},vn(C).catch(n=>console.error(`Could not save the agent session: ${n.message}`))),Rk(t)}async function xH(e,t){let n=e.assessment_id,r=e.stage;if(console.log(`Running assessment stage ${r}${e.stage_label&&e.stage_label!==r?` "${e.stage_label}"`:""} (${n}) with ${cl(e)}.`),!hf.has(n)){hf.add(n);try{let _=await O0(C.workspace);if(!_.exists)console.log("No accepted assessment exists yet; this run establishes the baseline.");else{let E=_.accepted_head_revision?_.current_head_revision?_.current_head_revision!==_.accepted_head_revision?`The workspace is now at commit \`${_.current_head_revision}\`; the accepted assessment is from \`${_.accepted_head_revision}\`.`:"The accepted assessment is already at the current commit.":`The accepted assessment is from \`${_.accepted_head_revision}\`; the current commit could not be read.`:"Its accepted commit is unavailable; this run will refresh that provenance.";console.log(`Last accepted assessment covers ${_.stages.length||"no"} section(s). ${E}`)}}catch(_){console.error(`Assessment freshness check failed: ${_.message}`)}}let o=t.startedAt,s=`assessment:${r}`,i=!1,a=!1,c=5,l=!1,u=!1,d=null,p=null,f=null,h=new Set,g=()=>!$t&&At.get(t.key)===t,y=async _=>{try{return await yc(Ko,_)||console.warn(`[${s}] ${pb}`),!0}catch(E){return console.error(`Assessment failure delivery: ${E.message}`),!1}},w=(_,{milestone:E=!0}={})=>{if(!g()||E&&f===_)return;E&&(f=_,h.has(_)||(h.add(_),c=Math.min(90,c+10)),console.log(`[assessment:${r}] ${_}.`));let m=String(_).slice(0,500);t.progressPercent=c,t.lastMessage=m,ft.status(s,m,o,{link:yi})};w(`Starting ${r} assessment stage`);let S=setInterval(()=>{let _=Date.now(),E=_-t.lastActivityAt,m=i&&!a?j0(r,E):null;if(!d&&m){d=m,console.error(`[assessment:${r}] ${d}`),wc(t.controller,t.child);return}d||dr.observe({at:_,level:"info",message:ft.status(s,`${t.lastMessage} \xB7 last agent activity ${Ie(E)} ago (${t.eventCount.toLocaleString()} events)`,o)})},15e3),v={onSession:async _=>{g()&&(p=String(_),await hg(C.workspace,n,r,_,{sourceRevision:e.source_revision,targetHeadRevision:e.target_head_revision}))},onController:_=>{g()&&(t.controller=_)},onProcess:_=>{g()&&(t.child=_,i=!0,t.phase!=="correcting"&&(t.phase="running",w("Connected agent process started")),t.lastActivityAt=Date.now())},onEvent:_=>{t.lastActivityAt=Date.now(),t.eventCount+=1;let E=I0(_);if(E&&w(E),!g())return;let m=Jr(_);!m||m===t.lastDetail||(t.lastDetail=m,$f(s,m))}},b=(_,E)=>tp(_,E,C,v,{draftPath:Rt.relative(C.workspace,Rt.join(Vt(C.workspace,n),_.report_file)).split(Rt.sep).join("/")});try{let _=ff-Date.now();_>0&&(w(`Waiting ${Math.ceil(_/1e3)}s for the model provider's rate limit to clear`),await new Promise(R=>setTimeout(R,_+Math.floor(Math.random()*3e3)))),e.assessment_mode==="incremental"&&(c=15,w("Calculating changed files and affected behavior"));let E=await _g(C.workspace,e),m=await pu(C.workspace,n,r,{expectedHeadRevision:e.target_head_revision,expectedSourceRevision:e.source_revision});if(m)b(m,E),w("Recovered completed stage report from connector storage");else{if(p=await mg(C.workspace,n,r,{expectedHeadRevision:e.target_head_revision,expectedSourceRevision:e.source_revision}),p&&w("Restoring interrupted agent session"),m=await A0(E,C,v,{previousSessionId:p}),d)throw new Error(d);a=!0,await du(C.workspace,n,E,m)}a=!0,t.phase="delivering",t.progressPercent=95,t.lastMessage=r==="synthesis"?"Delivering completed assessment bundle":"Checkpointing connector-local stage result";let k=R=>fetch(Fh(C.server_url,C.connector_id,n),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${C.token}`},body:JSON.stringify(R),signal:AbortSignal.timeout(p0)}),A=await J0(m,{submit:R=>X0(R,k,{isActive:()=>g()&&!$t,onRetry:(j,P)=>{w("Completed result is waiting for EngineerOS",{milestone:!1}),console.warn(`[assessment:${r}] Completed result delivery failed: ${jt(j)} Retrying in ${Math.round(P/1e3)}s without rerunning the agent.`)}}),payloadFor:R=>r==="synthesis"?fu(C.workspace,n,R,{expectedSourceRevision:e.source_revision}):Eg(R),rejectionFor:R=>ba(R,"the assessment"),correct:async(R,j)=>{if(a=!1,t.phase="correcting",t.lastMessage="Correcting a rejected stage result",!R.correctAfterRejection)throw new Error(`${j} The connector could not start the required agent correction.`);return R.correctAfterRejection(j)},onCorrected:async R=>{if(d)throw new Error(d);a=!0,await wg(C.workspace,n,r);let j=await du(C.workspace,n,E,R);return b(j,E),t.phase="delivering",t.lastMessage="Delivering corrected stage result",j}});if(d)throw new Error(d);m=A.result;let T=A.response;if(!T.ok)throw new Error(await ba(T,"the assessment"));if(l=!0,gi.record("assessment stage","completed",{durationMs:Date.now()-o,usage:m.usage}),r==="synthesis"){let R=await T.json(),j=await vg(C.workspace,n,e,m,R.report_markdown);console.log(`Workspace assessment ${n} was accepted by EngineerOS and saved to ${Rt.relative(C.workspace,j)}.`);try{let P=await Oi(C.workspace);P.committed&&console.log(`Assessment committed to Git as ${P.revision.slice(0,8)}.`)}catch(P){console.error(`The assessment is saved locally but could not be committed to Git: ${P.message}`)}}else console.log(`Workspace assessment stage ${r} was checkpointed by EngineerOS.`)}catch(_){let E=d||jt(_),m=G0(e,_),k=W0(_),x=U0(_);k&&(await gg(C.workspace,n,r).catch(T=>{console.error(`[assessment:${r}] Could not discard the unusable agent session checkpoint: ${T.message}`)}),p=null);let A=!d&&(p||k)&&(k||F0(_))&&m<x;if(g()&&A){t.phase="starting",t.lastMessage=k?"Agent session became unusable; restarting from saved assessment work":"Agent session interrupted; resuming checkpoint",t.resumeAssignment=B0(e,_);let T=H0(_,m);Vs(_)&&(ff=Math.max(ff,Date.now()+T)),console.warn(`[assessment:${r}] ${k?"Agent session became unusable":"Agent session interrupted"}: ${E} ${k?"Starting a fresh session from the saved draft":`Resuming session ${p}`} in ${Math.round(T/1e3)}s (${m+1}/${x}).`),await new Promise(R=>setTimeout(R,T))}else g()&&(u=await y({type:"workspace.assessment.failed",assessment_id:n,stage:r,message:E}));A||(gi.record("assessment stage","failed",{durationMs:Date.now()-o}),console.error(`[assessment:${r}] ${E}`))}finally{clearInterval(S),ft.clearStatus(s),r==="synthesis"&&l&&hf.delete(n),g()&&(At.delete(t.key),V0(Xo,t,{accepted:l,failureReported:u})&&console.log(`Resuming interrupted agent session for assessment stage ${r} from its checkpoint.`),Si())}}async function AH(e){let t=String(e.run_id||"");jr+=1;try{zn&&await zn;let n=await _0(C.workspace,String(e.base_revision||""),String(e.head_revision||""),String(e.integration_branch||"")||null);if(n.applied){console.log(`Accepted Goal Run ${t} applied to the connected repository at ${n.revision} (${n.method}).`),await al();return}console.warn(`Accepted Goal Run ${t} remains on its review branch. ${n.reason}`)}catch(n){console.error(`Accepted Goal Run ${t} could not be integrated: ${jt(n)}`)}finally{jr-=1,Si()}}function TH(e){if(!e)return[];try{let t=JSON.parse(e);if(!Array.isArray(t)||t.some(n=>typeof n!="string"))throw new Error;return t}catch{Be('--agent-args must be a JSON array, for example: --agent-args "[\\"acp\\"]"')}}function Be(e){console.error(e),process.exit(1)}
|