@engineeros/connector 1.43.3 → 1.43.4

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.
@@ -884,7 +884,7 @@ It is checked with the provider and stored in this machine's protected vault
884
884
  (Windows Data Protection, the macOS Keychain or the Linux Secret Service).
885
885
  EngineerOS never receives it; the running connector uses it when EngineerOS asks.`;function oL(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(`
886
886
  `),c?o(c):r(s.trim())},a=c=>{for(let l of c){if(l==="\r"||l===`
887
- `)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 u0=Symbol("missing");function sL(e,t){return new Promise(n=>{let r=nL(e,t,{stdio:"inherit",shell:!1});r.once("error",o=>n(o?.code==="ENOENT"?u0:o.message)),r.once("close",o=>n(o===0?null:`${e} exited with code ${o}.`))})}function d0(e,t){for(let n of Uo){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 p0(e,t,n,{vault:r=Ud(),run:o=ta,fetchImpl:s=fetch,secret:i=oL,interactive:a=sL,install:c=ea,log:l=console.log,error:d=console.error}={}){if(n.help||e!=="integrations"&&!t[0])return l(rL),n.help?0:2;if(e==="integrations")return d0(l,(await oa({run:o,vault:r})).providers),0;let p=t[0];if(!Uo.includes(p))return d(`Unknown provider ${p}. Choose one of: ${Uo.join(", ")}.`),2;if(p==="github"||p==="gitlab"){let f=Yn[p];if(e==="disconnect")return l(`${p} uses this machine's ${f} sign-in. Run \`${f} auth logout\` to sign out everywhere on this machine.`),0;let m=await a(f,["auth","login"]);if(m===u0){let h=await Mr(f);if(!h){l(`Installing the ${Lo[f].label} ${Lo[f].version} for the connector...`);try{h=(await c(f)).path}catch(g){return d(g.message),1}}m=await a(h,["auth","login"])}return m?(d(`${m} ${ra[p]} is how this machine signs in to ${p}.`),1):(d0(l,{[p]:(await oa({run:o,vault:r})).providers[p]}),0)}let u=je[p];if(e==="disconnect")return await r.delete("",p),l(`Removed the ${u.label} ${u.tokenName} from this machine.`),0;try{await zd(r);let f=await i(`${u.label} ${u.tokenName} (create one at ${u.tokenUrl}): `),m=await Gd(r,p,{token:f,site:n.site,email:n.email},s);return l(`Connected ${u.label}${m.account?` as ${m.account}`:""}. The token stays on this machine.`),0}catch(f){return d(f.message),1}}import{spawn as iL}from"node:child_process";async function f0({root:e,bundled:t,argv:n,workspace:r,spawnImpl:o=iL,log:s=console.log}){let i=n,a=!1;for(;;){let c=t;try{c=Rn(await at(e),t)}catch(p){s(`${p.message} Starting the installed connector ${t.version}.`)}let{code:l,signal:d}=await aL(o,c.entry,i,t);if(l===jo){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&&!d&&!a){let p=await at(e).catch(()=>null);if(p&&!p.confirmed&&p.active?.version===c.version)try{let u=await xd(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 ${u.version}.`);continue}catch(u){s(`Automatic rollback failed: ${u.message}`)}}return l??1}}function aL(e,t,n,r){return new Promise((o,s)=>{let i=e(process.execPath,[...process.execArgv,t,...n],{stdio:"inherit",env:{...process.env,[Or]:"1",[bd]:r.entry,[Sd]:r.version}}),a=process.platform==="win32"?[]:["SIGINT","SIGTERM","SIGHUP"],c=d=>i.kill(d);for(let d of a)process.on(d,c);let l=()=>{for(let d of a)process.off(d,c)};i.once("error",d=>{l(),s(d)}),i.once("exit",(d,p)=>{l(),o({code:d,signal:p})})})}var Nn="1.43.3",da="1.43.3",uL=3e5,ua=["queued","running","reporting"],pL=5e3,Hd={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."},Bd={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."},fL=6e4,mL=3e4,Wd={id:"tool_inventory",title:"Tool inventory refresh",remedy:"Run `engineeros-connector tools list` in this workspace for the full registry state."},qd={id:"runner_setup_reporting",title:"Goal runner setup reporting",remedy:"Restore the connection to EngineerOS; saved setup reports will retry automatically."},{command:ke,positional:et,flags:se}=O_(process.argv.slice(2));ke==="version"&&(console.log(Nn),process.exit(0));var mn=null,Ue=!1,In=null,k0=!1,$0=null,ru=null,Le=null,Vo=null,eu,m0,h0,Go,hL=c0({getWorkspace:()=>k.workspace}),Ho=P_();ke==="results"&&(et[0]!=="upload"&&(console.log(Ki),process.exit(se.help||!et[0]?0:2)),process.exit(await jv(se)));(ke==="connect"||ke==="disconnect"||ke==="integrations")&&process.exit(await p0(ke,et,se,{fetchImpl:s0}));if(ke==="runner"){let e=Pe.resolve(se.workspace||process.cwd()),t=et[0]||"status";try{if(t==="serve"||t==="worker"){let n=t==="worker"?Pe.join(Pe.dirname(pe(e,se["run-id"])),"worker.log"):Pe.join(e,".engineeros","runner","service.log");lL(Pe.dirname(n),{recursive:!0});let r=(...s)=>So(n,`${dL(...s)}
887
+ `)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 u0=Symbol("missing");function sL(e,t){return new Promise(n=>{let r=nL(e,t,{stdio:"inherit",shell:!1});r.once("error",o=>n(o?.code==="ENOENT"?u0:o.message)),r.once("close",o=>n(o===0?null:`${e} exited with code ${o}.`))})}function d0(e,t){for(let n of Uo){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 p0(e,t,n,{vault:r=Ud(),run:o=ta,fetchImpl:s=fetch,secret:i=oL,interactive:a=sL,install:c=ea,log:l=console.log,error:d=console.error}={}){if(n.help||e!=="integrations"&&!t[0])return l(rL),n.help?0:2;if(e==="integrations")return d0(l,(await oa({run:o,vault:r})).providers),0;let p=t[0];if(!Uo.includes(p))return d(`Unknown provider ${p}. Choose one of: ${Uo.join(", ")}.`),2;if(p==="github"||p==="gitlab"){let f=Yn[p];if(e==="disconnect")return l(`${p} uses this machine's ${f} sign-in. Run \`${f} auth logout\` to sign out everywhere on this machine.`),0;let m=await a(f,["auth","login"]);if(m===u0){let h=await Mr(f);if(!h){l(`Installing the ${Lo[f].label} ${Lo[f].version} for the connector...`);try{h=(await c(f)).path}catch(g){return d(g.message),1}}m=await a(h,["auth","login"])}return m?(d(`${m} ${ra[p]} is how this machine signs in to ${p}.`),1):(d0(l,{[p]:(await oa({run:o,vault:r})).providers[p]}),0)}let u=je[p];if(e==="disconnect")return await r.delete("",p),l(`Removed the ${u.label} ${u.tokenName} from this machine.`),0;try{await zd(r);let f=await i(`${u.label} ${u.tokenName} (create one at ${u.tokenUrl}): `),m=await Gd(r,p,{token:f,site:n.site,email:n.email},s);return l(`Connected ${u.label}${m.account?` as ${m.account}`:""}. The token stays on this machine.`),0}catch(f){return d(f.message),1}}import{spawn as iL}from"node:child_process";async function f0({root:e,bundled:t,argv:n,workspace:r,spawnImpl:o=iL,log:s=console.log}){let i=n,a=!1;for(;;){let c=t;try{c=Rn(await at(e),t)}catch(p){s(`${p.message} Starting the installed connector ${t.version}.`)}let{code:l,signal:d}=await aL(o,c.entry,i,t);if(l===jo){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&&!d&&!a){let p=await at(e).catch(()=>null);if(p&&!p.confirmed&&p.active?.version===c.version)try{let u=await xd(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 ${u.version}.`);continue}catch(u){s(`Automatic rollback failed: ${u.message}`)}}return l??1}}function aL(e,t,n,r){return new Promise((o,s)=>{let i=e(process.execPath,[...process.execArgv,t,...n],{stdio:"inherit",env:{...process.env,[Or]:"1",[bd]:r.entry,[Sd]:r.version}}),a=process.platform==="win32"?[]:["SIGINT","SIGTERM","SIGHUP"],c=d=>i.kill(d);for(let d of a)process.on(d,c);let l=()=>{for(let d of a)process.off(d,c)};i.once("error",d=>{l(),s(d)}),i.once("exit",(d,p)=>{l(),o({code:d,signal:p})})})}var Nn="1.43.4",da="1.43.4",uL=3e5,ua=["queued","running","reporting"],pL=5e3,Hd={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."},Bd={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."},fL=6e4,mL=3e4,Wd={id:"tool_inventory",title:"Tool inventory refresh",remedy:"Run `engineeros-connector tools list` in this workspace for the full registry state."},qd={id:"runner_setup_reporting",title:"Goal runner setup reporting",remedy:"Restore the connection to EngineerOS; saved setup reports will retry automatically."},{command:ke,positional:et,flags:se}=O_(process.argv.slice(2));ke==="version"&&(console.log(Nn),process.exit(0));var mn=null,Ue=!1,In=null,k0=!1,$0=null,ru=null,Le=null,Vo=null,eu,m0,h0,Go,hL=c0({getWorkspace:()=>k.workspace}),Ho=P_();ke==="results"&&(et[0]!=="upload"&&(console.log(Ki),process.exit(se.help||!et[0]?0:2)),process.exit(await jv(se)));(ke==="connect"||ke==="disconnect"||ke==="integrations")&&process.exit(await p0(ke,et,se,{fetchImpl:s0}));if(ke==="runner"){let e=Pe.resolve(se.workspace||process.cwd()),t=et[0]||"status";try{if(t==="serve"||t==="worker"){let n=t==="worker"?Pe.join(Pe.dirname(pe(e,se["run-id"])),"worker.log"):Pe.join(e,".engineeros","runner","service.log");lL(Pe.dirname(n),{recursive:!0});let r=(...s)=>So(n,`${dL(...s)}
888
888
  `),o=(s,i,a)=>(So(n,s),(typeof i=="function"?i:a)?.(),!0);process.stdout.write=process.stderr.write=o,console.log=console.error=console.warn=r}t==="install"?console.log(`Installed Goal runner service: ${await sd(e)}`):t==="start"?await Ir(e,{enable:!0}):t==="status"?console.log(JSON.stringify(await An(e),null,2)):t==="serve"?await E_(e):t==="worker"?await x_(e,se["run-id"]):we("Usage: engineeros-connector runner [install|start|status] --workspace PATH"),process.exit(0)}catch(n){we(n.message)}}se["assessment-workers"]!==void 0&&we("--assessment-workers is no longer supported. Select 3 to 8 parallel agents in EngineerOS before starting the assessment.");if(ke==="tools"){let e=Pe.resolve(se.workspace||process.cwd());try{let t=et[0]||"list";if(["sign-in","auth-status","sign-out"].includes(t)){let r=et[1];r||we(`Usage: engineeros-connector tools ${t} PROVIDER_ID --workspace PATH`);let o=await nl(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 el(e,{type:"tools.update",command_id:"00000000-0000-4000-8000-000000000002",action:t,provider_id:et[1],confirmed:!0},void 0,{confirmLocal:async()=>!0}):t!=="list"&&await Qc(e,t,et[1]);let n=await st(e);console.log(JSON.stringify(n,null,2)),process.exitCode=n.error?1:0}catch(t){we(t.message)}process.exit(process.exitCode||0)}if(ke==="agents"){let e;try{e=await yl()}catch(n){we(n instanceof Error?n.message:String(n))}let t=await Promise.all(e.map(async n=>{try{return await po(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(ke==="agent"){let e=et[0],t=et[1]||"check";(!e||!["check","install"].includes(t))&&we("Usage: engineeros-connector agent AGENT_ID [check|install]");try{let n=t==="install"?await Wg(e):await po(e);console.log(`${n.name} is ready (${n.version}, ${n.distribution}).`)}catch(n){we(n instanceof Error?n.message:String(n))}process.exit(0)}if(ke==="mcp"){let e=se.workspace||process.env.ENGINEEROS_MCP_WORKSPACE||process.cwd(),t=se["run-id"]||et[0]||process.env.ENGINEEROS_MCP_RUN_ID||null,n=await He(e);await pv({config:n,runId:t,version:Nn,input:process.stdin,output:process.stdout}),process.exit(0)}if(ke==="context-mcp"){let e=se["config-workspace"]||se.workspace||process.env.ENGINEEROS_MCP_WORKSPACE||process.cwd(),t=await He(e);t||we("This workspace is not paired with EngineerOS."),await Ev({config:t,workspace:se.workspace||process.env.ENGINEEROS_CONTEXT_WORKSPACE||t.workspace,version:Nn,input:process.stdin,output:process.stdout}),process.exit(0)}if(ke==="status"){let e=await He(se.workspace||process.cwd());console.log(e?`Paired as ${e.name} (${e.connector_id}) for ${e.workspace}`:"Not paired"),process.exit(e?0:1)}if(ke==="doctor"){let e=Pe.resolve(se.workspace||process.cwd()),t=await He(e),n=await av(e),r=await Hr(t||{workspace:e},e,ud(n));console.log(cd(r)),process.exit(r.status==="failed"?1:0)}if(ke==="update"){let e=et[0]||"status";try{let t=Ed(process.argv[1],da),n=await kd(qi(),t,{action:e,policy:et[1]??null});console.log(Mo($d(n,t,{supervised:!0})))}catch(t){we(`${t.message}
889
889
  Usage: engineeros-connector update [status|check|apply|rollback|policy manual|approve|auto-patch|auto-minor]`)}process.exit(0)}if((ke==="start"||ke==="pair")&&process.env[Or]!=="1"&&Ie(da))try{process.exit(await f0({root:qi(),bundled:{version:da,entry:Pe.resolve(process.argv[1])},argv:process.argv.slice(2),workspace:Pe.resolve(se.workspace||process.cwd())}))}catch(e){we(`The connector process could not be started: ${e.message}`)}var k,Gr,Bo;if(ke==="pair"){let e=et[0];e||we("Usage: engineeros-connector pair CODE --url URL [--agent AGENT_ID | --agent-protocol forge] [--name NAME] [--workspace PATH] [--skip-git-repo-check]");let t=se.url;t||we("Pairing requires --url with the EngineerOS backend address."),se.agent&&se["agent-command"]&&we("Use either --agent or --agent-command, not both.");let n=se["agent-protocol"]||(se["agent-command"]?"acp":"codex");["codex","acp","forge"].includes(n)||we(`Unknown --agent-protocol '${n}'. Use codex, acp, or forge.`),n==="forge"&&(se.agent||se["agent-command"])&&we("Forge runs its own agents. Drop --agent and --agent-command when pairing with --agent-protocol forge.");let r={};try{se.agent&&(await po(se.agent),r=await Bg(se.agent))}catch(o){we(o instanceof Error?o.message:String(o))}k={server_url:ba(t),workspace:Pe.resolve(se.workspace||process.cwd()),onboard:se.onboard===!0,onboarding_pending:se.onboard===!0,agent_protocol:n,agent_command:se["agent-command"]||null,agent_args:ML(se["agent-args"]),agent_name:se["agent-name"]||null,...r,skip_git_repo_check:se["skip-git-repo-check"]===!0,name:se.name||`${cL.hostname()} - ${Pe.basename(Pe.resolve(se.workspace||process.cwd()))}`},Bo=await He(k.workspace),Gr={type:"pair",pairing_code:e,name:k.name,capabilities:{},...xu(Bo,k.server_url)}}else ke==="start"?(k=await He(se.workspace||process.cwd()),k||we("This connector is not paired. Create a pairing command in EngineerOS first."),Gr={type:"authenticate",connector_id:k.connector_id,token:k.token}):we("Use `engineeros-connector pair`, `start`, `status`, `doctor`, `agents`, `agent`, `tools`, or `mcp`.");var A0=k_(k,{reportError:e=>console.error(e)}),jn=0,pa=!1,Wo=null,ze=new Map,Vd=0,Xd=new Set,Ur=[],Fe=new Map,Ne,tu,aa,Ht=null,ca=!1,T0=0,Jd=null,Kd=[],la,R0,zo=1e3,pn=!1,vt,Dr=!1,fa=!1,nu=0;function Yd(e){return nu+=1,e.finally(()=>{nu-=1})}var Fr,Qn=0;function qo({exitCode:e=0}={}){if(Qn=Math.max(Qn,e),Fr)return Fr;let t=setTimeout(()=>{console.error("Connector shutdown exceeded 15 seconds; inspect the retained agent logs before restarting."),process.exit(1)},15e3);return t.unref(),Fr=gL().finally(()=>clearTimeout(t)),Fr}async function gL(){if(Ue=!0,Vo?.stop(),mn?.stop(),ru?.stop(),$0?.stop(),clearInterval(eu),Le?.stop(),R0?.(),clearTimeout(la),clearInterval(tu),clearInterval(aa),await Promise.all([...[...ze.values()].map(e=>qe(e.child))]),await Promise.all([...Fe.values()].map(su)),await Go?.cancelAll(),await li(),await jf().catch(e=>{Qn=Math.max(Qn,1),console.error(`${e.message}. Stop those processes before restarting the connector.`)}),Ne?.close(),Qn&&Qn!==jo){let e;await Promise.race([(async()=>{await mn?.drain(),await Hr(k,k.workspace)})().catch(()=>{}),new Promise(t=>{e=setTimeout(t,1e4)})]).finally(()=>clearTimeout(e))}process.exit(Qn)}for(let e of["SIGINT","SIGTERM","SIGHUP"])process.on(e,()=>{qo()});var g0=!1;for(let e of["uncaughtException","unhandledRejection"])process.on(e,async t=>{g0||(g0=!0,console.error(`Connector stopping after an unhandled failure: ${t instanceof Error?t.stack||t.message:String(t)}`),await qo({exitCode:1}))});Le=H_();process.on("exit",()=>{Vo?.stop(),Le.stop()});Le.banner(`EngineerOS connector ${Nn}`,[k.workspace,k.server_url]);mn=M_({actions:{refresh_tool_inventory:async()=>{Me.tool_inventory=await st(k.workspace),Bt()},restart_goal_runner:()=>Ir(k.workspace)},onNotify:()=>Hr(k,k.workspace),explain:async e=>{if(!await C0())return null;let{reading:t}=await o_(k,e);return t},onUpdate:e=>iv(k.workspace,e)});$0=lv({render:(e,t)=>Le.write(e,t),onRecord:e=>mn.observe(e)});ru=dv({workspace:k.workspace,onRecord:e=>{mn.observe(e),Le.line(e.channel,e.level,e.message)}});mn.start();ru.start();Le.live&&(eu=setInterval(()=>{wL().catch(()=>{})},pL),eu.unref?.());var Zd=new Set;async function wL(){m0??=od(k.workspace);let{jobs:e}=await m0(),t=new Set,n=e.filter(r=>r.status!=="queued"&&ua.includes(r.status)).length;for(let r of e){if(!ua.includes(r.status))continue;t.add(r.runId),Zd.add(r.runId);let o=r.status==="queued"&&n>0?`queued behind running Goals (running: ${n})`:r.activity?.phase||r.status;Le.status(`goal:${r.runId}`,o,yL(r),{agent:r.status!=="queued",link:Wo&&`${Wo}/goals`}),Le.step(`goal:${r.runId}`,r.activity?.message)}for(let r of Zd)t.has(r)||(Zd.delete(r),Le.clearStatus(`goal:${r}`))}function yL(e){let t=e.startedAt??Date.parse(e.updatedAt??"");return Number.isFinite(t)?t:Date.now()}async function C0(){if(Ue||ze.size>0||Fe.size>0||jn>0||(Go?.active??0)>0)return!1;try{let{jobs:e}=await An(k.workspace);return!Ue&&!e.some(t=>ua.includes(t.status))}catch{return!1}}try{let e=await nr(k.workspace);e.committed&&(k.onboarding_pending=!0,k.connector_id&&await gn(k),console.log(`Local project repository ready at ${e.revision.slice(0,8)}. Source and design artifacts are committed locally.`))}catch(e){await N0(e)}var de;try{de=await Ii(k,k.workspace)}catch(e){await N0(e)}console.log(`Using ${de.name} through ${de.protocol} (${de.version}).`);var Me=dd(k,de,await st(k.workspace)),fn=Z_({running:Ed(process.argv[1],da),supervised:process.env[Or]==="1",isIdle:async()=>!Ue&&ze.size===0&&Ur.length===0&&Fe.size===0&&jn===0&&nu===0&&!Dr&&!fa&&!ca,restart:()=>qo({exitCode:jo}),onChange:e=>{Me.runtime_update=e,Ne?.readyState===WebSocket.OPEN&&Bt()}});try{await fn.refresh()}catch(e){console.error(`Connector updates are unavailable: ${e.message}`)}k={...k,execution_profiles:de.executionProfiles??null};ke==="pair"&&Bo?.connector_id||await gn(k);Gr.capabilities=Me;console.log(sn(k.worker_limit)===null?`Workers: automatic, ${Ar()} ${de.name} workers side by side for this machine's CPU and memory; change it with /workers.`:`Workers: ${sn(k.worker_limit)} ${de.name} workers side by side, set with /workers.`);var zr=e=>an(k,e),w0=Li(zr,{signature:p_});async function _L(){let e=await An(k.workspace).catch(()=>({service:null,jobs:[]}));return{version:Nn,now:Date.now(),workspace:k.workspace,config_path:Lt(k.workspace),config:k,agent:de,automatic_worker_limit:Ar(),worker_limit:sn(k.worker_limit),connection:{state:vL(),server_url:k.server_url,last_error:vt||null},work:{assessments:[...ze.values()].map(t=>({stage:t.stage,message:t.lastMessage,started_at:t.startedAt})),prompts:[...Fe.values()].map(t=>({id:String(t.runId).slice(0,8),purpose:t.purpose,started_at:t.startedAt})),integrations:jn},runner:e,runtime_update:fn.report(),health:mn?.health()??null,activity:Ho.snapshot()}}function vL(){return Ue||pn?"stopped":Ne?.readyState===WebSocket.OPEN?"connected":"connecting"}var bL={async cancelPrompt(e){let t=[...Fe.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=>O0(e),setVerbose(e){return e===pa?`Detailed agent activity is already ${e?"on":"off"}.`:(ou(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"?(fn.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 fn.command(e),Mo(await fn.refresh()))}};Vo=nv({ui:Le,snapshot:_L,actions:bL});Vo&&console.log(tv());await I0();var y0=new Set;async function I0(){if(Ue||pn)return;console.log(`Connecting ${k.name} to ${k.server_url}`),pn=!1,vt=void 0;let e=new WebSocket(k.server_url);Ne=e;let t=Rm(e,k.server_url,{onTimeout:r=>{Ne===e&&(vt=r,console.error(r),Qd())}});R0=t,e.addEventListener("open",()=>{if(Ne!==e){e.close();return}try{if(Em(Ne,e,Gr))return;throw new Error("The WebSocket was not open when authentication started.")}catch(r){vt=Be(r),console.error(`Could not authenticate the WebSocket connection: ${vt}`);try{e.close()}catch{}Qd()}}),e.addEventListener("message",r=>{if(Ne!==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: ${Be(s)}`)})});let n=async r=>{if(r.type==="authenticated"&&r.connector?.capabilities?.http_updates!==!0){Ue=!0,pn=!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=Bo?.connector_id===r.connector.id;if(k=ku(k,Bo,r.connector.id,r.token),await gn(k),r.connector?.capabilities?.http_updates!==!0){Ue=!0,pn=!0,console.error("Pairing saved. Update the EngineerOS backend for HTTP updates, then start this connector again."),e.close();return}Gr={type:"authenticate",connector_id:k.connector_id,token:k.token,capabilities:Me},console.log(s?`Reconnected existing workspace connector ${k.connector_id}; assessment history is preserved.`:`Paired. Connector ${k.connector_id} is online.`),v0(r);return}if(r.type==="authenticated"){t(),console.log("Connected and waiting for EngineerOS runs."),v0(r);return}if(r.type==="provider.login"||r.type==="provider.logout"){fa||EL(r);return}if(r.type==="workspace.refresh"){ma();return}if(r.type==="workers.update"){try{console.log(`EngineerOS changed the workers. ${await O0(r.worker_limit??"auto")}`)}catch(s){console.error(`Workers were not changed: ${s.message}`)}return}if(r.type==="logging.update"){ou(r.activity_log_enabled===!0);return}if(r.type==="tools.update"){try{Me.tool_inventory=await el(k.workspace,r,void 0,{confirmLocal:s=>Vo?.confirm(s)??!1}),e.send(JSON.stringify({type:"tools.updated",command_id:r.command_id,inventory:Me.tool_inventory})),Bt(),console.log(`Tool registry updated: ${r.action} ${r.provider_id}.`)}catch(s){let i=s instanceof Error?s.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:i})),console.error(`Tool registry update rejected: ${i}`)}return}if(r.type==="tools.auth"){try{let s=await nl(k.workspace,r,{onStatus:async()=>{Me.tool_inventory=await st(k.workspace),Bt()}});Me.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:Me.tool_inventory})),Bt(),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"){ur(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===a0){Yd(hL(r).then(s=>(s.error&&console.error(`${r.provider} ${r.operation} failed: ${s.error}`),l0(k,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}`;ql(Ur,ze.get(s),r)==="deferred"&&console.log(`Assessment stage ${r.stage} is already running here; EngineerOS will be answered when it finishes.`),Xo();return}if(r.type==="prompt.execute"){let s=Fe.get(r.prompt_id);s?L0(r)>s.executionRevision&&await IL(s,r):P0(r);return}if(r.type==="prompt.cancel"){let s=Fe.get(r.prompt_id);s&&await su(s);return}if(r.type==="agent.warm"){kL(r);return}if(r.type==="run.available"){try{let s=await A0.dispatch(r);s.blocked?console.error(s.message):console.log(`Goal ${r.run_id} queued for the independent runner. Logs: ${Pe.join(k.workspace,".engineeros","runs",r.run_id,"activity.log")}`)}catch(s){console.error(`Goal dispatch failed: ${Be(s)}`)}return}if(r.type==="goal.cleanup"){try{await S_(k.workspace),await Ir(k.workspace)}catch(s){console.error(`Goal cleanup is pending: ${s.message}`)}return}if(r.type==="run.accepted"){NL(r);return}if(r.type==="run.cancelled"){await rd(k.workspace,r.run_id);return}if(r.type===Jm){Go??=sh({getConfig:()=>k,onTestsCommitted:()=>ma()}),Yd(Go.handle(r));return}if(r.type===Km){await Go?.cancel(r);return}if(r.type===Nv){h0??=Mv({getConfig:()=>k}),Yd(h0.handle(r));return}if(r.type==="connector.update"){SL(e,r);return}if(r.type==="connector.disconnect"){console.log(r.message),await qo();return}if(r.type==="connector.revoked"){Ue=!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||(Dr=!1);return}if(r.type==="connection.error"){pn=!0,console.error(`EngineerOS: ${r.message}`);return}let o=String(r.type??"(missing)").replace(/[^a-zA-Z0-9_.-]/g,"_").slice(0,120);y0.has(o)||(y0.add(o),console.warn(`Unknown EngineerOS message type ${o}; connector ${Nn}. Update the connector and backend to compatible versions.`))};e.addEventListener("close",r=>{if(t(),Ne!==e||Fr)return;let o=xm(r);if(!o.retry||pn||Ue){console.error(o.message),o.retry&&pn&&console.error("Connection rejected. Create a new pairing command in EngineerOS if this connector was revoked."),qo();return}vt=vt?`${o.message} ${vt}`:o.message,Qd()}),e.addEventListener("error",r=>{Ne===e&&(vt=Sm(r),console.error(`WebSocket connection to ${k.server_url} failed: ${vt}`))})}async function SL(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=fn.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 fn.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 EL(e){let t=e.request_id,n=e.type==="provider.logout"?"logout":"login";fa=!0,console.log(`Starting interactive ${de.name} provider ${n}.`);try{await(n==="logout"?Tm:Am)(de,k.workspace),de=await Ii(k,k.workspace),Me=dd(k,de,Me.tool_inventory),Gr.capabilities=Me,Ne.readyState===WebSocket.OPEN&&(Ne.send(JSON.stringify({type:`provider.${n}.completed`,request_id:t,session:Me.agent_session})),Ne.close(1e3,`Provider ${n} completed`)),console.log(`${de.name} provider ${n} completed.`)}catch(r){let o=Be(r).slice(0,500);Ne.readyState===WebSocket.OPEN&&Ne.send(JSON.stringify({type:`provider.${n}.failed`,request_id:t,message:o})),console.error(`Provider ${n} failed: ${o}`)}finally{fa=!1}}function Qd(){if(Ue||pn||la)return;let e=vt?` Last error: ${vt}`:"";console.error(`Connection unavailable.${e} Retrying in ${Math.round(zo/1e3)}s.`),la=setTimeout(()=>{la=void 0,I0()},zo),zo=Math.min(3e4,zo*2)}async function ma(){if(!(Dr||Ne.readyState!==WebSocket.OPEN)){Dr=!0,console.log("Inspecting the workspace without executing its code.");try{let e=await i_(k.workspace),t=await fetch(rr(k.server_url,k.connector_id),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${k.token}`},body:JSON.stringify(e)});if(!t.ok)throw new Error(await Ns(t,"the workspace"));let n=await t.json();k={...k,onboarding_pending:!1},await gn(k),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 ${n.workspace_kind}. Start the baseline assessment in EngineerOS to continue.`);try{let r=await ms(k.workspace,k.connector_id);console.log(`Built the local context index: ${r.total_files.toLocaleString()} file(s) ready for assignment context.`)}catch(r){console.error(`Local context index build failed: ${r.message}`)}Dr=!1}catch(e){Dr=!1,console.error(`Workspace assessment failed: ${Be(e)}`)}}}var xL=6e4,_0=0;async function kL(e){let t=typeof e.session_key=="string"?e.session_key.trim():"",n=t?k.sessions?.[t]:void 0,r=[];Date.now()-_0>xL&&(_0=Date.now(),r.push(ms(k.workspace,k.connector_id).catch(o=>console.error(`Context index refresh ahead of a conversation failed: ${o.message}`)))),k.agent_protocol==="acp"&&r.push(Mg(k.workspace,k,{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(`${de?.name||"The agent"} could not be started ahead of the conversation: ${o.message}`))),await Promise.all(r)}function Bt(){let e=Xy(ze);w0.update({type:"assessment.workers",assessment_workers:e,tool_inventory:Me.tool_inventory,runtime_update:Me.runtime_update,...Oi(k.worker_limit)}),w0.flush().catch(t=>console.error(`Assessment status: ${t.message}`))}async function O0(e){let t=sn(e);return t===sn(k.worker_limit)?t===null?"Workers are already automatic.":`Workers are already set to ${t}.`:(k={...k,worker_limit:t},await gn(k),Xo(),Bt(),t===null?`Workers are automatic again: up to ${Ar()} side by side for this machine's CPU and memory, for assessment stages, generation, test design and Goals (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: assessment stages, generation, test design and Goals. A Goal that uses your working folder still runs alone. Running work finishes; waiting work starts as workers free up.`)}function ou(e){if(e!==pa){if(pa=e,!e)for(let t of ze.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."),Bt()}}function j0(e,t){Le.step(e,t)&&pa&&console.log(`[${e}] ${t}`)}function $L(){clearInterval(aa);let e=!1,t=()=>{e||ze.size>0||Fe.size>0||(e=!0,Hr(k,k.workspace).finally(()=>{e=!1}))};t(),aa=setInterval(t,uL),aa.unref?.()}async function Hr(e,t,n=mn?.healthChecks()??[]){let r=await C_({config:e,workspace:t,version:Nn,insights:n,agentSession:In,probes:{inspectAgent:(o,s)=>Ue?de:Ii(o,s),inspectTools:o=>Ue?Me.tool_inventory:st(o),runnerStatus:An}});try{k0=(await I_(e,r,an))?.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 N0(e){if(Ue)return Fr;let t=e instanceof Error?e.message:String(e),n=await Hr(k,k.workspace).catch(()=>null);n&&console.error(cd(n)),we(t)}function v0(e){ou(e.connector?.activity_log_enabled===!0),Wo=e.project_url??null,zo=1e3,AL(),fn.confirm().catch(t=>console.error(`Connector update state: ${t.message}`)),TL(),k.onboarding_pending&&ma()}async function AL(){if(In?.state!=="checking"){In={state:"checking",detail:`Asking ${de.name} one question to confirm its session.`},console.log(`Checking that ${de.name} can answer before accepting work.`);try{await Qy(k,de.name),In={state:"ready",detail:`${de.name} answered; its session is usable.`},console.log(In.detail)}catch(e){let t=de.sessionStatus?.login_command;In={state:"failed",detail:e instanceof Error?e.message:String(e),remedy:t?`Sign in to ${de.name} with Log in on the connected workspace, or run ${t} in ${k.workspace}.`:`Sign in to ${de.name} in ${k.workspace}, then restart this connector.`},console.error(`${In.detail}
890
890
  ${In.remedy}`)}await Hr(k,k.workspace).catch(()=>null)}}function TL(){clearInterval(tu);let e=!1,t=0,n=0,r=!1,o=()=>{fn.tick(),!r&&$o(qd.id)&&(r=!0,A0.flush().then(()=>ia(qd)).catch(s=>sa(qd,s)).finally(()=>{r=!1})),ze.size>0&&Bt(),!Ht&&Date.now()-t>=fL&&$o(Hd.id)&&(t=Date.now(),M0().then(()=>ia(Hd)).catch(s=>sa(Hd,s))),k0&&!ca&&$o(Bd.id)&&Date.now()-T0>=Sh&&(ca=!0,RL().then(()=>ia(Bd)).catch(s=>sa(Bd,s)).finally(()=>{ca=!1})),!e&&Date.now()-n>=mL&&$o(Wd.id)&&(e=!0,n=Date.now(),st(k.workspace).then(s=>{Me.tool_inventory=s,Bt(),ia(Wd)}).catch(s=>sa(Wd,s)).finally(()=>{e=!1}))};o(),tu=setInterval(o,1e4),$L()}function sa(e,t){let n=$_(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 ia(e){A_(e.id)&&console.log(`${e.title} recovered.`)}async function RL(){if(!await C0())return;T0=Date.now();let{jobs:e}=await An(k.workspace).catch(()=>({jobs:[]})),t=await Eh(k.workspace,{jobs:e});if(!xh(t))return;let n=`${t.fingerprint}:${Kd.join(",")}`,r=Jd?.key===n,o=r?Jd.candidates:await s_(k,t,Kd);Jd={key:n,candidates:o};let s=await zr(Ah(t,o,{version:Nn}));Array.isArray(s?.refused)&&(Kd=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 On=null,b0=null;async function M0(){if(Ht)return Ht;Ht=(async()=>{let e=await mh(k,{knownRevision:On?.revision??null});if(e.unchanged||(On=e),b0===On.revision)return On;let{jobs:t}=await An(k.workspace);return!t.some(r=>ua.includes(r.status))&&jn===0&&ze.size===0&&(await qs(k.workspace,On),b0=On.revision),On})();try{return await Ht}finally{Ht=null,Xo()}}function S0(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)),Fe.get(e)?.events.push(n)}var E0=null;function Xo(){let e=Ne.readyState===WebSocket.OPEN,t=ze.values().next().value,n=sn(k.worker_limit)??Math.min(Ar(),Xl(t?.workerLimit??Ur[0]?.worker_limit)),r=e&&!Ht&&jn===0?Fy(Ur,ze.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:Xl(s.worker_limit),lastActivityAt:Date.now(),eventCount:0,lastDetail:null};ze.set(i,a),jL(s,a)}r.length>0&&Bt();let o=Uy({queued:Ur,running:ze.size,workerLimit:n,connected:e,designSync:!!Ht,integrations:jn});o&&o!==E0&&console.log(o),E0=o}function ha(e){let t=Jl(e);return t?`${de.name} on ${t}`:de.name}async function P0(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:h_(zr),executionRevision:L0(e),sessionKey:ji(e),sessionId:null,replacement:null};Fe.set(t,s);let i,a=h=>{let g=h?JSON.stringify(h):null;!g||g===i||Fe.get(t)!==s||(i=g,S0(t,h))},c=`${r} \xB7 ${ha(e)}`,l=Zy(e,de.name);S0(t,{kind:"status",message:l});let d=Number(e.answer_within_seconds),p=d>0?o+d*1e3:void 0;console.log([`[${n}] ${l} for ${r}.`,`${de.name} can reason for several minutes without reporting a step.`,...p?[hd(p,o)]:[]].join(" ")),Le.status(n,c,o,{link:Wo,answerBy:p});let u=h=>{let g=Py(h),y=ao(h);Fe.get(t)===s&&j0(n,y??g?.message);let b=h.type==="forge.output"?null:y;a(g??(b?{kind:"status",message:b}:null))},f="failed",m=[r];try{Ni(e)||(u({type:"connector.step",message:"Syncing the design context from EngineerOS"}),e={...e,design_context:await _h(M0,{pinned:!!e.local_design_context,last:On,onFallback:(b,w)=>u({type:"connector.step",message:`Design context not refreshed (${b.message}); continuing with ${w?"the copy synced earlier":"none"}`})})});let h=await Cy(e,k,{onProcess:b=>{Fe.get(t)===s&&(s.child=b)},onController:b=>{Fe.get(t)===s&&(s.controller=b)},onSession:b=>{s.sessionId=b},onEvent:u},{signal:s.cancellation.signal});if(s.stoppedHere)throw new Error(x0);let g=h.singleTurn?$u(k.sessions,h.sessionKey):Sa(k.sessions,h.sessionKey,h.sessionId);if(JSON.stringify(g)!==JSON.stringify(k.sessions||{})&&(k={...k,sessions:g},await gn(k)),s.cancelled)return;await s.events.close().catch(b=>{console.error(`[${n}] Prompt progress delivery: ${b.message} The agent has finished; submitting its complete response separately.`)});let y=await Pi(zr,{type:"prompt.completed",prompt_id:t,execution_revision:s.executionRevision,content:h.content,model:h.model,session_id:h.sessionId,usage:h.usage});y||console.error(`[${n}] ${Ql}`),Ho.record("prompt","completed",{durationMs:Date.now()-o,usage:h.usage}),f=y?"finished":"undelivered",m=[CL(h.usage),r]}catch(h){let g=s.stoppedHere?x0:Be(h);if(Ho.record("prompt","failed",{durationMs:Date.now()-o}),s.stoppedHere&&(f="cancelled"),!s.cancelled){try{await Pi(zr,{type:"prompt.failed",prompt_id:t,execution_revision:s.executionRevision,message:g})||console.error(`[${n}] ${Ql}`)}catch(y){console.error(`[${n}] Prompt failure delivery: ${y.message}`)}console.error(g)}}finally{s.events.stop();let h=s.replacement;h?(f="replaced",m=[`continuing on ${ha(h)}`,r]):s.cancelled&&(f="cancelled"),Le.finish(n,f,m),Fe.get(t)===s&&Fe.delete(t),h&&OL(s,h)}}var x0="Cancelled from the connector terminal by the person running it.";function CL(e){let t=Number(e?.total_tokens)||(Number(e?.input_tokens)||0)+(Number(e?.output_tokens)||0);return t?`${t.toLocaleString()} tokens`:null}async function su(e){e.cancelled=!0,e.cancellation.abort(),await e.controller?.completed.catch(()=>{})}function L0(e){return Number(e.execution_revision)||1}async function IL(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 ${ha(t)}.`),await su(e))}function OL(e,t){e.sessionId&&(k={...k,sessions:Sa(k.sessions,e.sessionKey,e.sessionId)},gn(k).catch(n=>console.error(`Could not save the agent session: ${n.message}`))),P0(t)}async function jL(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 ${ha(e)}.`),!Xd.has(n)){Xd.add(n);try{let v=await jy(k.workspace);if(!v.exists)console.log("No accepted assessment exists yet; this run establishes the baseline.");else{let x=v.accepted_head_revision?v.current_head_revision?v.current_head_revision!==v.accepted_head_revision?`The workspace is now at commit \`${v.current_head_revision}\`; the accepted assessment is from \`${v.accepted_head_revision}\`.`:"The accepted assessment is already at the current commit.":`The accepted assessment is from \`${v.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 ${v.stages.length||"no"} section(s). ${x}`)}}catch(v){console.error(`Assessment freshness check failed: ${v.message}`)}}let o=t.startedAt,s=`assessment:${r}`,i=!1,a=!1,c=5,l=!1,d=!1,p=null,u=null,f=null,m=new Set,h=()=>!Ue&&ze.get(t.key)===t,g=async v=>{try{return await Pi(zr,v)||console.warn(`[${s}] ${f_}`),!0}catch(x){return console.error(`Assessment failure delivery: ${x.message}`),!1}},y=(v,{milestone:x=!0}={})=>{if(!h()||x&&f===v)return;x&&(f=v,m.has(v)||(m.add(v),c=Math.min(90,c+10)),console.log(`[assessment:${r}] ${v}.`));let _=String(v).slice(0,500);t.progressPercent=c,t.lastMessage=_,Le.status(s,_,o,{link:Wo})};y(`Starting ${r} assessment stage`);let b=setInterval(()=>{let v=Date.now(),x=v-t.lastActivityAt,_=i&&!a?My(r,x):null;if(!p&&_){p=_,console.error(`[assessment:${r}] ${p}`),Mi(t.controller,t.child);return}p||mn.observe({at:v,level:"info",message:Le.status(s,`${t.lastMessage} \xB7 last agent activity ${Ae(x)} ago (${t.eventCount.toLocaleString()} events)`,o)})},15e3),w={onSession:async v=>{h()&&(u=String(v),await af(k.workspace,n,r,v,{sourceRevision:e.source_revision,targetHeadRevision:e.target_head_revision}))},onController:v=>{h()&&(t.controller=v)},onProcess:v=>{h()&&(t.child=v,i=!0,t.phase!=="correcting"&&(t.phase="running",y("Connected agent process started")),t.lastActivityAt=Date.now())},onEvent:v=>{t.lastActivityAt=Date.now(),t.eventCount+=1;let x=Ny(v);if(x&&y(x),!h())return;let _=ao(v);!_||_===t.lastDetail||(t.lastDetail=_,j0(s,_))}},S=(v,x)=>Bl(v,x,k,w,{draftPath:Pe.relative(k.workspace,Pe.join(nt(k.workspace,n),v.report_file)).split(Pe.sep).join("/")});try{let v=Vd-Date.now();v>0&&(y(`Waiting ${Math.ceil(v/1e3)}s for the model provider's rate limit to clear`),await new Promise(C=>setTimeout(C,v+Math.floor(Math.random()*3e3)))),e.assessment_mode==="incremental"&&(c=15,y("Calculating changed files and affected behavior"));let x=await pf(k.workspace,e),_=await Qa(k.workspace,n,r,{expectedHeadRevision:e.target_head_revision,expectedSourceRevision:e.source_revision});if(_)S(_,x),y("Recovered completed stage report from connector storage");else{if(u=await cf(k.workspace,n,r,{expectedHeadRevision:e.target_head_revision,expectedSourceRevision:e.source_revision}),u&&y("Restoring interrupted agent session"),_=await Ry(x,k,w,{previousSessionId:u}),p)throw new Error(p);a=!0,await Za(k.workspace,n,x,_)}a=!0,t.phase="delivering",t.progressPercent=95,t.lastMessage=r==="synthesis"?"Delivering completed assessment bundle":"Checkpointing connector-local stage result";let R=C=>fetch(Ru(k.server_url,k.connector_id,n),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${k.token}`},body:JSON.stringify(C),signal:AbortSignal.timeout(my)}),N=await Yy(_,{submit:C=>Ky(C,R,{isActive:()=>h()&&!Ue,onRetry:(O,I)=>{y("Completed result is waiting for EngineerOS",{milestone:!1}),console.warn(`[assessment:${r}] Completed result delivery failed: ${Be(O)} Retrying in ${Math.round(I/1e3)}s without rerunning the agent.`)}}),payloadFor:C=>r==="synthesis"?ec(k.workspace,n,C,{expectedSourceRevision:e.source_revision}):gf(C),rejectionFor:C=>Ns(C,"the assessment"),correct:async(C,O)=>{if(a=!1,t.phase="correcting",t.lastMessage="Correcting a rejected stage result",!C.correctAfterRejection)throw new Error(`${O} The connector could not start the required agent correction.`);return C.correctAfterRejection(O)},onCorrected:async C=>{if(p)throw new Error(p);a=!0,await df(k.workspace,n,r);let O=await Za(k.workspace,n,x,C);return S(O,x),t.phase="delivering",t.lastMessage="Delivering corrected stage result",O}});if(p)throw new Error(p);_=N.result;let T=N.response;if(!T.ok)throw new Error(await Ns(T,"the assessment"));if(l=!0,Ho.record("assessment stage","completed",{durationMs:Date.now()-o,usage:_.usage}),r==="synthesis"){let C=await T.json(),O=await ff(k.workspace,n,e,_,C.report_markdown);console.log(`Workspace assessment ${n} was accepted by EngineerOS and saved to ${Pe.relative(k.workspace,O)}.`);try{let I=await ns(k.workspace);I.committed&&console.log(`Assessment committed to Git as ${I.revision.slice(0,8)}.`)}catch(I){console.error(`The assessment is saved locally but could not be committed to Git: ${I.message}`)}}else console.log(`Workspace assessment stage ${r} was checkpointed by EngineerOS.`)}catch(v){let x=p||Be(v),_=By(e,v),R=Vy(v),j=Gy(v);R&&(await lf(k.workspace,n,r).catch(T=>{console.error(`[assessment:${r}] Could not discard the unusable agent session checkpoint: ${T.message}`)}),u=null);let N=!p&&(u||R)&&(R||zy(v))&&_<j;if(h()&&N){t.phase="starting",t.lastMessage=R?"Agent session became unusable; restarting from saved assessment work":"Agent session interrupted; resuming checkpoint",t.resumeAssignment=Wy(e,v);let T=qy(v,_);bo(v)&&(Vd=Math.max(Vd,Date.now()+T)),console.warn(`[assessment:${r}] ${R?"Agent session became unusable":"Agent session interrupted"}: ${x} ${R?"Starting a fresh session from the saved draft":`Resuming session ${u}`} in ${Math.round(T/1e3)}s (${_+1}/${j}).`),await new Promise(C=>setTimeout(C,T))}else h()&&(d=await g({type:"workspace.assessment.failed",assessment_id:n,stage:r,message:x}));N||(Ho.record("assessment stage","failed",{durationMs:Date.now()-o}),console.error(`[assessment:${r}] ${x}`))}finally{clearInterval(b),Le.clearStatus(s),r==="synthesis"&&l&&Xd.delete(n),h()&&(ze.delete(t.key),Jy(Ur,t,{accepted:l,failureReported:d})&&console.log(`Resuming interrupted agent session for assessment stage ${r} from its checkpoint.`),Xo())}}async function NL(e){let t=String(e.run_id||"");jn+=1;try{Ht&&await Ht;let n=await by(k.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 ma();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: ${Be(n)}`)}finally{jn-=1,Xo()}}function ML(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{we('--agent-args must be a JSON array, for example: --agent-args "[\\"acp\\"]"')}}function we(e){console.error(e),process.exit(1)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@engineeros/connector",
3
- "version": "1.43.3",
3
+ "version": "1.43.4",
4
4
  "description": "Connect a local coding agent to EngineerOS, using ACP when supported.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",