@engineeros/connector 1.59.32 → 1.59.33

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.
@@ -965,7 +965,7 @@ ${r}`);if(!s&&c&&i.some(f=>xX.test(f)))return"consent";if(a&&i.some(f=>DO.test(f
965
965
  `)[0])}`)}let Je=await Oe.text().catch(()=>"");yt();let $t=null;try{$t=JSON.parse(Je)}catch{$t=null}return z.response={status:Oe.status(),text:Je,json:$t,ms:c()-Pe},{method:et,url:X}}let Pt=async F=>{let fe=[...new Set([...String(F??"").matchAll(cJ)].map(J=>J[1]))],ae=String(F??"");for(let J of fe){let et=f[J];if(et===void 0||et==="")throw new qe("blocked",`Set ${J} on the hunt host (\`engineeros-connector secret set ${J} --project ${I??"<project id>"}\`).`);let X;try{X=await ff({value:String(et),now:c,sleep:Sn})}catch{throw new qe("blocked",`${J} is not a valid authenticator secret.`)}ae=ae.replaceAll(`{totp:${J}}`,X)}return ae};async function wn(F,fe=Ie,{signingIn:ae=!1}={}){if(yt(),z.blockedRequest)throw new qe("blocked",z.blockedRequest);let J={action:F.action,target:Hs(await Pt(F.target),fe),data:Hs(await Pt(F.data),fe),check:Hs(F.check,fe)};if(yt(),J.action==="fill"&&!ae&&rO(J.data).blocked)throw new qe("blocked",Xy);if(ne&&(J.action==="request"&&!/^(GET|HEAD)\s+/i.test(J.target)||["use account","run","open app"].includes(J.action)||J.action==="press"&&/enter/i.test(J.data)))throw new qe("blocked","Public pages only permits signed-out browsing and GET or HEAD request steps, without submitting.");if(b){if(!["open","request","wait for"].includes(J.action)||J.action==="request"&&!/^GET\s+/.test(J.target)||J.data)throw new qe("blocked","This action is not production-safe.");await Sn(1e3)}if(!ae){let X=zr(J,ce);if(X)throw new qe("blocked",`Refused by the rule of engagement "${X}".`)}let et=J.check?zo(J.check):[];switch(J.action){case"open app":{if(g.app_surface!=="electron")throw new qe("blocked","open app requires an Electron or WebDriver hunter.");if(process.env.ENGINEEROS_HUNT_HOST!=="dedicated")throw new qe("blocked","Electron requires ENGINEEROS_HUNT_HOST=dedicated on a VM or spare machine.");if(Ce)throw new qe("needs_repair","Open the app once per case.");Ce=await y({executablePath:g.app_path,args:g.app_arguments||[],cwd:l}),K?.aborted&&(await He(),yt()),await Ot();break}case"use account":ft(await Qt(J.target.trim()));break;case"open":{await Ot();let X=Ue(J.target.trim(),Q),xe=Oe=>new qe("blocked",`${z.account.role}'s recorded sign-in has expired or was signed out: opening ${X} led to ${Oe}. Record it again in Bug Hunter Setup.`),we;try{we=await z.page.goto(X,{waitUntil:"domcontentloaded",timeout:D.navigation})}catch(Oe){let Je=String(Oe.message).split(`
966
966
  `)[0];throw z.account?.storage_state&&/ERR_BLOCKED_BY_CLIENT/.test(Je)?xe("another site"):new qe("blocked",`Opening ${X} failed: ${Kt(Je)}`)}if(await Jt(),z.account?.storage_state&&GO(X,z.page.url(),Y))throw xe(Kt(z.page.url(),200));await To({requested:X,reopen:async()=>{we=await z.page.goto(X,{waitUntil:"domcontentloaded",timeout:D.navigation}),await Jt()}}),await Le();let Pe=we?.status?.()??200;if(Pe>=500)throw new qe("failed",`The server answered ${Pe} for ${X}.`,`server error ${Pe}`);break}case"click":case"hover":case"check":case"uncheck":case"fill":case"select":{await Ot();let X=await hr(Fr(J.target));await An(async()=>{J.action==="click"?await X.click({timeout:D.action}):J.action==="hover"?await X.hover({timeout:D.action}):J.action==="check"?await X.check({timeout:D.action}):J.action==="uncheck"?await X.uncheck({timeout:D.action}):J.action==="fill"?await X.fill(J.data,{timeout:D.action}):await X.selectOption({label:J.data},{timeout:D.action})}),J.action==="click"&&await Jt();break}case"press":{if(await Ot(),J.target.trim()){let X=await hr(Fr(J.target));await An(()=>X.press(J.data.trim(),{timeout:D.action}))}else await An(()=>z.page.keyboard.press(J.data.trim()));await Jt();break}case"go back":await Ot(),await An(()=>z.page.goBack({timeout:D.navigation})),await Jt();break;case"reload":await Ot(),await An(()=>z.page.reload({timeout:D.navigation})),await Jt(),await Le();break;case"set viewport":{await Ot();let[X,xe]=(J.data||J.target).trim().toLowerCase().split("x").map(Number);await z.page.setViewportSize({width:X,height:xe});break}case"wait for":await Ot();break;case"request":{await Ot();let{method:X,url:xe}=await Qi(J.target,J.data);if(z.response.status>=500&&!et.some(we=>["status","status_below","status_in"].includes(we.kind)))throw new qe("failed",`The server answered ${z.response.status} for ${X} ${xe}.`,`status was ${z.response.status}: ${Kt(z.response.text,200)}`);break}case"poll":{await Ot();let X=c()+(Number(J.data.trim())||VX)*1e3;for(;;){await Qi(J.target,"");let xe=[];for(let we of et){let Pe=await lo(we);Pe!==null&&xe.push(Pe)}if(!xe.length)break;if(c()>=X)throw new qe("failed",`It never answered as expected: ${xe.join("; ")}.`,xe.join("; "));await Sn(XX)}return Wn()}case"set device":{if(z.page)throw new qe("needs_repair","Set the device before opening a page or using an account.");if(g.device_cloud_url){ot=J.data.trim(),Qe.hasTouch=!0;break}let X=J.data.trim().toLowerCase(),xe=Object.entries(m).find(([Oe])=>Oe.toLowerCase()===X);if(!xe)throw new qe("needs_repair",`${J.data.trim()} is not a device the browser knows; use a name such as iPhone 13 or Pixel 7.`);let{defaultBrowserType:we,...Pe}=xe[1];Object.assign(Qe,Pe);break}case"tap":{if(await Ot(),!Qe.hasTouch)throw new qe("needs_repair","tap needs a touch device; set one with set device first.");let X=await hr(Fr(J.target));await An(()=>X.tap({timeout:D.action})),await Jt();break}case"set locale":Qe.locale=J.data.trim();break;case"set time zone":Qe.timezoneId=J.data.trim();break;case"set network":{await Ot();let X=J.data.trim().toLowerCase();ln.setNetwork(X),await z.context.setOffline(X==="offline"),X!=="offline"&&await(await z.context.newCDPSession(z.page)).send("Network.emulateNetworkConditions",X==="slow"?qX:WX);break}case"run":{let X;try{X=En(J.target.trim())}catch(Pe){throw new qe("needs_repair",`\`${J.target}\` cannot run without a shell: ${Pe.message}`)}let xe=f_.basename(X[0]).replace(/\.(exe|cmd|bat)$/i,"").toLowerCase();if(!Z.has(xe))throw new qe("blocked",`${X[0]} is not a program this hunter may run (${[...Z].join(", ")||"none are allowed"}).`);let we=await p(X,{onChild:jt,cwd:l,timeoutMs:D.command,...u?{env:u}:{},...J.data?{input:J.data}:{}});if(we.notFound)throw new qe("blocked",`${X[0]} is not installed on the hunt host.`);z.command={exitCode:we.exitCode,output:nt(String(we.output??""))};break}case"use":{let X=ue.get(J.target.trim().toLowerCase());if(X?.builtin==="inbox"){if(!C)throw new qe("blocked","The test inbox is not set up on this hunt host.");z.command=await gf(C,J.data,Re);break}if(!X)throw new qe("blocked",`${J.target.trim()} is not an instrument approved for this environment (${[...ue.keys()].join(", ")||"none are"}).`);let xe=X.env??[],we=xe.filter(un=>f[un]===void 0);if(we.length)throw new qe("blocked",`Set ${we.join(", ")} on the hunt host to use ${X.name}.`);let Pe=Object.fromEntries(xe.map(un=>[un,String(f[un])])),Oe={...fe,...Pe,data:J.data,since:new Date(Re).toISOString()},Je=(X.command??[]).map(un=>Hs(String(un),Oe)),$t=await p(Je,{onChild:jt,cwd:l,timeoutMs:D.command,env:{...u??process.env,...Pe}});if($t.notFound)throw new qe("blocked",`${Je[0]} is not installed on the hunt host.`);let Gt=String($t.output??"");for(let un of Object.values(Pe))un&&(Gt=Gt.replaceAll(un,"[secret]"));z.command={exitCode:$t.exitCode,output:nt(Gt)};break}case"wait until":{let X=/^step\s+(\d+)$/i.exec(J.target.trim()),xe=X?Sc[Number(X[1])-1]:Re;if(xe===void 0)throw new qe("needs_repair",`wait until counts from step ${X[1]}, which has not run yet.`);let we=xe+(lf(J.data)??0);if(we-c()>KX)throw new qe("needs_repair","wait until may wait at most three hours.");we>c()&&await Sn(we-c());break}case"crawl":{await Ot();let X=Math.min(Number(J.data)||h_,YX),xe=z.account?.role??null,we=c(),Pe=()=>c()<we+Math.min(D.crawl+z.scanMs,3*D.crawl),Oe=W?[]:[{url:Ue(J.target.trim()||"/",Q),from:null,source:"link"}],Je=[];for(let _e of xf(oe,ce))try{Je.push({url:Ue(_e.path,Q),from:null,source:_e.source,seed:!0})}catch{}let $t=Je.some(_e=>_e.url.includes("/#/")),Gt=new Set(V),un=new Set(V),mi=new Map,q=!1,re=new Map,me={pages:0,server_errors:[],broken_links:[],routes:[],scripts:[],controls_explored:0,explore_blocked_writes:0,explore_stopped_pages:0,explore_stopped_time:0};z.crawl=me;let De=[],Fe=null,it=async()=>{let[_e,ke]=await Promise.all([z.page.title(),z.page.evaluate(Vs)]);return`${_e??""}\0${ke.elements.join("")}`},kt=async()=>{let _e=`__engineeros_probe_${Math.random().toString(36).slice(2,8)}`;try{return await z.page.goto(Ue($t?`/#/${_e}`:`/${_e}`,Q),{waitUntil:"domcontentloaded",timeout:D.navigation}),await Jt(),await it()}catch{return!1}};for(;(Oe.length||Je.length)&&me.pages<X&&Pe()&&!$e();){yt();let _e=Je.length&&(q||!Oe.length)?Je.shift():Oe.shift();q=!q;let ke=xr(new URL(_e.url));if(ke===null)continue;let ht=ql(ke);if(Gt.has(ke)||(re.get(ht)??0)>=QX||(Gt.add(ke),re.set(ht,(re.get(ht)??0)+1),zr({action:"open",target:ke,data:"",check:""},ce)))continue;_e.seed&&Fe===null&&(Fe=await kt()),z.path=_e.from,z.pathRole=xe;let Ve={path:ke.slice(0,300),source:_e.source,status:null,outcome:"reached",from_path:_e.from?_e.from.slice(0,300):null},tt=(en,dn=null)=>{_e.from&&(me.broken_links.push({from:_e.from,url:_e.url,status:en}),ln.note("broken_link",_e.from,{url:_e.url,status:en,error:dn,message:`A link to ${ke} ${en?`answers ${en}`:"cannot be opened"}`}))},gt;try{gt=await z.page.goto(_e.url,{waitUntil:"domcontentloaded",timeout:D.navigation})}catch(en){let dn=String(en.message).split(`
967
967
  `)[0];/ERR_(?!BLOCKED_BY_CLIENT)[A-Z_]+/.test(dn)&&tt(null,dn),me.routes.push({...Ve,outcome:"error"});continue}await Jt(),xe&&await To({requested:_e.url,crawling:!0,reopen:async()=>{gt=await z.page.goto(_e.url,{waitUntil:"domcontentloaded",timeout:D.navigation}),await Jt()}}).catch(()=>!1),await Le();let At=gt?.status?.()??200;Ve.status=At;let or=At===404||At===410;if(await(async()=>{if(!xe||or)return!1;if(At===403)return!0;if(At>=400)return!1;try{let[en,dn,gi]=await Promise.all([z.page.title(),z.page.evaluate(Vs),z.page.evaluate(()=>document.querySelector("h1")?.innerText??"")]);return iJ.test(`${en??""} ${gi??""}`)&&dn.elements.length<=aJ}catch{return!1}})()){me.routes.push({...Ve,outcome:"forbidden"});continue}let Jn=xr(new URL(z.page.url())),lt=At===401||At===403||GO(_e.url,z.page.url(),Y)||Jn!==ke&&Ws({key:Jn,elements:(await z.page.evaluate(Vs).catch(()=>({elements:[]}))).elements});if(lt){if(me.routes.push({...Ve,outcome:"sign_in"}),_e.seed){let en=new URL(z.page.url()),dn=`${en.origin}${At===401||At===403?`:${At}`:xr(en)}`,gi=(mi.get(dn)??0)+1;mi.set(dn,gi),gi>=3&&Je.length&&(me.deferred_seeds=Je.length,Je.length=0)}if(At===401||At===403)continue}else if(_e.seed){if(or||Fe&&await it()===Fe){me.routes.push({...Ve,outcome:"not_found"});continue}}else if(or){tt(At),me.routes.push({...Ve,outcome:"not_found"});continue}else At>=400&&At!==401&&At!==403&&tt(At);let Dt=new URL(z.page.url()),Ee=xr(Dt);if(lt||me.routes.push({...Ve,outcome:At>=500?"error":"reached"}),Ee===null||!Y.has(Dt.hostname.toLowerCase())||un.has(Ee))continue;un.add(Ee),me.pages+=1,lt&&Ee!==ke&&me.routes.push({path:Ee.slice(0,300),source:"navigation",status:At,outcome:"reached",from_path:null}),At>=500&&me.server_errors.push(Ee),await Wn(),await Xo();let jn=await z.page.evaluate(zO).catch(()=>[]);De.push({key:Ee,url:z.page.url(),links:Array.isArray(jn)?jn.length:0});for(let en of Array.isArray(jn)?jn:[]){let dn;try{dn=new URL(en,Dt)}catch{continue}!/^https?:$/.test(dn.protocol)||!Y.has(dn.hostname.toLowerCase())||Sf(xr(dn),ce)&&(m_.test(dn.hash)||(dn.hash=""),Gt.has(xr(dn))||Oe.push({url:dn.toString(),from:Ee,source:"link"}))}}if(await ve(),le&&!b&&De.length&&!$e()){let _e=c(),ke=()=>$e()||c()-_e>=D.explore,ht=[...De].sort((tt,gt)=>tt.links-gt.links),Ve=async tt=>{await z.page.goto(tt.url,{waitUntil:"domcontentloaded",timeout:D.navigation}).catch(()=>{}),await Jt()};z.exploring=!0;try{for(let tt=0;tt<ht.length&&!me.explore_stopped_time;tt+=1){if(yt(),ke()){me.explore_stopped_time=1;break}let gt=ht[tt];try{await z.page.goto(gt.url,{waitUntil:"domcontentloaded",timeout:D.navigation})}catch{continue}await Jt();let At=await z.page.evaluate(IO).catch(()=>[]),{chosen:or,cut:Xn}=jO(Array.isArray(At)?At:[],{forbidden:ce,limit:a_});Xn&&(me.explore_stopped_pages+=1);let Jn=0;for(let lt of or){if(yt(),ke()){me.explore_stopped_time=1;break}let Dt=lt.role?z.page.getByRole(lt.role,{name:lt.name,exact:!0}):z.page.getByText(lt.name,{exact:!0});if(await Dt.count()!==1)continue;let Ee=(await z.page.evaluate(Vs)).elements;try{await Dt.click({timeout:D.action})}catch{}me.controls_explored+=1,await Sn(D.exploreSettle),await Jt();let jn=z.page.url(),en=null,dn=!1;try{let wi=new URL(jn);en=xr(wi),dn=Y.has(wi.hostname.toLowerCase())}catch{}if(en!==null&&en!==gt.key&&dn){!un.has(en)&&me.pages<X&&(un.add(en),Gt.add(en),z.path=gt.key,z.pathRole=xe,me.pages+=1,me.routes.push({path:en.slice(0,300),source:"navigation",status:200,outcome:"reached",from_path:gt.key.slice(0,300)}),await Wn(),await Xo(),Jn=0,ht.push({key:en,url:jn,links:0})),await Ve(gt);continue}let gi=(await z.page.evaluate(Vs)).elements,sb=gi.filter(wi=>!Ee.includes(wi));if(sb.length>=2){let wi={key:gt.key.slice(0,300),title:String(await z.page.title().catch(()=>"")??"").slice(0,300),elements:[...new Set([...Ee,...gi])].slice(0,d_),role:xe};i(wi),B(wi)}if(await Xo(),sb.length)Jn=0,await Ve(gt);else if(++Jn>=3){ke()&&(me.explore_stopped_time=1);break}}}}finally{z.exploring=!1}me.explore_blocked_writes=z.blockedWrites}me.scripts=ln.scripts(),me.remaining_routes=[...Oe,...Je].flatMap(_e=>{let ke=xr(new URL(_e.url));return ke&&!Gt.has(ke)?[{path:ke,source:_e.source}]:[]});return}case"remember":{let X=J.data.trim(),xe=J.target.trim();if(xe==="url")await Ot(),fe[X]=z.page.url();else if(/^output(?:\s+field\s+|$)/i.test(xe)){if(!z.command)throw new qe("needs_repair","Nothing was run before this step to remember output from.");let we=xe.replace(/^output\s*(?:field\s+)?/i,"");if(!we)fe[X]=z.command.output.trim();else{let Pe=null;try{Pe=JSON.parse(z.command.output)}catch{Pe=null}let Oe=Pe===null?{found:!1}:Jl(Pe,we);if(!Oe.found)throw new qe("needs_repair",`The last output has no field ${we} to remember.`);fe[X]=ec(Oe.value)}}else if(/^field\s+/i.test(xe)){let we=xe.replace(/^field\s+/i,""),Pe=z.response?Jl(z.response.json,we):{found:!1};if(!Pe.found)throw new qe("needs_repair",`The last response has no field ${we} to remember.`);fe[X]=ec(Pe.value)}else{await Ot();let we=await hr(Fr(xe));fe[X]=String(await we.innerText()).trim()}break}default:throw new qe("needs_repair",`\`${J.action}\` is not an action.`)}yt(),await Rr(et),await Wn()}let hi=async()=>(await ln.settled(),{signals:ln.signals(),api_calls:b?[]:ln.apiCalls(),vitals:Zi,scanned:di,scan_ms:z.scanMs});try{for(let[F,fe]of Ke.entries())try{if(z.step=F+1,await wn(fe),z.blockedRequest)throw new qe("blocked",z.blockedRequest);Sc[F]=c(),await Xo()}catch(ae){let J=z.blockedRequest?new qe("blocked",z.blockedRequest):ae instanceof qe?ae:K?.aborted?new qe("blocked",Kt(K.reason?.message??"The hunt was stopped; remaining actions were not run.")):new qe("failed",Kt(ae.message));z.crawl||await Wn({final:!0}).catch(()=>{});let et=await Gr(),X=et?[{label:"after",step:F+1,media_type:"image/jpeg",data_base64:et}]:[];return{outcome:J.outcome,failed_step:F+1,message:`${Et} step ${F+1}: ${Kt(J.message,1e3)}`,observed:J.observed?Kt(J.observed,1e3):null,duration_ms:c()-Re,evidence:[...X,...Xt],...await hi(),...z.crawl?{crawl:z.crawl}:{}}}return z.crawl||await Wn({final:!0}).catch(()=>{}),{outcome:"passed",failed_step:null,message:null,observed:null,duration_ms:c()-Re,evidence:Xt,...await hi(),...z.crawl?{crawl:z.crawl}:{}}}finally{K?.removeEventListener("abort",cn);let fe=(await Promise.allSettled([$n,He()])).find(ae=>ae.status==="rejected");if(fe)throw fe.reason}}return{run:Ut}}gr();import In from"node:path";import{mkdirSync as Kne}from"node:fs";import{format as Yne}from"node:util";Dn();N();ea();N();var Kl=new Map;function Yl(e,t=Date.now()){let n=Kl.get(e);return!n||t>=n.retryAt}function WO(e,t,n,{remedy:r=null,now:o=Date.now()}={}){let s=Kl.get(e),i=(s?.failures??0)+1,a=Math.min(3e4*2**(i-1),6e5),c={id:e,title:t,remedy:r,message:lJ(n),failures:i,firstFailedAt:s?.firstFailedAt??o,retryAt:o+a,retryInMs:a};return Kl.set(e,c),c}function VO(e){return Kl.delete(e)}function XO(e=Date.now()){return[...Kl.values()].map(t=>({...t,status:t.failures>=5?"failed":"warning",retryInMs:Math.max(t.retryAt-e,0)}))}function lJ(e){return(e instanceof Error?e.message:String(e??"")).trim()||"No detail was reported."}Dn();var g_=22,uJ=500,dJ=300,pJ=20,JO={ok:0,warning:1,failed:2},YO={codex:{url:"https://registry.npmjs.org/@openai%2fcodex/latest",version:e=>e?.version,remedy:"Run `npm install -g @openai/codex@latest`, then restart this connector."},forge:{url:"https://api.github.com/repos/tailcallhq/forgecode/releases/latest",version:e=>String(e?.tag_name??"").replace(/^v/,""),remedy:"Run `forge update`, then restart this connector."}},fJ=360*6e4,KO=new WeakMap,hJ="connector.diagnostics";function mJ(e){return e.reduce((t,n)=>JO[n.status]>JO[t]?n.status:t,"ok")}async function ZO({config:e,workspace:t=e?.workspace,version:n="development",probes:r,insights:o=[],agentSession:s=null,fetchImpl:i=fetch,nodeVersion:a=process.version}){let c=[gJ(a),wJ(e),await Zl("backend","EngineerOS backend",()=>yJ(e,i)),await Zl("coding_agent","Coding agent",()=>_J(e,t,r.inspectAgent,i)),...s?[bJ(s)]:[],...r.connectorJobs?[await Zl("local_execution","Local testing work",()=>kJ(r.connectorJobs))]:[],await Zl("tool_registry","Tool registry",()=>SJ(t,r.inspectTools)),...e?.hunt_host?[]:[await Zl("goal_runner","Goal runner",()=>xJ(t,r.runnerStatus,{serviceStatus:r.macRunnerStatus}))],...XO().map(EJ),...o.map(l=>Bt(l.id,l.title,l.status,l.detail,l.remedy))].slice(0,pJ);return{checked_at:new Date().toISOString(),connector_version:String(n).slice(0,50),status:mJ(c),checks:c}}function w_(e){let t=[`Connector self-check: ${e.status} (${e.connector_version})`];for(let n of e.checks)t.push(`- ${n.title}: ${n.status} - ${n.detail}`),n.remedy&&t.push(` ${n.remedy}`);return t.join(`
968
- `)}async function QO(e,t,n){return!e?.connector_id||!e.token?null:await n(e,{type:hJ,...t})??{}}function gJ(e){let t=Number.parseInt(String(e).replace(/^v/,""),10);return Number.isFinite(t)&&t>=g_?Bt("node_runtime","Node runtime","ok",`Node ${e}.`):Bt("node_runtime","Node runtime","failed",`Node ${e} is older than the Node ${g_} this connector requires.`,`Install Node ${g_} or later, then start the connector again.`)}function wJ(e){return e?.connector_id&&e.token?Bt("pairing","Workspace pairing","ok",`Paired as ${e.name||e.connector_id} for ${e.workspace}.`):Bt("pairing","Workspace pairing","failed","This workspace holds no connector credential.","Create a pairing command in EngineerOS and run it in this folder.")}async function yJ(e,t){if(!e?.server_url)return Bt("backend","EngineerOS backend","failed","No EngineerOS address is configured.","Pair this workspace with --url pointing at the EngineerOS backend.");let n=k0(e.server_url),r;try{r=await t(n,{signal:AbortSignal.timeout(1e4)})}catch(s){return Bt("backend","EngineerOS backend","failed",`${n} is unreachable from this machine: ${y_(s)}`,"Check the address, the network between this machine and EngineerOS, and that the backend is running.")}if(!r.ok)return Bt("backend","EngineerOS backend","failed",`${n} answered ${r.status}.`,"Check that the address points at the EngineerOS backend rather than another service.");let o=await r.json().then(s=>s?.status).catch(()=>{});return o&&o!=="healthy"?Bt("backend","EngineerOS backend","warning",`${n} reports itself as ${o}.`,"Open Admin > System in EngineerOS for the failing dependency."):Bt("backend","EngineerOS backend","ok",`${n} is reachable.`)}async function _J(e,t,n,r){try{let o=await n(e,t),s=`${o.name} ${o.version} through ${o.protocol}.`,i=String(o.version??"").match(/\d+\.\d+\.\d+/)?.[0],a=i?await vJ(o.protocol,r):null;return a&&fo(a,i)>0?Bt("coding_agent","Coding agent","warning",`${s} ${o.name} ${a} is available.`,YO[o.protocol].remedy):Bt("coding_agent","Coding agent","ok",s)}catch(o){return Bt("coding_agent","Coding agent","failed",y_(o),null)}}async function vJ(e,t){let n=YO[e];if(!n)return null;let r=KO.get(t)??new Map;KO.set(t,r);let o=r.get(e);if(o&&Date.now()-o.at<fJ)return o.version;let s=null;try{let i=await t(n.url,{headers:{accept:"application/json"},signal:AbortSignal.timeout(5e3)}),a=i.ok?n.version(await i.json()):null;fn(a)&&(s=a)}catch{}return r.set(e,{at:Date.now(),version:s}),s}function bJ({state:e,detail:t,remedy:n=null}){return Bt("agent_session","Coding agent session",e==="ready"?"ok":e==="checking"?"warning":"failed",t,n)}async function kJ(e){let n=(await e()).filter(r=>r.status==="blocked");if(n.length){let r=n[0];return Bt("local_execution","Local testing work","failed",`${n.length} local testing job(s) are blocked. ${r.blocked_report?.error?.message||r.error||r.checkpoint?.error||"An execution or report was refused; its original evidence remains saved on this machine."}`,"Inspect the saved connector job and its first blocked report on this machine. Fix the reported cause, then explicitly retry report delivery; do not rerun completed tests or delete their evidence.")}return Bt("local_execution","Local testing work","ok","No local testing jobs are blocked.")}async function SJ(e,t){let n=await t(e);if(n?.error)return Bt("tool_registry","Tool registry","warning",n.error,"Run `engineeros-connector tools list` in this workspace for the full registry state.");let r=n?.entries?.length||0;return Bt("tool_registry","Tool registry","ok",`${r} provider(s) registered.`)}async function xJ(e,t,{platform:n=process.platform,serviceStatus:r=OR}={}){if(n==="darwin"){let i=await r(e),a=`Run engineeros-connector runner start --workspace "${e}".`;if(i.disabled)return Bt("goal_runner","Goal runner","warning","The macOS Goal runner is disabled.",`Turn it on in System Settings > General > Login Items. ${a}`);if(!i.loaded)return Bt("goal_runner","Goal runner","warning",i.installed?"The macOS Goal runner is not loaded in this login session.":"The macOS Goal runner is not installed.",a);if(i.lastExitCode&&i.state!=="running")return Bt("goal_runner","Goal runner","warning",`The macOS Goal runner exited with status ${i.lastExitCode} (${i.state||"unknown state"}).`,`Read .engineeros/runner/launchd.log. For protected folders, allow node under Privacy & Security > Files and Folders, or move the workspace. ${a}`)}let{jobs:o}=await t(e),s=o.filter(i=>["failed","recovering"].includes(i.status));if(s.length){let i=s[0];return Bt("goal_runner","Goal runner","warning",`${s.length} local Goal job(s) need attention. ${i.runId} is ${i.status}${i.error?`: ${i.error}`:"."}`,"Open the Goal in EngineerOS, or read .engineeros/runs/<run-id>/activity.log in this workspace.")}return Bt("goal_runner","Goal runner","ok",`${o.length} local Goal job(s) recorded, none stuck.`)}function EJ(e){return Bt(e.id,e.title,e.status,`Failing since ${qr(e.firstFailedAt)} after ${e.failures} attempt(s); retrying in ${Math.round(e.retryInMs/1e3)}s. ${e.message}`,e.remedy)}async function Zl(e,t,n){try{return await n()}catch(r){return Bt(e,t,"failed",y_(r),null)}}function Bt(e,t,n,r,o=null){return{id:e,title:t,status:n,detail:String(r||"No detail was reported.").slice(0,uJ),remedy:o?String(o).slice(0,dJ):null}}function y_(e){return(e instanceof Error?e.message:String(e??"")).trim()||"No detail was reported."}N();import DJ from"node:path";N();import $J from"node:path";var tC=2,AJ=300*1e3,TJ={pytest:40,"node:test":40,vitest:60,jest:60},RJ=3,OJ=new Set(["pytest","vitest","jest","node:test","go-test","junit"]),CJ=new Set(["pytest-asyncio","pytest-cov","hypothesis","schemathesis","locust","bandit","pip-audit","@testing-library/react","@axe-core/playwright","k6","testify"]),eC=new Map([["@playwright/test","It drives a browser against the running app. Add an environment, then schedule it."],["cypress","It drives a browser against the running app. Add an environment, then schedule it."]]);function Rf(e,t=process.env){return e?.quality_baseline===!1?!1:!["off","0","false","no"].includes(String(t.ENGINEEROS_QUALITY_BASELINE??"").trim().toLowerCase())}function nC(e=process.env){let t=Number(e.ENGINEEROS_BASELINE_IDLE_MS);return Number.isFinite(t)&&t>0?Math.floor(t):600*1e3}function IJ(e){let t=String(e?.name??"");return CJ.has(t)?{support:"helper"}:OJ.has(t)?{support:"run"}:eC.has(t)?{support:"skipped",reason:eC.get(t)}:{support:"unsupported",reason:`There is no baseline recipe for ${t||"this runner"}. Schedule its command and upload the JUnit report instead.`}}var __=e=>String(e??"").replace(/\\/g,"/").replace(/^\.\//,"").replace(/\/+$/,""),jJ=(e,t)=>!t||e.startsWith(`${t}/`);function NJ(e,t){let n=null;for(let r of t)r.name!==e.framework||!jJ(e.file,r.root)||(!n||r.root.length>n.root.length)&&(n=r);return n}function MJ(e,{perShard:t,durations:n}){let r=e.map(c=>n[c]).filter(c=>Number.isFinite(c)&&c>0),o=[];if(!r.length){for(let c=0;c<e.length;c+=t)o.push(e.slice(c,c+t));return o}let s=r.reduce((c,l)=>c+l,0)/r.length,i=[],a=0;for(let c of e){let l=Number.isFinite(n[c])&&n[c]>0?n[c]:s;i.length&&a+l>AJ&&(o.push(i),i=[],a=0),i.push(c),a+=l}return i.length&&o.push(i),o}function rC({runners:e=[],testFiles:t=[],selection:n=null,durations:r={},workerLimit:o=1}={}){let s=n?.test_files?new Set(n.test_files.map(__)):null,i=[];for(let l of e){let u=IJ(l);u.support!=="helper"&&i.push({index:i.length,name:l.name,root:__(l.root),ecosystem:l.ecosystem??null,run_command:l.run_command??null,support:u.support,reason:u.reason??null,files:[],shards:[]})}for(let l of t.map(u=>({...u,file:__(u.file)})))s&&!s.has(l.file)||NJ(l,i.filter(u=>u.support==="run"))?.files.push(l.file);for(let l of i){if(l.files=[...new Set(l.files)].sort(),l.support!=="run")continue;if(!l.files.length){l.support="skipped",l.reason=s?"None of the selected test files belong to it.":"No test files were found for it.";continue}let u=PJ(l,r);l.shards=u.map(({files:p,packages:d},f)=>({id:`${l.index}-${f}`,index:f,total:u.length,files:p,directory:l.root,packages:d}))}let a=Number(o);return{concurrency:Math.max(1,Math.min(RJ,Number.isInteger(a)&&a>0?a:1)),runners:i.map(({files:l,...u})=>u)}}function PJ(e,t){if(e.name==="go-test"){let n=new Map;for(let r of e.files){let o=e.root?r.slice(e.root.length+1):r,s=$J.posix.dirname(o);n.set(s,[...n.get(s)??[],r])}return[...n.entries()].map(([r,o])=>({files:o,packages:[r==="."?".":r]}))}return e.name==="junit"?[{files:e.files,packages:[]}]:MJ(e.files,{perShard:TJ[e.name]??40,durations:t}).map(n=>({files:n,packages:[]}))}var LJ=2;function Of(e,t,n,{secretNames:r=[]}={}){let o=t.executionProfiles||{model_selection:!1,model_profiles:[],reasoning_efforts:[]},s=t.sessionStatus||{status:"unknown",message:"Agent authentication status was not reported.",login_command:null,logout_command:null},i=gx(t.protocol);return{agent_protocols:[t.protocol],coding_agent:!0,connector_jobs:!0,bug_hunt_development_v1:!0,...e.hunt_host?{hunt_host:!0}:{},capability_delivery:!e.hunt_host,measured_test_evidence:!e.hunt_host,test_automation_task:!e.hunt_host,test_checks:!e.hunt_host&&String(process.env.ENGINEEROS_TEST_CHECKS??"").trim().toLowerCase()!=="off",test_automation_workers:!e.hunt_host,model_probe:!0,test_schedules:!e.hunt_host,quality_baseline:!e.hunt_host&&Rf(e),quality_baseline_contract:tC,quality_map:!e.hunt_host,workspace_head:!e.hunt_host,bug_hunt:!0,bug_hunt_actions:[...cf],bug_hunt_electron:process.env.ENGINEEROS_HUNT_HOST==="dedicated",bug_hunt_webdriver:!0,bug_hunt_native:!0,bug_hunt_browser:Bi(n),bug_hunt_sign_in:!0,bug_hunt_inputs:1,bug_hunt_checks:[...Wy],bug_hunt_secret_names:[...r],resumable_runs:!e.hunt_host,goal_run_contract:LJ,delivery_tasks:{protocol_version:1,backend_contract:1,schema_revision:"20261027_000183",connector_version:"1.59.32",runtime:e.agent_id||t.protocol,runtime_version:t.version||null,adapter_version:"1",worker_version:Yp,operations:e.hunt_host?[]:["start","cancel"]},http_updates:!0,product_stage_handover:!e.hunt_host,local_design_context:!e.hunt_host,agent_warm:!e.hunt_host,test_environments:!0,integrations:!0,workspace_opportunities:!e.hunt_host,codex_cli:t.protocol==="codex",platform:process.platform,workspace_name:DJ.basename(e.workspace),agent_name:t.name,agent_version:t.version,...e.agent_id?{agent_id:e.agent_id}:{},...zp(e.worker_limit),agent_session:s,provider_login:{supported:i,mode:i?"connector_terminal":null},...SA(),...n?{tool_inventory:n}:{},execution_profiles:{...o,models:(o.model_profiles||[]).map(a=>a.id)}}}N();pn();Ei();import{createHash as sC}from"node:crypto";import{readFile as UJ}from"node:fs/promises";import FJ from"node:os";import b_ from"node:path";var zJ=/^[A-Z_][A-Z0-9_]*$/,BJ=80,GJ=64,oC="hunt-secret-";function eu(e){return typeof e=="string"&&e.length>0&&e.length<=BJ&&zJ.test(e)}function Cf(e){let t=`${oC}${String(e).toLowerCase().replace(/_/g,"-")}`;return t.length<=GJ?t:`${oC}h${sC("sha256").update(String(e)).digest("hex").slice(0,40)}`}function HJ(e){let t=sC("sha256").update(b_.resolve(e??process.cwd())).digest("hex").slice(0,16);return b_.join(FJ.homedir(),".engineeros","hunt-secrets",t)}function v_(e){if(!eu(e))throw new Error("A secret name uses capital letters, digits and underscores, for example ADMIN_TOTP_SECRET.");return e}function tu({workspace:e=process.cwd(),vault:t,directory:n}={}){let r=n??HJ(e),o=t??Kn({directory:r}),s=b_.join(r,"names.json");async function i(){let u;try{u=await UJ(s,"utf8")}catch(p){if(p?.code==="ENOENT")return[];throw p}try{let p=JSON.parse(u);return(Array.isArray(p?.names)?p.names:[]).filter(eu)}catch{return[]}}let a=Promise.resolve(),c=u=>{let p=a.then(async()=>{let d=new Set(await i());u(d),await Ne(s,`${JSON.stringify({names:[...d].sort()},null,2)}
968
+ `)}async function QO(e,t,n){return!e?.connector_id||!e.token?null:await n(e,{type:hJ,...t})??{}}function gJ(e){let t=Number.parseInt(String(e).replace(/^v/,""),10);return Number.isFinite(t)&&t>=g_?Bt("node_runtime","Node runtime","ok",`Node ${e}.`):Bt("node_runtime","Node runtime","failed",`Node ${e} is older than the Node ${g_} this connector requires.`,`Install Node ${g_} or later, then start the connector again.`)}function wJ(e){return e?.connector_id&&e.token?Bt("pairing","Workspace pairing","ok",`Paired as ${e.name||e.connector_id} for ${e.workspace}.`):Bt("pairing","Workspace pairing","failed","This workspace holds no connector credential.","Create a pairing command in EngineerOS and run it in this folder.")}async function yJ(e,t){if(!e?.server_url)return Bt("backend","EngineerOS backend","failed","No EngineerOS address is configured.","Pair this workspace with --url pointing at the EngineerOS backend.");let n=k0(e.server_url),r;try{r=await t(n,{signal:AbortSignal.timeout(1e4)})}catch(s){return Bt("backend","EngineerOS backend","failed",`${n} is unreachable from this machine: ${y_(s)}`,"Check the address, the network between this machine and EngineerOS, and that the backend is running.")}if(!r.ok)return Bt("backend","EngineerOS backend","failed",`${n} answered ${r.status}.`,"Check that the address points at the EngineerOS backend rather than another service.");let o=await r.json().then(s=>s?.status).catch(()=>{});return o&&o!=="healthy"?Bt("backend","EngineerOS backend","warning",`${n} reports itself as ${o}.`,"Open Admin > System in EngineerOS for the failing dependency."):Bt("backend","EngineerOS backend","ok",`${n} is reachable.`)}async function _J(e,t,n,r){try{let o=await n(e,t),s=`${o.name} ${o.version} through ${o.protocol}.`,i=String(o.version??"").match(/\d+\.\d+\.\d+/)?.[0],a=i?await vJ(o.protocol,r):null;return a&&fo(a,i)>0?Bt("coding_agent","Coding agent","warning",`${s} ${o.name} ${a} is available.`,YO[o.protocol].remedy):Bt("coding_agent","Coding agent","ok",s)}catch(o){return Bt("coding_agent","Coding agent","failed",y_(o),null)}}async function vJ(e,t){let n=YO[e];if(!n)return null;let r=KO.get(t)??new Map;KO.set(t,r);let o=r.get(e);if(o&&Date.now()-o.at<fJ)return o.version;let s=null;try{let i=await t(n.url,{headers:{accept:"application/json"},signal:AbortSignal.timeout(5e3)}),a=i.ok?n.version(await i.json()):null;fn(a)&&(s=a)}catch{}return r.set(e,{at:Date.now(),version:s}),s}function bJ({state:e,detail:t,remedy:n=null}){return Bt("agent_session","Coding agent session",e==="ready"?"ok":e==="checking"?"warning":"failed",t,n)}async function kJ(e){let n=(await e()).filter(r=>r.status==="blocked");if(n.length){let r=n[0];return Bt("local_execution","Local testing work","failed",`${n.length} local testing job(s) are blocked. ${r.blocked_report?.error?.message||r.error||r.checkpoint?.error||"An execution or report was refused; its original evidence remains saved on this machine."}`,"Inspect the saved connector job and its first blocked report on this machine. Fix the reported cause, then explicitly retry report delivery; do not rerun completed tests or delete their evidence.")}return Bt("local_execution","Local testing work","ok","No local testing jobs are blocked.")}async function SJ(e,t){let n=await t(e);if(n?.error)return Bt("tool_registry","Tool registry","warning",n.error,"Run `engineeros-connector tools list` in this workspace for the full registry state.");let r=n?.entries?.length||0;return Bt("tool_registry","Tool registry","ok",`${r} provider(s) registered.`)}async function xJ(e,t,{platform:n=process.platform,serviceStatus:r=OR}={}){if(n==="darwin"){let i=await r(e),a=`Run engineeros-connector runner start --workspace "${e}".`;if(i.disabled)return Bt("goal_runner","Goal runner","warning","The macOS Goal runner is disabled.",`Turn it on in System Settings > General > Login Items. ${a}`);if(!i.loaded)return Bt("goal_runner","Goal runner","warning",i.installed?"The macOS Goal runner is not loaded in this login session.":"The macOS Goal runner is not installed.",a);if(i.lastExitCode&&i.state!=="running")return Bt("goal_runner","Goal runner","warning",`The macOS Goal runner exited with status ${i.lastExitCode} (${i.state||"unknown state"}).`,`Read .engineeros/runner/launchd.log. For protected folders, allow node under Privacy & Security > Files and Folders, or move the workspace. ${a}`)}let{jobs:o}=await t(e),s=o.filter(i=>["failed","recovering"].includes(i.status));if(s.length){let i=s[0];return Bt("goal_runner","Goal runner","warning",`${s.length} local Goal job(s) need attention. ${i.runId} is ${i.status}${i.error?`: ${i.error}`:"."}`,"Open the Goal in EngineerOS, or read .engineeros/runs/<run-id>/activity.log in this workspace.")}return Bt("goal_runner","Goal runner","ok",`${o.length} local Goal job(s) recorded, none stuck.`)}function EJ(e){return Bt(e.id,e.title,e.status,`Failing since ${qr(e.firstFailedAt)} after ${e.failures} attempt(s); retrying in ${Math.round(e.retryInMs/1e3)}s. ${e.message}`,e.remedy)}async function Zl(e,t,n){try{return await n()}catch(r){return Bt(e,t,"failed",y_(r),null)}}function Bt(e,t,n,r,o=null){return{id:e,title:t,status:n,detail:String(r||"No detail was reported.").slice(0,uJ),remedy:o?String(o).slice(0,dJ):null}}function y_(e){return(e instanceof Error?e.message:String(e??"")).trim()||"No detail was reported."}N();import DJ from"node:path";N();import $J from"node:path";var tC=2,AJ=300*1e3,TJ={pytest:40,"node:test":40,vitest:60,jest:60},RJ=3,OJ=new Set(["pytest","vitest","jest","node:test","go-test","junit"]),CJ=new Set(["pytest-asyncio","pytest-cov","hypothesis","schemathesis","locust","bandit","pip-audit","@testing-library/react","@axe-core/playwright","k6","testify"]),eC=new Map([["@playwright/test","It drives a browser against the running app. Add an environment, then schedule it."],["cypress","It drives a browser against the running app. Add an environment, then schedule it."]]);function Rf(e,t=process.env){return e?.quality_baseline===!1?!1:!["off","0","false","no"].includes(String(t.ENGINEEROS_QUALITY_BASELINE??"").trim().toLowerCase())}function nC(e=process.env){let t=Number(e.ENGINEEROS_BASELINE_IDLE_MS);return Number.isFinite(t)&&t>0?Math.floor(t):600*1e3}function IJ(e){let t=String(e?.name??"");return CJ.has(t)?{support:"helper"}:OJ.has(t)?{support:"run"}:eC.has(t)?{support:"skipped",reason:eC.get(t)}:{support:"unsupported",reason:`There is no baseline recipe for ${t||"this runner"}. Schedule its command and upload the JUnit report instead.`}}var __=e=>String(e??"").replace(/\\/g,"/").replace(/^\.\//,"").replace(/\/+$/,""),jJ=(e,t)=>!t||e.startsWith(`${t}/`);function NJ(e,t){let n=null;for(let r of t)r.name!==e.framework||!jJ(e.file,r.root)||(!n||r.root.length>n.root.length)&&(n=r);return n}function MJ(e,{perShard:t,durations:n}){let r=e.map(c=>n[c]).filter(c=>Number.isFinite(c)&&c>0),o=[];if(!r.length){for(let c=0;c<e.length;c+=t)o.push(e.slice(c,c+t));return o}let s=r.reduce((c,l)=>c+l,0)/r.length,i=[],a=0;for(let c of e){let l=Number.isFinite(n[c])&&n[c]>0?n[c]:s;i.length&&a+l>AJ&&(o.push(i),i=[],a=0),i.push(c),a+=l}return i.length&&o.push(i),o}function rC({runners:e=[],testFiles:t=[],selection:n=null,durations:r={},workerLimit:o=1}={}){let s=n?.test_files?new Set(n.test_files.map(__)):null,i=[];for(let l of e){let u=IJ(l);u.support!=="helper"&&i.push({index:i.length,name:l.name,root:__(l.root),ecosystem:l.ecosystem??null,run_command:l.run_command??null,support:u.support,reason:u.reason??null,files:[],shards:[]})}for(let l of t.map(u=>({...u,file:__(u.file)})))s&&!s.has(l.file)||NJ(l,i.filter(u=>u.support==="run"))?.files.push(l.file);for(let l of i){if(l.files=[...new Set(l.files)].sort(),l.support!=="run")continue;if(!l.files.length){l.support="skipped",l.reason=s?"None of the selected test files belong to it.":"No test files were found for it.";continue}let u=PJ(l,r);l.shards=u.map(({files:p,packages:d},f)=>({id:`${l.index}-${f}`,index:f,total:u.length,files:p,directory:l.root,packages:d}))}let a=Number(o);return{concurrency:Math.max(1,Math.min(RJ,Number.isInteger(a)&&a>0?a:1)),runners:i.map(({files:l,...u})=>u)}}function PJ(e,t){if(e.name==="go-test"){let n=new Map;for(let r of e.files){let o=e.root?r.slice(e.root.length+1):r,s=$J.posix.dirname(o);n.set(s,[...n.get(s)??[],r])}return[...n.entries()].map(([r,o])=>({files:o,packages:[r==="."?".":r]}))}return e.name==="junit"?[{files:e.files,packages:[]}]:MJ(e.files,{perShard:TJ[e.name]??40,durations:t}).map(n=>({files:n,packages:[]}))}var LJ=2;function Of(e,t,n,{secretNames:r=[]}={}){let o=t.executionProfiles||{model_selection:!1,model_profiles:[],reasoning_efforts:[]},s=t.sessionStatus||{status:"unknown",message:"Agent authentication status was not reported.",login_command:null,logout_command:null},i=gx(t.protocol);return{agent_protocols:[t.protocol],coding_agent:!0,connector_jobs:!0,bug_hunt_development_v1:!0,...e.hunt_host?{hunt_host:!0}:{},capability_delivery:!e.hunt_host,measured_test_evidence:!e.hunt_host,test_automation_task:!e.hunt_host,test_checks:!e.hunt_host&&String(process.env.ENGINEEROS_TEST_CHECKS??"").trim().toLowerCase()!=="off",test_automation_workers:!e.hunt_host,model_probe:!0,test_schedules:!e.hunt_host,quality_baseline:!e.hunt_host&&Rf(e),quality_baseline_contract:tC,quality_map:!e.hunt_host,workspace_head:!e.hunt_host,bug_hunt:!0,bug_hunt_actions:[...cf],bug_hunt_electron:process.env.ENGINEEROS_HUNT_HOST==="dedicated",bug_hunt_webdriver:!0,bug_hunt_native:!0,bug_hunt_browser:Bi(n),bug_hunt_sign_in:!0,bug_hunt_inputs:1,bug_hunt_checks:[...Wy],bug_hunt_secret_names:[...r],resumable_runs:!e.hunt_host,goal_run_contract:LJ,delivery_tasks:{protocol_version:1,backend_contract:1,schema_revision:"20261027_000183",connector_version:"1.59.33",runtime:e.agent_id||t.protocol,runtime_version:t.version||null,adapter_version:"1",worker_version:Yp,operations:e.hunt_host?[]:["start","cancel"]},http_updates:!0,product_stage_handover:!e.hunt_host,local_design_context:!e.hunt_host,agent_warm:!e.hunt_host,test_environments:!0,integrations:!0,workspace_opportunities:!e.hunt_host,codex_cli:t.protocol==="codex",platform:process.platform,workspace_name:DJ.basename(e.workspace),agent_name:t.name,agent_version:t.version,...e.agent_id?{agent_id:e.agent_id}:{},...zp(e.worker_limit),agent_session:s,provider_login:{supported:i,mode:i?"connector_terminal":null},...SA(),...n?{tool_inventory:n}:{},execution_profiles:{...o,models:(o.model_profiles||[]).map(a=>a.id)}}}N();pn();Ei();import{createHash as sC}from"node:crypto";import{readFile as UJ}from"node:fs/promises";import FJ from"node:os";import b_ from"node:path";var zJ=/^[A-Z_][A-Z0-9_]*$/,BJ=80,GJ=64,oC="hunt-secret-";function eu(e){return typeof e=="string"&&e.length>0&&e.length<=BJ&&zJ.test(e)}function Cf(e){let t=`${oC}${String(e).toLowerCase().replace(/_/g,"-")}`;return t.length<=GJ?t:`${oC}h${sC("sha256").update(String(e)).digest("hex").slice(0,40)}`}function HJ(e){let t=sC("sha256").update(b_.resolve(e??process.cwd())).digest("hex").slice(0,16);return b_.join(FJ.homedir(),".engineeros","hunt-secrets",t)}function v_(e){if(!eu(e))throw new Error("A secret name uses capital letters, digits and underscores, for example ADMIN_TOTP_SECRET.");return e}function tu({workspace:e=process.cwd(),vault:t,directory:n}={}){let r=n??HJ(e),o=t??Kn({directory:r}),s=b_.join(r,"names.json");async function i(){let u;try{u=await UJ(s,"utf8")}catch(p){if(p?.code==="ENOENT")return[];throw p}try{let p=JSON.parse(u);return(Array.isArray(p?.names)?p.names:[]).filter(eu)}catch{return[]}}let a=Promise.resolve(),c=u=>{let p=a.then(async()=>{let d=new Set(await i());u(d),await Ne(s,`${JSON.stringify({names:[...d].sort()},null,2)}
969
969
  `)});return a=p.catch(()=>{}),p},l={directory:r,async get(u){v_(u);let p=await o.get(e,Cf(u));return typeof p=="string"&&p!==""?p:null},async set(u,p){if(v_(u),typeof p!="string"||p==="")throw new Error("A secret needs a value.");await o.put(e,Cf(u),p),await c(d=>d.add(u))},async remove(u){v_(u),await o.delete(e,Cf(u)),await c(p=>p.delete(u))},async names(){return(await i()).sort()},async has(u){return eu(u)?!!await o.has(e,Cf(u)):!1},async values(u){let p={};for(let d of[...new Set(u??[])]){if(!eu(d))continue;let f=await l.get(d);f!==null&&(p[d]=f)}return p}};return l}async function iC({input:e=process.stdin,output:t=process.stderr,label:n="Value"}={}){if(!e.isTTY){let r=[];for await(let o of e)r.push(Buffer.from(o));return Buffer.concat(r).toString("utf8")}return t.write(`${n} (typing is hidden): `),await new Promise((r,o)=>{let s="";e.setRawMode?.(!0),e.resume(),e.setEncoding("utf8");let i=c=>{e.setRawMode?.(!1),e.pause(),e.off("data",a),t.write(`
970
970
  `),c?o(c):r(s)},a=c=>{for(let l of c){if(l==="\r"||l===`
971
971
  `||l==="")return i();if(l==="")return i(new Error("Cancelled."));l==="\x7F"||l==="\b"?s=s.slice(0,-1):s+=l}};e.on("data",a)})}var Ql=(e,t)=>(t?.(e),{ok:!1,message:e});async function aC({action:e,name:t,workspace:n=process.cwd(),readValue:r,vault:o,directory:s,write:i}={}){let a=(l,u)=>(i?.(u),{ok:l,message:u});if(e!=="set"&&e!=="list"&&e!=="remove")return Ql("Use `secret set NAME`, `secret list` or `secret remove NAME`.",i);let c=tu({workspace:n,vault:o,directory:s});try{if(e==="list"){let p=await c.names();return a(!0,p.length?p.join(`
@@ -1202,7 +1202,7 @@ It is checked with the provider and stored in this machine's protected vault
1202
1202
  (Windows Data Protection, the macOS Keychain or the Linux Secret Service).
1203
1203
  EngineerOS never receives it; the running connector uses it when EngineerOS asks.`;function qne(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(`
1204
1204
  `),c?o(c):r(s.trim())},a=c=>{for(let l of c){if(l==="\r"||l===`
1205
- `)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 HN=Symbol("missing");function Wne(e,t){return new Promise(n=>{let r=Gne(e,t,{stdio:"inherit",shell:!1});r.once("error",o=>n(o?.code==="ENOENT"?HN:o.message)),r.once("close",o=>n(o===0?null:`${e} exited with code ${o}.`))})}function GN(e,t){for(let n of ku){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 qN(e,t,n,{vault:r=jv(),run:o=bh,fetchImpl:s=fetch,secret:i=qne,interactive:a=Wne,install:c=wh,log:l=console.log,error:u=console.error}={}){if(n.help||e!=="integrations"&&!t[0])return l(Hne),n.help?0:2;if(e==="integrations")return GN(l,(await xh({run:o,vault:r})).providers),0;let p=t[0];if(!ku.includes(p))return u(`Unknown provider ${p}. Choose one of: ${ku.join(", ")}.`),2;if(p==="github"||p==="gitlab"){let f=Wi[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 h=await a(f,["auth","login"]);if(h===HN){let m=await oi(f);if(!m){l(`Installing the ${mu[f].label} ${mu[f].version} for the connector...`);try{m=(await c(f)).path}catch(g){return u(g.message),1}}h=await a(m,["auth","login"])}return h?(u(`${h} ${Sh[p]} is how this machine signs in to ${p}.`),1):(GN(l,{[p]:(await xh({run:o,vault:r})).providers[p]}),0)}let d=Hn[p];if(e==="disconnect")return await r.delete("",p),l(`Removed the ${d.label} ${d.tokenName} from this machine.`),0;try{await Nv(r);let f=await i(`${d.label} ${d.tokenName} (create one at ${d.tokenUrl}): `),h=await Mv(r,p,{token:f,site:n.site,email:n.email},s);return l(`Connected ${d.label}${h.account?` as ${h.account}`:""}. The token stays on this machine.`),0}catch(f){return u(f.message),1}}N();import{spawn as Vne}from"node:child_process";async function WN({root:e,bundled:t,argv:n,workspace:r,spawnImpl:o=Vne,log:s=console.log}){let i=n,a=!1;for(;;){let c=t;try{c=As(await ar(e),t)}catch(p){s(`${p.message} Starting the installed connector ${t.version}.`)}let{code:l,signal:u}=await Xne(o,c.entry,i,t);if(l===Nc){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 p=await ar(e).catch(()=>null);if(p&&!p.confirmed&&p.active?.version===c.version)try{let d=await lm(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 ${d.version}.`);continue}catch(d){s(`Automatic rollback failed: ${d.message}`)}}return l??1}}function Xne(e,t,n,r){return new Promise((o,s)=>{let i=e(process.execPath,[...process.execArgv,t,...n],{stdio:"inherit",env:{...process.env,[na]:"1",[om]:r.entry,[sm]: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,p)=>{l(),o({code:u,signal:p})})})}var ui="1.59.32",Ch="1.59.32",Zne=3e5,Ih=["queued","running","reporting"],Qne=5e3,Pv={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."},Dv={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."},ere=6e4,tre=3e4,nre=60*6e4,Lv={id:"tool_inventory",title:"Tool inventory refresh",remedy:"Run `engineeros-connector tools list` in this workspace for the full registry state."},Uv={id:"runner_setup_reporting",title:"Goal runner setup reporting",remedy:"Restore the connection to EngineerOS; saved setup reports will retry automatically."},{command:Vt,positional:Yt,flags:Ze}=cC(process.argv.slice(2));Vt==="version"&&(console.log(ui),process.exit(0));var xs=null,an=!1,qn=null,Au=null,aM=!1,cM=null,tb=null,gn=null,Iu=null,Yv,VN,Tu,Fv,XN,fc,_c,lM=th({getWorkspace:()=>M.workspace,onRecorded:e=>wj(M,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}`))}),rre=zN({getWorkspace:()=>M.workspace,getConfig:()=>M,huntSignIns:lM}),Ru=pC();Vt==="results"&&(Yt[0]!=="upload"&&(console.log(Uf),process.exit(Ze.help||!Yt[0]?0:2)),process.exit(await vI(Ze)));(Vt==="connect"||Vt==="disconnect"||Vt==="integrations")&&process.exit(await qN(Vt,Yt,Ze,{fetchImpl:LN}));if(Vt==="delivery"){let e=In.resolve(Ze.workspace||process.cwd());try{if(Yt[0]==="execute")await BR(Ze.input);else if(Yt[0]==="worker"){let t=await Tn(e);if(!t)throw new Error("Restore the paired connector configuration before reporting or executing delivery work.");await yR(t,Ze["attempt-id"])}else if(Yt[0]==="probe"){let t=await Zp().probe();console.log(JSON.stringify(t))}else throw new Error("Use delivery worker --attempt-id <attempt>, delivery execute --input <file> inside the qualified image, or delivery probe.");process.exit(0)}catch(t){console.error(Ln(t)),process.exit(1)}}if(Vt==="runner"){let e=In.resolve(Ze.workspace||process.cwd()),t=Yt[0]||"status";try{if(t==="serve"||t==="worker"){let n=t==="worker"?In.join(In.dirname(tn(e,Ze["run-id"])),"worker.log"):In.join(e,".engineeros","runner","service.log");Kne(In.dirname(n),{recursive:!0});let r=(...s)=>Il(n,`${Yne(...s)}
1205
+ `)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 HN=Symbol("missing");function Wne(e,t){return new Promise(n=>{let r=Gne(e,t,{stdio:"inherit",shell:!1});r.once("error",o=>n(o?.code==="ENOENT"?HN:o.message)),r.once("close",o=>n(o===0?null:`${e} exited with code ${o}.`))})}function GN(e,t){for(let n of ku){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 qN(e,t,n,{vault:r=jv(),run:o=bh,fetchImpl:s=fetch,secret:i=qne,interactive:a=Wne,install:c=wh,log:l=console.log,error:u=console.error}={}){if(n.help||e!=="integrations"&&!t[0])return l(Hne),n.help?0:2;if(e==="integrations")return GN(l,(await xh({run:o,vault:r})).providers),0;let p=t[0];if(!ku.includes(p))return u(`Unknown provider ${p}. Choose one of: ${ku.join(", ")}.`),2;if(p==="github"||p==="gitlab"){let f=Wi[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 h=await a(f,["auth","login"]);if(h===HN){let m=await oi(f);if(!m){l(`Installing the ${mu[f].label} ${mu[f].version} for the connector...`);try{m=(await c(f)).path}catch(g){return u(g.message),1}}h=await a(m,["auth","login"])}return h?(u(`${h} ${Sh[p]} is how this machine signs in to ${p}.`),1):(GN(l,{[p]:(await xh({run:o,vault:r})).providers[p]}),0)}let d=Hn[p];if(e==="disconnect")return await r.delete("",p),l(`Removed the ${d.label} ${d.tokenName} from this machine.`),0;try{await Nv(r);let f=await i(`${d.label} ${d.tokenName} (create one at ${d.tokenUrl}): `),h=await Mv(r,p,{token:f,site:n.site,email:n.email},s);return l(`Connected ${d.label}${h.account?` as ${h.account}`:""}. The token stays on this machine.`),0}catch(f){return u(f.message),1}}N();import{spawn as Vne}from"node:child_process";async function WN({root:e,bundled:t,argv:n,workspace:r,spawnImpl:o=Vne,log:s=console.log}){let i=n,a=!1;for(;;){let c=t;try{c=As(await ar(e),t)}catch(p){s(`${p.message} Starting the installed connector ${t.version}.`)}let{code:l,signal:u}=await Xne(o,c.entry,i,t);if(l===Nc){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 p=await ar(e).catch(()=>null);if(p&&!p.confirmed&&p.active?.version===c.version)try{let d=await lm(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 ${d.version}.`);continue}catch(d){s(`Automatic rollback failed: ${d.message}`)}}return l??1}}function Xne(e,t,n,r){return new Promise((o,s)=>{let i=e(process.execPath,[...process.execArgv,t,...n],{stdio:"inherit",env:{...process.env,[na]:"1",[om]:r.entry,[sm]: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,p)=>{l(),o({code:u,signal:p})})})}var ui="1.59.33",Ch="1.59.33",Zne=3e5,Ih=["queued","running","reporting"],Qne=5e3,Pv={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."},Dv={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."},ere=6e4,tre=3e4,nre=60*6e4,Lv={id:"tool_inventory",title:"Tool inventory refresh",remedy:"Run `engineeros-connector tools list` in this workspace for the full registry state."},Uv={id:"runner_setup_reporting",title:"Goal runner setup reporting",remedy:"Restore the connection to EngineerOS; saved setup reports will retry automatically."},{command:Vt,positional:Yt,flags:Ze}=cC(process.argv.slice(2));Vt==="version"&&(console.log(ui),process.exit(0));var xs=null,an=!1,qn=null,Au=null,aM=!1,cM=null,tb=null,gn=null,Iu=null,Yv,VN,Tu,Fv,XN,fc,_c,lM=th({getWorkspace:()=>M.workspace,onRecorded:e=>wj(M,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}`))}),rre=zN({getWorkspace:()=>M.workspace,getConfig:()=>M,huntSignIns:lM}),Ru=pC();Vt==="results"&&(Yt[0]!=="upload"&&(console.log(Uf),process.exit(Ze.help||!Yt[0]?0:2)),process.exit(await vI(Ze)));(Vt==="connect"||Vt==="disconnect"||Vt==="integrations")&&process.exit(await qN(Vt,Yt,Ze,{fetchImpl:LN}));if(Vt==="delivery"){let e=In.resolve(Ze.workspace||process.cwd());try{if(Yt[0]==="execute")await BR(Ze.input);else if(Yt[0]==="worker"){let t=await Tn(e);if(!t)throw new Error("Restore the paired connector configuration before reporting or executing delivery work.");await yR(t,Ze["attempt-id"])}else if(Yt[0]==="probe"){let t=await Zp().probe();console.log(JSON.stringify(t))}else throw new Error("Use delivery worker --attempt-id <attempt>, delivery execute --input <file> inside the qualified image, or delivery probe.");process.exit(0)}catch(t){console.error(Ln(t)),process.exit(1)}}if(Vt==="runner"){let e=In.resolve(Ze.workspace||process.cwd()),t=Yt[0]||"status";try{if(t==="serve"||t==="worker"){let n=t==="worker"?In.join(In.dirname(tn(e,Ze["run-id"])),"worker.log"):In.join(e,".engineeros","runner","service.log");Kne(In.dirname(n),{recursive:!0});let r=(...s)=>Il(n,`${Yne(...s)}
1206
1206
  `),o=(s,i,a)=>(Il(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(Ze["keep-awake"]!==void 0){if(!["on","off"].includes(Ze["keep-awake"]))throw new Error("Use --keep-awake on or off.");let n=await Tn(e);if(!n)throw new Error("Pair this workspace before changing its runner keep-awake setting.");await Xr({...n,runner_keep_awake:Ze["keep-awake"]==="on"})}console.log(`Installed Goal runner service: ${await TR(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 CR(e),console.log("Goal runner service removed. Saved and queued jobs are kept.")):t==="start"?await Ui(e,{enable:!0}):t==="status"?console.log(JSON.stringify(await Bs(e),null,2)):t==="serve"?await MR(e):t==="worker"?await PR(e,Ze["run-id"]):Lt("Usage: engineeros-connector runner [install|start|status|uninstall] --workspace PATH [--keep-awake on|off]");process.exit(0)}catch(n){Lt(Fy(n,e).message)}}Ze["assessment-workers"]!==void 0&&Lt("--assessment-workers is no longer supported. Select 3 to 8 parallel agents in EngineerOS before starting the assessment.");if(Vt==="secret")try{let e=Hy(Ze),t=Yt[0]||"list",n=await aC({action:t,name:Yt[1],workspace:e,readValue:()=>iC({label:`Value for ${Yt[1]}`}),write:r=>console.log(r)});process.exit(n.ok?0:1)}catch(e){Lt(e.message)}if(Vt==="tools"){try{let e=Hy(Ze),t=Yt[0]||"list";if(["sign-in","auth-status","sign-out"].includes(t)){let r=Yt[1];r||Lt(`Usage: engineeros-connector tools ${t} PROVIDER_ID [--workspace PATH | --project PROJECT_UUID]`);let o=await hw(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 wl(e,{type:"tools.update",command_id:"00000000-0000-4000-8000-000000000002",action:t,provider_id:Yt[1],confirmed:!0},void 0,{confirmLocal:async()=>!0}):t!=="list"&&await dw(e,t,Yt[1]);let n=await Ur(e);console.log(JSON.stringify(n,null,2)),process.exitCode=n.error?1:0}catch(e){Lt(e.message)}process.exit(process.exitCode||0)}if(Vt==="agents"){let e;try{e=await Ow()}catch(n){Lt(n instanceof Error?n.message:String(n))}let t=await Promise.all(e.map(async n=>{try{return await _l(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(Vt==="agent"){let e=Yt[0],t=Yt[1]||"check";(!e||!["check","install"].includes(t))&&Lt("Usage: engineeros-connector agent AGENT_ID [check|install]");try{let n=t==="install"?await vl(e):await _l(e);console.log(`${n.name} is ready (${n.version}, ${n.distribution}).`)}catch(n){Lt(n instanceof Error?n.message:String(n))}process.exit(0)}if(Vt==="mcp"){let e=Ze.workspace||process.env.ENGINEEROS_MCP_WORKSPACE||process.cwd(),t=Ze["run-id"]||Yt[0]||process.env.ENGINEEROS_MCP_RUN_ID||null,n=await Tn(e);await OC({config:n,runId:t,version:ui,input:process.stdin,output:process.stdout}),process.exit(0)}if(Vt==="context-mcp"){let e=Ze["config-workspace"]||Ze.workspace||process.env.ENGINEEROS_MCP_WORKSPACE||process.cwd(),t=await Tn(e);t||Lt("This workspace is not paired with EngineerOS."),await uI({config:t,workspace:Ze.workspace||process.env.ENGINEEROS_CONTEXT_WORKSPACE||t.workspace,version:ui,input:process.stdin,output:process.stdout}),process.exit(0)}if(Vt==="status"){let e=await Tn(Ze.workspace||process.cwd());console.log(e?`Paired as ${e.name} (${e.connector_id}) for ${e.workspace}`:"Not paired"),process.exit(e?0:1)}if(Vt==="doctor"){let e=In.resolve(Ze.workspace||process.cwd()),t=await Tn(e),n=await SC(e),r=await Yi(t||{workspace:e},e,k_(n));console.log(w_(r)),process.exit(r.status==="failed"?1:0)}if(Vt==="update"){let e=Yt[0]||"status";try{let t=am(process.argv[1],Ch),n=await um(Ir(),t,{action:e,policy:Yt[1]??null});console.log(Pc(dm(n,t,{supervised:!0})))}catch(t){Lt(`${t.message}
1207
1207
  Usage: engineeros-connector update [status|check|apply|rollback|policy manual|approve|auto-patch|auto-minor]`)}process.exit(0)}var mc=Vt==="hunt-host";if(mc)try{Ze.workspace=qR(Yt,Ze)}catch(e){Lt(e.message)}if((Vt==="start"||Vt==="pair"||mc)&&process.env[na]!=="1"&&fn(Ch))try{process.exit(await WN({root:Ir(),bundled:{version:Ch,entry:In.resolve(process.argv[1])},argv:process.argv.slice(2),workspace:In.resolve(Ze.workspace||process.cwd())}))}catch(e){Lt(`The connector process could not be started: ${e.message}`)}if(mc){try{await WR(Ze.workspace,Yt[0]?Ze.agent:null)}catch(e){Lt(e.message)}Vt=Yt[0]?"pair":"start"}var M,Ki,Ou;if(Vt==="pair"){let e=Yt[0];e||Lt("Usage: engineeros-connector pair CODE --url URL [--agent AGENT_ID | --agent-protocol forge] [--name NAME] [--workspace PATH] [--skip-git-repo-check]");let t=Ze.url;t||Lt("Pairing requires --url with the EngineerOS backend address."),Ze.agent&&Ze["agent-command"]&&Lt("Use either --agent or --agent-command, not both.");let n=Ze["agent-protocol"]||(Ze["agent-command"]?"acp":"codex");["codex","acp","forge"].includes(n)||Lt(`Unknown --agent-protocol '${n}'. Use codex, acp, or forge.`),n==="forge"&&(Ze.agent||Ze["agent-command"])&&Lt("Forge runs its own agents. Drop --agent and --agent-command when pairing with --agent-protocol forge.");let r={};try{Ze.agent&&(await _l(Ze.agent),r=await Cw(Ze.agent))}catch(o){Lt(o instanceof Error?o.message:String(o))}M={server_url:hm(t),workspace:In.resolve(Ze.workspace||process.cwd()),onboard:Ze.onboard===!0,onboarding_pending:Ze.onboard===!0,hunt_host:mc,agent_protocol:n,agent_command:Ze["agent-command"]||null,agent_args:Tre(Ze["agent-args"]),agent_name:Ze["agent-name"]||null,...r,skip_git_repo_check:mc||Ze["skip-git-repo-check"]===!0,name:Ze.name||`${Jne.hostname()} - ${In.basename(In.resolve(Ze.workspace||process.cwd()))}`},Ou=await Tn(M.workspace),Ki={type:"pair",pairing_code:e,name:M.name,capabilities:{},...h0(Ou,M.server_url)}}else Vt==="start"?(M=await Tn(Ze.workspace||process.cwd()),M||Lt("This connector is not paired. Create a pairing command in EngineerOS first."),mc&&!M.hunt_host&&Lt("This folder is not a paired hunt host. Generate a new hunt-host command in EngineerOS."),M.token||Lt("This connector's token is no longer in this machine's credential store. Create a new pairing command in EngineerOS and pair again."),Ki={type:"authenticate",connector_id:M.connector_id,token:M.token}):Lt("Use `engineeros-connector pair`, `start`, `status`, `doctor`, `agents`, `agent`, `tools`, `secret`, or `mcp`.");var uM=DR(M,{reportError:e=>console.error(e)}),li=0,jh=!1,vc=null,fr=new Map,zv=0,Bv=new Set,gc=[],tr=new Map,mn,Zv,Ah,Vo=null,Th=!1,dM=0,Gv=null,Hv=[],Rh,pM,xu=1e3,wc,JN=0,qv=!1,Wo=!1,co,ai=!1,Nh=!1,Qv=0;function si(e){return Qv+=1,e.finally(()=>{Qv-=1})}var hc,Xi=0;function bc({exitCode:e=0}={}){if(Xi=Math.max(Xi,e),hc)return hc;let t=setTimeout(()=>{console.error("Connector shutdown exceeded 15 seconds; inspect the retained agent logs before restarting."),process.exit(1)},15e3);return t.unref(),hc=ore().finally(()=>clearTimeout(t)),hc}async function ore(){if(an=!0,Iu?.stop(),xs?.stop(),tb?.stop(),cM?.stop(),clearInterval(Yv),gn?.stop(),pM?.(),clearTimeout(Rh),clearInterval(Zv),clearInterval(Ah),await Promise.all([...[...fr.values()].map(e=>ur(e.child))]),await Promise.all([...tr.values()].map(ob)),await fc?.cancelAll(),await Tu?.stop(),await _c?.abortAll(),await yl(),await fb().catch(e=>{Xi=Math.max(Xi,1),console.error(`${e.message}. Stop those processes before restarting the connector.`)}),mn?.close(),Xi&&Xi!==Nc){let e;await Promise.race([(async()=>{await xs?.drain(),await Yi(M,M.workspace)})().catch(()=>{}),new Promise(t=>{e=setTimeout(t,1e4)})]).finally(()=>clearTimeout(e))}process.exit(Xi)}for(let e of["SIGINT","SIGTERM","SIGHUP"])process.on(e,()=>{bc()});var KN=!1;for(let e of["uncaughtException","unhandledRejection"])process.on(e,async t=>{KN||(KN=!0,console.error(`Connector stopping after an unhandled failure: ${t instanceof Error?t.stack||t.message:String(t)}`),await bc({exitCode:1}))});gn=_b();process.on("exit",()=>{Iu?.stop(),gn.stop()});gn.banner(`EngineerOS connector ${ui}`,[M.workspace,M.server_url]);xs=dC({actions:{refresh_tool_inventory:async()=>{ct.tool_inventory=await Ur(M.workspace),Ar()},restart_goal_runner:()=>Ui(M.workspace)},onNotify:()=>Yi(M,M.workspace),explain:async e=>{if(!await ks())return null;let{reading:t}=await P1(M,e);return t},onUpdate:e=>kC(M.workspace,e)});cM=EC({render:(e,t)=>gn.write(e,t),onRecord:e=>xs.observe(e)});tb=$C({workspace:M.workspace,onRecord:e=>{xs.observe(e),gn.line(e.channel,e.level,e.message)}});xs.start();M.hunt_host||tb.start();gn.live&&!M.hunt_host&&(Yv=setInterval(()=>{sre().catch(()=>{})},Qne),Yv.unref?.());var Wv=new Set;async function sre(){if(M.hunt_host)return;VN??=Dy(M.workspace);let{jobs:e}=await VN(),t=new Set,n=e.filter(r=>r.status!=="queued"&&Ih.includes(r.status)).length;for(let r of e){if(!Ih.includes(r.status))continue;t.add(r.runId),Wv.add(r.runId);let o=r.status==="queued"&&n>0?`queued behind running Goals (running: ${n})`:r.activity?.phase||r.status;gn.status(`goal:${r.runId}`,r.activity?.message||o,ire(r),{agent:r.status!=="queued",link:vc&&`${vc}/goals`,phase:o}),gn.step(`goal:${r.runId}`,r.activity?.message)}for(let r of Wv)t.has(r)||(Wv.delete(r),gn.clearStatus(`goal:${r}`))}function ire(e){let t=e.startedAt??Date.parse(e.updatedAt??"");return Number.isFinite(t)?t:Date.now()}async function ks({ignoreBugHunt:e=!1}={}){if(an||fr.size>0||tr.size>0||li>0||(fc?.active??0)>0||(Tu?.active??0)>0||!e&&(_c?.active??0)>0)return!1;try{let{jobs:t}=await Bs(M.workspace);return!an&&!t.some(n=>Ih.includes(n.status))}catch{return!1}}try{let e=M.hunt_host?{}:await ta(M.workspace);e.committed&&(M.onboarding_pending=!0,M.connector_id&&await Xr(M),console.log(`Local project repository ready at ${e.revision.slice(0,8)}. Source and design artifacts are committed locally.`))}catch(e){await _M(e)}var fM=await ar(Ir()).then(e=>e.policy!=="manual",()=>!1),Ct;try{Ct=await Ol(M,M.workspace)}catch(e){await _M(e)}console.log(`Using ${Ct.name} through ${Ct.protocol} (${Ct.version}).`);console.log(`System time: ${qr()} (${Intl.DateTimeFormat().resolvedOptions().timeZone}).`);var hM=async()=>tu({workspace:M.workspace}).names().catch(()=>[]),ct=Of(M,Ct,await Ur(M.workspace),{secretNames:await hM()}),Ss=e0({workspace:M.workspace,running:am(process.argv[1],Ch),supervised:process.env[na]==="1",isIdle:async()=>!an&&fr.size===0&&gc.length===0&&tr.size===0&&li===0&&Qv===0&&!ai&&!Nh&&(_c?.active??0)===0&&(Tu?.active??0)===0&&!Th,restart:()=>bc({exitCode:Nc}),onChange:e=>{ct.runtime_update=e,mn?.readyState===WebSocket.OPEN&&Ar()}});try{await Ss.refresh()}catch(e){console.error(`Connector updates are unavailable: ${e.message}`)}M={...M,execution_profiles:Ct.executionProfiles??null};Vt==="pair"&&Ou?.connector_id||await Xr(M);ct.agent_session={...ct.agent_session,status:"checking",message:`Checking that ${Ct.name} can answer.`};ct.bug_hunt_browser=!1;Ki.capabilities=ct;console.log(ls(M.worker_limit)===null?`Workers: automatic, ${Ma()} ${Ct.name} workers side by side for this machine's CPU and memory; change it with /workers.`:`Workers: ${ls(M.worker_limit)} ${Ct.name} workers side by side, set with /workers.`);var Cu=iu({getConfig:()=>M}),Ji=async e=>{let t;try{t=await ds(M,e)}catch(n){throw[401,403].includes(n.status)&&(Wo=!0,console.error("EngineerOS withdrew this connector's authorization. Local work is stopping; saved reports are retained."),bc()),n}return t?.execution_sync&&await are(t.execution_sync),t},YN=qp(Ji,{signature:W1}),Vv,Xv=!1,Su,$u=new Map,eb=new Set,Jv;function ci(){return Tu??=TI({getConfig:()=>M,jobStore:Cu,canRun:()=>ks()}),_c??=pN({getConfig:()=>({...M,tool_inventory:ct.tool_inventory}),jobStore:Cu,recordedSignIns:lM,isIdle:()=>ks({ignoreBugHunt:!0}),canRun:async e=>{if(!await ks({ignoreBugHunt:!0}))return!1;let t=e.assignment;return t.kind!=="production_check"&&qn?.state!=="ready"?!1:t.surface?.app_surface==="webdriver"||ct.bug_hunt_browser===!0},activity:{status:gn.status,step:rb,agents:gn.agents,finish:gn.finish}}),{scheduledTests:Tu,bugHunts:_c}}async function are(e){let t=ci(),n=[];for(let r of e.jobs??[])await Cu.get(r.kind,r.id)&&n.push(r);await Promise.all([t.bugHunts.sync(n),t.scheduledTests.sync(n)]);for(let r of e.assignments??[]){if(r.type==="bug_hunt.grant"&&!await t.bugHunts.stage(r))continue;let o=`${r.type}:${r.grant_id??r.session_id??r.run_id}`;eb.has(o)||$u.set(o,r)}mM()}function mM(){Jv||an||(Jv=(async()=>{let e=ci();for(;$u.size&&!an;){let[t,n]=$u.entries().next().value;$u.delete(t),eb.add(t);try{if(n.type==="bug_hunt.grant")await e.bugHunts.configure(n);else if(n.type===Hf)await e.scheduledTests.configure(n);else if(n.type===av)await e.bugHunts.handle(n);else if(n.type===Gf)await e.scheduledTests.handle(n);else throw new Error(`Unsupported cached work ${n.type}. Update the connector before accepting it.`)}catch(r){console.error(`Caching connector work: ${r.message}`)}finally{eb.delete(t)}}})().finally(()=>{Jv=null}))}async function gM(){if(!(!M.connector_id||!M.token||an))return Su||(Su=(async()=>{let e=ci();await Promise.all([e.bugHunts.start(),e.scheduledTests.start()]);let t=await Cu.list();for(let n of t)if(n.kind==="bug_hunt_grant"&&n.status==="provisioning"){let r=n.checkpoint?.pending_context??n.assignment;$u.set(`bug_hunt.grant:${n.id}`,r)}mM(),t.some(n=>["authorized","queued","running"].includes(n.status)&&Date.parse(n.execution_lease.expires_at)>Date.now())&&(bM(),Ph()),bre()})().catch(e=>{throw Su=null,e}),Su)}async function cre(){let e=await Bs(M.workspace).catch(()=>({service:null,jobs:[]}));return{version:ui,now:Date.now(),workspace:M.workspace,config_path:yr(M.workspace),config:M,agent:Ct,automatic_worker_limit:Ma(),worker_limit:ls(M.worker_limit),connection:{state:lre(),server_url:M.server_url,last_error:co||null},work:{assessments:[...fr.values()].map(t=>({stage:t.stage,phase:t.phase,message:t.lastMessage,started_at:t.startedAt,pid:t.child?.pid??null,agent:Ct.name})),prompts:[...tr.values()].map(t=>({id:String(t.runId).slice(0,8),purpose:t.purpose,phase:t.phase,message:t.lastMessage,started_at:t.startedAt,pid:t.child?.pid??null,agent:Ct.name})),integrations:li},runner:e,runtime_update:Ss.report(),health:xs?.health()??null,activity:Ru.snapshot()}}function lre(){return an||Wo?"stopped":mn?.readyState===WebSocket.OPEN?"connected":"connecting"}var ure={async cancelPrompt(e){let t=[...tr.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=>yM(e),setVerbose(e){return e===jh?`Detailed agent activity is already ${e?"on":"off"}.`:(nb(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"?(Ss.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 Ss.command(e),Pc(await Ss.refresh()))}};Iu=gC({ui:gn,snapshot:cre,actions:ure});Iu&&console.log(mC());await wM();var ZN=new Set;async function wM(){if(an||Wo)return;console.log(`Connecting ${M.name} to ${M.server_url}`),Wo=!1,co=void 0;let e=new WebSocket(M.server_url);mn=e;let t=vx(e,M.server_url,{onTimeout:r=>{mn===e&&(co=r,console.error(r),Kv())}});pM=t,e.addEventListener("open",()=>{if(mn!==e){e.close();return}try{if(hx(mn,e,Ki))return;throw new Error("The WebSocket was not open when authentication started.")}catch(r){co=Ln(r),console.error(`Could not authenticate the WebSocket connection: ${co}`);try{e.close()}catch{}Kv()}}),e.addEventListener("message",r=>{if(mn!==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: ${Ln(s)}`)})});let n=async r=>{if(r.type==="authenticated"&&r.connector?.capabilities?.http_updates!==!0){an=!0,Wo=!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=Ou?.connector_id===r.connector.id;if(M=m0(M,Ou,r.connector.id,r.token),await Xr(M),r.connector?.capabilities?.http_updates!==!0){an=!0,Wo=!0,console.error("Pairing saved. Update the EngineerOS backend for HTTP updates, then start this connector again."),e.close();return}Ki={type:"authenticate",connector_id:M.connector_id,token:M.token,capabilities:ct},console.log(s?`Reconnected existing workspace connector ${M.connector_id}; assessment history is preserved.`:`Paired. Connector ${M.connector_id} is online.`),nM(r);return}if(r.type==="authenticated"){t();let s=M.hunt_host?"Bug Hunter sessions":"EngineerOS runs";console.log(wc?`Reconnected after ${_t(Date.now()-wc)} offline; waiting for ${s}.`:`Connected and waiting for ${s}.`),wc=void 0,nM(r);return}if(r.type==="provider.login"||r.type==="provider.logout"){Nh||pre(r);return}if(r.type==="workspace.refresh"){yc();return}if(r.type==="workers.update"){try{console.log(`EngineerOS changed the workers. ${await yM(r.worker_limit??"auto")}`)}catch(s){console.error(`Workers were not changed: ${s.message}`)}return}if(r.type==="logging.update"){nb(r.activity_log_enabled===!0);return}if(r.type==="tools.update"){let s=r.provider_id==="playwright"&&["setup","upgrade","rollback"].includes(r.action);s&&(bs=!1,ct.bug_hunt_browser=!1,Ar());try{ct.tool_inventory=await wl(M.workspace,r,void 0,{confirmLocal:i=>Iu?.confirm(i)??!1,log:Oh}),s&&(bs=!0),ct.bug_hunt_browser=Bi(ct.tool_inventory)&&bs,e.send(JSON.stringify({type:"tools.updated",command_id:r.command_id,inventory:ct.tool_inventory})),Ar(),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 hw(M.workspace,r,{onStatus:async()=>{ct.tool_inventory=await Ur(M.workspace),Ar()}});ct.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:ct.tool_inventory})),Ar(),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"){fa(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===FN){si(rre(r).then(s=>(s.error&&console.error(`${r.provider} ${r.operation} failed: ${s.error}`),BN(M,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}`;py(gc,fr.get(s),r)==="deferred"&&console.log(`Assessment stage ${r.stage} is already running here; EngineerOS will be answered when it finishes.`),kc();return}if(r.type==="prompt.execute"){let s=tr.get(r.prompt_id);s?xM(r)>s.executionRevision&&await xre(s,r):SM(r);return}if(r.type==="prompt.cancel"){let s=tr.get(r.prompt_id);s&&await ob(s);return}if(r.type==="agent.warm"){wre(r);return}if(r.type==="run.available"){if(M.hunt_host){console.error("A hunt host cannot run Goals. Use Connect your code to pair a repository connector.");return}try{let s=await uM.dispatch(r);s.blocked?console.error(s.message):console.log(`Goal ${r.run_id} queued for the independent runner. Logs: ${In.join(M.workspace,".engineeros","runs",r.run_id,"activity.log")}`)}catch(s){console.error(`Goal dispatch failed: ${Ln(s)}`)}return}if(r.type==="delivery.task.start"||r.type==="delivery.task.cancel"){if(M.hunt_host)throw new Error("Pair a repository connector before dispatching delivery tasks.");await gR(M.workspace,M.connector_id,r),await Ui(M.workspace);return}if(r.type==="goal.cleanup"){try{await NR(M.workspace),await Ui(M.workspace)}catch(s){console.error(`Goal cleanup is pending: ${s.message}`)}return}if(r.type==="run.accepted"){Are(r);return}if(r.type==="run.cancelled"){await Py(M.workspace,r.run_id);return}if(r.type===yE){fc??=qg({getConfig:()=>M,onTestsCommitted:()=>yc()}),si(fc.handle(r));return}if(r.type===_E){fc??=qg({getConfig:()=>M,onTestsCommitted:()=>yc()}),await fc.cancel(r);return}if(r.type===av){si(ci().bugHunts.handle(r)).catch(s=>console.error(`Bug Hunter assignment: ${s.message}`));return}if(r.type==="bug_hunt.grant"){si(ci().bugHunts.configure(r)).catch(s=>console.error(`Bug Hunter settings: ${s.message}`));return}if(r.type===oN){_c?.stop(r);return}if(r.type===Gf){si(ci().scheduledTests.handle(r)).catch(s=>console.error(`Scheduled test assignment: ${s.message}`));return}if(r.type===Hf){si(ci().scheduledTests.configure(r)).catch(s=>console.error(`Scheduled test settings: ${s.message}`));return}if(r.type===jI){Fv??=BI({getConfig:()=>M}),si(Fv.handle(r));return}if(r.type===NI){await Fv?.cancel(r);return}if(r.type===HI){XN??=qI({getConfig:()=>M,isIdle:()=>ks(),agentTurn:a1}),si(XN.handle(r));return}if(r.type==="connector.update"){dre(e,r);return}if(r.type==="connector.disconnect"){console.log(r.message),await bc();return}if(r.type==="connector.revoked"){an=!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||(ai=!1);return}if(r.type==="connection.error"){Wo=!0,console.error(`EngineerOS: ${r.message}`);return}let o=String(r.type??"(missing)").replace(/[^a-zA-Z0-9_.-]/g,"_").slice(0,120);ZN.has(o)||(ZN.add(o),console.warn(`Unknown EngineerOS message type ${o}; connector ${ui}. Update the connector and backend to compatible versions.`))};e.addEventListener("close",r=>{if(t(),mn!==e||hc)return;let o=mx(r);if(!o.retry||Wo||an){console.error(o.message),o.retry&&Wo&&console.error("Connection rejected. Create a new pairing command in EngineerOS if this connector was revoked."),bc();return}co=co?`${o.message} ${co}`:o.message,Kv()}),e.addEventListener("error",r=>{mn===e&&(co=fx(r),console.error(`WebSocket connection to ${M.server_url} failed: ${co}`))})}async function dre(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=Ss.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 Ss.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 pre(e){let t=e.request_id,n=e.type==="provider.logout"?"logout":"login";Nh=!0,console.log(`Starting interactive ${Ct.name} provider ${n}.`);try{await(n==="logout"?_x:yx)(Ct,M.workspace),Ct=await Ol(M,M.workspace),qn=null,ct=Of(M,Ct,ct.tool_inventory,{secretNames:await hM()}),Ki.capabilities=ct,mn.readyState===WebSocket.OPEN&&(mn.send(JSON.stringify({type:`provider.${n}.completed`,request_id:t,session:ct.agent_session})),mn.close(1e3,`Provider ${n} completed`)),console.log(`${Ct.name} provider ${n} completed.`)}catch(r){let o=Ln(r).slice(0,500);mn.readyState===WebSocket.OPEN&&mn.send(JSON.stringify({type:`provider.${n}.failed`,request_id:t,message:o})),console.error(`Provider ${n} failed: ${o}`)}finally{Nh=!1}}function Kv(){if(an||Wo||Rh)return;let e=co?` Last error: ${co}`:"",t=wc?` Offline for ${_t(Date.now()-wc)}.`:"";wc??=Date.now(),console.error(`Connection unavailable.${e}${t} Retrying in ${Math.round(xu/1e3)}s.`),Rh=setTimeout(()=>{Rh=void 0,wM()},xu),xu=Math.min(3e4,xu*2)}async function yc(){if(!M.hunt_host&&!(ai||mn.readyState!==WebSocket.OPEN)){ai=!0,console.log("Inspecting the workspace without executing its code.");try{let e=await F1(M.workspace),t=await U1(M.workspace,M.last_head_reported??M.last_snapshot_head,e.head_revision).catch(()=>null);t&&(e.changed_since=t);let n=await fetch(cr(M.server_url,M.connector_id),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${M.token}`},body:JSON.stringify(e)});if(!n.ok)throw new Error(await ya(n,"the workspace"));let r=await n.json(),o=r.source_revision;M={...M,onboarding_pending:!1,last_snapshot_head:e.head_revision??M.last_snapshot_head,last_head_reported:e.head_revision??M.last_head_reported,last_head_branch:e.head_revision?e.branch??null:M.last_head_branch},await Xr(M),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.`);let{encoded:s,stats:i}=await R_({workspace:M.workspace,connectorId:M.connector_id,snapshot:e,refresh:ca,buildMap:(a,c)=>Pf(M.workspace,a,{head:c.head_revision,branch:c.branch}),log:a=>console.error(a)});if(s&&o){let a=await fetch(y0(M.server_url,M.connector_id),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${M.token}`},body:JSON.stringify({source_revision:o,quality_map_base64:s.base64})});a.ok?await Df(M.workspace,M.connector_id,s.map).catch(()=>{}):console.error(await ya(a,"the workspace quality map"))}i&&console.log(`Built the local context index: ${i.total_files.toLocaleString()} file(s) ready for assignment context.`),ai=!1}catch(e){ai=!1,console.error(`Workspace assessment failed: ${Ln(e)}`)}}}var fre=8e6,QN,eM="";async function hre({current:e,previous:t}){if(ai||mn?.readyState!==WebSocket.OPEN)throw new Error("A snapshot is running or the connection is down.");let n=In.resolve(M.workspace),r=async()=>{M={...M,last_head_reported:e.head,last_head_branch:e.branch??null},await Xr(M)},o=await T_(M.workspace,M.connector_id),s=async()=>{if(await yc(),M.last_head_reported!==e.head)throw new Error("The snapshot did not report this commit.")};if(!o)return s();let{index:i}=await ca(M.workspace,M.connector_id),a=null,c=await QC({previous:{head:t.head,branch:t.branch??null},current:e,compare:(d,f)=>_y(M.workspace,d,f),inventoryDelta:d=>Q0(n,Object.entries(i.files).map(([f,h])=>({path:f,size:h.size})),d),mapDelta:async()=>(a=await Pf(M.workspace,i,{head:e.head,branch:e.branch}),A_(o,a)),contentHead:(await Ed(n).catch(()=>null))?.content_head_revision??null});if(c.status==="snapshot")return s();if(c.status==="nothing")return r();let l=JSON.stringify(c.report);if(Buffer.byteLength(l)>fre)return s();let u=await fetch(_0(M.server_url,M.connector_id),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${M.token}`},body:l});if(!u.ok)throw new Error(await ya(u,"the new commit"));let p=await u.json().catch(()=>({}));if(p.needs_snapshot)return s();await r(),a&&await Df(M.workspace,M.connector_id,a).catch(()=>{}),console.log(`Reported ${c.report.reason==="branch_switch"?"the switch to ":"commit "}${e.head.slice(0,7)}${p.flagged_cases?`: ${p.flagged_cases} test case(s) to check again`:""}.`)}function mre(){M.hunt_host||M.onboarding_pending||ai||mn?.readyState!==WebSocket.OPEN||(QN??=ZC({readHead:()=>YC(M.workspace),getLastReported:()=>({head:M.last_head_reported??M.last_snapshot_head,branch:M.last_head_branch}),onChange:hre,onError:e=>{e.message!==eM&&(eM=e.message,console.error(`The new commit could not be reported yet: ${Ln(e)}`))}}),QN.poll().catch(()=>{}))}var gre=6e4,tM=0;async function wre(e){if(M.hunt_host)return;let t=typeof e.session_key=="string"?e.session_key.trim():"",n=t?M.sessions?.[t]:void 0,r=[];Date.now()-tM>gre&&(tM=Date.now(),r.push(ca(M.workspace,M.connector_id).catch(o=>console.error(`Context index refresh ahead of a conversation failed: ${o.message}`)))),M.agent_protocol==="acp"&&r.push(oA(M.workspace,M,{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(`${Ct?.name||"The agent"} could not be started ahead of the conversation: ${o.message}`))),await Promise.all(r)}function Ar(){an||!M.connector_id||!M.token||(Xv=!0,!Vv&&(Vv=(async()=>{do Xv=!1,await yre();while(Xv&&!an)})().catch(e=>console.error(`Connector synchronization: ${e.message}`)).finally(()=>{Vv=null})))}async function yre(){let e=$1(fr),t=await Cu.snapshot();YN.update({type:"assessment.workers",assessment_workers:e,tool_inventory:ct.tool_inventory,runtime_update:ct.runtime_update,agent_session:ct.agent_session,bug_hunt_browser:ct.bug_hunt_browser,connector_jobs:t.jobs,...zp(M.worker_limit)}),await YN.flush()}async function yM(e){let t=ls(e);return t===ls(M.worker_limit)?t===null?"Workers are already automatic.":`Workers are already set to ${t}.`:(M={...M,worker_limit:t},await Xr(M),kc(),Ar(),t===null?`Workers are automatic again: up to ${Ma()} side by side for this machine's CPU and memory, for ${ru} (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: ${ru}. A Goal that uses your working folder still runs alone. Running work finishes; waiting work starts as workers free up.`)}function nb(e){if(e!==jh){if(jh=e,!e)for(let t of fr.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."),Ar()}}function rb(e,t,n=null){gn.step(e,t,n)&&jh&&console.log(`[${e}] ${n?`${n}: `:""}${t}`)}function _re(){clearInterval(Ah);let e=!1,t=()=>{e||fr.size>0||tr.size>0||(e=!0,Yi(M,M.workspace).finally(()=>{e=!1}))};t(),Ah=setInterval(t,Zne),Ah.unref?.()}async function Yi(e,t,n=xs?.healthChecks()??[]){let r=await ZO({config:e,workspace:t,version:ui,insights:[...n,...Au?[Au]:[]],agentSession:qn,probes:{inspectAgent:(o,s)=>an?Ct:Ol(o,s),inspectTools:o=>an?ct.tool_inventory:Ur(o),runnerStatus:Bs,connectorJobs:()=>iu({getConfig:()=>e}).list()}});try{aM=(await QO(e,r,ds))?.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 _M(e){if(an)return hc;let t=e instanceof Error?e.message:String(e),n=await Yi(M,M.workspace).catch(()=>null);n&&console.error(w_(n)),Lt(t)}function nM(e){nb(e.connector?.activity_log_enabled===!0),vc=e.project_url??null,xu=1e3,bM(),Ph(),Ss.confirm().catch(t=>console.error(`Connector update state: ${t.message}`)),gM().catch(t=>console.error(`Saved connector work: ${t.message}`)),M.onboarding_pending&&yc()}var Eu=null,bs=!1,vM=0,vre=Date.now();async function bM(){return Eu||(Eu=(async()=>{fM&&await U$(M.workspace,{log:t=>console.log(`[tools] ${t}`)}).catch(t=>console.error(`[tools] Tool updates were skipped: ${t.message}`));let e=Date.now();try{Oh("Preparing Bug Hunter's browser: Playwright, then a check that a browser starts. The first setup can take a few minutes."),await VR(M.workspace,{log:Oh}),bs=!0,Au=null,ct.tool_inventory=await Ur(M.workspace),ct.bug_hunt_browser=Bi(ct.tool_inventory)&&bs,Oh(`Bug Hunter's browser is ready (${_t(Date.now()-e)}).`)}catch(t){console.error(`[browser] Bug Hunter's browser setup failed after ${_t(Date.now()-e)}: ${t.message}`),ct.bug_hunt_browser=!1,Au={id:"hunt_browser",title:"Bug Hunter browser",status:"failed",detail:t.message,remedy:`Run engineeros-connector tools setup playwright --workspace "${M.workspace}", then restart this connector to retry browser setup.`},Yi(M,M.workspace).catch(()=>null)}Ar()})(),Eu)}function Oh(e){console.log(`[browser] ${e}`)}async function Ph(){if(!["checking","ready"].includes(qn?.state)){vM=Date.now(),ct.agent_session={...ct.agent_session,status:"checking",message:`Checking that ${Ct.name} can answer.`},Ar(),qn={state:"checking",detail:`Asking ${Ct.name} one question to confirm its session.`},console.log(`Checking that ${Ct.name} can answer before accepting work.`);try{await C1(M,Ct.name),qn={state:"ready",detail:`${Ct.name} answered; its session is usable.`},ct.agent_session={...ct.agent_session,status:"authenticated",message:qn.detail},console.log(qn.detail)}catch(e){qn={state:"failed",detail:e instanceof Error?e.message:String(e),remedy:M.hunt_host?JR(M.agent_id||M.agent_protocol):Oa(M.agent_id||M.agent_protocol)},ct.agent_session={...ct.agent_session,status:"logged_out",message:qn.remedy},console.error(`${qn.detail}
1208
1208
  ${qn.remedy}`)}Ar(),qn.state==="ready"&&(kc(),ci().bugHunts.wake().catch(e=>console.error(`Bug Hunter local scheduler: ${e.message}`))),await Yi(M,M.workspace).catch(()=>null)}}function bre(){clearInterval(Zv);let e=!1,t=0,n=0,r=!1,o=()=>{Ss.tick(),kre(),mre(),Eu&&(qn===null||M.hunt_host&&qn?.state==="failed"&&Date.now()-vM>=XR(vre))&&ks().then(s=>{if(s)return Ph()}),!M.hunt_host&&!r&&Yl(Uv.id)&&(r=!0,uM.flush().then(()=>$h(Uv)).catch(s=>Eh(Uv,s)).finally(()=>{r=!1})),Ar(),!M.hunt_host&&!Vo&&Date.now()-t>=ere&&Yl(Pv.id)&&(t=Date.now(),kM().then(()=>$h(Pv)).catch(s=>Eh(Pv,s))),!M.hunt_host&&aM&&!Th&&Yl(Dv.id)&&Date.now()-dM>=YE&&(Th=!0,Sre().then(()=>$h(Dv)).catch(s=>Eh(Dv,s)).finally(()=>{Th=!1})),!e&&Date.now()-n>=tre&&Yl(Lv.id)&&(e=!0,n=Date.now(),Ur(M.workspace).then(async s=>{if(ct.tool_inventory=s,!bs&&Bi(s))try{await(await yi(await Xs(M.workspace))).close(),bs=!0}catch{bs=!1}ct.bug_hunt_browser=Bi(s)&&bs,ct.bug_hunt_browser&&(Au=null),Ar(),$h(Lv)}).catch(s=>Eh(Lv,s)).finally(()=>{e=!1}))};o(),Zv=setInterval(o,1e4),_re()}async function kre(){if(!(!fM||M.agent_protocol!=="acp"||!M.agent_id||qv||qn?.state==="checking"||Date.now()-JN<nre)){qv=!0;try{if(!await ks())return;JN=Date.now();let e,t=await pA(M,{verify:async r=>{e=await Ol(r,M.workspace)},log:r=>console.log(`[agent] ${r}`)});if(t===M||an)return;M={...t,execution_profiles:e.executionProfiles??null},await Xr(M),Ct=e,qn=null;let n=Of(M,Ct,ct.tool_inventory);if(Object.assign(ct,{agent_name:n.agent_name,agent_version:n.agent_version,execution_profiles:n.execution_profiles}),Ki.capabilities=ct,!await ks())return;await yl(),Ph(),mn?.readyState===WebSocket.OPEN&&mn.close(1e3,"Coding agent updated")}catch(e){console.error(`[agent] The agent update check failed: ${e.message}`)}finally{qv=!1}}}function Eh(e,t){let n=WO(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 $h(e){VO(e.id)&&console.log(`${e.title} recovered.`)}async function Sre(){if(M.hunt_host||!await ks())return;dM=Date.now();let{jobs:e}=await Bs(M.workspace).catch(()=>({jobs:[]})),t=await ZE(M.workspace,{jobs:e});if(!QE(t))return;let n=`${t.fingerprint}:${Hv.join(",")}`,r=Gv?.key===n,o=r?Gv.candidates:await D1(M,t,Hv);Gv={key:n,candidates:o};let s=await Ji(n$(t,o,{version:ui}));Array.isArray(s?.refused)&&(Hv=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 ii=null,rM=null;async function kM(){if(!M.hunt_host){if(Vo)return Vo;Vo=(async()=>{let e=await GE(M,{knownRevision:ii?.revision??null});if(e.unchanged||(ii=e),rM===ii.revision)return ii;let{jobs:t}=await Bs(M.workspace);return!t.some(r=>Ih.includes(r.status))&&li===0&&fr.size===0&&(await sp(M.workspace,ii),rM=ii.revision),ii})();try{return await Vo}finally{Vo=null,kc()}}}function oM(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)),tr.get(e)?.events.push(n)}var sM=null;function kc(){let e=mn.readyState===WebSocket.OPEN,t=fr.values().next().value,n=ls(M.worker_limit)??Math.min(Ma(),fy(t?.workerLimit??gc[0]?.worker_limit)),r=e&&!Vo&&li===0?w1(gc,fr.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:fy(s.worker_limit),lastActivityAt:Date.now(),eventCount:0,lastDetail:null};fr.set(i,a),$re(s,a)}r.length>0&&Ar();let o=y1({queued:gc,running:fr.size,workerLimit:n,connected:e,designSync:!!Vo,integrations:li});o&&o!==sM&&console.log(o),sM=o}function Mh(e){let t=hy(e);return t?`${Ct.name} on ${t}`:Ct.name}async function SM(e){let t=e.prompt_id,n=`prompt:${String(t).slice(0,8)}`,r=e.purpose||"project",o=Date.now(),s=`${r} \xB7 ${Mh(e)}`,i=O1(e,Ct.name),a={runId:t,purpose:r,startedAt:o,child:null,controller:null,cancelled:!1,stoppedHere:!1,cancellation:new AbortController,events:K1(Ji),executionRevision:xM(e),sessionKey:Bp(e),sessionId:null,phase:"preparing",lastMessage:s,replacement:null};tr.set(t,a);let c=J1(Ji,{type:"prompt.heartbeat",prompt_id:t,execution_revision:a.executionRevision},{onError:g=>console.error(`[${n}] Prompt heartbeat: ${g.message}`)}),l,u=g=>{let y=g?JSON.stringify(g):null;!y||y===l||tr.get(t)!==a||(l=y,oM(t,g))},p=Number(e.answer_within_seconds),d=p>0?o+p*1e3:void 0;console.log([`[${n}] ${i} for ${r}.`,`${Ct.name} can reason for several minutes without reporting a step.`,...d?[Gh(d,o)]:[]].join(" ")),oM(t,{kind:"status",message:i}),gn.status(n,s,o,{link:vc,answerBy:d,phase:a.phase});let f=g=>{let y=h1(g),v=f1(g),_=Mi(g);tr.get(t)===a&&(v&&(a.phase=v),(_??y?.message)&&(a.lastMessage=_??y?.message),gn.status(n,a.lastMessage,o,{link:vc,answerBy:d,phase:a.phase}),rb(n,_??y?.message));let w=g.type==="forge.output"?null:_;u(y??(w?{kind:"status",message:w}:null))},h="failed",m=[r];try{Gp(e)||(f({type:"connector.step",message:"Syncing the design context from EngineerOS"}),e={...e,design_context:await XE(kM,{pinned:!!e.local_design_context,last:ii,onFallback:(_,w)=>f({type:"connector.step",message:`Design context not refreshed (${_.message}); continuing with ${w?"the copy synced earlier":"none"}`})})});let g=await s1(e,M,{onProcess:_=>{tr.get(t)===a&&(a.child=_)},onController:_=>{tr.get(t)===a&&(a.controller=_)},onSession:_=>{a.sessionId=_},onEvent:f},{signal:a.cancellation.signal});if(a.stoppedHere)throw new Error(iM);let y=g.singleTurn?g0(M.sessions,g.sessionKey):mm(M.sessions,g.sessionKey,g.sessionId);if(JSON.stringify(y)!==JSON.stringify(M.sessions||{})&&(M={...M,sessions:y},await Xr(M)),a.cancelled)return;await a.events.close().catch(_=>{console.error(`[${n}] Prompt progress delivery: ${_.message} The agent has finished; submitting its complete response separately.`)});let v=await Hp(Ji,{type:"prompt.completed",prompt_id:t,execution_revision:a.executionRevision,content:g.content,model:g.model,session_id:g.sessionId,usage:g.usage});v||console.error(`[${n}] ${ky}`),Ru.record("prompt","completed",{durationMs:Date.now()-o,usage:g.usage}),h=v?"finished":"undelivered",m=[Du(g.usage),r]}catch(g){let y=a.stoppedHere?iM:Ln(g);if(Ru.record("prompt","failed",{durationMs:Date.now()-o}),a.stoppedHere&&(h="cancelled"),!a.cancelled){try{await Hp(Ji,{type:"prompt.failed",prompt_id:t,execution_revision:a.executionRevision,message:y})||console.error(`[${n}] ${ky}`)}catch(v){console.error(`[${n}] Prompt failure delivery: ${v.message}`)}console.error(y)}}finally{await c.stop(),a.events.stop();let g=a.replacement;g?(h="replaced",m=[`continuing on ${Mh(g)}`,r]):a.cancelled&&(h="cancelled"),gn.finish(n,h,m),tr.get(t)===a&&tr.delete(t),g&&Ere(a,g)}}var iM="Cancelled from the connector terminal by the person running it.";async function ob(e){e.cancelled=!0,e.cancellation.abort(),await e.controller?.completed.catch(()=>{})}function xM(e){return Number(e.execution_revision)||1}async function xre(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 ${Mh(t)}.`),await ob(e))}function Ere(e,t){e.sessionId&&(M={...M,sessions:mm(M.sessions,e.sessionKey,e.sessionId)},Xr(M).catch(n=>console.error(`Could not save the agent session: ${n.message}`))),SM(t)}async function $re(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 ${Mh(e)}.`),!Bv.has(n)){Bv.add(n);try{let b=await u1(M.workspace);if(!b.exists)console.log("No accepted assessment exists yet; this run establishes the baseline.");else{let x=b.accepted_head_revision?b.current_head_revision?b.current_head_revision!==b.accepted_head_revision?`The workspace is now at commit \`${b.current_head_revision}\`; the accepted assessment is from \`${b.accepted_head_revision}\`.`:"The accepted assessment is already at the current commit.":`The accepted assessment is from \`${b.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 ${b.stages.length||"no"} section(s). ${x}`)}}catch(b){console.error(`Assessment freshness check failed: ${b.message}`)}}let o=t.startedAt,s=`assessment:${r}`,i=!1,a=!1,c=5,l=!1,u=!1,p=null,d=null,f=null,h=new Set,m=()=>!an&&fr.get(t.key)===t,g=async b=>{try{return await Hp(Ji,b)||console.warn(`[${s}] ${V1}`),!0}catch(x){return console.error(`Assessment failure delivery: ${x.message}`),!1}},y=(b,{milestone:x=!0}={})=>{if(!m()||x&&f===b)return;x&&(f=b,h.has(b)||(h.add(b),c=Math.min(90,c+10)),console.log(`[assessment:${r}] ${b}.`));let k=String(b).slice(0,500);t.progressPercent=c,t.lastMessage=k,gn.status(s,k,o,{link:vc,phase:t.phase})};y(`Starting ${r} assessment stage`);let v=setInterval(()=>{let b=Date.now(),x=b-t.lastActivityAt,k=i&&!a?p1(r,x):null;if(!p&&k){p=k,console.error(`[assessment:${r}] ${p}`),yy(t.controller,t.child);return}p||xs.observe({at:b,level:"info",message:gn.status(s,`${t.lastMessage} \xB7 last agent activity ${_t(x)} ago (${t.eventCount.toLocaleString()} events)`,o,{phase:t.phase})})},15e3),_={onSession:async b=>{m()&&(d=String(b),await cS(M.workspace,n,r,b,{sourceRevision:e.source_revision,targetHeadRevision:e.target_head_revision}))},onController:b=>{m()&&(t.controller=b)},onProcess:b=>{m()&&(t.child=b,i=!0,t.phase!=="correcting"&&(t.phase="running",y("Connected agent process started")),t.lastActivityAt=Date.now())},onEvent:b=>{t.lastActivityAt=Date.now(),t.eventCount+=1;let x=d1(b);if(x&&y(x),!m())return;let k=Mi(b);!k||k===t.lastDetail||(t.lastDetail=k,rb(s,k))}},w=(b,x)=>uy(b,x,M,_,{draftPath:In.relative(M.workspace,In.join(Mr(M.workspace,n),b.report_file)).split(In.sep).join("/")});try{let b=zv-Date.now();b>0&&(y(`Waiting ${Math.ceil(b/1e3)}s for the model provider's rate limit to clear`),await new Promise(C=>setTimeout(C,b+Math.floor(Math.random()*3e3)))),e.assessment_mode==="incremental"&&(c=15,y("Calculating changed files and affected behavior"));let x=await fS(M.workspace,e),k=await sg(M.workspace,n,r,{expectedHeadRevision:e.target_head_revision,expectedSourceRevision:e.source_revision});if(k)w(k,x),y("Recovered completed stage report from connector storage");else{if(d=await lS(M.workspace,n,r,{expectedHeadRevision:e.target_head_revision,expectedSourceRevision:e.source_revision}),d&&y("Restoring interrupted agent session"),k=await o1(x,M,_,{previousSessionId:d}),p)throw new Error(p);a=!0,await og(M.workspace,n,x,k)}a=!0,t.phase="delivering",t.progressPercent=95,t.lastMessage=r==="synthesis"?"Delivering completed assessment bundle":"Checkpointing connector-local stage result";let S=C=>fetch(b0(M.server_url,M.connector_id,n),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${M.token}`},body:JSON.stringify(C),signal:AbortSignal.timeout(GT)}),T=await R1(k,{submit:C=>T1(C,S,{isActive:()=>m()&&!an,onRetry:(I,j)=>{y("Completed result is waiting for EngineerOS",{milestone:!1}),console.warn(`[assessment:${r}] Completed result delivery failed: ${Ln(I)} Retrying in ${Math.round(j/1e3)}s without rerunning the agent.`)}}),payloadFor:C=>r==="synthesis"?ig(M.workspace,n,C,{expectedSourceRevision:e.source_revision}):wS(C),rejectionFor:C=>ya(C,"the assessment"),correct:async(C,I)=>{if(a=!1,t.phase="correcting",t.lastMessage="Correcting a rejected stage result",!C.correctAfterRejection)throw new Error(`${I} The connector could not start the required agent correction.`);return C.correctAfterRejection(I)},onCorrected:async C=>{if(p)throw new Error(p);a=!0,await dS(M.workspace,n,r);let I=await og(M.workspace,n,x,C);return w(I,x),t.phase="delivering",t.lastMessage="Delivering corrected stage result",I}});if(p)throw new Error(p);k=T.result;let R=T.response;if(!R.ok)throw new Error(await ya(R,"the assessment"));if(l=!0,Ru.record("assessment stage","completed",{durationMs:Date.now()-o,usage:k.usage}),r==="synthesis"){let C=await R.json(),I=await hS(M.workspace,n,e,k,C.report_markdown);console.log(`Workspace assessment ${n} was accepted by EngineerOS and saved to ${In.relative(M.workspace,I)}.`);try{let j=await zu(M.workspace);j.committed&&console.log(`Assessment committed to Git as ${j.revision.slice(0,8)}.`)}catch(j){console.error(`The assessment is saved locally but could not be committed to Git: ${j.message}`)}}else console.log(`Workspace assessment stage ${r} was checkpointed by EngineerOS.`)}catch(b){let x=p||Ln(b),k=k1(e,b),S=E1(b),$=v1(b);S&&(await uS(M.workspace,n,r).catch(R=>{console.error(`[assessment:${r}] Could not discard the unusable agent session checkpoint: ${R.message}`)}),d=null);let T=!p&&(d||S)&&(S||_1(b))&&k<$;if(m()&&T){t.phase="starting",t.lastMessage=S?"Agent session became unusable; restarting from saved assessment work":"Agent session interrupted; resuming checkpoint",t.resumeAssignment=S1(e,b);let R=x1(b,k);Cl(b)&&(zv=Math.max(zv,Date.now()+R)),console.warn(`[assessment:${r}] ${S?"Agent session became unusable":"Agent session interrupted"}: ${x} ${S?"Starting a fresh session from the saved draft":`Resuming session ${d}`} in ${Math.round(R/1e3)}s (${k+1}/${$}).`),await new Promise(C=>setTimeout(C,R))}else m()&&(u=await g({type:"workspace.assessment.failed",assessment_id:n,stage:r,message:x}));T||(Ru.record("assessment stage","failed",{durationMs:Date.now()-o}),console.error(`[assessment:${r}] ${x}`))}finally{clearInterval(v),gn.clearStatus(s),r==="synthesis"&&l&&Bv.delete(n),m()&&(fr.delete(t.key),A1(gc,t,{accepted:l,failureReported:u})&&console.log(`Resuming interrupted agent session for assessment stage ${r} from its checkpoint.`),kc())}}async function Are(e){let t=String(e.run_id||"");li+=1;try{Vo&&await Vo;let n=await KT(M.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 yc();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: ${Ln(n)}`)}finally{li-=1,kc()}}function Tre(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{Lt('--agent-args must be a JSON array, for example: --agent-args "[\\"acp\\"]"')}}function Lt(e){console.error(e),process.exit(1)}gM().catch(e=>console.error(`Saved connector work: ${e.message}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@engineeros/connector",
3
- "version": "1.59.32",
3
+ "version": "1.59.33",
4
4
  "description": "Connect a local coding agent to EngineerOS, using ACP when supported.",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",