@duckmind/dm-windows-x64 0.59.9 → 0.60.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/extensions/.dm-extensions.json +6 -6
- package/extensions/dm-cua/bin/browser-cua.mjs +4 -4
- package/extensions/dm-cua/index.js +3 -3
- package/extensions/dm-cua/src/browser-cua-lib.mjs +3 -3
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +5 -3
- package/extensions/greedysearch-dm/bin/mcp.mjs +52 -52
- package/extensions/greedysearch-dm/bin/search.mjs +130 -131
- package/extensions/greedysearch-dm/extractors/consensus.mjs +42 -43
- package/extensions/greedysearch-dm/extractors/gemini.mjs +52 -53
- package/extensions/greedysearch-dm/extractors/logically.mjs +33 -34
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +9 -10
- package/extensions/greedysearch-dm/src/search/chrome.mjs +21 -22
- package/extensions/greedysearch-dm/src/search/engines.mjs +7 -7
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +48 -48
- package/extensions/greedysearch-dm/src/search/paths.mjs +1 -1
- package/extensions/greedysearch-dm/src/search/research.mjs +119 -119
- package/extensions/greedysearch-dm/src/search/scale-aware.mjs +7 -7
- package/extensions/greedysearch-dm/src/search/simple-research.mjs +125 -125
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +11 -11
- package/package.json +1 -1
|
@@ -222,8 +222,8 @@
|
|
|
222
222
|
"src/tui/render.js"
|
|
223
223
|
],
|
|
224
224
|
"file_count": 93,
|
|
225
|
-
"before_bytes":
|
|
226
|
-
"after_bytes":
|
|
225
|
+
"before_bytes": 1545179,
|
|
226
|
+
"after_bytes": 3104611,
|
|
227
227
|
"externals": [
|
|
228
228
|
"@duckmind/dm-agent-core",
|
|
229
229
|
"@duckmind/dm-ai",
|
|
@@ -413,8 +413,8 @@
|
|
|
413
413
|
"src/utils/system-cmds.mjs"
|
|
414
414
|
],
|
|
415
415
|
"file_count": 62,
|
|
416
|
-
"before_bytes":
|
|
417
|
-
"after_bytes":
|
|
416
|
+
"before_bytes": 612563,
|
|
417
|
+
"after_bytes": 1185020,
|
|
418
418
|
"externals": [
|
|
419
419
|
"@duckmind/dm-agent-core",
|
|
420
420
|
"@duckmind/dm-ai",
|
|
@@ -640,8 +640,8 @@
|
|
|
640
640
|
"src/browser-install.mjs"
|
|
641
641
|
],
|
|
642
642
|
"file_count": 4,
|
|
643
|
-
"before_bytes":
|
|
644
|
-
"after_bytes":
|
|
643
|
+
"before_bytes": 35004,
|
|
644
|
+
"after_bytes": 58342,
|
|
645
645
|
"externals": [
|
|
646
646
|
"@duckmind/dm-agent-core",
|
|
647
647
|
"@duckmind/dm-ai",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{createHash as
|
|
3
|
-
${h.trim()}`:""}`})}),c.on("close",(i,l)=>{s({status:i===0?"ok":"failed",exitCode:i,message:h.trim()||(l?`installer terminated by signal ${l}`:"")})}),u=setTimeout(()=>{c.kill(),s({status:"timeout",exitCode:null,message:`installer timed out after ${t}ms`})},t)})}function so(o){if(o.startsWith("homebrew-"))return"Homebrew";if(o.startsWith("winget-"))return"winget";return o.split("-")[0]}function ao(o){let n=o.message?`: ${o.message}`:"";return`${o.id} ${o.status}${n}`}async function Q({env:o=process.env,platformName:n=D(),uid:m=typeof process.getuid==="function"?process.getuid():void 0,findExecutable:t=()=>v({env:o,platformName:n,homeDir:I()}),runCommand:d=(h,u)=>io(h,u,{env:o}),sleep:a=(h)=>new Promise((u)=>{setTimeout(u,h)})}={}){let h=t();if(h)return{status:"existing",path:h,method:null,attempts:[]};if(!no(o))throw Error("Chrome was not found and automatic installation is disabled by DM_CUA_AUTO_INSTALL.");let u=oo({platformName:n,uid:m});if(u.length===0)throw Error(`Chrome was not found and no automatic Chrome installer is defined for ${n}.`);let c=[];for(let i of u){let l={status:"ok",exitCode:0,message:""};for(let $ of i.commands)if(l=await d($.command,$.args),l.status!=="ok")break;if(l.status!=="ok"){c.push({id:i.id,status:l.status,exitCode:l.exitCode,message:l.message});continue}let w;for(let $=0;$<V;$+=1){if(w=t(),w)break;if($<V-1)await a(P)}if(w)return c.push({id:i.id,status:"installed",exitCode:l.exitCode,message:l.message}),{status:"installed",path:w,method:i.id,attempts:c};c.push({id:i.id,status:"missing-after-success",exitCode:l.exitCode,message:`${so(i.id)} reported success, but Chrome was not found`})}let s=c.map(ao).join("; ");throw Error(`Chrome automatic installation failed. ${s}`)}var g=O(Ao(import.meta.url)),Fo=C(g,".."),ro=9322,wo=400,X=60000,To=/^(about:|https?:\/\/|file:|chrome-error:\/\/)/i,eo={chrome:"Chrome",cloak:"CloakBrowser"};function q(o){let n=Number.parseInt(String(o??""),10);return Number.isInteger(n)&&n>1024&&n<65535?n:null}function Lo(o){return to("sha256").update(String(o||"default")).digest("hex")}function Co(o){let n=String(o||"chrome").trim().toLowerCase();if(n==="cloakbrowser"||n==="cloak-browser")return"cloak";if(n==="chromium"||n==="google-chrome"||n==="chrome")return"chrome";return n.replace(/[^a-z0-9_.-]/g,"-")||"chrome"}function Mo(o,n){let m=o.DM_CUA_BROWSER_PATH||(n==="cloak"?o.DM_CUA_CLOAK_PATH||o.CLOAKBROWSER_BINARY_PATH:void 0)||o.CHROME_PATH;return m?C(String(m)):void 0}function bo(o=process.env,n=process.cwd()){let m=o.DM_CUA_SCOPE||o.DM_CODING_AGENT_DIR||o.PI_CODING_AGENT_DIR||n,t=Lo(C(String(m||"."))),d=String(o.DM_CUA_INSTANCE_ID||t.slice(0,12)).replace(/[^a-zA-Z0-9_.-]/g,"-"),a=Co(o.DM_CUA_BROWSER||o.DM_BROWSER_CUA_BROWSER||o.DM_CUA_BROWSER_KIND),h=o.DM_CUA_BROWSER_DISPLAY_NAME||eo[a]||a,u=Mo(o,a),c=q(o.DM_CUA_PORT)??q(o.GREEDY_SEARCH_PORT)??ro+Number.parseInt(t.slice(0,8),16)%wo,s=a==="chrome"?"chrome":a,i=C(o.DM_CUA_PROFILE_DIR||r(Z(),`dm-cua-${s}-profile-${d}`)),l=fo()==="win32"?Z():"/tmp";return{instanceId:d,browserKind:a,browserDisplayName:h,browserExecutablePath:u,browserExecutableIsExplicit:Boolean(u),browserInstallation:void 0,port:c,profileDir:i,pidFile:r(i,"chrome.pid"),modeFile:r(i,"chrome-mode"),pagesCache:r(i,"cdp-pages.json"),socketDir:r(l,`dm-cua-cdp-${d}`)}}var A=bo(),yo=A.port,So=A.profileDir;function T(){return{kind:A.browserKind,displayName:A.browserDisplayName,executablePath:A.browserExecutablePath,installation:A.browserInstallation??null,profileDir:A.profileDir,port:A.port}}async function $o(o=A,{env:n=process.env,exists:m=_,ensureChrome:t=Q}={}){if(o.browserKind==="cloak"&&!o.browserExecutablePath)throw Error(["CloakBrowser selected for browser CUA, but no executable path was provided.","Install/pre-download CloakBrowser yourself, then set DM_CUA_BROWSER_PATH, DM_CUA_CLOAK_PATH, CLOAKBROWSER_BINARY_PATH, or CHROME_PATH.","DM does not bundle the compiled CloakBrowser binary because its upstream license allows use but not redistribution."].join(" "));if(o.browserExecutablePath&&!m(o.browserExecutablePath))throw Error(`${o.browserDisplayName} executable not found: ${o.browserExecutablePath}`);if(o.browserExecutablePath)return o;if(o.browserKind!=="chrome")throw Error(`${o.browserDisplayName} browser CUA requires an explicit executable path via DM_CUA_BROWSER_PATH.`);let d=await t({env:n});return o.browserExecutablePath=d.path,o.browserInstallation={status:d.status,method:d.method,attempts:d.attempts.map(({id:a,status:h,exitCode:u})=>({id:a,status:h,exitCode:u}))},o}var k;async function jo(){if(!k)k=$o(A).catch((o)=>{throw k=void 0,o});return k}function W(){let n=[C(g,"..","greedysearch-dm"),C(g,"..","..","greedysearch-dm")].map((m)=>({launchScript:r(m,"bin","launch.mjs"),cdpScript:r(m,"bin","cdp.mjs")}));for(let m of n)if(_(m.launchScript)&&_(m.cdpScript))return m;return n[0]}function _o(o=A,n=process.env){let m=n.GREEDY_SEARCH_VISIBLE??n.DM_CUA_VISIBLE??n.DM_BROWSER_CUA_VISIBLE;return{...n,...o.browserExecutablePath?{CHROME_PATH:o.browserExecutablePath}:{},CDP_PROFILE_DIR:o.profileDir.replace(/\\/g,"/"),CDP_PAGES_CACHE:o.pagesCache.replace(/\\/g,"/"),CDP_SOCKET_DIR:o.socketDir.replace(/\\/g,"/"),GREEDY_SEARCH_BROWSER_LABEL:o.browserDisplayName,GREEDY_SEARCH_PORT:String(o.port),GREEDY_SEARCH_PROFILE_DIR:o.profileDir.replace(/\\/g,"/"),GREEDY_SEARCH_PID_FILE:o.pidFile.replace(/\\/g,"/"),GREEDY_SEARCH_MODE_FILE:o.modeFile.replace(/\\/g,"/"),GREEDY_SEARCH_ALLOW_PORT_CLEANUP:n.GREEDY_SEARCH_ALLOW_PORT_CLEANUP??"0",...m===void 0?{}:{GREEDY_SEARCH_VISIBLE:m}}}function Y(){return _o(A,process.env)}function ko(o){return To.test(o)}function Uo(o){return o.split(/\r?\n/).map((n)=>n.trimEnd()).filter(Boolean).map((n)=>{let m=n.trim().split(/\s{2,}/).filter(Boolean);if(m.length===0)return null;let t=m[0];if(m.length===1)return{target:t,title:"",url:""};if(m.length===2&&ko(m[1]))return{target:t,title:"",url:m[1]};let d=m.at(-1)??"",a=m.slice(1,-1).join(" ");return{target:t,title:a,url:d}}).filter(Boolean)}function Do(){let o=process.env.DM_CODING_AGENT_DIR||process.env.PI_CODING_AGENT_DIR;return o?C(o):r(lo(),".dm","agent")}function go(){let o=r(Do(),"cua","screenshots");E(o,{recursive:!0});let n=new Date().toISOString().replace(/[:.]/g,"-");return r(o,`browser-${n}.png`)}function p(o,n,{env:m=process.env,timeoutMs:t=X}={}){return new Promise((d,a)=>{let h=ho("node",[o,...n],{env:m,stdio:["ignore","pipe","pipe"]}),u="",c="",s=!1,i=setTimeout(()=>{if(s)return;s=!0,h.kill("SIGTERM"),a(Error(`Timed out running ${o}`))},t);h.stdout.on("data",(l)=>{u+=l.toString()}),h.stderr.on("data",(l)=>{c+=l.toString()}),h.on("error",(l)=>{if(s)return;s=!0,clearTimeout(i),a(l)}),h.on("close",(l)=>{if(s)return;if(s=!0,clearTimeout(i),l!==0){a(Error((c||u||`exit ${l}`).trim()));return}d({stdout:u,stderr:c})})})}function Jo(o,n){return new Promise((m,t)=>{let d=co.request({host:"127.0.0.1",port:yo,path:n,method:o},(a)=>{let h="";a.on("data",(u)=>{h+=u.toString()}),a.on("end",()=>{if((a.statusCode??500)>=400){t(Error(`Browser CDP HTTP ${a.statusCode}: ${h.trim()}`));return}try{m(h?JSON.parse(h):{})}catch(u){t(u)}})});d.on("error",t),d.end()})}async function Xo(o="about:blank"){return Jo("PUT",`/json/new?${encodeURIComponent(o)}`)}async function e(o,n={}){let{cdpScript:m}=W();return p(m,o,{env:Y(),timeoutMs:n.timeoutMs??X})}async function J(){let o=await e(["list"]);return Uo(o.stdout)}function G(o,n){if(!n)return o[0]??null;let m=n.toUpperCase();return o.find((t)=>t.target.toUpperCase().startsWith(m))??null}async function K(){let{launchScript:o,cdpScript:n}=W();if(!_(o)||!_(n))throw Error("Bundled browser helpers are missing. Rebuild DM so dm-cua and greedysearch-dm are staged together.");return{launchScript:o,cdpScript:n}}async function N(){let{launchScript:o}=await K();await jo(),await p(o,[],{env:Y(),timeoutMs:X});let n=await J();if(n.length===0)await Xo("about:blank"),n=await J();return n}async function y(o){let n=await N(),m=G(n,o);if(!m){if(o)throw Error(`No browser tab matching prefix "${o}". Run browser_cua(list) first.`);throw Error("No browser tab available after browser bootstrap.")}return{tab:m.target,page:m,pages:n}}async function B({action:o,tab:n,url:m,selector:t,x:d,y:a,text:h,expression:u,outputPath:c}={}){switch(o){case"list":{let s=await N();return{status:"ok",action:o,browser:T(),pages:s}}case"navigate":{if(!m)throw Error("url is required for action=navigate");let s=await y(n),i=await e(["nav",s.tab,m],{timeoutMs:90000}),l=await J(),w=G(l,s.tab)??s.page;return{status:"ok",action:o,browser:T(),tab:s.tab,url:w?.url||m,title:w?.title||"",message:i.stdout.trim(),pages:l}}case"snapshot":{let s=await y(n),i=await e(["snap",s.tab]);return{status:"ok",action:o,browser:T(),tab:s.tab,title:s.page?.title||"",url:s.page?.url||"",snapshot:i.stdout.trim()}}case"screenshot":{let s=await y(n),i=c?C(c):go();E(O(i),{recursive:!0});let l=await e(["shot",s.tab,i],{timeoutMs:120000}),w=uo(i).toString("base64");return{status:"ok",action:o,browser:T(),tab:s.tab,title:s.page?.title||"",url:s.page?.url||"",imagePath:i,imageBase64:w,mimeType:"image/png",message:l.stdout.trim()}}case"click":{if(!t)throw Error("selector is required for action=click");let s=await y(n),i=await e(["click",s.tab,t]);return{status:"ok",action:o,browser:T(),tab:s.tab,selector:t,message:i.stdout.trim()}}case"click_xy":{if(typeof d!=="number"||Number.isNaN(d)||typeof a!=="number"||Number.isNaN(a))throw Error("x and y are required numbers for action=click_xy");let s=await y(n),i=await e(["clickxy",s.tab,String(d),String(a)]);return{status:"ok",action:o,browser:T(),tab:s.tab,x:d,y:a,message:i.stdout.trim()}}case"type":{if(h==null||h==="")throw Error("text is required for action=type");let s=await y(n),i=await e(["type",s.tab,h]);return{status:"ok",action:o,browser:T(),tab:s.tab,textLength:h.length,message:i.stdout.trim()}}case"evaluate":{if(!u)throw Error("expression is required for action=evaluate");let s=await y(n),i=await e(["eval",s.tab,u]);return{status:"ok",action:o,browser:T(),tab:s.tab,value:i.stdout.trim()}}case"stop":{let{launchScript:s}=await K();try{await e(["stop"])}catch{}let i=await p(s,["--kill"],{env:Y(),timeoutMs:30000});return{status:"ok",action:o,browser:T(),message:(i.stdout||"Stopped browser CUA lane.").trim()}}default:throw Error(`Unsupported browser action: ${o}`)}}function F(o){switch(o.action){case"list":{if(!Array.isArray(o.pages)||o.pages.length===0)return"Browser CUA is ready, but no pages are open.";return["Open browser tabs:",...o.pages.map((n)=>n.url?`${n.target} ${n.title||"(untitled)"} ${n.url}`:`${n.target} ${n.title||"(untitled)"}`)].join(`
|
|
2
|
+
import{createHash as ho}from"node:crypto";import{spawn as to}from"node:child_process";import{existsSync as _,mkdirSync as E,readFileSync as uo}from"node:fs";import co from"node:http";import{homedir as fo,platform as lo,tmpdir as Z}from"node:os";import{dirname as O,join as w,resolve as e}from"node:path";import{fileURLToPath as Ao}from"node:url";import{spawn as S}from"node:child_process";import{existsSync as x}from"node:fs";import{homedir as I,platform as D}from"node:os";import b from"node:path";var R=900000,z=16384,V=5,P=1000;function j(...o){return b.win32.join(...o)}function C(o,n){if(n&&!o.includes(n))o.push(n)}function U(o,n,m){let t=o.PATH??o.Path??o.path??"",d=n==="win32"?";":b.delimiter,a=n==="win32"?(o.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean):[""],h=[];for(let u of t.split(d).filter(Boolean))for(let f of m){if(n==="win32"&&b.win32.extname(f)){C(h,j(u,f));continue}for(let s of a){let i=n==="win32"?`${f}${s.toLowerCase()}`:f;C(h,n==="win32"?j(u,i):b.join(u,i))}}return h}function v({env:o=process.env,platformName:n=D(),homeDir:m=I(),exists:t=x}={}){let d=[];if(n==="win32"){for(let a of[o.LOCALAPPDATA,o.ProgramFiles,o["ProgramFiles(x86)"]]){if(!a)continue;C(d,j(a,"Google","Chrome","Application","chrome.exe")),C(d,j(a,"Chromium","Application","chrome.exe"))}C(d,m?j(m,"AppData","Local","Google","Chrome","Application","chrome.exe"):void 0),d.push(...U(o,n,["chrome","chromium"]))}else if(n==="darwin"){for(let a of["/Applications",b.join(m,"Applications")])C(d,b.join(a,"Google Chrome.app","Contents","MacOS","Google Chrome")),C(d,b.join(a,"Chromium.app","Contents","MacOS","Chromium"));d.push(...U(o,n,["google-chrome-stable","google-chrome","chromium","chromium-browser"]))}else if(n==="linux"){for(let a of["/usr/bin/google-chrome-stable","/usr/bin/google-chrome","/usr/bin/chromium","/usr/bin/chromium-browser","/snap/bin/chromium","/usr/local/bin/google-chrome","/usr/local/bin/chromium"])C(d,a);d.push(...U(o,n,["google-chrome-stable","google-chrome","chromium","chromium-browser"]))}return d.find((a)=>t(a))}function l(o,...n){return{command:o,args:n}}function M(o,n){if(n===0)return o;return o.map(({command:m,args:t})=>l("sudo","-n",m,...t))}function oo({platformName:o=D(),uid:n=typeof process.getuid==="function"?process.getuid():void 0}={}){if(o==="darwin")return[{id:"homebrew-google-chrome",commands:[l("brew","install","--cask","google-chrome")]}];if(o==="win32"){let m=["install","--id","Google.Chrome","-e","--silent","--accept-package-agreements","--accept-source-agreements","--disable-interactivity"];return[{id:"winget-user-google-chrome",commands:[l("winget",...m.slice(0,4),"--scope","user",...m.slice(4))]},{id:"winget-machine-google-chrome",commands:[l("winget",...m)]},{id:"chocolatey-google-chrome",commands:[l("choco","install","googlechrome","-y","--no-progress")]}]}if(o==="linux")return[{id:"apt-chromium",commands:M([l("apt-get","update"),l("apt-get","install","-y","chromium")],n)},{id:"apt-chromium-browser",commands:M([l("apt-get","update"),l("apt-get","install","-y","chromium-browser")],n)},{id:"dnf-chromium",commands:M([l("dnf","install","-y","chromium")],n)},{id:"yum-chromium",commands:M([l("yum","install","-y","chromium")],n)},{id:"pacman-chromium",commands:M([l("pacman","-S","--noconfirm","--needed","chromium")],n)},{id:"zypper-chromium",commands:M([l("zypper","--non-interactive","install","chromium")],n)},{id:"apk-chromium",commands:M([l("apk","add","chromium")],n)}];return[]}function no(o=process.env){let n=o.DM_CUA_AUTO_INSTALL;if(n===void 0)return!0;return!["0","false","no","off"].includes(n.trim().toLowerCase())}function mo(o){let n=Number(o.DM_CUA_INSTALL_TIMEOUT_MS);return Number.isFinite(n)&&n>0?n:R}function H(o,n){let m=`${o}${n}`;if(Buffer.byteLength(m)<=z)return m;return m.slice(-z)}function io(o,n,{env:m=process.env,timeoutMs:t=mo(m)}={}){return new Promise((d)=>{let a=!1,h="",u,f=S(o,n,{env:m,shell:!1,stdio:["ignore","pipe","pipe"],windowsHide:!0}),s=(i)=>{if(a)return;a=!0,clearTimeout(u),d(i)};f.stdout?.on("data",(i)=>{h=H(h,i.toString())}),f.stderr?.on("data",(i)=>{h=H(h,i.toString())}),f.on("error",(i)=>{s({status:i.code==="ENOENT"?"unavailable":"failed",exitCode:null,message:`${i.message}${h?`
|
|
3
|
+
${h.trim()}`:""}`})}),f.on("close",(i,c)=>{s({status:i===0?"ok":"failed",exitCode:i,message:h.trim()||(c?`installer terminated by signal ${c}`:"")})}),u=setTimeout(()=>{f.kill(),s({status:"timeout",exitCode:null,message:`installer timed out after ${t}ms`})},t)})}function so(o){if(o.startsWith("homebrew-"))return"Homebrew";if(o.startsWith("winget-"))return"winget";return o.split("-")[0]}function ao(o){let n=o.message?`: ${o.message}`:"";return`${o.id} ${o.status}${n}`}async function Q({env:o=process.env,platformName:n=D(),uid:m=typeof process.getuid==="function"?process.getuid():void 0,findExecutable:t=()=>v({env:o,platformName:n,homeDir:I()}),runCommand:d=(h,u)=>io(h,u,{env:o}),sleep:a=(h)=>new Promise((u)=>{setTimeout(u,h)})}={}){let h=t();if(h)return{status:"existing",path:h,method:null,attempts:[]};if(!no(o))throw Error("Chrome was not found and automatic installation is disabled by DM_CUA_AUTO_INSTALL.");let u=oo({platformName:n,uid:m});if(u.length===0)throw Error(`Chrome was not found and no automatic Chrome installer is defined for ${n}.`);let f=[];for(let i of u){let c={status:"ok",exitCode:0,message:""};for(let $ of i.commands)if(c=await d($.command,$.args),c.status!=="ok")break;if(c.status!=="ok"){f.push({id:i.id,status:c.status,exitCode:c.exitCode,message:c.message});continue}let r;for(let $=0;$<V;$+=1){if(r=t(),r)break;if($<V-1)await a(P)}if(r)return f.push({id:i.id,status:"installed",exitCode:c.exitCode,message:c.message}),{status:"installed",path:r,method:i.id,attempts:f};f.push({id:i.id,status:"missing-after-success",exitCode:c.exitCode,message:`${so(i.id)} reported success, but Chrome was not found`})}let s=f.map(ao).join("; ");throw Error(`Chrome automatic installation failed. ${s}`)}var g=O(Ao(import.meta.url)),So=e(g,".."),wo=9322,ro=400,X=60000,To=/^(about:|https?:\/\/|file:|chrome-error:\/\/)/i,Lo={chrome:"Chrome",cloak:"CloakBrowser"};function q(o){let n=Number.parseInt(String(o??""),10);return Number.isInteger(n)&&n>1024&&n<65535?n:null}function Co(o){return ho("sha256").update(String(o||"default")).digest("hex")}function eo(o){let n=String(o||"chrome").trim().toLowerCase();if(n==="cloakbrowser"||n==="cloak-browser")return"cloak";if(n==="chromium"||n==="google-chrome"||n==="chrome")return"chrome";return n.replace(/[^a-z0-9_.-]/g,"-")||"chrome"}function Mo(o,n){let m=o.DM_CUA_BROWSER_PATH||(n==="cloak"?o.DM_CUA_CLOAK_PATH||o.CLOAKBROWSER_BINARY_PATH:void 0)||o.CHROME_PATH;return m?e(String(m)):void 0}function bo(o=process.env,n=process.cwd()){let m=o.DM_CUA_SCOPE||o.DM_CODING_AGENT_DIR||o.PI_CODING_AGENT_DIR||n,t=Co(e(String(m||"."))),d=String(o.DM_CUA_INSTANCE_ID||t.slice(0,12)).replace(/[^a-zA-Z0-9_.-]/g,"-"),a=eo(o.DM_CUA_BROWSER||o.DM_BROWSER_CUA_BROWSER||o.DM_CUA_BROWSER_KIND),h=o.DM_CUA_BROWSER_DISPLAY_NAME||Lo[a]||a,u=Mo(o,a),f=q(o.DM_CUA_PORT)??q(o.GREEDY_SEARCH_PORT)??wo+Number.parseInt(t.slice(0,8),16)%ro,s=a==="chrome"?"chrome":a,i=e(o.DM_CUA_PROFILE_DIR||w(Z(),`dm-cua-${s}-profile-${d}`)),c=lo()==="win32"?Z():"/tmp";return{instanceId:d,browserKind:a,browserDisplayName:h,browserExecutablePath:u,browserExecutableIsExplicit:Boolean(u),browserInstallation:void 0,port:f,profileDir:i,pidFile:w(i,"chrome.pid"),modeFile:w(i,"chrome-mode"),pagesCache:w(i,"cdp-pages.json"),socketDir:w(c,`dm-cua-cdp-${d}`)}}var A=bo(),yo=A.port,xo=A.profileDir;function T(){return{kind:A.browserKind,displayName:A.browserDisplayName,executablePath:A.browserExecutablePath,installation:A.browserInstallation??null,profileDir:A.profileDir,port:A.port}}async function $o(o=A,{env:n=process.env,exists:m=_,ensureChrome:t=Q}={}){if(o.browserKind==="cloak"&&!o.browserExecutablePath)throw Error(["CloakBrowser selected for browser CUA, but no executable path was provided.","Install/pre-download CloakBrowser yourself, then set DM_CUA_BROWSER_PATH, DM_CUA_CLOAK_PATH, CLOAKBROWSER_BINARY_PATH, or CHROME_PATH.","DM does not bundle the compiled CloakBrowser binary because its upstream license allows use but not redistribution."].join(" "));if(o.browserExecutablePath&&!m(o.browserExecutablePath))throw Error(`${o.browserDisplayName} executable not found: ${o.browserExecutablePath}`);if(o.browserExecutablePath)return o;if(o.browserKind!=="chrome")throw Error(`${o.browserDisplayName} browser CUA requires an explicit executable path via DM_CUA_BROWSER_PATH.`);let d=await t({env:n});return o.browserExecutablePath=d.path,o.browserInstallation={status:d.status,method:d.method,attempts:d.attempts.map(({id:a,status:h,exitCode:u})=>({id:a,status:h,exitCode:u}))},o}var k;async function jo(){if(!k)k=$o(A).catch((o)=>{throw k=void 0,o});return k}function W(){let n=[e(g,"..","greedysearch-dm"),e(g,"..","..","greedysearch-dm")].map((m)=>({launchScript:w(m,"bin","launch.mjs"),cdpScript:w(m,"bin","cdp.mjs")}));for(let m of n)if(_(m.launchScript)&&_(m.cdpScript))return m;return n[0]}function _o(o=A,n=process.env){let m=n.GREEDY_SEARCH_VISIBLE??n.DM_CUA_VISIBLE??n.DM_BROWSER_CUA_VISIBLE;return{...n,...o.browserExecutablePath?{CHROME_PATH:o.browserExecutablePath}:{},CDP_PROFILE_DIR:o.profileDir.replace(/\\/g,"/"),CDP_PAGES_CACHE:o.pagesCache.replace(/\\/g,"/"),CDP_SOCKET_DIR:o.socketDir.replace(/\\/g,"/"),GREEDY_SEARCH_BROWSER_LABEL:o.browserDisplayName,GREEDY_SEARCH_PORT:String(o.port),GREEDY_SEARCH_PROFILE_DIR:o.profileDir.replace(/\\/g,"/"),GREEDY_SEARCH_PID_FILE:o.pidFile.replace(/\\/g,"/"),GREEDY_SEARCH_MODE_FILE:o.modeFile.replace(/\\/g,"/"),GREEDY_SEARCH_ALLOW_PORT_CLEANUP:n.GREEDY_SEARCH_ALLOW_PORT_CLEANUP??"0",...m===void 0?{}:{GREEDY_SEARCH_VISIBLE:m}}}function Y(){return _o(A,process.env)}function ko(o){return To.test(o)}function Uo(o){return o.split(/\r?\n/).map((n)=>n.trimEnd()).filter(Boolean).map((n)=>{let m=n.trim().split(/\s{2,}/).filter(Boolean);if(m.length===0)return null;let t=m[0];if(m.length===1)return{target:t,title:"",url:""};if(m.length===2&&ko(m[1]))return{target:t,title:"",url:m[1]};let d=m.at(-1)??"",a=m.slice(1,-1).join(" ");return{target:t,title:a,url:d}}).filter(Boolean)}function Do(o){let n=String(o??"").trim();if(!n)throw Error("selector is required for action=click");if(/:contains\s*\(/i.test(n))throw Error(":contains(...) is not a standard CSS selector. Use browser_cua(snapshot) to inspect a standard selector, or browser_cua(evaluate) for text matching.");return n}function go(){let o=process.env.DM_CODING_AGENT_DIR||process.env.PI_CODING_AGENT_DIR;return o?e(o):w(fo(),".dm","agent")}function Jo(){let o=w(go(),"cua","screenshots");E(o,{recursive:!0});let n=new Date().toISOString().replace(/[:.]/g,"-");return w(o,`browser-${n}.png`)}function p(o,n,{env:m=process.env,timeoutMs:t=X}={}){return new Promise((d,a)=>{let h=to("node",[o,...n],{env:m,stdio:["ignore","pipe","pipe"]}),u="",f="",s=!1,i=setTimeout(()=>{if(s)return;s=!0,h.kill("SIGTERM"),a(Error(`Timed out running ${o}`))},t);h.stdout.on("data",(c)=>{u+=c.toString()}),h.stderr.on("data",(c)=>{f+=c.toString()}),h.on("error",(c)=>{if(s)return;s=!0,clearTimeout(i),a(c)}),h.on("close",(c)=>{if(s)return;if(s=!0,clearTimeout(i),c!==0){a(Error((f||u||`exit ${c}`).trim()));return}d({stdout:u,stderr:f})})})}function Xo(o,n){return new Promise((m,t)=>{let d=co.request({host:"127.0.0.1",port:yo,path:n,method:o},(a)=>{let h="";a.on("data",(u)=>{h+=u.toString()}),a.on("end",()=>{if((a.statusCode??500)>=400){t(Error(`Browser CDP HTTP ${a.statusCode}: ${h.trim()}`));return}try{m(h?JSON.parse(h):{})}catch(u){t(u)}})});d.on("error",t),d.end()})}async function Yo(o="about:blank"){return Xo("PUT",`/json/new?${encodeURIComponent(o)}`)}async function L(o,n={}){let{cdpScript:m}=W();return p(m,o,{env:Y(),timeoutMs:n.timeoutMs??X})}async function J(){let o=await L(["list"]);return Uo(o.stdout)}function G(o,n){if(!n)return o[0]??null;let m=n.toUpperCase();return o.find((t)=>t.target.toUpperCase().startsWith(m))??null}async function K(){let{launchScript:o,cdpScript:n}=W();if(!_(o)||!_(n))throw Error("Bundled browser helpers are missing. Rebuild DM so dm-cua and greedysearch-dm are staged together.");return{launchScript:o,cdpScript:n}}async function N(){let{launchScript:o}=await K();await jo(),await p(o,[],{env:Y(),timeoutMs:X});let n=await J();if(n.length===0)await Yo("about:blank"),n=await J();return n}async function y(o){let n=await N(),m=G(n,o);if(!m){if(o)throw Error(`No browser tab matching prefix "${o}". Run browser_cua(list) first.`);throw Error("No browser tab available after browser bootstrap.")}return{tab:m.target,page:m,pages:n}}async function F({action:o,tab:n,url:m,selector:t,x:d,y:a,text:h,expression:u,outputPath:f}={}){switch(o){case"list":{let s=await N();return{status:"ok",action:o,browser:T(),pages:s}}case"navigate":{if(!m)throw Error("url is required for action=navigate");let s=await y(n),i=await L(["nav",s.tab,m],{timeoutMs:90000}),c=await J(),r=G(c,s.tab)??s.page;return{status:"ok",action:o,browser:T(),tab:s.tab,url:r?.url||m,title:r?.title||"",message:i.stdout.trim(),pages:c}}case"snapshot":{let s=await y(n),i=await L(["snap",s.tab]);return{status:"ok",action:o,browser:T(),tab:s.tab,title:s.page?.title||"",url:s.page?.url||"",snapshot:i.stdout.trim()}}case"screenshot":{let s=await y(n),i=f?e(f):Jo();E(O(i),{recursive:!0});let c=await L(["shot",s.tab,i],{timeoutMs:120000}),r=uo(i).toString("base64");return{status:"ok",action:o,browser:T(),tab:s.tab,title:s.page?.title||"",url:s.page?.url||"",imagePath:i,imageBase64:r,mimeType:"image/png",message:c.stdout.trim()}}case"click":{let s=Do(t),i=await y(n),c=await L(["click",i.tab,s]);return{status:"ok",action:o,browser:T(),tab:i.tab,selector:s,message:c.stdout.trim()}}case"click_xy":{if(typeof d!=="number"||Number.isNaN(d)||typeof a!=="number"||Number.isNaN(a))throw Error("x and y are required numbers for action=click_xy");let s=await y(n),i=await L(["clickxy",s.tab,String(d),String(a)]);return{status:"ok",action:o,browser:T(),tab:s.tab,x:d,y:a,message:i.stdout.trim()}}case"type":{if(h==null||h==="")throw Error("text is required for action=type");let s=await y(n),i=await L(["type",s.tab,h]);return{status:"ok",action:o,browser:T(),tab:s.tab,textLength:h.length,message:i.stdout.trim()}}case"evaluate":{if(!u)throw Error("expression is required for action=evaluate");let s=await y(n),i=await L(["eval",s.tab,u]);return{status:"ok",action:o,browser:T(),tab:s.tab,value:i.stdout.trim()}}case"stop":{let{launchScript:s}=await K();try{await L(["stop"])}catch{}let i=await p(s,["--kill"],{env:Y(),timeoutMs:30000});return{status:"ok",action:o,browser:T(),message:(i.stdout||"Stopped browser CUA lane.").trim()}}default:throw Error(`Unsupported browser action: ${o}`)}}function B(o){switch(o.action){case"list":{if(!Array.isArray(o.pages)||o.pages.length===0)return"Browser CUA is ready, but no pages are open.";return["Open browser tabs:",...o.pages.map((n)=>n.url?`${n.target} ${n.title||"(untitled)"} ${n.url}`:`${n.target} ${n.title||"(untitled)"}`)].join(`
|
|
4
4
|
`)}case"navigate":return[`Navigated browser tab ${o.tab} to ${o.url||"(unknown URL)"}`,o.title?`Title: ${o.title}`:""].filter(Boolean).join(`
|
|
5
5
|
`);case"snapshot":return[`Browser snapshot for ${o.tab}`,o.snapshot||"(empty snapshot)"].join(`
|
|
6
6
|
`);case"screenshot":return[`Saved browser screenshot for ${o.tab} at ${o.imagePath}`,o.title?`Title: ${o.title}`:"",o.url?`URL: ${o.url}`:""].filter(Boolean).join(`
|
|
7
|
-
`);case"click":return`Clicked selector ${JSON.stringify(o.selector)} on browser tab ${o.tab}`;case"click_xy":return`Clicked browser tab ${o.tab} at CSS coordinates (${o.x}, ${o.y})`;case"type":return`Typed ${o.textLength} characters into browser tab ${o.tab}`;case"evaluate":return`Browser evaluate result for ${o.tab}: ${o.value}`;case"stop":return o.message||"Stopped browser CUA lane.";default:return JSON.stringify(o,null,2)}}function
|
|
7
|
+
`);case"click":return`Clicked selector ${JSON.stringify(o.selector)} on browser tab ${o.tab}`;case"click_xy":return`Clicked browser tab ${o.tab} at CSS coordinates (${o.x}, ${o.y})`;case"type":return`Typed ${o.textLength} characters into browser tab ${o.tab}`;case"evaluate":return`Browser evaluate result for ${o.tab}: ${o.value}`;case"stop":return o.message||"Stopped browser CUA lane.";default:return JSON.stringify(o,null,2)}}function po(){console.log(`dm-cua browser helper
|
|
8
8
|
|
|
9
9
|
Usage:
|
|
10
10
|
node browser-cua.mjs list [--json]
|
|
@@ -24,4 +24,4 @@ Usage:
|
|
|
24
24
|
package-manager install; set DM_CUA_AUTO_INSTALL=0 to opt out.
|
|
25
25
|
- To try CloakBrowser, set DM_CUA_BROWSER=cloak
|
|
26
26
|
and point DM_CUA_BROWSER_PATH or CLOAKBROWSER_BINARY_PATH at its Chromium binary.
|
|
27
|
-
- screenshot defaults to ~/.dm/agent/cua/screenshots when --output is omitted.`)}function
|
|
27
|
+
- screenshot defaults to ~/.dm/agent/cua/screenshots when --output is omitted.`)}function zo(o){let n={},m=[];for(let t=0;t<o.length;t+=1){let d=o[t];if(!d.startsWith("--")){m.push(d);continue}let a=d.indexOf("="),h=a>2,u=h?d.slice(2,a):d.slice(2);if(u==="json"||u==="help"){n[u]=!0;continue}if(h){n[u]=d.slice(a+1);continue}let f=o[t+1];if(typeof f>"u"||f.startsWith("--"))throw Error(`Missing value for --${u}`);n[u]=f,t+=1}return{options:n,positionals:m}}async function Vo(){let{options:o,positionals:n}=zo(process.argv.slice(2));if(o.help||n.length===0){po();return}let m=n[0],t=await F({action:m,tab:o.tab,url:o.url,selector:o.selector,x:o.x==null?void 0:Number(o.x),y:o.y==null?void 0:Number(o.y),text:o.text,expression:o.expression,outputPath:o.output});if(o.json){console.log(JSON.stringify(t,null,2));return}console.log(B(t))}try{await Vo()}catch(o){let n=o instanceof Error?o.message:String(o),m=!1;try{m=process.argv.slice(2).includes("--json")}catch{}if(m)console.log(JSON.stringify({status:"error",message:n},null,2));else console.error(n);process.exit(1)}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{existsSync as x}from"node:fs";import{Type as l}from"@sinclair/typebox";import{createHash as ho}from"node:crypto";import{spawn as ro}from"node:child_process";import{existsSync as k,mkdirSync as E,readFileSync as eo}from"node:fs";import lo from"node:http";import{homedir as uo,platform as fo,tmpdir as q}from"node:os";import{dirname as F,join as w,resolve as C}from"node:path";import{fileURLToPath as wo}from"node:url";import{spawn as R}from"node:child_process";import{existsSync as P}from"node:fs";import{homedir as H,platform as S}from"node:os";import
|
|
2
|
-
${c.trim()}`:""}`})}),e.on("close",(n,r)=>{t({status:n===0?"ok":"failed",exitCode:n,message:c.trim()||(r?`installer terminated by signal ${r}`:"")})}),h=setTimeout(()=>{e.kill(),t({status:"timeout",exitCode:null,message:`installer timed out after ${a}ms`})},a)})}function so(o){if(o.startsWith("homebrew-"))return"Homebrew";if(o.startsWith("winget-"))return"winget";return o.split("-")[0]}function co(o){let i=o.message?`: ${o.message}`:"";return`${o.id} ${o.status}${i}`}async function O({env:o=process.env,platformName:i=S(),uid:m=typeof process.getuid==="function"?process.getuid():void 0,findExecutable:a=()=>io({env:o,platformName:i,homeDir:H()}),runCommand:s=(c,h)=>ao(c,h,{env:o}),sleep:d=(c)=>new Promise((h)=>{setTimeout(h,c)})}={}){let c=a();if(c)return{status:"existing",path:c,method:null,attempts:[]};if(!no(o))throw Error("Chrome was not found and automatic installation is disabled by DM_CUA_AUTO_INSTALL.");let h=mo({platformName:i,uid:m});if(h.length===0)throw Error(`Chrome was not found and no automatic Chrome installer is defined for ${i}.`);let e=[];for(let n of h){let r={status:"ok",exitCode:0,message:""};for(let b of n.commands)if(r=await s(b.command,b.args),r.status!=="ok")break;if(r.status!=="ok"){e.push({id:n.id,status:r.status,exitCode:r.exitCode,message:r.message});continue}let L;for(let b=0;b<V;b+=1){if(L=a(),L)break;if(b<V-1)await d(oo)}if(L)return e.push({id:n.id,status:"installed",exitCode:r.exitCode,message:r.message}),{status:"installed",path:L,method:n.id,attempts:e};e.push({id:n.id,status:"missing-after-success",exitCode:r.exitCode,message:`${so(n.id)} reported success, but Chrome was not found`})}let t=e.map(co).join("; ");throw Error(`Chrome automatic installation failed. ${t}`)}var X=F(wo(import.meta.url)),No=C(X,".."),Lo=9322,Ao=400,Y=60000,To=/^(about:|https?:\/\/|file:|chrome-error:\/\/)/i,po={chrome:"Chrome",cloak:"CloakBrowser"};function j(o){let i=Number.parseInt(String(o??""),10);return Number.isInteger(i)&&i>1024&&i<65535?i:null}function Co(o){return ho("sha256").update(String(o||"default")).digest("hex")}function yo(o){let i=String(o||"chrome").trim().toLowerCase();if(i==="cloakbrowser"||i==="cloak-browser")return"cloak";if(i==="chromium"||i==="google-chrome"||i==="chrome")return"chrome";return i.replace(/[^a-z0-9_.-]/g,"-")||"chrome"}function Mo(o,i){let m=o.DM_CUA_BROWSER_PATH||(i==="cloak"?o.DM_CUA_CLOAK_PATH||o.CLOAKBROWSER_BINARY_PATH:void 0)||o.CHROME_PATH;return m?C(String(m)):void 0}function $o(o=process.env,i=process.cwd()){let m=o.DM_CUA_SCOPE||o.DM_CODING_AGENT_DIR||o.PI_CODING_AGENT_DIR||i,a=Co(C(String(m||"."))),s=String(o.DM_CUA_INSTANCE_ID||a.slice(0,12)).replace(/[^a-zA-Z0-9_.-]/g,"-"),d=yo(o.DM_CUA_BROWSER||o.DM_BROWSER_CUA_BROWSER||o.DM_CUA_BROWSER_KIND),c=o.DM_CUA_BROWSER_DISPLAY_NAME||po[d]||d,h=Mo(o,d),e=j(o.DM_CUA_PORT)??j(o.GREEDY_SEARCH_PORT)??Lo+Number.parseInt(a.slice(0,8),16)%Ao,t=d==="chrome"?"chrome":d,n=C(o.DM_CUA_PROFILE_DIR||w(q(),`dm-cua-${t}-profile-${s}`)),r=fo()==="win32"?q():"/tmp";return{instanceId:s,browserKind:d,browserDisplayName:c,browserExecutablePath:h,browserExecutableIsExplicit:Boolean(h),browserInstallation:void 0,port:e,profileDir:n,pidFile:w(n,"chrome.pid"),modeFile:w(n,"chrome-mode"),pagesCache:w(n,"cdp-pages.json"),socketDir:w(r,`dm-cua-cdp-${s}`)}}var f=$o(),bo=f.port,xo=f.profileDir;function A(){return{kind:f.browserKind,displayName:f.browserDisplayName,executablePath:f.browserExecutablePath,installation:f.browserInstallation??null,profileDir:f.profileDir,port:f.port}}async function go(o=f,{env:i=process.env,exists:m=k,ensureChrome:a=O}={}){if(o.browserKind==="cloak"&&!o.browserExecutablePath)throw Error(["CloakBrowser selected for browser CUA, but no executable path was provided.","Install/pre-download CloakBrowser yourself, then set DM_CUA_BROWSER_PATH, DM_CUA_CLOAK_PATH, CLOAKBROWSER_BINARY_PATH, or CHROME_PATH.","DM does not bundle the compiled CloakBrowser binary because its upstream license allows use but not redistribution."].join(" "));if(o.browserExecutablePath&&!m(o.browserExecutablePath))throw Error(`${o.browserDisplayName} executable not found: ${o.browserExecutablePath}`);if(o.browserExecutablePath)return o;if(o.browserKind!=="chrome")throw Error(`${o.browserDisplayName} browser CUA requires an explicit executable path via DM_CUA_BROWSER_PATH.`);let s=await a({env:i});return o.browserExecutablePath=s.path,o.browserInstallation={status:s.status,method:s.method,attempts:s.attempts.map(({id:d,status:c,exitCode:h})=>({id:d,status:c,exitCode:h}))},o}var _;async function ko(){if(!_)_=go(f).catch((o)=>{throw _=void 0,o});return _}function U(){let i=[C(X,"..","greedysearch-dm"),C(X,"..","..","greedysearch-dm")].map((m)=>({launchScript:w(m,"bin","launch.mjs"),cdpScript:w(m,"bin","cdp.mjs")}));for(let m of i)if(k(m.launchScript)&&k(m.cdpScript))return m;return i[0]}function _o(o=f,i=process.env){let m=i.GREEDY_SEARCH_VISIBLE??i.DM_CUA_VISIBLE??i.DM_BROWSER_CUA_VISIBLE;return{...i,...o.browserExecutablePath?{CHROME_PATH:o.browserExecutablePath}:{},CDP_PROFILE_DIR:o.profileDir.replace(/\\/g,"/"),CDP_PAGES_CACHE:o.pagesCache.replace(/\\/g,"/"),CDP_SOCKET_DIR:o.socketDir.replace(/\\/g,"/"),GREEDY_SEARCH_BROWSER_LABEL:o.browserDisplayName,GREEDY_SEARCH_PORT:String(o.port),GREEDY_SEARCH_PROFILE_DIR:o.profileDir.replace(/\\/g,"/"),GREEDY_SEARCH_PID_FILE:o.pidFile.replace(/\\/g,"/"),GREEDY_SEARCH_MODE_FILE:o.modeFile.replace(/\\/g,"/"),GREEDY_SEARCH_ALLOW_PORT_CLEANUP:i.GREEDY_SEARCH_ALLOW_PORT_CLEANUP??"0",...m===void 0?{}:{GREEDY_SEARCH_VISIBLE:m}}}function z(){return _o(f,process.env)}function Uo(o){return To.test(o)}function Do(o){return o.split(/\r?\n/).map((i)=>i.trimEnd()).filter(Boolean).map((i)=>{let m=i.trim().split(/\s{2,}/).filter(Boolean);if(m.length===0)return null;let a=m[0];if(m.length===1)return{target:a,title:"",url:""};if(m.length===2&&Uo(m[1]))return{target:a,title:"",url:m[1]};let s=m.at(-1)??"",d=m.slice(1,-1).join(" ");return{target:a,title:d,url:s}}).filter(Boolean)}function So(){let o=process.env.DM_CODING_AGENT_DIR||process.env.PI_CODING_AGENT_DIR;return o?C(o):w(uo(),".dm","agent")}function Xo(){let o=w(So(),"cua","screenshots");E(o,{recursive:!0});let i=new Date().toISOString().replace(/[:.]/g,"-");return w(o,`browser-${i}.png`)}function I(o,i,{env:m=process.env,timeoutMs:a=Y}={}){return new Promise((s,d)=>{let c=ro("node",[o,...i],{env:m,stdio:["ignore","pipe","pipe"]}),h="",e="",t=!1,n=setTimeout(()=>{if(t)return;t=!0,c.kill("SIGTERM"),d(Error(`Timed out running ${o}`))},a);c.stdout.on("data",(r)=>{h+=r.toString()}),c.stderr.on("data",(r)=>{e+=r.toString()}),c.on("error",(r)=>{if(t)return;t=!0,clearTimeout(n),d(r)}),c.on("close",(r)=>{if(t)return;if(t=!0,clearTimeout(n),r!==0){d(Error((e||h||`exit ${r}`).trim()));return}s({stdout:h,stderr:e})})})}function Jo(o,i){return new Promise((m,a)=>{let s=lo.request({host:"127.0.0.1",port:bo,path:i,method:o},(d)=>{let c="";d.on("data",(h)=>{c+=h.toString()}),d.on("end",()=>{if((d.statusCode??500)>=400){a(Error(`Browser CDP HTTP ${d.statusCode}: ${c.trim()}`));return}try{m(c?JSON.parse(c):{})}catch(h){a(h)}})});s.on("error",a),s.end()})}async function Yo(o="about:blank"){return Jo("PUT",`/json/new?${encodeURIComponent(o)}`)}async function T(o,i={}){let{cdpScript:m}=U();return I(m,o,{env:z(),timeoutMs:i.timeoutMs??Y})}async function J(){let o=await T(["list"]);return Do(o.stdout)}function G(o,i){if(!i)return o[0]??null;let m=i.toUpperCase();return o.find((a)=>a.target.toUpperCase().startsWith(m))??null}async function B(){let{launchScript:o,cdpScript:i}=U();if(!k(o)||!k(i))throw Error("Bundled browser helpers are missing. Rebuild DM so dm-cua and greedysearch-dm are staged together.");return{launchScript:o,cdpScript:i}}async function K(){let{launchScript:o}=await B();await ko(),await I(o,[],{env:z(),timeoutMs:Y});let i=await J();if(i.length===0)await Yo("about:blank"),i=await J();return i}async function $(o){let i=await K(),m=G(i,o);if(!m){if(o)throw Error(`No browser tab matching prefix "${o}". Run browser_cua(list) first.`);throw Error("No browser tab available after browser bootstrap.")}return{tab:m.target,page:m,pages:i}}async function W({action:o,tab:i,url:m,selector:a,x:s,y:d,text:c,expression:h,outputPath:e}={}){switch(o){case"list":{let t=await K();return{status:"ok",action:o,browser:A(),pages:t}}case"navigate":{if(!m)throw Error("url is required for action=navigate");let t=await $(i),n=await T(["nav",t.tab,m],{timeoutMs:90000}),r=await J(),L=G(r,t.tab)??t.page;return{status:"ok",action:o,browser:A(),tab:t.tab,url:L?.url||m,title:L?.title||"",message:n.stdout.trim(),pages:r}}case"snapshot":{let t=await $(i),n=await T(["snap",t.tab]);return{status:"ok",action:o,browser:A(),tab:t.tab,title:t.page?.title||"",url:t.page?.url||"",snapshot:n.stdout.trim()}}case"screenshot":{let t=await $(i),n=e?C(e):Xo();E(F(n),{recursive:!0});let r=await T(["shot",t.tab,n],{timeoutMs:120000}),L=eo(n).toString("base64");return{status:"ok",action:o,browser:A(),tab:t.tab,title:t.page?.title||"",url:t.page?.url||"",imagePath:n,imageBase64:L,mimeType:"image/png",message:r.stdout.trim()}}case"click":{if(!a)throw Error("selector is required for action=click");let t=await $(i),n=await T(["click",t.tab,a]);return{status:"ok",action:o,browser:A(),tab:t.tab,selector:a,message:n.stdout.trim()}}case"click_xy":{if(typeof s!=="number"||Number.isNaN(s)||typeof d!=="number"||Number.isNaN(d))throw Error("x and y are required numbers for action=click_xy");let t=await $(i),n=await T(["clickxy",t.tab,String(s),String(d)]);return{status:"ok",action:o,browser:A(),tab:t.tab,x:s,y:d,message:n.stdout.trim()}}case"type":{if(c==null||c==="")throw Error("text is required for action=type");let t=await $(i),n=await T(["type",t.tab,c]);return{status:"ok",action:o,browser:A(),tab:t.tab,textLength:c.length,message:n.stdout.trim()}}case"evaluate":{if(!h)throw Error("expression is required for action=evaluate");let t=await $(i),n=await T(["eval",t.tab,h]);return{status:"ok",action:o,browser:A(),tab:t.tab,value:n.stdout.trim()}}case"stop":{let{launchScript:t}=await B();try{await T(["stop"])}catch{}let n=await I(t,["--kill"],{env:z(),timeoutMs:30000});return{status:"ok",action:o,browser:A(),message:(n.stdout||"Stopped browser CUA lane.").trim()}}default:throw Error(`Unsupported browser action: ${o}`)}}function N(o){switch(o.action){case"list":{if(!Array.isArray(o.pages)||o.pages.length===0)return"Browser CUA is ready, but no pages are open.";return["Open browser tabs:",...o.pages.map((i)=>i.url?`${i.target} ${i.title||"(untitled)"} ${i.url}`:`${i.target} ${i.title||"(untitled)"}`)].join(`
|
|
1
|
+
import{existsSync as x}from"node:fs";import{Type as l}from"@sinclair/typebox";import{createHash as ho}from"node:crypto";import{spawn as ro}from"node:child_process";import{existsSync as k,mkdirSync as E,readFileSync as eo}from"node:fs";import lo from"node:http";import{homedir as uo,platform as fo,tmpdir as q}from"node:os";import{dirname as F,join as w,resolve as C}from"node:path";import{fileURLToPath as wo}from"node:url";import{spawn as R}from"node:child_process";import{existsSync as P}from"node:fs";import{homedir as H,platform as S}from"node:os";import g from"node:path";var v=900000,Q=16384,V=5,oo=1000;function b(...o){return g.win32.join(...o)}function p(o,i){if(i&&!o.includes(i))o.push(i)}function D(o,i,m){let s=o.PATH??o.Path??o.path??"",a=i==="win32"?";":g.delimiter,d=i==="win32"?(o.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean):[""],c=[];for(let r of s.split(a).filter(Boolean))for(let e of m){if(i==="win32"&&g.win32.extname(e)){p(c,b(r,e));continue}for(let t of d){let n=i==="win32"?`${e}${t.toLowerCase()}`:e;p(c,i==="win32"?b(r,n):g.join(r,n))}}return c}function io({env:o=process.env,platformName:i=S(),homeDir:m=H(),exists:s=P}={}){let a=[];if(i==="win32"){for(let d of[o.LOCALAPPDATA,o.ProgramFiles,o["ProgramFiles(x86)"]]){if(!d)continue;p(a,b(d,"Google","Chrome","Application","chrome.exe")),p(a,b(d,"Chromium","Application","chrome.exe"))}p(a,m?b(m,"AppData","Local","Google","Chrome","Application","chrome.exe"):void 0),a.push(...D(o,i,["chrome","chromium"]))}else if(i==="darwin"){for(let d of["/Applications",g.join(m,"Applications")])p(a,g.join(d,"Google Chrome.app","Contents","MacOS","Google Chrome")),p(a,g.join(d,"Chromium.app","Contents","MacOS","Chromium"));a.push(...D(o,i,["google-chrome-stable","google-chrome","chromium","chromium-browser"]))}else if(i==="linux"){for(let d of["/usr/bin/google-chrome-stable","/usr/bin/google-chrome","/usr/bin/chromium","/usr/bin/chromium-browser","/snap/bin/chromium","/usr/local/bin/google-chrome","/usr/local/bin/chromium"])p(a,d);a.push(...D(o,i,["google-chrome-stable","google-chrome","chromium","chromium-browser"]))}return a.find((d)=>s(d))}function u(o,...i){return{command:o,args:i}}function y(o,i){if(i===0)return o;return o.map(({command:m,args:s})=>u("sudo","-n",m,...s))}function mo({platformName:o=S(),uid:i=typeof process.getuid==="function"?process.getuid():void 0}={}){if(o==="darwin")return[{id:"homebrew-google-chrome",commands:[u("brew","install","--cask","google-chrome")]}];if(o==="win32"){let m=["install","--id","Google.Chrome","-e","--silent","--accept-package-agreements","--accept-source-agreements","--disable-interactivity"];return[{id:"winget-user-google-chrome",commands:[u("winget",...m.slice(0,4),"--scope","user",...m.slice(4))]},{id:"winget-machine-google-chrome",commands:[u("winget",...m)]},{id:"chocolatey-google-chrome",commands:[u("choco","install","googlechrome","-y","--no-progress")]}]}if(o==="linux")return[{id:"apt-chromium",commands:y([u("apt-get","update"),u("apt-get","install","-y","chromium")],i)},{id:"apt-chromium-browser",commands:y([u("apt-get","update"),u("apt-get","install","-y","chromium-browser")],i)},{id:"dnf-chromium",commands:y([u("dnf","install","-y","chromium")],i)},{id:"yum-chromium",commands:y([u("yum","install","-y","chromium")],i)},{id:"pacman-chromium",commands:y([u("pacman","-S","--noconfirm","--needed","chromium")],i)},{id:"zypper-chromium",commands:y([u("zypper","--non-interactive","install","chromium")],i)},{id:"apk-chromium",commands:y([u("apk","add","chromium")],i)}];return[]}function no(o=process.env){let i=o.DM_CUA_AUTO_INSTALL;if(i===void 0)return!0;return!["0","false","no","off"].includes(i.trim().toLowerCase())}function to(o){let i=Number(o.DM_CUA_INSTALL_TIMEOUT_MS);return Number.isFinite(i)&&i>0?i:v}function Z(o,i){let m=`${o}${i}`;if(Buffer.byteLength(m)<=Q)return m;return m.slice(-Q)}function ao(o,i,{env:m=process.env,timeoutMs:s=to(m)}={}){return new Promise((a)=>{let d=!1,c="",r,e=R(o,i,{env:m,shell:!1,stdio:["ignore","pipe","pipe"],windowsHide:!0}),t=(n)=>{if(d)return;d=!0,clearTimeout(r),a(n)};e.stdout?.on("data",(n)=>{c=Z(c,n.toString())}),e.stderr?.on("data",(n)=>{c=Z(c,n.toString())}),e.on("error",(n)=>{t({status:n.code==="ENOENT"?"unavailable":"failed",exitCode:null,message:`${n.message}${c?`
|
|
2
|
+
${c.trim()}`:""}`})}),e.on("close",(n,h)=>{t({status:n===0?"ok":"failed",exitCode:n,message:c.trim()||(h?`installer terminated by signal ${h}`:"")})}),r=setTimeout(()=>{e.kill(),t({status:"timeout",exitCode:null,message:`installer timed out after ${s}ms`})},s)})}function so(o){if(o.startsWith("homebrew-"))return"Homebrew";if(o.startsWith("winget-"))return"winget";return o.split("-")[0]}function co(o){let i=o.message?`: ${o.message}`:"";return`${o.id} ${o.status}${i}`}async function O({env:o=process.env,platformName:i=S(),uid:m=typeof process.getuid==="function"?process.getuid():void 0,findExecutable:s=()=>io({env:o,platformName:i,homeDir:H()}),runCommand:a=(c,r)=>ao(c,r,{env:o}),sleep:d=(c)=>new Promise((r)=>{setTimeout(r,c)})}={}){let c=s();if(c)return{status:"existing",path:c,method:null,attempts:[]};if(!no(o))throw Error("Chrome was not found and automatic installation is disabled by DM_CUA_AUTO_INSTALL.");let r=mo({platformName:i,uid:m});if(r.length===0)throw Error(`Chrome was not found and no automatic Chrome installer is defined for ${i}.`);let e=[];for(let n of r){let h={status:"ok",exitCode:0,message:""};for(let $ of n.commands)if(h=await a($.command,$.args),h.status!=="ok")break;if(h.status!=="ok"){e.push({id:n.id,status:h.status,exitCode:h.exitCode,message:h.message});continue}let L;for(let $=0;$<V;$+=1){if(L=s(),L)break;if($<V-1)await d(oo)}if(L)return e.push({id:n.id,status:"installed",exitCode:h.exitCode,message:h.message}),{status:"installed",path:L,method:n.id,attempts:e};e.push({id:n.id,status:"missing-after-success",exitCode:h.exitCode,message:`${so(n.id)} reported success, but Chrome was not found`})}let t=e.map(co).join("; ");throw Error(`Chrome automatic installation failed. ${t}`)}var X=F(wo(import.meta.url)),xo=C(X,".."),Lo=9322,Ao=400,Y=60000,To=/^(about:|https?:\/\/|file:|chrome-error:\/\/)/i,po={chrome:"Chrome",cloak:"CloakBrowser"};function j(o){let i=Number.parseInt(String(o??""),10);return Number.isInteger(i)&&i>1024&&i<65535?i:null}function Co(o){return ho("sha256").update(String(o||"default")).digest("hex")}function yo(o){let i=String(o||"chrome").trim().toLowerCase();if(i==="cloakbrowser"||i==="cloak-browser")return"cloak";if(i==="chromium"||i==="google-chrome"||i==="chrome")return"chrome";return i.replace(/[^a-z0-9_.-]/g,"-")||"chrome"}function go(o,i){let m=o.DM_CUA_BROWSER_PATH||(i==="cloak"?o.DM_CUA_CLOAK_PATH||o.CLOAKBROWSER_BINARY_PATH:void 0)||o.CHROME_PATH;return m?C(String(m)):void 0}function Mo(o=process.env,i=process.cwd()){let m=o.DM_CUA_SCOPE||o.DM_CODING_AGENT_DIR||o.PI_CODING_AGENT_DIR||i,s=Co(C(String(m||"."))),a=String(o.DM_CUA_INSTANCE_ID||s.slice(0,12)).replace(/[^a-zA-Z0-9_.-]/g,"-"),d=yo(o.DM_CUA_BROWSER||o.DM_BROWSER_CUA_BROWSER||o.DM_CUA_BROWSER_KIND),c=o.DM_CUA_BROWSER_DISPLAY_NAME||po[d]||d,r=go(o,d),e=j(o.DM_CUA_PORT)??j(o.GREEDY_SEARCH_PORT)??Lo+Number.parseInt(s.slice(0,8),16)%Ao,t=d==="chrome"?"chrome":d,n=C(o.DM_CUA_PROFILE_DIR||w(q(),`dm-cua-${t}-profile-${a}`)),h=fo()==="win32"?q():"/tmp";return{instanceId:a,browserKind:d,browserDisplayName:c,browserExecutablePath:r,browserExecutableIsExplicit:Boolean(r),browserInstallation:void 0,port:e,profileDir:n,pidFile:w(n,"chrome.pid"),modeFile:w(n,"chrome-mode"),pagesCache:w(n,"cdp-pages.json"),socketDir:w(h,`dm-cua-cdp-${a}`)}}var f=Mo(),$o=f.port,Ro=f.profileDir;function A(){return{kind:f.browserKind,displayName:f.browserDisplayName,executablePath:f.browserExecutablePath,installation:f.browserInstallation??null,profileDir:f.profileDir,port:f.port}}async function bo(o=f,{env:i=process.env,exists:m=k,ensureChrome:s=O}={}){if(o.browserKind==="cloak"&&!o.browserExecutablePath)throw Error(["CloakBrowser selected for browser CUA, but no executable path was provided.","Install/pre-download CloakBrowser yourself, then set DM_CUA_BROWSER_PATH, DM_CUA_CLOAK_PATH, CLOAKBROWSER_BINARY_PATH, or CHROME_PATH.","DM does not bundle the compiled CloakBrowser binary because its upstream license allows use but not redistribution."].join(" "));if(o.browserExecutablePath&&!m(o.browserExecutablePath))throw Error(`${o.browserDisplayName} executable not found: ${o.browserExecutablePath}`);if(o.browserExecutablePath)return o;if(o.browserKind!=="chrome")throw Error(`${o.browserDisplayName} browser CUA requires an explicit executable path via DM_CUA_BROWSER_PATH.`);let a=await s({env:i});return o.browserExecutablePath=a.path,o.browserInstallation={status:a.status,method:a.method,attempts:a.attempts.map(({id:d,status:c,exitCode:r})=>({id:d,status:c,exitCode:r}))},o}var U;async function ko(){if(!U)U=bo(f).catch((o)=>{throw U=void 0,o});return U}function _(){let i=[C(X,"..","greedysearch-dm"),C(X,"..","..","greedysearch-dm")].map((m)=>({launchScript:w(m,"bin","launch.mjs"),cdpScript:w(m,"bin","cdp.mjs")}));for(let m of i)if(k(m.launchScript)&&k(m.cdpScript))return m;return i[0]}function Uo(o=f,i=process.env){let m=i.GREEDY_SEARCH_VISIBLE??i.DM_CUA_VISIBLE??i.DM_BROWSER_CUA_VISIBLE;return{...i,...o.browserExecutablePath?{CHROME_PATH:o.browserExecutablePath}:{},CDP_PROFILE_DIR:o.profileDir.replace(/\\/g,"/"),CDP_PAGES_CACHE:o.pagesCache.replace(/\\/g,"/"),CDP_SOCKET_DIR:o.socketDir.replace(/\\/g,"/"),GREEDY_SEARCH_BROWSER_LABEL:o.browserDisplayName,GREEDY_SEARCH_PORT:String(o.port),GREEDY_SEARCH_PROFILE_DIR:o.profileDir.replace(/\\/g,"/"),GREEDY_SEARCH_PID_FILE:o.pidFile.replace(/\\/g,"/"),GREEDY_SEARCH_MODE_FILE:o.modeFile.replace(/\\/g,"/"),GREEDY_SEARCH_ALLOW_PORT_CLEANUP:i.GREEDY_SEARCH_ALLOW_PORT_CLEANUP??"0",...m===void 0?{}:{GREEDY_SEARCH_VISIBLE:m}}}function z(){return Uo(f,process.env)}function _o(o){return To.test(o)}function Do(o){return o.split(/\r?\n/).map((i)=>i.trimEnd()).filter(Boolean).map((i)=>{let m=i.trim().split(/\s{2,}/).filter(Boolean);if(m.length===0)return null;let s=m[0];if(m.length===1)return{target:s,title:"",url:""};if(m.length===2&&_o(m[1]))return{target:s,title:"",url:m[1]};let a=m.at(-1)??"",d=m.slice(1,-1).join(" ");return{target:s,title:d,url:a}}).filter(Boolean)}function So(o){let i=String(o??"").trim();if(!i)throw Error("selector is required for action=click");if(/:contains\s*\(/i.test(i))throw Error(":contains(...) is not a standard CSS selector. Use browser_cua(snapshot) to inspect a standard selector, or browser_cua(evaluate) for text matching.");return i}function Xo(){let o=process.env.DM_CODING_AGENT_DIR||process.env.PI_CODING_AGENT_DIR;return o?C(o):w(uo(),".dm","agent")}function Jo(){let o=w(Xo(),"cua","screenshots");E(o,{recursive:!0});let i=new Date().toISOString().replace(/[:.]/g,"-");return w(o,`browser-${i}.png`)}function I(o,i,{env:m=process.env,timeoutMs:s=Y}={}){return new Promise((a,d)=>{let c=ro("node",[o,...i],{env:m,stdio:["ignore","pipe","pipe"]}),r="",e="",t=!1,n=setTimeout(()=>{if(t)return;t=!0,c.kill("SIGTERM"),d(Error(`Timed out running ${o}`))},s);c.stdout.on("data",(h)=>{r+=h.toString()}),c.stderr.on("data",(h)=>{e+=h.toString()}),c.on("error",(h)=>{if(t)return;t=!0,clearTimeout(n),d(h)}),c.on("close",(h)=>{if(t)return;if(t=!0,clearTimeout(n),h!==0){d(Error((e||r||`exit ${h}`).trim()));return}a({stdout:r,stderr:e})})})}function Yo(o,i){return new Promise((m,s)=>{let a=lo.request({host:"127.0.0.1",port:$o,path:i,method:o},(d)=>{let c="";d.on("data",(r)=>{c+=r.toString()}),d.on("end",()=>{if((d.statusCode??500)>=400){s(Error(`Browser CDP HTTP ${d.statusCode}: ${c.trim()}`));return}try{m(c?JSON.parse(c):{})}catch(r){s(r)}})});a.on("error",s),a.end()})}async function zo(o="about:blank"){return Yo("PUT",`/json/new?${encodeURIComponent(o)}`)}async function T(o,i={}){let{cdpScript:m}=_();return I(m,o,{env:z(),timeoutMs:i.timeoutMs??Y})}async function J(){let o=await T(["list"]);return Do(o.stdout)}function G(o,i){if(!i)return o[0]??null;let m=i.toUpperCase();return o.find((s)=>s.target.toUpperCase().startsWith(m))??null}async function K(){let{launchScript:o,cdpScript:i}=_();if(!k(o)||!k(i))throw Error("Bundled browser helpers are missing. Rebuild DM so dm-cua and greedysearch-dm are staged together.");return{launchScript:o,cdpScript:i}}async function B(){let{launchScript:o}=await K();await ko(),await I(o,[],{env:z(),timeoutMs:Y});let i=await J();if(i.length===0)await zo("about:blank"),i=await J();return i}async function M(o){let i=await B(),m=G(i,o);if(!m){if(o)throw Error(`No browser tab matching prefix "${o}". Run browser_cua(list) first.`);throw Error("No browser tab available after browser bootstrap.")}return{tab:m.target,page:m,pages:i}}async function W({action:o,tab:i,url:m,selector:s,x:a,y:d,text:c,expression:r,outputPath:e}={}){switch(o){case"list":{let t=await B();return{status:"ok",action:o,browser:A(),pages:t}}case"navigate":{if(!m)throw Error("url is required for action=navigate");let t=await M(i),n=await T(["nav",t.tab,m],{timeoutMs:90000}),h=await J(),L=G(h,t.tab)??t.page;return{status:"ok",action:o,browser:A(),tab:t.tab,url:L?.url||m,title:L?.title||"",message:n.stdout.trim(),pages:h}}case"snapshot":{let t=await M(i),n=await T(["snap",t.tab]);return{status:"ok",action:o,browser:A(),tab:t.tab,title:t.page?.title||"",url:t.page?.url||"",snapshot:n.stdout.trim()}}case"screenshot":{let t=await M(i),n=e?C(e):Jo();E(F(n),{recursive:!0});let h=await T(["shot",t.tab,n],{timeoutMs:120000}),L=eo(n).toString("base64");return{status:"ok",action:o,browser:A(),tab:t.tab,title:t.page?.title||"",url:t.page?.url||"",imagePath:n,imageBase64:L,mimeType:"image/png",message:h.stdout.trim()}}case"click":{let t=So(s),n=await M(i),h=await T(["click",n.tab,t]);return{status:"ok",action:o,browser:A(),tab:n.tab,selector:t,message:h.stdout.trim()}}case"click_xy":{if(typeof a!=="number"||Number.isNaN(a)||typeof d!=="number"||Number.isNaN(d))throw Error("x and y are required numbers for action=click_xy");let t=await M(i),n=await T(["clickxy",t.tab,String(a),String(d)]);return{status:"ok",action:o,browser:A(),tab:t.tab,x:a,y:d,message:n.stdout.trim()}}case"type":{if(c==null||c==="")throw Error("text is required for action=type");let t=await M(i),n=await T(["type",t.tab,c]);return{status:"ok",action:o,browser:A(),tab:t.tab,textLength:c.length,message:n.stdout.trim()}}case"evaluate":{if(!r)throw Error("expression is required for action=evaluate");let t=await M(i),n=await T(["eval",t.tab,r]);return{status:"ok",action:o,browser:A(),tab:t.tab,value:n.stdout.trim()}}case"stop":{let{launchScript:t}=await K();try{await T(["stop"])}catch{}let n=await I(t,["--kill"],{env:z(),timeoutMs:30000});return{status:"ok",action:o,browser:A(),message:(n.stdout||"Stopped browser CUA lane.").trim()}}default:throw Error(`Unsupported browser action: ${o}`)}}function N(o){switch(o.action){case"list":{if(!Array.isArray(o.pages)||o.pages.length===0)return"Browser CUA is ready, but no pages are open.";return["Open browser tabs:",...o.pages.map((i)=>i.url?`${i.target} ${i.title||"(untitled)"} ${i.url}`:`${i.target} ${i.title||"(untitled)"}`)].join(`
|
|
3
3
|
`)}case"navigate":return[`Navigated browser tab ${o.tab} to ${o.url||"(unknown URL)"}`,o.title?`Title: ${o.title}`:""].filter(Boolean).join(`
|
|
4
4
|
`);case"snapshot":return[`Browser snapshot for ${o.tab}`,o.snapshot||"(empty snapshot)"].join(`
|
|
5
5
|
`);case"screenshot":return[`Saved browser screenshot for ${o.tab} at ${o.imagePath}`,o.title?`Title: ${o.title}`:"",o.url?`URL: ${o.url}`:""].filter(Boolean).join(`
|
|
6
|
-
`);case"click":return`Clicked selector ${JSON.stringify(o.selector)} on browser tab ${o.tab}`;case"click_xy":return`Clicked browser tab ${o.tab} at CSS coordinates (${o.x}, ${o.y})`;case"type":return`Typed ${o.textLength} characters into browser tab ${o.tab}`;case"evaluate":return`Browser evaluate result for ${o.tab}: ${o.value}`;case"stop":return o.message||"Stopped browser CUA lane.";default:return JSON.stringify(o,null,2)}}var
|
|
6
|
+
`);case"click":return`Clicked selector ${JSON.stringify(o.selector)} on browser tab ${o.tab}`;case"click_xy":return`Clicked browser tab ${o.tab} at CSS coordinates (${o.x}, ${o.y})`;case"type":return`Typed ${o.textLength} characters into browser tab ${o.tab}`;case"evaluate":return`Browser evaluate result for ${o.tab}: ${o.value}`;case"stop":return o.message||"Stopped browser CUA lane.";default:return JSON.stringify(o,null,2)}}var Io=l.Object({action:l.Union([l.Literal("list"),l.Literal("navigate"),l.Literal("snapshot"),l.Literal("screenshot"),l.Literal("click"),l.Literal("click_xy"),l.Literal("type"),l.Literal("evaluate"),l.Literal("stop")],{description:"Browser action. Start with list, snapshot, or screenshot before mutating actions on unfamiliar pages."}),tab:l.Optional(l.String({description:"Optional target tab prefix from browser_cua(list). If omitted, the first live page in the dedicated profile is used."})),url:l.Optional(l.String({description:"URL for action=navigate."})),selector:l.Optional(l.String({description:"Standard CSS selector for action=click; :contains(...) is not supported. Use evaluate for text matching."})),x:l.Optional(l.Number({description:"CSS x coordinate for action=click_xy."})),y:l.Optional(l.Number({description:"CSS y coordinate for action=click_xy."})),text:l.Optional(l.String({description:"Text for action=type."})),expression:l.Optional(l.String({description:"JavaScript expression for action=evaluate."}))},{additionalProperties:!1});function Qo(o){o.on("session_start",async(i,m)=>{let{launchScript:s,cdpScript:a}=_();if(!x(s)||!x(a))m.ui.notify("dm-cua: bundled browser helpers are missing. Rebuild DM so dm-cua and greedysearch-dm are staged together.","warning")}),o.registerTool({name:"browser_cua",label:"Browser CUA",description:"Drive a dedicated Chrome browser profile through DM's bundled browser CUA lane. If Chrome/Chromium is absent, DM attempts a non-interactive OS package-manager install before launch. Inspect first with list, snapshot, or screenshot. Fresh empty profiles auto-bootstrap a blank tab. Use navigate for deterministic URLs, click with a standard CSS selector/click_xy/type for page interaction, evaluate for focused DOM reads or text matching, and stop to close the dedicated browser lane.",promptSnippet:"First-class browser CUA for Chrome with automatic browser bootstrap. Inspect before acting. Screenshot complex pages before click/scroll loops.",parameters:Io,async execute(i,m){try{let s=await W(m),a=[{type:"text",text:N(s)}];if(s.imageBase64&&s.mimeType)a.push({type:"image",data:s.imageBase64,mimeType:s.mimeType});return{content:a,details:s}}catch(s){let a=s instanceof Error?s.message:String(s);return{content:[{type:"text",text:`browser_cua failed: ${a}`}],details:{status:"error",action:m?.action??null,message:a}}}}})}export{Qo as default};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{createHash as dm}from"node:crypto";import{spawn as nm}from"node:child_process";import{existsSync as
|
|
2
|
-
${A.trim()}`:""}`})}),M.on("close",(h,$)=>{d({status:h===0?"ok":"failed",exitCode:h,message:A.trim()||($?`installer terminated by signal ${$}`:"")})}),w=setTimeout(()=>{M.kill(),d({status:"timeout",exitCode:null,message:`installer timed out after ${L}ms`})},L)})}function im(m){if(m.startsWith("homebrew-"))return"Homebrew";if(m.startsWith("winget-"))return"winget";return m.split("-")[0]}function hm(m){let o=m.message?`: ${m.message}`:"";return`${m.id} ${m.status}${o}`}async function c({env:m=process.env,platformName:o=H(),uid:i=typeof process.getuid==="function"?process.getuid():void 0,findExecutable:L=()=>v({env:m,platformName:o,homeDir:W()}),runCommand:T=(A,w)=>om(A,w,{env:m}),sleep:n=(A)=>new Promise((w)=>{setTimeout(w,A)})}={}){let A=L();if(A)return{status:"existing",path:A,method:null,attempts:[]};if(!e(m))throw Error("Chrome was not found and automatic installation is disabled by DM_CUA_AUTO_INSTALL.");let w=r({platformName:o,uid:i});if(w.length===0)throw Error(`Chrome was not found and no automatic Chrome installer is defined for ${o}.`);let M=[];for(let h of w){let $={status:"ok",exitCode:0,message:""};for(let y of h.commands)if($=await T(y.command,y.args),$.status!=="ok")break;if($.status!=="ok"){M.push({id:h.id,status:$.status,exitCode:$.exitCode,message:$.message});continue}let a;for(let y=0;y<K;y+=1){if(a=L(),a)break;if(y<K-1)await n(t)}if(a)return M.push({id:h.id,status:"installed",exitCode:$.exitCode,message:$.message}),{status:"installed",path:a,method:h.id,attempts:M};M.push({id:h.id,status:"missing-after-success",exitCode:$.exitCode,message:`${im(h.id)} reported success, but Chrome was not found`})}let d=M.map(hm).join("; ");throw Error(`Chrome automatic installation failed. ${d}`)}var q=N($m(import.meta.url)),Nm=_(q,".."),Mm=9322,Cm=400,j=60000,um=/^(about:|https?:\/\/|file:|chrome-error:\/\/)/i,fm={chrome:"Chrome",cloak:"CloakBrowser"};function O(m){let o=Number.parseInt(String(m??""),10);return Number.isInteger(o)&&o>1024&&o<65535?o:null}function am(m){return dm("sha256").update(String(m||"default")).digest("hex")}function Um(m){let o=String(m||"chrome").trim().toLowerCase();if(o==="cloakbrowser"||o==="cloak-browser")return"cloak";if(o==="chromium"||o==="google-chrome"||o==="chrome")return"chrome";return o.replace(/[^a-z0-9_.-]/g,"-")||"chrome"}function km(m,o){let i=m.DM_CUA_BROWSER_PATH||(o==="cloak"?m.DM_CUA_CLOAK_PATH||m.CLOAKBROWSER_BINARY_PATH:void 0)||m.CHROME_PATH;return i?_(String(i)):void 0}function Xm(m=process.env,o=process.cwd()){let i=m.DM_CUA_SCOPE||m.DM_CODING_AGENT_DIR||m.PI_CODING_AGENT_DIR||o,L=am(_(String(i||"."))),T=String(m.DM_CUA_INSTANCE_ID||L.slice(0,12)).replace(/[^a-zA-Z0-9_.-]/g,"-"),n=Um(m.DM_CUA_BROWSER||m.DM_BROWSER_CUA_BROWSER||m.DM_CUA_BROWSER_KIND),A=m.DM_CUA_BROWSER_DISPLAY_NAME||fm[n]||n,w=km(m,n),M=O(m.DM_CUA_PORT)??O(m.GREEDY_SEARCH_PORT)??Mm+Number.parseInt(L.slice(0,8),16)%Cm,d=n==="chrome"?"chrome":n,h=_(m.DM_CUA_PROFILE_DIR||f(b(),`dm-cua-${d}-profile-${T}`)),$=wm()==="win32"?b():"/tmp";return{instanceId:T,browserKind:n,browserDisplayName:A,browserExecutablePath:w,browserExecutableIsExplicit:Boolean(w),browserInstallation:void 0,port:M,profileDir:h,pidFile:f(h,"chrome.pid"),modeFile:f(h,"chrome-mode"),pagesCache:f(h,"cdp-pages.json"),socketDir:f($,`dm-cua-cdp-${T}`)}}var u=Xm(),_m=u.port,Bm=u.profileDir;function U(){return{kind:u.browserKind,displayName:u.browserDisplayName,executablePath:u.browserExecutablePath,installation:u.browserInstallation??null,profileDir:u.profileDir,port:u.port}}async function Ym(m=u,{env:o=process.env,exists:i=Q,ensureChrome:L=c}={}){if(m.browserKind==="cloak"&&!m.browserExecutablePath)throw Error(["CloakBrowser selected for browser CUA, but no executable path was provided.","Install/pre-download CloakBrowser yourself, then set DM_CUA_BROWSER_PATH, DM_CUA_CLOAK_PATH, CLOAKBROWSER_BINARY_PATH, or CHROME_PATH.","DM does not bundle the compiled CloakBrowser binary because its upstream license allows use but not redistribution."].join(" "));if(m.browserExecutablePath&&!i(m.browserExecutablePath))throw Error(`${m.browserDisplayName} executable not found: ${m.browserExecutablePath}`);if(m.browserExecutablePath)return m;if(m.browserKind!=="chrome")throw Error(`${m.browserDisplayName} browser CUA requires an explicit executable path via DM_CUA_BROWSER_PATH.`);let T=await L({env:o});return m.browserExecutablePath=T.path,m.browserInstallation={status:T.status,method:T.method,attempts:T.attempts.map(({id:n,status:A,exitCode:w})=>({id:n,status:A,exitCode:w}))},m}var V;async function zm(){if(!V)V=Ym(u).catch((m)=>{throw V=void 0,m});return V}function B(){let o=[_(q,"..","greedysearch-dm"),_(q,"..","..","greedysearch-dm")].map((i)=>({launchScript:f(i,"bin","launch.mjs"),cdpScript:f(i,"bin","cdp.mjs")}));for(let i of o)if(Q(i.launchScript)&&Q(i.cdpScript))return i;return o[0]}function Jm(m=u,o=process.env){let i=o.GREEDY_SEARCH_VISIBLE??o.DM_CUA_VISIBLE??o.DM_BROWSER_CUA_VISIBLE;return{...o,...m.browserExecutablePath?{CHROME_PATH:m.browserExecutablePath}:{},CDP_PROFILE_DIR:m.profileDir.replace(/\\/g,"/"),CDP_PAGES_CACHE:m.pagesCache.replace(/\\/g,"/"),CDP_SOCKET_DIR:m.socketDir.replace(/\\/g,"/"),GREEDY_SEARCH_BROWSER_LABEL:m.browserDisplayName,GREEDY_SEARCH_PORT:String(m.port),GREEDY_SEARCH_PROFILE_DIR:m.profileDir.replace(/\\/g,"/"),GREEDY_SEARCH_PID_FILE:m.pidFile.replace(/\\/g,"/"),GREEDY_SEARCH_MODE_FILE:m.modeFile.replace(/\\/g,"/"),GREEDY_SEARCH_ALLOW_PORT_CLEANUP:o.GREEDY_SEARCH_ALLOW_PORT_CLEANUP??"0",...i===void 0?{}:{GREEDY_SEARCH_VISIBLE:i}}}function s(){return Jm(u,process.env)}function ym(m){return um.test(m)}function Dm(m){return m.split(/\r?\n/).map((o)=>o.trimEnd()).filter(Boolean).map((o)=>{let i=o.trim().split(/\s{2,}/).filter(Boolean);if(i.length===0)return null;let L=i[0];if(i.length===1)return{target:L,title:"",url:""};if(i.length===2&&ym(i[1]))return{target:L,title:"",url:i[1]};let T=i.at(-1)??"",n=i.slice(1,-1).join(" ");return{target:L,title:n,url:T}}).filter(Boolean)}function Qm(){let m=process.env.DM_CODING_AGENT_DIR||process.env.PI_CODING_AGENT_DIR;return m?_(m):f(Lm(),".dm","agent")}function Vm(){let m=f(Qm(),"cua","screenshots");g(m,{recursive:!0});let o=new Date().toISOString().replace(/[:.]/g,"-");return f(m,`browser-${o}.png`)}function G(m,o,{env:i=process.env,timeoutMs:L=j}={}){return new Promise((T,n)=>{let A=nm("node",[m,...o],{env:i,stdio:["ignore","pipe","pipe"]}),w="",M="",d=!1,h=setTimeout(()=>{if(d)return;d=!0,A.kill("SIGTERM"),n(Error(`Timed out running ${m}`))},L);A.stdout.on("data",($)=>{w+=$.toString()}),A.stderr.on("data",($)=>{M+=$.toString()}),A.on("error",($)=>{if(d)return;d=!0,clearTimeout(h),n($)}),A.on("close",($)=>{if(d)return;if(d=!0,clearTimeout(h),$!==0){n(Error((M||w||`exit ${$}`).trim()));return}T({stdout:w,stderr:M})})})}function Zm(m,o){return new Promise((i,L)=>{let T=Tm.request({host:"127.0.0.1",port:_m,path:o,method:m},(n)=>{let A="";n.on("data",(w)=>{A+=w.toString()}),n.on("end",()=>{if((n.statusCode??500)>=400){L(Error(`Browser CDP HTTP ${n.statusCode}: ${A.trim()}`));return}try{i(A?JSON.parse(A):{})}catch(w){L(w)}})});T.on("error",L),T.end()})}async function Hm(m="about:blank"){return Zm("PUT",`/json/new?${encodeURIComponent(m)}`)}async function k(m,o={}){let{cdpScript:i}=B();return G(i,m,{env:s(),timeoutMs:o.timeoutMs??j})}async function I(){let m=await k(["list"]);return Dm(m.stdout)}function l(m,o){if(!o)return m[0]??null;let i=o.toUpperCase();return m.find((L)=>L.target.toUpperCase().startsWith(i))??null}async function S(){let{launchScript:m,cdpScript:o}=B();if(!Q(m)||!Q(o))throw Error("Bundled browser helpers are missing. Rebuild DM so dm-cua and greedysearch-dm are staged together.");return{launchScript:m,cdpScript:o}}async function R(){let{launchScript:m}=await S();await zm(),await G(m,[],{env:s(),timeoutMs:j});let o=await I();if(o.length===0)await Hm("about:blank"),o=await I();return o}async function J(m){let o=await R(),i=l(o,m);if(!i){if(m)throw Error(`No browser tab matching prefix "${m}". Run browser_cua(list) first.`);throw Error("No browser tab available after browser bootstrap.")}return{tab:i.target,page:i,pages:o}}async function lm({action:m,tab:o,url:i,selector:L,x:T,y:n,text:A,expression:w,outputPath:M}={}){switch(m){case"list":{let d=await R();return{status:"ok",action:m,browser:U(),pages:d}}case"navigate":{if(!i)throw Error("url is required for action=navigate");let d=await J(o),h=await k(["nav",d.tab,i],{timeoutMs:90000}),$=await I(),a=l($,d.tab)??d.page;return{status:"ok",action:m,browser:U(),tab:d.tab,url:a?.url||i,title:a?.title||"",message:h.stdout.trim(),pages:$}}case"snapshot":{let d=await J(o),h=await k(["snap",d.tab]);return{status:"ok",action:m,browser:U(),tab:d.tab,title:d.page?.title||"",url:d.page?.url||"",snapshot:h.stdout.trim()}}case"screenshot":{let d=await J(o),h=M?_(M):Vm();g(N(h),{recursive:!0});let $=await k(["shot",d.tab,h],{timeoutMs:120000}),a=Am(h).toString("base64");return{status:"ok",action:m,browser:U(),tab:d.tab,title:d.page?.title||"",url:d.page?.url||"",imagePath:h,imageBase64:a,mimeType:"image/png",message:$.stdout.trim()}}case"click":{if(!L)throw Error("selector is required for action=click");let d=await J(o),h=await k(["click",d.tab,L]);return{status:"ok",action:m,browser:U(),tab:d.tab,selector:L,message:h.stdout.trim()}}case"click_xy":{if(typeof T!=="number"||Number.isNaN(T)||typeof n!=="number"||Number.isNaN(n))throw Error("x and y are required numbers for action=click_xy");let d=await J(o),h=await k(["clickxy",d.tab,String(T),String(n)]);return{status:"ok",action:m,browser:U(),tab:d.tab,x:T,y:n,message:h.stdout.trim()}}case"type":{if(A==null||A==="")throw Error("text is required for action=type");let d=await J(o),h=await k(["type",d.tab,A]);return{status:"ok",action:m,browser:U(),tab:d.tab,textLength:A.length,message:h.stdout.trim()}}case"evaluate":{if(!w)throw Error("expression is required for action=evaluate");let d=await J(o),h=await k(["eval",d.tab,w]);return{status:"ok",action:m,browser:U(),tab:d.tab,value:h.stdout.trim()}}case"stop":{let{launchScript:d}=await S();try{await k(["stop"])}catch{}let h=await G(d,["--kill"],{env:s(),timeoutMs:30000});return{status:"ok",action:m,browser:U(),message:(h.stdout||"Stopped browser CUA lane.").trim()}}default:throw Error(`Unsupported browser action: ${m}`)}}function Sm(m){switch(m.action){case"list":{if(!Array.isArray(m.pages)||m.pages.length===0)return"Browser CUA is ready, but no pages are open.";return["Open browser tabs:",...m.pages.map((o)=>o.url?`${o.target} ${o.title||"(untitled)"} ${o.url}`:`${o.target} ${o.title||"(untitled)"}`)].join(`
|
|
1
|
+
import{createHash as dm}from"node:crypto";import{spawn as nm}from"node:child_process";import{existsSync as V,mkdirSync as g,readFileSync as Am}from"node:fs";import Tm from"node:http";import{homedir as Lm,platform as $m,tmpdir as c}from"node:os";import{dirname as N,join as f,resolve as Y}from"node:path";import{fileURLToPath as wm}from"node:url";import{spawn as P}from"node:child_process";import{existsSync as p}from"node:fs";import{homedir as W,platform as H}from"node:os";import J from"node:path";var x=900000,E=16384,K=5,t=1000;function Q(...m){return J.win32.join(...m)}function _(m,o){if(o&&!m.includes(o))m.push(o)}function a(m,o,i){let L=m.PATH??m.Path??m.path??"",T=o==="win32"?";":J.delimiter,n=o==="win32"?(m.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean):[""],A=[];for(let w of L.split(T).filter(Boolean))for(let M of i){if(o==="win32"&&J.win32.extname(M)){_(A,Q(w,M));continue}for(let d of n){let h=o==="win32"?`${M}${d.toLowerCase()}`:M;_(A,o==="win32"?Q(w,h):J.join(w,h))}}return A}function v({env:m=process.env,platformName:o=H(),homeDir:i=W(),exists:L=p}={}){let T=[];if(o==="win32"){for(let n of[m.LOCALAPPDATA,m.ProgramFiles,m["ProgramFiles(x86)"]]){if(!n)continue;_(T,Q(n,"Google","Chrome","Application","chrome.exe")),_(T,Q(n,"Chromium","Application","chrome.exe"))}_(T,i?Q(i,"AppData","Local","Google","Chrome","Application","chrome.exe"):void 0),T.push(...a(m,o,["chrome","chromium"]))}else if(o==="darwin"){for(let n of["/Applications",J.join(i,"Applications")])_(T,J.join(n,"Google Chrome.app","Contents","MacOS","Google Chrome")),_(T,J.join(n,"Chromium.app","Contents","MacOS","Chromium"));T.push(...a(m,o,["google-chrome-stable","google-chrome","chromium","chromium-browser"]))}else if(o==="linux"){for(let n of["/usr/bin/google-chrome-stable","/usr/bin/google-chrome","/usr/bin/chromium","/usr/bin/chromium-browser","/snap/bin/chromium","/usr/local/bin/google-chrome","/usr/local/bin/chromium"])_(T,n);T.push(...a(m,o,["google-chrome-stable","google-chrome","chromium","chromium-browser"]))}return T.find((n)=>L(n))}function C(m,...o){return{command:m,args:o}}function z(m,o){if(o===0)return m;return m.map(({command:i,args:L})=>C("sudo","-n",i,...L))}function r({platformName:m=H(),uid:o=typeof process.getuid==="function"?process.getuid():void 0}={}){if(m==="darwin")return[{id:"homebrew-google-chrome",commands:[C("brew","install","--cask","google-chrome")]}];if(m==="win32"){let i=["install","--id","Google.Chrome","-e","--silent","--accept-package-agreements","--accept-source-agreements","--disable-interactivity"];return[{id:"winget-user-google-chrome",commands:[C("winget",...i.slice(0,4),"--scope","user",...i.slice(4))]},{id:"winget-machine-google-chrome",commands:[C("winget",...i)]},{id:"chocolatey-google-chrome",commands:[C("choco","install","googlechrome","-y","--no-progress")]}]}if(m==="linux")return[{id:"apt-chromium",commands:z([C("apt-get","update"),C("apt-get","install","-y","chromium")],o)},{id:"apt-chromium-browser",commands:z([C("apt-get","update"),C("apt-get","install","-y","chromium-browser")],o)},{id:"dnf-chromium",commands:z([C("dnf","install","-y","chromium")],o)},{id:"yum-chromium",commands:z([C("yum","install","-y","chromium")],o)},{id:"pacman-chromium",commands:z([C("pacman","-S","--noconfirm","--needed","chromium")],o)},{id:"zypper-chromium",commands:z([C("zypper","--non-interactive","install","chromium")],o)},{id:"apk-chromium",commands:z([C("apk","add","chromium")],o)}];return[]}function e(m=process.env){let o=m.DM_CUA_AUTO_INSTALL;if(o===void 0)return!0;return!["0","false","no","off"].includes(o.trim().toLowerCase())}function mm(m){let o=Number(m.DM_CUA_INSTALL_TIMEOUT_MS);return Number.isFinite(o)&&o>0?o:x}function F(m,o){let i=`${m}${o}`;if(Buffer.byteLength(i)<=E)return i;return i.slice(-E)}function om(m,o,{env:i=process.env,timeoutMs:L=mm(i)}={}){return new Promise((T)=>{let n=!1,A="",w,M=P(m,o,{env:i,shell:!1,stdio:["ignore","pipe","pipe"],windowsHide:!0}),d=(h)=>{if(n)return;n=!0,clearTimeout(w),T(h)};M.stdout?.on("data",(h)=>{A=F(A,h.toString())}),M.stderr?.on("data",(h)=>{A=F(A,h.toString())}),M.on("error",(h)=>{d({status:h.code==="ENOENT"?"unavailable":"failed",exitCode:null,message:`${h.message}${A?`
|
|
2
|
+
${A.trim()}`:""}`})}),M.on("close",(h,$)=>{d({status:h===0?"ok":"failed",exitCode:h,message:A.trim()||($?`installer terminated by signal ${$}`:"")})}),w=setTimeout(()=>{M.kill(),d({status:"timeout",exitCode:null,message:`installer timed out after ${L}ms`})},L)})}function im(m){if(m.startsWith("homebrew-"))return"Homebrew";if(m.startsWith("winget-"))return"winget";return m.split("-")[0]}function hm(m){let o=m.message?`: ${m.message}`:"";return`${m.id} ${m.status}${o}`}async function b({env:m=process.env,platformName:o=H(),uid:i=typeof process.getuid==="function"?process.getuid():void 0,findExecutable:L=()=>v({env:m,platformName:o,homeDir:W()}),runCommand:T=(A,w)=>om(A,w,{env:m}),sleep:n=(A)=>new Promise((w)=>{setTimeout(w,A)})}={}){let A=L();if(A)return{status:"existing",path:A,method:null,attempts:[]};if(!e(m))throw Error("Chrome was not found and automatic installation is disabled by DM_CUA_AUTO_INSTALL.");let w=r({platformName:o,uid:i});if(w.length===0)throw Error(`Chrome was not found and no automatic Chrome installer is defined for ${o}.`);let M=[];for(let h of w){let $={status:"ok",exitCode:0,message:""};for(let D of h.commands)if($=await T(D.command,D.args),$.status!=="ok")break;if($.status!=="ok"){M.push({id:h.id,status:$.status,exitCode:$.exitCode,message:$.message});continue}let U;for(let D=0;D<K;D+=1){if(U=L(),U)break;if(D<K-1)await n(t)}if(U)return M.push({id:h.id,status:"installed",exitCode:$.exitCode,message:$.message}),{status:"installed",path:U,method:h.id,attempts:M};M.push({id:h.id,status:"missing-after-success",exitCode:$.exitCode,message:`${im(h.id)} reported success, but Chrome was not found`})}let d=M.map(hm).join("; ");throw Error(`Chrome automatic installation failed. ${d}`)}var q=N(wm(import.meta.url)),Bm=Y(q,".."),Mm=9322,Cm=400,j=60000,um=/^(about:|https?:\/\/|file:|chrome-error:\/\/)/i,fm={chrome:"Chrome",cloak:"CloakBrowser"};function O(m){let o=Number.parseInt(String(m??""),10);return Number.isInteger(o)&&o>1024&&o<65535?o:null}function Um(m){return dm("sha256").update(String(m||"default")).digest("hex")}function km(m){let o=String(m||"chrome").trim().toLowerCase();if(o==="cloakbrowser"||o==="cloak-browser")return"cloak";if(o==="chromium"||o==="google-chrome"||o==="chrome")return"chrome";return o.replace(/[^a-z0-9_.-]/g,"-")||"chrome"}function Xm(m,o){let i=m.DM_CUA_BROWSER_PATH||(o==="cloak"?m.DM_CUA_CLOAK_PATH||m.CLOAKBROWSER_BINARY_PATH:void 0)||m.CHROME_PATH;return i?Y(String(i)):void 0}function _m(m=process.env,o=process.cwd()){let i=m.DM_CUA_SCOPE||m.DM_CODING_AGENT_DIR||m.PI_CODING_AGENT_DIR||o,L=Um(Y(String(i||"."))),T=String(m.DM_CUA_INSTANCE_ID||L.slice(0,12)).replace(/[^a-zA-Z0-9_.-]/g,"-"),n=km(m.DM_CUA_BROWSER||m.DM_BROWSER_CUA_BROWSER||m.DM_CUA_BROWSER_KIND),A=m.DM_CUA_BROWSER_DISPLAY_NAME||fm[n]||n,w=Xm(m,n),M=O(m.DM_CUA_PORT)??O(m.GREEDY_SEARCH_PORT)??Mm+Number.parseInt(L.slice(0,8),16)%Cm,d=n==="chrome"?"chrome":n,h=Y(m.DM_CUA_PROFILE_DIR||f(c(),`dm-cua-${d}-profile-${T}`)),$=$m()==="win32"?c():"/tmp";return{instanceId:T,browserKind:n,browserDisplayName:A,browserExecutablePath:w,browserExecutableIsExplicit:Boolean(w),browserInstallation:void 0,port:M,profileDir:h,pidFile:f(h,"chrome.pid"),modeFile:f(h,"chrome-mode"),pagesCache:f(h,"cdp-pages.json"),socketDir:f($,`dm-cua-cdp-${T}`)}}var u=_m(),Ym=u.port,Sm=u.profileDir;function k(){return{kind:u.browserKind,displayName:u.browserDisplayName,executablePath:u.browserExecutablePath,installation:u.browserInstallation??null,profileDir:u.profileDir,port:u.port}}async function zm(m=u,{env:o=process.env,exists:i=V,ensureChrome:L=b}={}){if(m.browserKind==="cloak"&&!m.browserExecutablePath)throw Error(["CloakBrowser selected for browser CUA, but no executable path was provided.","Install/pre-download CloakBrowser yourself, then set DM_CUA_BROWSER_PATH, DM_CUA_CLOAK_PATH, CLOAKBROWSER_BINARY_PATH, or CHROME_PATH.","DM does not bundle the compiled CloakBrowser binary because its upstream license allows use but not redistribution."].join(" "));if(m.browserExecutablePath&&!i(m.browserExecutablePath))throw Error(`${m.browserDisplayName} executable not found: ${m.browserExecutablePath}`);if(m.browserExecutablePath)return m;if(m.browserKind!=="chrome")throw Error(`${m.browserDisplayName} browser CUA requires an explicit executable path via DM_CUA_BROWSER_PATH.`);let T=await L({env:o});return m.browserExecutablePath=T.path,m.browserInstallation={status:T.status,method:T.method,attempts:T.attempts.map(({id:n,status:A,exitCode:w})=>({id:n,status:A,exitCode:w}))},m}var Z;async function Jm(){if(!Z)Z=zm(u).catch((m)=>{throw Z=void 0,m});return Z}function B(){let o=[Y(q,"..","greedysearch-dm"),Y(q,"..","..","greedysearch-dm")].map((i)=>({launchScript:f(i,"bin","launch.mjs"),cdpScript:f(i,"bin","cdp.mjs")}));for(let i of o)if(V(i.launchScript)&&V(i.cdpScript))return i;return o[0]}function ym(m=u,o=process.env){let i=o.GREEDY_SEARCH_VISIBLE??o.DM_CUA_VISIBLE??o.DM_BROWSER_CUA_VISIBLE;return{...o,...m.browserExecutablePath?{CHROME_PATH:m.browserExecutablePath}:{},CDP_PROFILE_DIR:m.profileDir.replace(/\\/g,"/"),CDP_PAGES_CACHE:m.pagesCache.replace(/\\/g,"/"),CDP_SOCKET_DIR:m.socketDir.replace(/\\/g,"/"),GREEDY_SEARCH_BROWSER_LABEL:m.browserDisplayName,GREEDY_SEARCH_PORT:String(m.port),GREEDY_SEARCH_PROFILE_DIR:m.profileDir.replace(/\\/g,"/"),GREEDY_SEARCH_PID_FILE:m.pidFile.replace(/\\/g,"/"),GREEDY_SEARCH_MODE_FILE:m.modeFile.replace(/\\/g,"/"),GREEDY_SEARCH_ALLOW_PORT_CLEANUP:o.GREEDY_SEARCH_ALLOW_PORT_CLEANUP??"0",...i===void 0?{}:{GREEDY_SEARCH_VISIBLE:i}}}function s(){return ym(u,process.env)}function Dm(m){return um.test(m)}function Qm(m){return m.split(/\r?\n/).map((o)=>o.trimEnd()).filter(Boolean).map((o)=>{let i=o.trim().split(/\s{2,}/).filter(Boolean);if(i.length===0)return null;let L=i[0];if(i.length===1)return{target:L,title:"",url:""};if(i.length===2&&Dm(i[1]))return{target:L,title:"",url:i[1]};let T=i.at(-1)??"",n=i.slice(1,-1).join(" ");return{target:L,title:n,url:T}}).filter(Boolean)}function Vm(m){let o=String(m??"").trim();if(!o)throw Error("selector is required for action=click");if(/:contains\s*\(/i.test(o))throw Error(":contains(...) is not a standard CSS selector. Use browser_cua(snapshot) to inspect a standard selector, or browser_cua(evaluate) for text matching.");return o}function Zm(){let m=process.env.DM_CODING_AGENT_DIR||process.env.PI_CODING_AGENT_DIR;return m?Y(m):f(Lm(),".dm","agent")}function am(){let m=f(Zm(),"cua","screenshots");g(m,{recursive:!0});let o=new Date().toISOString().replace(/[:.]/g,"-");return f(m,`browser-${o}.png`)}function G(m,o,{env:i=process.env,timeoutMs:L=j}={}){return new Promise((T,n)=>{let A=nm("node",[m,...o],{env:i,stdio:["ignore","pipe","pipe"]}),w="",M="",d=!1,h=setTimeout(()=>{if(d)return;d=!0,A.kill("SIGTERM"),n(Error(`Timed out running ${m}`))},L);A.stdout.on("data",($)=>{w+=$.toString()}),A.stderr.on("data",($)=>{M+=$.toString()}),A.on("error",($)=>{if(d)return;d=!0,clearTimeout(h),n($)}),A.on("close",($)=>{if(d)return;if(d=!0,clearTimeout(h),$!==0){n(Error((M||w||`exit ${$}`).trim()));return}T({stdout:w,stderr:M})})})}function Hm(m,o){return new Promise((i,L)=>{let T=Tm.request({host:"127.0.0.1",port:Ym,path:o,method:m},(n)=>{let A="";n.on("data",(w)=>{A+=w.toString()}),n.on("end",()=>{if((n.statusCode??500)>=400){L(Error(`Browser CDP HTTP ${n.statusCode}: ${A.trim()}`));return}try{i(A?JSON.parse(A):{})}catch(w){L(w)}})});T.on("error",L),T.end()})}async function qm(m="about:blank"){return Hm("PUT",`/json/new?${encodeURIComponent(m)}`)}async function X(m,o={}){let{cdpScript:i}=B();return G(i,m,{env:s(),timeoutMs:o.timeoutMs??j})}async function I(){let m=await X(["list"]);return Qm(m.stdout)}function S(m,o){if(!o)return m[0]??null;let i=o.toUpperCase();return m.find((L)=>L.target.toUpperCase().startsWith(i))??null}async function l(){let{launchScript:m,cdpScript:o}=B();if(!V(m)||!V(o))throw Error("Bundled browser helpers are missing. Rebuild DM so dm-cua and greedysearch-dm are staged together.");return{launchScript:m,cdpScript:o}}async function R(){let{launchScript:m}=await l();await Jm(),await G(m,[],{env:s(),timeoutMs:j});let o=await I();if(o.length===0)await qm("about:blank"),o=await I();return o}async function y(m){let o=await R(),i=S(o,m);if(!i){if(m)throw Error(`No browser tab matching prefix "${m}". Run browser_cua(list) first.`);throw Error("No browser tab available after browser bootstrap.")}return{tab:i.target,page:i,pages:o}}async function lm({action:m,tab:o,url:i,selector:L,x:T,y:n,text:A,expression:w,outputPath:M}={}){switch(m){case"list":{let d=await R();return{status:"ok",action:m,browser:k(),pages:d}}case"navigate":{if(!i)throw Error("url is required for action=navigate");let d=await y(o),h=await X(["nav",d.tab,i],{timeoutMs:90000}),$=await I(),U=S($,d.tab)??d.page;return{status:"ok",action:m,browser:k(),tab:d.tab,url:U?.url||i,title:U?.title||"",message:h.stdout.trim(),pages:$}}case"snapshot":{let d=await y(o),h=await X(["snap",d.tab]);return{status:"ok",action:m,browser:k(),tab:d.tab,title:d.page?.title||"",url:d.page?.url||"",snapshot:h.stdout.trim()}}case"screenshot":{let d=await y(o),h=M?Y(M):am();g(N(h),{recursive:!0});let $=await X(["shot",d.tab,h],{timeoutMs:120000}),U=Am(h).toString("base64");return{status:"ok",action:m,browser:k(),tab:d.tab,title:d.page?.title||"",url:d.page?.url||"",imagePath:h,imageBase64:U,mimeType:"image/png",message:$.stdout.trim()}}case"click":{let d=Vm(L),h=await y(o),$=await X(["click",h.tab,d]);return{status:"ok",action:m,browser:k(),tab:h.tab,selector:d,message:$.stdout.trim()}}case"click_xy":{if(typeof T!=="number"||Number.isNaN(T)||typeof n!=="number"||Number.isNaN(n))throw Error("x and y are required numbers for action=click_xy");let d=await y(o),h=await X(["clickxy",d.tab,String(T),String(n)]);return{status:"ok",action:m,browser:k(),tab:d.tab,x:T,y:n,message:h.stdout.trim()}}case"type":{if(A==null||A==="")throw Error("text is required for action=type");let d=await y(o),h=await X(["type",d.tab,A]);return{status:"ok",action:m,browser:k(),tab:d.tab,textLength:A.length,message:h.stdout.trim()}}case"evaluate":{if(!w)throw Error("expression is required for action=evaluate");let d=await y(o),h=await X(["eval",d.tab,w]);return{status:"ok",action:m,browser:k(),tab:d.tab,value:h.stdout.trim()}}case"stop":{let{launchScript:d}=await l();try{await X(["stop"])}catch{}let h=await G(d,["--kill"],{env:s(),timeoutMs:30000});return{status:"ok",action:m,browser:k(),message:(h.stdout||"Stopped browser CUA lane.").trim()}}default:throw Error(`Unsupported browser action: ${m}`)}}function Rm(m){switch(m.action){case"list":{if(!Array.isArray(m.pages)||m.pages.length===0)return"Browser CUA is ready, but no pages are open.";return["Open browser tabs:",...m.pages.map((o)=>o.url?`${o.target} ${o.title||"(untitled)"} ${o.url}`:`${o.target} ${o.title||"(untitled)"}`)].join(`
|
|
3
3
|
`)}case"navigate":return[`Navigated browser tab ${m.tab} to ${m.url||"(unknown URL)"}`,m.title?`Title: ${m.title}`:""].filter(Boolean).join(`
|
|
4
4
|
`);case"snapshot":return[`Browser snapshot for ${m.tab}`,m.snapshot||"(empty snapshot)"].join(`
|
|
5
5
|
`);case"screenshot":return[`Saved browser screenshot for ${m.tab} at ${m.imagePath}`,m.title?`Title: ${m.title}`:"",m.url?`URL: ${m.url}`:""].filter(Boolean).join(`
|
|
6
|
-
`);case"click":return`Clicked selector ${JSON.stringify(m.selector)} on browser tab ${m.tab}`;case"click_xy":return`Clicked browser tab ${m.tab} at CSS coordinates (${m.x}, ${m.y})`;case"type":return`Typed ${m.textLength} characters into browser tab ${m.tab}`;case"evaluate":return`Browser evaluate result for ${m.tab}: ${m.value}`;case"stop":return m.message||"Stopped browser CUA lane.";default:return JSON.stringify(m,null,2)}}export{lm as runBrowserAction,
|
|
6
|
+
`);case"click":return`Clicked selector ${JSON.stringify(m.selector)} on browser tab ${m.tab}`;case"click_xy":return`Clicked browser tab ${m.tab} at CSS coordinates (${m.x}, ${m.y})`;case"type":return`Typed ${m.textLength} characters into browser tab ${m.tab}`;case"evaluate":return`Browser evaluate result for ${m.tab}: ${m.value}`;case"stop":return m.message||"Stopped browser CUA lane.";default:return JSON.stringify(m,null,2)}}export{Vm as validateBrowserSelector,lm as runBrowserAction,_m as resolveBrowserRuntimeConfig,ym as resolveBrowserProcessEnv,B as resolveBrowserHelperPaths,Rm as renderBrowserActionText,Qm as parseListOutput,zm as ensureBrowserSelectionUsable,R as ensureBrowserReady,Sm as BROWSER_PROFILE_DIR};
|
|
@@ -72,7 +72,9 @@ ${q$}`:q$:S?.error;if(G&&j.artifactConfig?.enabled!==!1){if(j.artifactConfig?.in
|
|
|
72
72
|
${U}`}function a5($,j){let J=r.join($,"progress.md");if(!j.parallel.some((Z)=>Z.task.includes(`Update progress at: ${J}`)))return;ej($)}function fj($){if(!$.artifactsDir||$.artifactConfig?.enabled===!1||$.artifactConfig?.includeTranscript===!1)return;return c1($.artifactsDir,$.runId,$.agent,$.flatStepCount>1?$.flatIndex:void 0).transcriptPath}async function r8($){let{id:j,steps:J,resultPath:Z,cwd:Q,placeholder:X,taskIndex:W,totalTasks:U,maxOutput:G,artifactsDir:B,artifactConfig:q}=$,O=new y1($.globalConcurrencyLimit??tj),T="",y={},h=[],S=Date.now(),v$=$.share===!0,k=$.asyncDir,f=r.join(k,"status.json"),n=r.join(k,"events.jsonl"),d$=r.join(k,`subagent-log-${j}.md`),W$=$.controlConfig??LJ,y$=new Map,K$=new Map,g$=new Map,A$=[],s=!1,E$,X$,_$,E=!1,t=!1,p=$.timeoutMs!==void 0?`Subagent timed out after ${$.timeoutMs}ms.`:void 0,q$=new AbortController,Y$={input:0,output:0,total:0},o$,u$=aj(J),j$=u$.length,c=[],H$=[],k$=0;for(let H=0;H<J.length;H++){let V=J[H];if($0(V)){c.push({start:k$,count:V.parallel.length,stepIndex:H});for(let K of V.parallel){let _=k$,z=fj({artifactsDir:B,artifactConfig:q,runId:j,agent:K.agent,flatIndex:_,flatStepCount:j$});H$.push({agent:K.agent,phase:K.phase,label:K.label,outputName:K.outputName,structured:K.structured,status:"pending",...K.toolBudget?{toolBudget:C0(K.toolBudget)}:{},...K.sessionFile?{sessionFile:K.sessionFile}:{},...z?{transcriptPath:z}:{},skills:K.skills,model:K.model,thinking:K.thinking,attemptedModels:K.modelCandidates&&K.modelCandidates.length>0?K.modelCandidates:K.model?[K.model]:void 0,recentTools:[],recentOutput:[]}),k$++}}else if(j0(V))c.push({start:k$,count:1,stepIndex:H}),H$.push({agent:`expand:${V.parallel.agent}`,phase:V.phase??V.parallel.phase,label:V.label??V.parallel.label??`Dynamic fanout (${V.collect.as})`,outputName:V.collect.as,structured:Boolean(V.collect.outputSchema),status:"pending",...V.parallel.toolBudget?{toolBudget:C0(V.parallel.toolBudget)}:{},recentTools:[],recentOutput:[]}),k$++;else{let K=k$,_=fj({artifactsDir:B,artifactConfig:q,runId:j,agent:V.agent,flatIndex:K,flatStepCount:j$});H$.push({agent:V.agent,phase:V.phase,label:V.label,outputName:V.outputName,structured:V.structured,status:"pending",...V.toolBudget?{toolBudget:C0(V.toolBudget)}:{},...V.sessionFile?{sessionFile:V.sessionFile}:{},..._?{transcriptPath:_}:{},skills:V.skills,model:V.model,thinking:V.thinking,attemptedModels:V.modelCandidates&&V.modelCandidates.length>0?V.modelCandidates:V.model?[V.model]:void 0,recentTools:[],recentOutput:[]}),k$++}}let W0=Boolean($.sessionDir)||v$||u$.some((H)=>Boolean(H.sessionFile)),Y={lifecycleArtifactVersion:S0,runId:j,...$.sessionId?{sessionId:$.sessionId}:{},mode:$.resultMode??(u$.length>1?"chain":"single"),state:"running",lastActivityAt:S,startedAt:S,lastUpdate:S,...$.timeoutMs!==void 0?{timeoutMs:$.timeoutMs}:{},...$.deadlineAt!==void 0?{deadlineAt:$.deadlineAt}:{},...$.turnBudget?{turnBudget:Rj($.turnBudget)}:{},...$.toolBudget?{toolBudget:C0($.toolBudget)}:{},pid:process.pid,cwd:Q,currentStep:0,chainStepCount:J.length,parallelGroups:c,workflowGraph:$.workflowGraph,steps:H$,artifactsDir:B,sessionDir:$.sessionDir,outputFile:r.join(k,"output-0.log")};e.mkdirSync(k,{recursive:!0}),D$(f,Y);let u=(H)=>{if(!$.nestedRoute||!$.nestedSelf)return;try{Y8($.nestedRoute,{type:H,ts:Date.now(),parentRunId:$.nestedSelf.parentRunId,parentStepIndex:$.nestedSelf.parentStepIndex,child:W8(Y,k,{id:j,parentRunId:$.nestedSelf.parentRunId,parentStepIndex:$.nestedSelf.parentStepIndex,depth:$.nestedSelf.depth,path:$.nestedSelf.path,mode:Y.mode,ts:Date.now()})})}catch(V){console.error("Failed to emit nested async status event:",V)}},U$=()=>{if(!$.workflowGraph)return;let H=structuredClone(Y.workflowGraph??$.workflowGraph),V=(_)=>{if(_==="complete"||_==="completed")return"completed";if(_==="running"||_==="failed"||_==="paused"||_==="pending")return _;return"pending"},K=(_)=>{if(_.flatIndex!==void 0){let z=Y.steps[_.flatIndex];if(z)_.status=V(z.status),_.error=z.error,_.acceptanceStatus=z.acceptance?.status;if(Y.currentStep===_.flatIndex)H.currentNodeId=_.id}for(let z of _.children??[])K(z);if(_.children?.length){if(_.children.every((z)=>z.status==="completed"))_.status="completed";else if(_.children.some((z)=>z.status==="running"))_.status="running";else if(_.children.some((z)=>z.status==="failed"))_.status="failed";else if(_.children.some((z)=>z.status==="paused"))_.status="paused"}if(_.error)_.status="failed"};for(let _ of H.nodes)K(_);Y.workflowGraph=H},a=()=>{U$(),D$(f,Y),u(Y.state==="running"||Y.state==="queued"?"subagent.nested.updated":"subagent.nested.completed")},N$=(H,V)=>{if(!V){y$.delete(H);return}if(y$.set(H,V),s)V()},f$=(H,V)=>{if(!V){K$.delete(H);return}if(K$.set(H,V),E)V()},S$=(H,V)=>{if(!V){g$.delete(H);return}g$.set(H,V)},t$=()=>{for(let H of[...y$.values()])H()},P$=()=>{for(let H of[...K$.values()])H()},V$=function*(H){for(let V of H??[])yield V,yield*V$(V.children),yield*V$(V.steps?.flatMap((K)=>K.children??[]))},l$=()=>{if(!$.nestedRoute)return;let H;try{H=Mj($.nestedRoute)}catch(V){$$(n,JSON.stringify({type:"subagent.nested.interrupt_failed",ts:Date.now(),runId:j,message:V instanceof Error?V.message:String(V)}));return}for(let V of V$(H.children)){if(V.state!=="running"&&V.state!=="queued")continue;let K=V.asyncDir??_j($.nestedRoute.rootRunId,V);if(!K)continue;try{KJ({asyncDir:K,pid:V.pid,source:"ancestor-interrupt"})}catch(_){$$(n,JSON.stringify({type:"subagent.nested.interrupt_failed",ts:Date.now(),runId:j,targetRunId:V.id,message:_ instanceof Error?_.message:String(_)}))}}},p$=()=>{if(!$.nestedRoute)return;let H;try{H=Mj($.nestedRoute)}catch(V){$$(n,JSON.stringify({type:"subagent.nested.timeout_failed",ts:Date.now(),runId:j,message:V instanceof Error?V.message:String(V)}));return}for(let V of V$(H.children)){if(V.state!=="running"&&V.state!=="queued")continue;let K=V.asyncDir??_j($.nestedRoute.rootRunId,V);if(!K)continue;try{m1({asyncDir:K,pid:V.pid,source:"ancestor-timeout"})}catch(_){$$(n,JSON.stringify({type:"subagent.nested.timeout_failed",ts:Date.now(),runId:j,targetRunId:V.id,message:_ instanceof Error?_.message:String(_)}))}}},e$=(H)=>({agent:H,output:"Paused after interrupt. Waiting for explicit next action.",exitCode:0,interrupted:!0}),P=(H)=>({agent:H,output:p??"Subagent timed out.",error:p??"Subagent timed out.",exitCode:1,timedOut:!0}),D=()=>{if(Y.mode!=="chain"||Y.state!=="running")return;let H=g8(k);if(H.length===0){let N=Dj(k);if((Y.pendingAppends??0)!==N)Y.pendingAppends=N,Y.lastUpdate=Date.now(),a();return}let V=H.flatMap((N)=>N.steps);J.push(...V);let K=Date.now(),_=Dj(k),z=c8({status:Y,steps:V,now:K,pendingAppends:_});if(p0.push(...Array.from({length:z.addedFlatSteps},()=>G1())),T0.push(...Array.from({length:z.addedFlatSteps},()=>{return})),$.childIntercomTargets)$.childIntercomTargets=Y.steps.map((N,w)=>Aj(j,N.agent,w));a();for(let N of H)$$(n,JSON.stringify({type:"subagent.chain.append.accepted",ts:K,runId:j,requestId:N.id,stepCount:N.steps.length,pendingAppends:_}))},i=(H,V,K,_)=>{let z=Y.workflowGraph?.nodes.find((N)=>N.id===`step-${H}`);if(!z)return;z.status=V,z.error=K,z.acceptanceStatus=_?.status??z.acceptanceStatus},M$=(H)=>{let V=Y.steps[H],K=V?.lastActivityAt??V?.startedAt??S,_=r.join(k,`output-${H}.log`);try{K=Math.max(K,e.statSync(_).mtimeMs)}catch(z){if(z.code!=="ENOENT")console.error(`Failed to inspect async output file '${_}':`,z)}return K},l0=new Set,vj=new Set,p0=H$.map(()=>G1()),T0=H$.map(()=>{return}),s8=300000,E0=(H)=>{if(!W$.enabled)return;let V=$.childIntercomTargets?.[H.index??Y.currentStep],K=H.type==="active_long_running"?W$.notifyChannels.filter((_)=>_!=="intercom"):W$.notifyChannels;if(K.length===0||!FJ(W$,H,l0,V))return;$$(n,JSON.stringify({type:"subagent.control",event:H,channels:K,childIntercomTarget:V,noticeText:p1(H,V),...$.controlIntercomTarget&&K.includes("intercom")?{intercom:{to:$.controlIntercomTarget,message:OJ(H,V)}}:{}}))},A1=()=>{let H=Y.steps.filter((V)=>V.status==="running"&&typeof V.currentTool==="string"&&V.currentTool.length>0).sort((V,K)=>(K.currentToolStartedAt??0)-(V.currentToolStartedAt??0))[0];Y.currentTool=H?.currentTool,Y.currentToolStartedAt=H?.currentToolStartedAt,Y.currentPath=H?.currentPath},gj=(H,V)=>{if(!W$.enabled||vj.has(H))return!1;let K=Y.steps[H];if(!K||K.status!=="running"||K.activityState==="needs_attention")return!1;let _=G8(W$,{startedAt:K.startedAt??S,now:V,turns:K.turnCount??0,tokens:K.tokens?.total??0});if(!_)return!1;vj.add(H);let z=K.activityState;K.activityState="active_long_running",Y.activityState=Y.activityState==="needs_attention"?"needs_attention":"active_long_running";let N=A0({type:"active_long_running",from:z,to:"active_long_running",runId:j,agent:K.agent,index:H,ts:V,message:`${K.agent} is still active but long-running`,reason:_,turns:K.turnCount,tokens:K.tokens?.total,toolCount:K.toolCount,currentTool:K.currentTool,currentToolDurationMs:K.currentToolStartedAt?Math.max(0,V-K.currentToolStartedAt):void 0,currentPath:K.currentPath,elapsedMs:V-(K.startedAt??S)});return E0(N),!0},N1=(H)=>{if(Y.state!=="running")return;let V=Y.steps.map((w,d)=>({step:w,index:d})).filter(({step:w})=>w.status==="running").map(({index:w})=>w),K=H.targetIndex!==void 0?[H.targetIndex]:V,_=Date.now(),z=[],N=[];for(let w of K){let d=Y.steps[w];if(!d){N.push({index:w,reason:"child index out of range"});continue}if(d.status!=="running"){N.push({index:w,reason:`child is ${d.status}`});continue}VJ(k,w,H),d.steerCount=(d.steerCount??0)+1,d.lastSteerAt=_,z.push(w)}if(z.length>0)Y.steerCount=(Y.steerCount??0)+z.length,Y.lastSteerAt=_,Y.lastUpdate=_,a();$$(n,JSON.stringify({type:"subagent.steer.requested",ts:_,runId:j,requestId:H.id,message:H.message,...H.source?{source:H.source}:{},...H.targetIndex!==void 0?{targetIndex:H.targetIndex}:{},acceptedIndexes:z,...N.length?{rejected:N}:{}}))},C1=(H)=>{let V=[];for(let K of A$.splice(0))if(K.targetIndex===void 0)N1({...K,targetIndex:H});else if(K.targetIndex===H)N1(K);else V.push(K);A$.push(...V)},T1=(H,V,K,_=Date.now())=>{let z=Y.steps[H];if(!z)return;z.model=V,z.thinking=K,Y.lastUpdate=_,a()},a8=(H,V,K,_)=>{let z=$.turnBudget,N=Y.steps[H];if(!z||!N||E||t||N.turnBudgetExceeded)return;if(V<z.maxTurns){let v={...z,outcome:"within-budget",turnCount:V};N.turnBudget=v,Y.turnBudget=v;return}let w=O1(z,V,!1);if(N.turnBudget=w,Y.turnBudget=w,!N.wrapUpRequested)N.wrapUpRequested=!0,Y.wrapUpRequested=!0,Ij(N,[bj(z,V)]);if(!wj(z,V,_))return;let d=O1(z,V,!0),Z$=u0(z,V);N.turnBudget=d,N.turnBudgetExceeded=!0,N.wrapUpRequested=!0,N.error=Z$,t=!0,Y.turnBudget=d,Y.turnBudgetExceeded=!0,Y.wrapUpRequested=!0,Y.error=Z$,Y.lastUpdate=K,$$(n,JSON.stringify({type:"subagent.step.turn_budget_exceeded",ts:K,runId:j,stepIndex:H,agent:N.agent,turnCount:V,maxTurns:z.maxTurns,graceTurns:z.graceTurns,message:Z$})),g$.get(H)?.(Z$,d)},E1=(H,V)=>{let K=Y.steps[H];if(!K)return;let _=Date.now();if(Y.currentStep=H,V.type==="tool_execution_start"&&V.toolName){let z=qj(V.toolName,V.args),N=U8(V.toolName,V.args);K.toolCount=(K.toolCount??0)+1;let w=u$[H]?.toolBudget;if(w)K.toolBudget=Z1(w,K.toolCount),Y.toolBudget=K.toolBudget;K.currentTool=V.toolName,K.currentToolArgs=w0(V.args??{}),K.currentToolStartedAt=_,K.currentPath=N,T0[H]={tool:V.toolName,path:N,mutates:z,startedAt:_},Y.toolCount=(Y.toolCount??0)+1,A1()}else if(V.type==="tool_execution_end"){if(K.currentTool)K.recentTools??=[],K.recentTools.push({tool:K.currentTool,args:K.currentToolArgs||"",endMs:_});K.currentTool=void 0,K.currentToolArgs=void 0,K.currentToolStartedAt=void 0,K.currentPath=void 0,A1()}else if(V.type==="tool_result_end"&&V.message){let z=T0[H];T0[H]=void 0;let N=s$(V.message.content);if(z&&N.includes("Tool budget hard limit reached")){let w=u$[H]?.toolBudget;if(w)K.toolBudget=Z1(w,K.toolCount??0,z.tool),K.toolBudgetBlocked=!0,Y.toolBudget=K.toolBudget,Y.toolBudgetBlocked=!0}if(Ij(K,N.split(`
|
|
73
73
|
`).slice(-10)),z?.mutates&&z8(N)){let w=p0[H];if(_8(w,{tool:z.tool,path:z.path,error:N.split(`
|
|
74
74
|
`).find((d)=>d.trim())?.trim().slice(0,180)??"mutating tool failed",ts:_},s8),W$.enabled&&M8(w,W$.failedToolAttemptsBeforeAttention)&&K.activityState!=="needs_attention"){let d=K.activityState;K.activityState="needs_attention",Y.activityState="needs_attention",E0(A0({type:"needs_attention",from:d,to:"needs_attention",runId:j,agent:K.agent,index:H,ts:_,message:`${K.agent} needs attention after repeated mutating tool failures`,reason:"tool_failures",turns:K.turnCount,tokens:K.tokens?.total,toolCount:K.toolCount,currentTool:z.tool,currentToolDurationMs:z.startedAt?Math.max(0,_-z.startedAt):void 0,currentPath:z.path,recentFailureSummary:L8(w)}))}}else if(z?.mutates)B8(p0[H])}else if(V.type==="message_end"&&V.message?.role==="assistant"){Ij(K,Cj(s$(V.message.content)).split(`
|
|
75
|
-
`).slice(-10)),K.turnCount=(K.turnCount??0)+1;let z=V.message.usage;if(z){let N=z.input??z.inputTokens??0,w=z.output??z.outputTokens??0,d=K.tokens?.input??0,Z$=K.tokens?.output??0;K.tokens={input:d+N,output:Z$+w,total:d+Z$+N+w};let v=Y.totalTokens?.input??0,F=Y.totalTokens?.output??0;Y.totalTokens={input:v+N,output:F+w,total:v+F+N+w}}Y.turnCount=Math.max(Y.turnCount??0,K.turnCount),a8(H,K.turnCount,_,hj(V.message))}A1(),K.lastActivityAt=_,Y.lastActivityAt=_,Y.lastUpdate=_,gj(H,_),a()},t8=(H)=>{if(!W$.enabled)return!1;let V=!1,K=Y.lastActivityAt??S;for(let z=0;z<Y.steps.length;z++){let N=Y.steps[z];if(N.status!=="running")continue;let w=M$(z);if(K=Math.max(K,w),N.lastActivityAt!==w)N.lastActivityAt=w,V=!0;if(qJ({config:W$,startedAt:N.startedAt??S,lastActivityAt:w,now:H})==="needs_attention"){let Z$=N.activityState;if(N.activityState="needs_attention",Z$!=="needs_attention")E0(A0({from:Z$,to:"needs_attention",runId:j,agent:N.agent,index:z,ts:H,lastActivityAt:w})),V=!0}else if(gj(z,H))V=!0}if(Y.lastActivityAt!==K)Y.lastActivityAt=K,V=!0;let _=Y.steps.some((z)=>z.activityState==="needs_attention")?"needs_attention":Y.steps.some((z)=>z.activityState==="active_long_running")?"active_long_running":void 0;if(_!==E$)E$=_,Y.activityState=_,V=!0;if(Y.lastUpdate=H,V)a();return V};if(W$.enabled)X$=setInterval(()=>{if(Y.state!=="running")return;let H=Date.now();t8(H)},1000),X$.unref?.();let mj=()=>{if(g1(k),s||Y.state!=="running")return;s=!0;let H=Date.now();Y.state="paused",E$=void 0,Y.activityState=void 0,Y.lastUpdate=H;for(let V of Y.steps)if(V.status==="running")V.status="paused",V.activityState=void 0,V.endedAt=H,V.durationMs=V.startedAt?H-V.startedAt:void 0,V.lastActivityAt=H;a(),$$(n,JSON.stringify({type:"subagent.run.paused",ts:H,runId:j})),l$(),t$()},cj=()=>{if(E||s||Y.state!=="running")return;E=!0;let H=Date.now(),V=p??"Subagent timed out.";Y.state="failed",Y.timedOut=!0,Y.error=V,E$=void 0,Y.activityState=void 0,Y.lastUpdate=H;for(let K of Y.steps){if(K.status!=="running"&&K.status!=="pending")continue;K.status="failed",K.error=V,K.exitCode=1,K.timedOut=!0,K.activityState=void 0,K.endedAt=H,K.durationMs=K.startedAt?H-K.startedAt:0,K.lastActivityAt=H}a(),$$(n,JSON.stringify({type:"subagent.run.timed_out",ts:H,runId:j,timeoutMs:$.timeoutMs,deadlineAt:$.deadlineAt,message:V})),q$.abort(),p$(),P$()};process.on(y5,mj);let e8=UJ(k,{onInterrupt:mj,onTimeout:cj,onSteer:(H)=>{if((H.targetIndex!==void 0?Y.steps[H.targetIndex]:void 0)?.status==="pending")A$.push(H);else if(H.targetIndex!==void 0||Y.steps.some((K)=>K.status==="running"))N1(H);else A$.push(H)}});if($.deadlineAt!==void 0){let H=Math.max(0,$.deadlineAt-Date.now());_$=setTimeout(cj,H),_$.unref?.()}$$(n,JSON.stringify({type:"subagent.run.started",lifecycleArtifactVersion:S0,ts:S,runId:j,mode:Y.mode,cwd:Q,pid:process.pid}));let R=0,dj=0;while(!0){if(s||E||t)break;if(D(),dj>=J.length)break;let H=dj++,V=J[H];if(j0(V)){let K=R,_;try{if(_=tJ(V,y,H,{maxItems:$.dynamicFanoutMaxItems,allowRunnerFields:!0}),_.collectedOnEmpty)Yj(V.collect.outputSchema,_.collectedOnEmpty)}catch(M){let o=Date.now(),L=M instanceof x?M.message:M instanceof Error?M.message:String(M);Y.state="failed",Y.error=L,Y.currentStep=R;let A=Y.steps[K];if(A)A.status="failed",A.error=L,A.startedAt=o,A.endedAt=o,A.durationMs=0,A.exitCode=1;Y.lastUpdate=o,i(H,"failed",L),a(),h.push({agent:V.parallel.agent,output:L,error:L,success:!1,exitCode:1});break}if(_.parallel.length===0){let M=Date.now(),o=_.collectedOnEmpty??[];y[V.collect.as]={text:JSON.stringify(o),structured:o,agent:V.parallel.agent,stepIndex:H},Y.outputs=y;let L=Y.steps[K];if(L)L.status="complete",L.startedAt=M,L.endedAt=M,L.durationMs=0;T="Dynamic fanout produced 0 results.";let A=V.effectiveAcceptance?.explicit&&!E?await M1({acceptance:V.effectiveAcceptance,output:"",report:Ej({results:[],notes:"Dynamic fanout produced 0 results."}),cwd:Q,signal:q$.signal,abortMessage:p??"Subagent timed out."}):void 0,I=E||q$.signal.aborted,G$=I?void 0:A;if(L&&G$)L.acceptance=G$;let x$=G$?L1(G$):void 0;if(I||x$){let g=I?p??"Subagent timed out.":x$;if(Y.state="failed",Y.error=g,L)L.status="failed",L.error=g,L.exitCode=1,L.timedOut=I?!0:void 0;i(H,"failed",g,G$),Y.lastUpdate=Date.now(),a(),h.push({agent:V.parallel.agent,output:g,error:g,success:!1,exitCode:1,timedOut:I?!0:void 0,acceptance:G$});break}R++,Y.lastUpdate=M,i(H,"completed",void 0,G$),a();continue}let z=_.parallel.map((M,o)=>{let L=V.thinkingOverrides?.[o],A=L?W1(V.parallel.model,L,!0):V.parallel.model,I=L?O0(A,L):void 0;return{...V.parallel,task:M.task??V.parallel.task,label:M.label??V.parallel.label,...V.sessionFiles?.[o]?{sessionFile:V.sessionFiles[o]}:{},...L?{...A?{model:A}:{},...I?{thinking:I}:{},...V.parallel.modelCandidates?{modelCandidates:V.parallel.modelCandidates.map((G$)=>W1(G$,L,!0))}:{}}:{},structuredOutput:void 0,structuredOutputSchema:V.parallel.structuredOutputSchema??V.parallel.structuredOutput?.schema}}),N=Math.max(Y.steps.length-1+z.length,1),w=z.map((M,o)=>{let L=fj({artifactsDir:B,artifactConfig:q,runId:j,agent:M.agent,flatIndex:K+o,flatStepCount:N});return{agent:M.agent,phase:M.phase??V.phase,label:M.label,outputName:void 0,structured:Boolean(M.structuredOutputSchema),status:"pending",...M.sessionFile?{sessionFile:M.sessionFile}:{},...L?{transcriptPath:L}:{},skills:M.skills,model:M.model,thinking:M.thinking,attemptedModels:M.modelCandidates&&M.modelCandidates.length>0?M.modelCandidates:M.model?[M.model]:void 0,recentTools:[],recentOutput:[]}});if(Y.steps.splice(K,1,...w),$.childIntercomTargets)$.childIntercomTargets=Y.steps.map((M,o)=>Aj(j,M.agent,o));p0.splice(K,1,...w.map(()=>G1())),T0.splice(K,1,...w.map(()=>{return}));let d=w.length-1;for(let M of Y.parallelGroups)if(M.stepIndex===H)M.start=K,M.count=w.length;else if(M.start>K)M.start+=d;if(Y.workflowGraph){let M=(L)=>{for(let A of L){if(A.stepIndex!==void 0&&A.stepIndex>H&&A.flatIndex!==void 0&&A.flatIndex>=K)A.flatIndex+=w.length;if(A.children)M(A.children)}};M(Y.workflowGraph.nodes);let o=Y.workflowGraph.nodes.find((L)=>L.id===`step-${H}`);if(o)o.children=_.items.map((L,A)=>({id:`step-${H}-item-${L.idKey}`,kind:"agent",agent:V.parallel.agent,phase:z[A]?.phase??V.phase,label:z[A]?.label?.trim()||`${V.parallel.agent} ${L.key}`,status:"pending",flatIndex:K+A,stepIndex:H,itemKey:L.key,structured:Boolean(z[A]?.structuredOutputSchema)}))}a();let Z$=V.concurrency??k1,v=V.failFast??!1,F=!1,F$=await t0(z,Z$,async(M,o)=>{let L=K+o;if(E)return P(M.agent);if(s)return e$(M.agent);if(F&&v){let g=Date.now();return Y.steps[L].status="failed",Y.steps[L].error="Skipped due to fail-fast",Y.steps[L].startedAt=g,Y.steps[L].endedAt=g,Y.steps[L].durationMs=0,Y.steps[L].exitCode=-1,Y.lastUpdate=g,a(),{agent:M.agent,output:"(skipped — fail-fast)",exitCode:-1,skipped:!0}}let A=Date.now();Y.currentStep=L,Y.steps[L].status="running",Y.steps[L].error=void 0,Y.steps[L].activityState=void 0,yj(Y.steps[L]),Y.steps[L].startedAt=A,Y.steps[L].lastActivityAt=A,Y.outputFile=r.join(k,`output-${L}.log`),Y.lastActivityAt=A,Y.lastUpdate=A,a(),$$(n,JSON.stringify({type:"subagent.step.started",ts:A,runId:j,stepIndex:L,agent:M.agent})),C1(L);let I=await kj(M,{previousOutput:T,placeholder:X,cwd:Q,sessionEnabled:W0,outputs:y,sessionDir:$.sessionDir?r.join($.sessionDir,`dynamic-${H}-${o}`):void 0,artifactsDir:B,artifactConfig:q,id:j,flatIndex:L,flatStepCount:Math.max(Y.steps.length,1),outputFile:r.join(k,`output-${L}.log`),steerInboxDir:y0(k,L),piPackageRoot:$.piPackageRoot,piArgv1:$.piArgv1,childIntercomTarget:$.childIntercomTargets?.[L],orchestratorIntercomTarget:$.controlIntercomTarget,nestedRoute:$.nestedRoute,registerInterrupt:(g)=>N$(L,g),registerTimeout:(g)=>f$(L,g),registerTurnBudgetAbort:(g)=>S$(L,g),timeoutSignal:q$.signal,timeoutMessage:p,turnBudget:$.turnBudget,onAttemptStart:(g)=>T1(L,g.model,g.thinking),onChildEvent:(g)=>E1(L,g),skipAcceptance:()=>E}),G$=Date.now(),x$=I.interrupted===!0;if(Y.steps[L].status=E?"failed":x$?"paused":I.exitCode===0?"complete":"failed",Y.steps[L].endedAt=G$,Y.steps[L].durationMs=G$-A,Y.steps[L].exitCode=E?1:x$?0:I.exitCode,Y.steps[L].timedOut=E||I.timedOut?!0:void 0,Y.steps[L].turnBudget=I.turnBudget,Y.steps[L].turnBudgetExceeded=I.turnBudgetExceeded,Y.steps[L].wrapUpRequested=I.wrapUpRequested,Y.steps[L].toolBudget=I.toolBudget,Y.steps[L].toolBudgetBlocked=I.toolBudgetBlocked,I.toolBudget)Y.toolBudget=I.toolBudget;if(I.toolBudgetBlocked)Y.toolBudgetBlocked=!0;if(I.turnBudget)Y.turnBudget=I.turnBudget;if(I.turnBudgetExceeded)Y.turnBudgetExceeded=!0;if(I.wrapUpRequested)Y.wrapUpRequested=!0;if(Y.steps[L].model=I.model,Y.steps[L].thinking=O0(I.model,Y.steps[L].thinking),Y.steps[L].attemptedModels=I.attemptedModels,Y.steps[L].modelAttempts=I.modelAttempts,Y.steps[L].totalCost=I.totalCost,Y.steps[L].error=E?p??"Subagent timed out.":I.error,Y.steps[L].transcriptPath=I.transcriptPath??Y.steps[L].transcriptPath,Y.steps[L].transcriptError=I.transcriptError,Y.steps[L].structuredOutput=I.structuredOutput,Y.steps[L].structuredOutputPath=I.structuredOutputPath,Y.steps[L].structuredOutputSchemaPath=I.structuredOutputSchemaPath,Y.steps[L].acceptance=I.acceptance,Y.lastUpdate=G$,a(),$$(n,JSON.stringify({type:E?"subagent.step.failed":x$?"subagent.step.paused":I.exitCode===0?"subagent.step.completed":"subagent.step.failed",ts:G$,runId:j,stepIndex:L,agent:M.agent,exitCode:E?1:x$?0:I.exitCode,durationMs:G$-A})),I.exitCode!==0&&v)F=!0;return E?{...I,output:p??"Subagent timed out.",error:p??"Subagent timed out.",exitCode:1,interrupted:!1,timedOut:!0,skipped:!1}:{...I,skipped:!1}},O);R+=z.length;for(let M of F$)h.push({agent:M.agent,output:M.output,error:M.error,success:M.interrupted!==!0&&M.exitCode===0,exitCode:M.interrupted===!0?0:M.exitCode,skipped:M.skipped,interrupted:M.interrupted,timedOut:M.timedOut,turnBudget:M.turnBudget,turnBudgetExceeded:M.turnBudgetExceeded,wrapUpRequested:M.wrapUpRequested,toolBudget:M.toolBudget,toolBudgetBlocked:M.toolBudgetBlocked,sessionFile:M.sessionFile,intercomTarget:M.intercomTarget,model:M.model,attemptedModels:M.attemptedModels,modelAttempts:M.modelAttempts,totalCost:M.totalCost,artifactPaths:M.artifactPaths,transcriptPath:M.transcriptPath,transcriptError:M.transcriptError,structuredOutput:M.structuredOutput,structuredOutputPath:M.structuredOutputPath,structuredOutputSchemaPath:M.structuredOutputSchemaPath,acceptance:M.acceptance});let C=eJ(V,_.items,F$),z$=F$.filter((M)=>M.exitCode!==0&&M.exitCode!==-1);if(z$.length===0)try{Yj(V.collect.outputSchema,C),y[V.collect.as]={text:JSON.stringify(C),structured:C,agent:V.parallel.agent,stepIndex:H},Y.outputs=y;let M=V.effectiveAcceptance&&!E?await M1({acceptance:V.effectiveAcceptance,output:"",report:Ej({results:F$,notes:`Dynamic fanout collected ${C.length} result(s) into ${V.collect.as}.`}),cwd:Q,signal:q$.signal,abortMessage:p??"Subagent timed out."}):void 0,o=E||q$.signal.aborted,L=o?void 0:M,A=L?L1(L):void 0,I=o?p??"Subagent timed out.":A;if(i(H,I?"failed":"completed",I,L),I)h.push({agent:V.parallel.agent,output:I,error:I,success:!1,exitCode:1,timedOut:o?!0:void 0,structuredOutput:C,acceptance:L}),Y.error=I}catch(M){let o=M instanceof x?M.message:M instanceof Error?M.message:String(M);h.push({agent:V.parallel.agent,output:o,error:o,success:!1,exitCode:1,structuredOutput:C}),Y.error=o,i(H,"failed",o)}if(T=e0(F$.map((M,o)=>({agent:M.agent,taskIndex:o,output:M.output,exitCode:M.exitCode,error:M.error})),(M,o)=>`=== Dynamic Item ${M+1} (${o}, key ${_.items[M]?.key??M}) ===`),$$(n,JSON.stringify({type:"subagent.dynamic.completed",ts:Date.now(),runId:j,stepIndex:H,success:z$.length===0})),z$.length>0)i(H,"failed",z$[0]?.error??"Dynamic fanout child failed.");if(Y.lastUpdate=Date.now(),a(),z$.length>0||Y.error)break;continue}if($0(V)){let K=V,_=K.concurrency??k1,z=K.failFast??!1,N=R,w=!1,d;if(K.worktree){let Z$=N8(K.parallel,Q);if(Z$){let v=Date.now();i8({statusPayload:Y,results:h,group:K,groupStartFlatIndex:N,setupError:C8(Z$,Q),failedAt:v,statusPath:f,eventsPath:n,asyncDir:k,runId:j,stepIndex:H}),R+=K.parallel.length;break}try{d=E8(Q,`${j}-s${H}`,K.parallel.length,{agents:K.parallel.map((v)=>v.agent),setupHook:$.worktreeSetupHook?{hookPath:$.worktreeSetupHook,timeoutMs:$.worktreeSetupHookTimeoutMs}:void 0,baseDir:$.worktreeBaseDir})}catch(v){let F=v instanceof Error?v.message:String(v),F$=Date.now();i8({statusPayload:Y,results:h,group:K,groupStartFlatIndex:N,setupError:F,failedAt:F$,statusPath:f,eventsPath:n,asyncDir:k,runId:j,stepIndex:H}),R+=K.parallel.length;break}}try{if(K.worktree)a5(Q,K);let Z$=Date.now();i5({statusPayload:Y,group:K,groupStartFlatIndex:N,groupStartTime:Z$,statusPath:f,eventsPath:n,asyncDir:k,runId:j,stepIndex:H});let v=await t0(K.parallel,_,async(F,F$)=>{let C=N+F$;if(E)return P(F.agent);if(s)return e$(F.agent);if(w&&z){let g=Date.now();return Y.steps[C].status="failed",Y.steps[C].error="Skipped due to fail-fast",Y.steps[C].startedAt=g,Y.steps[C].endedAt=g,Y.steps[C].durationMs=0,Y.steps[C].exitCode=-1,Y.steps[C].activityState=void 0,Y.lastUpdate=g,a(),$$(n,JSON.stringify({type:"subagent.step.failed",ts:g,runId:j,stepIndex:C,agent:F.agent,exitCode:-1,durationMs:0})),{agent:F.agent,output:"(skipped — fail-fast)",exitCode:-1,skipped:!0}}let z$=Date.now();Y.currentStep=C,Y.steps[C].status="running",Y.steps[C].error=void 0,Y.steps[C].activityState=void 0,yj(Y.steps[C]),Y.steps[C].startedAt=z$,Y.steps[C].endedAt=void 0,Y.steps[C].durationMs=void 0,Y.steps[C].lastActivityAt=z$,Y.outputFile=r.join(k,`output-${C}.log`),Y.lastActivityAt=z$,Y.lastUpdate=z$,a(),$$(n,JSON.stringify({type:"subagent.step.started",ts:z$,runId:j,stepIndex:C,agent:F.agent}));let M=$.sessionDir?r.join($.sessionDir,`parallel-${F$}`):void 0,{taskForRun:o,taskCwd:L}=r5(F,Q,d,F$);C1(C);let A=await kj(o,{previousOutput:T,placeholder:X,cwd:L,sessionEnabled:W0,outputs:y,sessionDir:M,artifactsDir:B,artifactConfig:q,id:j,flatIndex:C,flatStepCount:Math.max(Y.steps.length,1),outputFile:r.join(k,`output-${C}.log`),steerInboxDir:y0(k,C),piPackageRoot:$.piPackageRoot,piArgv1:$.piArgv1,childIntercomTarget:$.childIntercomTargets?.[C],orchestratorIntercomTarget:$.controlIntercomTarget,nestedRoute:$.nestedRoute,registerInterrupt:(g)=>N$(C,g),registerTimeout:(g)=>f$(C,g),registerTurnBudgetAbort:(g)=>S$(C,g),timeoutSignal:q$.signal,timeoutMessage:p,turnBudget:$.turnBudget,onAttemptStart:(g)=>T1(C,g.model,g.thinking),onChildEvent:(g)=>E1(C,g),skipAcceptance:()=>E});if(F.sessionFile)o$=F.sessionFile;let I=Date.now(),G$=I-z$,x$=A.interrupted===!0;if(Y.steps[C].status=E?"failed":x$?"paused":A.exitCode===0?"complete":"failed",Y.steps[C].endedAt=I,Y.steps[C].durationMs=G$,Y.steps[C].exitCode=E?1:x$?0:A.exitCode,Y.steps[C].timedOut=E||A.timedOut?!0:void 0,Y.steps[C].turnBudget=A.turnBudget,Y.steps[C].turnBudgetExceeded=A.turnBudgetExceeded,Y.steps[C].wrapUpRequested=A.wrapUpRequested,Y.steps[C].toolBudget=A.toolBudget,Y.steps[C].toolBudgetBlocked=A.toolBudgetBlocked,A.toolBudget)Y.toolBudget=A.toolBudget;if(A.toolBudgetBlocked)Y.toolBudgetBlocked=!0;if(A.turnBudget)Y.turnBudget=A.turnBudget;if(A.turnBudgetExceeded)Y.turnBudgetExceeded=!0;if(A.wrapUpRequested)Y.wrapUpRequested=!0;if(Y.steps[C].model=A.model,Y.steps[C].thinking=O0(A.model,Y.steps[C].thinking),Y.steps[C].attemptedModels=A.attemptedModels,Y.steps[C].modelAttempts=A.modelAttempts,Y.steps[C].totalCost=A.totalCost,Y.steps[C].error=E?p??"Subagent timed out.":A.error,Y.steps[C].transcriptPath=A.transcriptPath??Y.steps[C].transcriptPath,Y.steps[C].transcriptError=A.transcriptError,Y.steps[C].structuredOutput=A.structuredOutput,Y.steps[C].structuredOutputPath=A.structuredOutputPath,Y.steps[C].structuredOutputSchemaPath=A.structuredOutputSchemaPath,Y.steps[C].acceptance=A.acceptance,Y.lastUpdate=I,a(),$$(n,JSON.stringify({type:E?"subagent.step.failed":x$?"subagent.step.paused":A.exitCode===0?"subagent.step.completed":"subagent.step.failed",ts:I,runId:j,stepIndex:C,agent:F.agent,exitCode:E?1:x$?0:A.exitCode,durationMs:G$})),A.completionGuardTriggered){let g=A0({from:Y.steps[C].activityState,to:"needs_attention",runId:j,agent:F.agent,index:C,ts:I,message:`${F.agent} completed without making edits for an implementation task`,reason:"completion_guard"});E0(g)}if(A.exitCode!==0&&z)w=!0;return E?{...A,output:p??"Subagent timed out.",error:p??"Subagent timed out.",exitCode:1,interrupted:!1,timedOut:!0,skipped:!1}:{...A,skipped:!1}},O);R+=K.parallel.length;for(let F=0;F<K.parallel.length;F++){let F$=N+F,z$=($.sessionDir?Fj(r.join($.sessionDir,`parallel-${F}`)):null)??p8(v[F]?.modelAttempts);if(!z$)continue;Y.steps[F$].tokens=z$,Y$={input:Y$.input+z$.input,output:Y$.output+z$.output,total:Y$.total+z$.total}}Y.totalTokens={...Y$},Y.lastUpdate=Date.now(),a();for(let F of v)h.push({agent:F.agent,output:F.output,error:F.error,success:F.interrupted!==!0&&F.exitCode===0,exitCode:F.interrupted===!0?0:F.exitCode,skipped:F.skipped,interrupted:F.interrupted,timedOut:F.timedOut,turnBudget:F.turnBudget,turnBudgetExceeded:F.turnBudgetExceeded,wrapUpRequested:F.wrapUpRequested,toolBudget:F.toolBudget,toolBudgetBlocked:F.toolBudgetBlocked,sessionFile:F.sessionFile,intercomTarget:F.intercomTarget,model:F.model,attemptedModels:F.attemptedModels,modelAttempts:F.modelAttempts,totalCost:F.totalCost,artifactPaths:F.artifactPaths,transcriptPath:F.transcriptPath,transcriptError:F.transcriptError,structuredOutput:F.structuredOutput,structuredOutputPath:F.structuredOutputPath,structuredOutputSchemaPath:F.structuredOutputSchemaPath,acceptance:F.acceptance});for(let F=0;F<K.parallel.length;F++){let F$=K.parallel[F]?.outputName;if(F$)y[F$]=Hj({agent:v[F].agent,output:v[F].output,structuredOutput:v[F].structuredOutput},H)}if(Y.outputs=y,T=e0(v.map((F)=>({agent:F.agent,output:F.output,exitCode:F.exitCode,error:F.error,model:F.model,attemptedModels:F.attemptedModels}))),T=s5(T,d,k,H,K),$$(n,JSON.stringify({type:"subagent.parallel.completed",ts:Date.now(),runId:j,stepIndex:H,success:v.every((F)=>F.exitCode===0||F.exitCode===-1)})),v.some((F)=>F.exitCode!==0&&F.exitCode!==-1))break}finally{if(d)Oj(d)}}else{let K=V,_=Date.now();Y.currentStep=R,Y.steps[R].status="running",Y.steps[R].activityState=void 0,Y.activityState=void 0,yj(Y.steps[R]),Y.steps[R].skills=K.skills,Y.steps[R].startedAt=_,Y.steps[R].lastActivityAt=_,Y.lastActivityAt=_,Y.lastUpdate=_,Y.outputFile=r.join(k,`output-${R}.log`),a(),$$(n,JSON.stringify({type:"subagent.step.started",ts:_,runId:j,stepIndex:R,agent:K.agent})),C1(R);let z=await kj(K,{previousOutput:T,placeholder:X,cwd:Q,sessionEnabled:W0,outputs:y,sessionDir:$.sessionDir,artifactsDir:B,artifactConfig:q,id:j,flatIndex:R,flatStepCount:Math.max(Y.steps.length,1),outputFile:r.join(k,`output-${R}.log`),steerInboxDir:y0(k,R),piPackageRoot:$.piPackageRoot,piArgv1:$.piArgv1,childIntercomTarget:$.childIntercomTargets?.[R],orchestratorIntercomTarget:$.controlIntercomTarget,nestedRoute:$.nestedRoute,registerInterrupt:(v)=>N$(R,v),registerTimeout:(v)=>f$(R,v),registerTurnBudgetAbort:(v)=>S$(R,v),timeoutSignal:q$.signal,timeoutMessage:p,turnBudget:$.turnBudget,onAttemptStart:(v)=>T1(R,v.model,v.thinking),onChildEvent:(v)=>E1(R,v),skipAcceptance:()=>E});if(K.sessionFile)o$=K.sessionFile;if(T=z.output,h.push({agent:z.agent,output:E?p??"Subagent timed out.":z.output,error:E?p??"Subagent timed out.":z.error,success:!E&&z.interrupted!==!0&&z.exitCode===0,exitCode:E?1:z.interrupted===!0?0:z.exitCode,sessionFile:z.sessionFile,intercomTarget:z.intercomTarget,model:z.model,attemptedModels:z.attemptedModels,modelAttempts:z.modelAttempts,totalCost:z.totalCost,artifactPaths:z.artifactPaths,transcriptPath:z.transcriptPath,transcriptError:z.transcriptError,structuredOutput:z.structuredOutput,structuredOutputPath:z.structuredOutputPath,structuredOutputSchemaPath:z.structuredOutputSchemaPath,acceptance:z.acceptance,interrupted:z.interrupted,timedOut:E||z.timedOut?!0:void 0,turnBudget:z.turnBudget,turnBudgetExceeded:z.turnBudgetExceeded,wrapUpRequested:z.wrapUpRequested,toolBudget:z.toolBudget,toolBudgetBlocked:z.toolBudgetBlocked}),K.outputName)y[K.outputName]=Hj({agent:z.agent,output:z.output,structuredOutput:z.structuredOutput},H);Y.outputs=y;let N=$.sessionDir?Fj($.sessionDir):null,w=N?{input:N.input-Y$.input,output:N.output-Y$.output,total:N.total-Y$.total}:null;if(N)Y$=N;else if(w=p8(z.modelAttempts),w)Y$={input:Y$.input+w.input,output:Y$.output+w.output,total:Y$.total+w.total};let d=Date.now(),Z$=z.interrupted===!0;if(Y.steps[R].status=E?"failed":Z$?"paused":z.exitCode===0?"complete":"failed",Y.steps[R].endedAt=d,Y.steps[R].durationMs=d-_,Y.steps[R].exitCode=E?1:Z$?0:z.exitCode,Y.steps[R].timedOut=E||z.timedOut?!0:void 0,Y.steps[R].turnBudget=z.turnBudget,Y.steps[R].turnBudgetExceeded=z.turnBudgetExceeded,Y.steps[R].wrapUpRequested=z.wrapUpRequested,Y.steps[R].toolBudget=z.toolBudget,Y.steps[R].toolBudgetBlocked=z.toolBudgetBlocked,z.toolBudget)Y.toolBudget=z.toolBudget;if(z.toolBudgetBlocked)Y.toolBudgetBlocked=!0;if(z.turnBudget)Y.turnBudget=z.turnBudget;if(z.turnBudgetExceeded)Y.turnBudgetExceeded=!0;if(z.wrapUpRequested)Y.wrapUpRequested=!0;if(Y.steps[R].model=z.model,Y.steps[R].thinking=O0(z.model,Y.steps[R].thinking),Y.steps[R].attemptedModels=z.attemptedModels,Y.steps[R].modelAttempts=z.modelAttempts,Y.steps[R].totalCost=z.totalCost,Y.steps[R].error=E?p??"Subagent timed out.":z.error,Y.steps[R].transcriptPath=z.transcriptPath??Y.steps[R].transcriptPath,Y.steps[R].transcriptError=z.transcriptError,Y.steps[R].structuredOutput=z.structuredOutput,Y.steps[R].structuredOutputPath=z.structuredOutputPath,Y.steps[R].structuredOutputSchemaPath=z.structuredOutputSchemaPath,Y.steps[R].acceptance=z.acceptance,w)Y.steps[R].tokens=w,Y.totalTokens={...Y$};if(Y.lastUpdate=d,a(),$$(n,JSON.stringify({type:E?"subagent.step.failed":Z$?"subagent.step.paused":z.exitCode===0?"subagent.step.completed":"subagent.step.failed",ts:d,runId:j,stepIndex:R,agent:K.agent,exitCode:E?1:Z$?0:z.exitCode,durationMs:d-_,tokens:w})),z.completionGuardTriggered){let v=A0({from:Y.steps[R].activityState,to:"needs_attention",runId:j,agent:K.agent,index:R,ts:d,message:`${K.agent} completed without making edits for an implementation task`,reason:"completion_guard"});E0(v)}if(R++,z.exitCode!==0)break}}let n0=h.map((H)=>`${H.agent}:
|
|
76
|
-
${H.output}`).join(`
|
|
75
|
+
`).slice(-10)),K.turnCount=(K.turnCount??0)+1;let z=V.message.usage;if(z){let N=z.input??z.inputTokens??0,w=z.output??z.outputTokens??0,d=K.tokens?.input??0,Z$=K.tokens?.output??0;K.tokens={input:d+N,output:Z$+w,total:d+Z$+N+w};let v=Y.totalTokens?.input??0,F=Y.totalTokens?.output??0;Y.totalTokens={input:v+N,output:F+w,total:v+F+N+w}}Y.turnCount=Math.max(Y.turnCount??0,K.turnCount),a8(H,K.turnCount,_,hj(V.message))}A1(),K.lastActivityAt=_,Y.lastActivityAt=_,Y.lastUpdate=_,gj(H,_),a()},t8=(H)=>{if(!W$.enabled)return!1;let V=!1,K=Y.lastActivityAt??S;for(let z=0;z<Y.steps.length;z++){let N=Y.steps[z];if(N.status!=="running")continue;let w=M$(z);if(K=Math.max(K,w),N.lastActivityAt!==w)N.lastActivityAt=w,V=!0;if(qJ({config:W$,startedAt:N.startedAt??S,lastActivityAt:w,now:H})==="needs_attention"){let Z$=N.activityState;if(N.activityState="needs_attention",Z$!=="needs_attention")E0(A0({from:Z$,to:"needs_attention",runId:j,agent:N.agent,index:z,ts:H,lastActivityAt:w})),V=!0}else if(gj(z,H))V=!0}if(Y.lastActivityAt!==K)Y.lastActivityAt=K,V=!0;let _=Y.steps.some((z)=>z.activityState==="needs_attention")?"needs_attention":Y.steps.some((z)=>z.activityState==="active_long_running")?"active_long_running":void 0;if(_!==E$)E$=_,Y.activityState=_,V=!0;if(Y.lastUpdate=H,V)a();return V};if(W$.enabled)X$=setInterval(()=>{if(Y.state!=="running")return;let H=Date.now();t8(H)},1000),X$.unref?.();let mj=()=>{if(g1(k),s||Y.state!=="running")return;s=!0;let H=Date.now();Y.state="paused",E$=void 0,Y.activityState=void 0,Y.lastUpdate=H;for(let V of Y.steps)if(V.status==="running")V.status="paused",V.activityState=void 0,V.endedAt=H,V.durationMs=V.startedAt?H-V.startedAt:void 0,V.lastActivityAt=H;a(),$$(n,JSON.stringify({type:"subagent.run.paused",ts:H,runId:j})),l$(),t$()},cj=()=>{if(E||s||Y.state!=="running")return;E=!0;let H=Date.now(),V=p??"Subagent timed out.";Y.state="failed",Y.timedOut=!0,Y.error=V,E$=void 0,Y.activityState=void 0,Y.lastUpdate=H;for(let K of Y.steps){if(K.status!=="running"&&K.status!=="pending")continue;K.status="failed",K.error=V,K.exitCode=1,K.timedOut=!0,K.activityState=void 0,K.endedAt=H,K.durationMs=K.startedAt?H-K.startedAt:0,K.lastActivityAt=H}a(),$$(n,JSON.stringify({type:"subagent.run.timed_out",ts:H,runId:j,timeoutMs:$.timeoutMs,deadlineAt:$.deadlineAt,message:V})),q$.abort(),p$(),P$()};process.on(y5,mj);let e8=UJ(k,{onInterrupt:mj,onTimeout:cj,onSteer:(H)=>{if((H.targetIndex!==void 0?Y.steps[H.targetIndex]:void 0)?.status==="pending")A$.push(H);else if(H.targetIndex!==void 0||Y.steps.some((K)=>K.status==="running"))N1(H);else A$.push(H)}});if($.deadlineAt!==void 0){let H=Math.max(0,$.deadlineAt-Date.now());_$=setTimeout(cj,H),_$.unref?.()}$$(n,JSON.stringify({type:"subagent.run.started",lifecycleArtifactVersion:S0,ts:S,runId:j,mode:Y.mode,cwd:Q,pid:process.pid}));let R=0,dj=0;while(!0){if(s||E||t)break;if(D(),dj>=J.length)break;let H=dj++,V=J[H];if(j0(V)){let K=R,_;try{if(_=tJ(V,y,H,{maxItems:$.dynamicFanoutMaxItems,allowRunnerFields:!0}),_.collectedOnEmpty)Yj(V.collect.outputSchema,_.collectedOnEmpty)}catch(M){let o=Date.now(),L=M instanceof x?M.message:M instanceof Error?M.message:String(M);Y.state="failed",Y.error=L,Y.currentStep=R;let A=Y.steps[K];if(A)A.status="failed",A.error=L,A.startedAt=o,A.endedAt=o,A.durationMs=0,A.exitCode=1;Y.lastUpdate=o,i(H,"failed",L),a(),h.push({agent:V.parallel.agent,output:L,error:L,success:!1,exitCode:1});break}if(_.parallel.length===0){let M=Date.now(),o=_.collectedOnEmpty??[];y[V.collect.as]={text:JSON.stringify(o),structured:o,agent:V.parallel.agent,stepIndex:H},Y.outputs=y;let L=Y.steps[K];if(L)L.status="complete",L.startedAt=M,L.endedAt=M,L.durationMs=0;T="Dynamic fanout produced 0 results.";let A=V.effectiveAcceptance?.explicit&&!E?await M1({acceptance:V.effectiveAcceptance,output:"",report:Ej({results:[],notes:"Dynamic fanout produced 0 results."}),cwd:Q,signal:q$.signal,abortMessage:p??"Subagent timed out."}):void 0,I=E||q$.signal.aborted,G$=I?void 0:A;if(L&&G$)L.acceptance=G$;let x$=G$?L1(G$):void 0;if(I||x$){let g=I?p??"Subagent timed out.":x$;if(Y.state="failed",Y.error=g,L)L.status="failed",L.error=g,L.exitCode=1,L.timedOut=I?!0:void 0;i(H,"failed",g,G$),Y.lastUpdate=Date.now(),a(),h.push({agent:V.parallel.agent,output:g,error:g,success:!1,exitCode:1,timedOut:I?!0:void 0,acceptance:G$});break}R++,Y.lastUpdate=M,i(H,"completed",void 0,G$),a();continue}let z=_.parallel.map((M,o)=>{let L=V.thinkingOverrides?.[o],A=L?W1(V.parallel.model,L,!0):V.parallel.model,I=L?O0(A,L):void 0;return{...V.parallel,task:M.task??V.parallel.task,label:M.label??V.parallel.label,...V.sessionFiles?.[o]?{sessionFile:V.sessionFiles[o]}:{},...L?{...A?{model:A}:{},...I?{thinking:I}:{},...V.parallel.modelCandidates?{modelCandidates:V.parallel.modelCandidates.map((G$)=>W1(G$,L,!0))}:{}}:{},structuredOutput:void 0,structuredOutputSchema:V.parallel.structuredOutputSchema??V.parallel.structuredOutput?.schema}}),N=Math.max(Y.steps.length-1+z.length,1),w=z.map((M,o)=>{let L=fj({artifactsDir:B,artifactConfig:q,runId:j,agent:M.agent,flatIndex:K+o,flatStepCount:N});return{agent:M.agent,phase:M.phase??V.phase,label:M.label,outputName:void 0,structured:Boolean(M.structuredOutputSchema),status:"pending",...M.sessionFile?{sessionFile:M.sessionFile}:{},...L?{transcriptPath:L}:{},skills:M.skills,model:M.model,thinking:M.thinking,attemptedModels:M.modelCandidates&&M.modelCandidates.length>0?M.modelCandidates:M.model?[M.model]:void 0,recentTools:[],recentOutput:[]}});if(Y.steps.splice(K,1,...w),$.childIntercomTargets)$.childIntercomTargets=Y.steps.map((M,o)=>Aj(j,M.agent,o));p0.splice(K,1,...w.map(()=>G1())),T0.splice(K,1,...w.map(()=>{return}));let d=w.length-1;for(let M of Y.parallelGroups)if(M.stepIndex===H)M.start=K,M.count=w.length;else if(M.start>K)M.start+=d;if(Y.workflowGraph){let M=(L)=>{for(let A of L){if(A.stepIndex!==void 0&&A.stepIndex>H&&A.flatIndex!==void 0&&A.flatIndex>=K)A.flatIndex+=w.length;if(A.children)M(A.children)}};M(Y.workflowGraph.nodes);let o=Y.workflowGraph.nodes.find((L)=>L.id===`step-${H}`);if(o)o.children=_.items.map((L,A)=>({id:`step-${H}-item-${L.idKey}`,kind:"agent",agent:V.parallel.agent,phase:z[A]?.phase??V.phase,label:z[A]?.label?.trim()||`${V.parallel.agent} ${L.key}`,status:"pending",flatIndex:K+A,stepIndex:H,itemKey:L.key,structured:Boolean(z[A]?.structuredOutputSchema)}))}a();let Z$=V.concurrency??k1,v=V.failFast??!1,F=!1,F$=await t0(z,Z$,async(M,o)=>{let L=K+o;if(E)return P(M.agent);if(s)return e$(M.agent);if(F&&v){let g=Date.now();return Y.steps[L].status="failed",Y.steps[L].error="Skipped due to fail-fast",Y.steps[L].startedAt=g,Y.steps[L].endedAt=g,Y.steps[L].durationMs=0,Y.steps[L].exitCode=-1,Y.lastUpdate=g,a(),{agent:M.agent,output:"(skipped — fail-fast)",exitCode:-1,skipped:!0}}let A=Date.now();Y.currentStep=L,Y.steps[L].status="running",Y.steps[L].error=void 0,Y.steps[L].activityState=void 0,yj(Y.steps[L]),Y.steps[L].startedAt=A,Y.steps[L].lastActivityAt=A,Y.outputFile=r.join(k,`output-${L}.log`),Y.lastActivityAt=A,Y.lastUpdate=A,a(),$$(n,JSON.stringify({type:"subagent.step.started",ts:A,runId:j,stepIndex:L,agent:M.agent})),C1(L);let I=await kj(M,{previousOutput:T,placeholder:X,cwd:Q,sessionEnabled:W0,outputs:y,sessionDir:$.sessionDir?r.join($.sessionDir,`dynamic-${H}-${o}`):void 0,artifactsDir:B,artifactConfig:q,id:j,flatIndex:L,flatStepCount:Math.max(Y.steps.length,1),outputFile:r.join(k,`output-${L}.log`),steerInboxDir:y0(k,L),piPackageRoot:$.piPackageRoot,piArgv1:$.piArgv1,childIntercomTarget:$.childIntercomTargets?.[L],orchestratorIntercomTarget:$.controlIntercomTarget,nestedRoute:$.nestedRoute,registerInterrupt:(g)=>N$(L,g),registerTimeout:(g)=>f$(L,g),registerTurnBudgetAbort:(g)=>S$(L,g),timeoutSignal:q$.signal,timeoutMessage:p,turnBudget:$.turnBudget,onAttemptStart:(g)=>T1(L,g.model,g.thinking),onChildEvent:(g)=>E1(L,g),skipAcceptance:()=>E}),G$=Date.now(),x$=I.interrupted===!0;if(Y.steps[L].status=E?"failed":x$?"paused":I.exitCode===0?"complete":"failed",Y.steps[L].endedAt=G$,Y.steps[L].durationMs=G$-A,Y.steps[L].exitCode=E?1:x$?0:I.exitCode,Y.steps[L].timedOut=E||I.timedOut?!0:void 0,Y.steps[L].turnBudget=I.turnBudget,Y.steps[L].turnBudgetExceeded=I.turnBudgetExceeded,Y.steps[L].wrapUpRequested=I.wrapUpRequested,Y.steps[L].toolBudget=I.toolBudget,Y.steps[L].toolBudgetBlocked=I.toolBudgetBlocked,I.toolBudget)Y.toolBudget=I.toolBudget;if(I.toolBudgetBlocked)Y.toolBudgetBlocked=!0;if(I.turnBudget)Y.turnBudget=I.turnBudget;if(I.turnBudgetExceeded)Y.turnBudgetExceeded=!0;if(I.wrapUpRequested)Y.wrapUpRequested=!0;if(Y.steps[L].model=I.model,Y.steps[L].thinking=O0(I.model,Y.steps[L].thinking),Y.steps[L].attemptedModels=I.attemptedModels,Y.steps[L].modelAttempts=I.modelAttempts,Y.steps[L].totalCost=I.totalCost,Y.steps[L].error=E?p??"Subagent timed out.":I.error,Y.steps[L].transcriptPath=I.transcriptPath??Y.steps[L].transcriptPath,Y.steps[L].transcriptError=I.transcriptError,Y.steps[L].structuredOutput=I.structuredOutput,Y.steps[L].structuredOutputPath=I.structuredOutputPath,Y.steps[L].structuredOutputSchemaPath=I.structuredOutputSchemaPath,Y.steps[L].acceptance=I.acceptance,Y.lastUpdate=G$,a(),$$(n,JSON.stringify({type:E?"subagent.step.failed":x$?"subagent.step.paused":I.exitCode===0?"subagent.step.completed":"subagent.step.failed",ts:G$,runId:j,stepIndex:L,agent:M.agent,exitCode:E?1:x$?0:I.exitCode,durationMs:G$-A})),I.exitCode!==0&&v)F=!0;return E?{...I,output:p??"Subagent timed out.",error:p??"Subagent timed out.",exitCode:1,interrupted:!1,timedOut:!0,skipped:!1}:{...I,skipped:!1}},O);R+=z.length;for(let M of F$)h.push({agent:M.agent,output:M.output,error:M.error,success:M.interrupted!==!0&&M.exitCode===0,exitCode:M.interrupted===!0?0:M.exitCode,skipped:M.skipped,interrupted:M.interrupted,timedOut:M.timedOut,turnBudget:M.turnBudget,turnBudgetExceeded:M.turnBudgetExceeded,wrapUpRequested:M.wrapUpRequested,toolBudget:M.toolBudget,toolBudgetBlocked:M.toolBudgetBlocked,sessionFile:M.sessionFile,intercomTarget:M.intercomTarget,model:M.model,attemptedModels:M.attemptedModels,modelAttempts:M.modelAttempts,totalCost:M.totalCost,artifactPaths:M.artifactPaths,transcriptPath:M.transcriptPath,transcriptError:M.transcriptError,structuredOutput:M.structuredOutput,structuredOutputPath:M.structuredOutputPath,structuredOutputSchemaPath:M.structuredOutputSchemaPath,acceptance:M.acceptance});let C=eJ(V,_.items,F$),z$=F$.filter((M)=>M.exitCode!==0&&M.exitCode!==-1);if(z$.length===0)try{Yj(V.collect.outputSchema,C),y[V.collect.as]={text:JSON.stringify(C),structured:C,agent:V.parallel.agent,stepIndex:H},Y.outputs=y;let M=V.effectiveAcceptance&&!E?await M1({acceptance:V.effectiveAcceptance,output:"",report:Ej({results:F$,notes:`Dynamic fanout collected ${C.length} result(s) into ${V.collect.as}.`}),cwd:Q,signal:q$.signal,abortMessage:p??"Subagent timed out."}):void 0,o=E||q$.signal.aborted,L=o?void 0:M,A=L?L1(L):void 0,I=o?p??"Subagent timed out.":A;if(i(H,I?"failed":"completed",I,L),I)h.push({agent:V.parallel.agent,output:I,error:I,success:!1,exitCode:1,timedOut:o?!0:void 0,structuredOutput:C,acceptance:L}),Y.error=I}catch(M){let o=M instanceof x?M.message:M instanceof Error?M.message:String(M);h.push({agent:V.parallel.agent,output:o,error:o,success:!1,exitCode:1,structuredOutput:C}),Y.error=o,i(H,"failed",o)}if(T=e0(F$.map((M,o)=>({agent:M.agent,taskIndex:o,output:M.output,exitCode:M.exitCode,error:M.error})),(M,o)=>`=== Dynamic Item ${M+1} (${o}, key ${_.items[M]?.key??M}) ===`),$$(n,JSON.stringify({type:"subagent.dynamic.completed",ts:Date.now(),runId:j,stepIndex:H,success:z$.length===0})),z$.length>0)i(H,"failed",z$[0]?.error??"Dynamic fanout child failed.");if(Y.lastUpdate=Date.now(),a(),z$.length>0||Y.error)break;continue}if($0(V)){let K=V,_=K.concurrency??k1,z=K.failFast??!1,N=R,w=!1,d;if(K.worktree){let Z$=N8(K.parallel,Q);if(Z$){let v=Date.now();i8({statusPayload:Y,results:h,group:K,groupStartFlatIndex:N,setupError:C8(Z$,Q),failedAt:v,statusPath:f,eventsPath:n,asyncDir:k,runId:j,stepIndex:H}),R+=K.parallel.length;break}try{d=E8(Q,`${j}-s${H}`,K.parallel.length,{agents:K.parallel.map((v)=>v.agent),setupHook:$.worktreeSetupHook?{hookPath:$.worktreeSetupHook,timeoutMs:$.worktreeSetupHookTimeoutMs}:void 0,baseDir:$.worktreeBaseDir})}catch(v){let F=v instanceof Error?v.message:String(v),F$=Date.now();i8({statusPayload:Y,results:h,group:K,groupStartFlatIndex:N,setupError:F,failedAt:F$,statusPath:f,eventsPath:n,asyncDir:k,runId:j,stepIndex:H}),R+=K.parallel.length;break}}try{if(K.worktree)a5(Q,K);let Z$=Date.now();i5({statusPayload:Y,group:K,groupStartFlatIndex:N,groupStartTime:Z$,statusPath:f,eventsPath:n,asyncDir:k,runId:j,stepIndex:H});let v=await t0(K.parallel,_,async(F,F$)=>{let C=N+F$;if(E)return P(F.agent);if(s)return e$(F.agent);if(w&&z){let g=Date.now();return Y.steps[C].status="failed",Y.steps[C].error="Skipped due to fail-fast",Y.steps[C].startedAt=g,Y.steps[C].endedAt=g,Y.steps[C].durationMs=0,Y.steps[C].exitCode=-1,Y.steps[C].activityState=void 0,Y.lastUpdate=g,a(),$$(n,JSON.stringify({type:"subagent.step.failed",ts:g,runId:j,stepIndex:C,agent:F.agent,exitCode:-1,durationMs:0})),{agent:F.agent,output:"(skipped — fail-fast)",exitCode:-1,skipped:!0}}let z$=Date.now();Y.currentStep=C,Y.steps[C].status="running",Y.steps[C].error=void 0,Y.steps[C].activityState=void 0,yj(Y.steps[C]),Y.steps[C].startedAt=z$,Y.steps[C].endedAt=void 0,Y.steps[C].durationMs=void 0,Y.steps[C].lastActivityAt=z$,Y.outputFile=r.join(k,`output-${C}.log`),Y.lastActivityAt=z$,Y.lastUpdate=z$,a(),$$(n,JSON.stringify({type:"subagent.step.started",ts:z$,runId:j,stepIndex:C,agent:F.agent}));let M=$.sessionDir?r.join($.sessionDir,`parallel-${F$}`):void 0,{taskForRun:o,taskCwd:L}=r5(F,Q,d,F$);C1(C);let A=await kj(o,{previousOutput:T,placeholder:X,cwd:L,sessionEnabled:W0,outputs:y,sessionDir:M,artifactsDir:B,artifactConfig:q,id:j,flatIndex:C,flatStepCount:Math.max(Y.steps.length,1),outputFile:r.join(k,`output-${C}.log`),steerInboxDir:y0(k,C),piPackageRoot:$.piPackageRoot,piArgv1:$.piArgv1,childIntercomTarget:$.childIntercomTargets?.[C],orchestratorIntercomTarget:$.controlIntercomTarget,nestedRoute:$.nestedRoute,registerInterrupt:(g)=>N$(C,g),registerTimeout:(g)=>f$(C,g),registerTurnBudgetAbort:(g)=>S$(C,g),timeoutSignal:q$.signal,timeoutMessage:p,turnBudget:$.turnBudget,onAttemptStart:(g)=>T1(C,g.model,g.thinking),onChildEvent:(g)=>E1(C,g),skipAcceptance:()=>E});if(F.sessionFile)o$=F.sessionFile;let I=Date.now(),G$=I-z$,x$=A.interrupted===!0;if(Y.steps[C].status=E?"failed":x$?"paused":A.exitCode===0?"complete":"failed",Y.steps[C].endedAt=I,Y.steps[C].durationMs=G$,Y.steps[C].exitCode=E?1:x$?0:A.exitCode,Y.steps[C].timedOut=E||A.timedOut?!0:void 0,Y.steps[C].turnBudget=A.turnBudget,Y.steps[C].turnBudgetExceeded=A.turnBudgetExceeded,Y.steps[C].wrapUpRequested=A.wrapUpRequested,Y.steps[C].toolBudget=A.toolBudget,Y.steps[C].toolBudgetBlocked=A.toolBudgetBlocked,A.toolBudget)Y.toolBudget=A.toolBudget;if(A.toolBudgetBlocked)Y.toolBudgetBlocked=!0;if(A.turnBudget)Y.turnBudget=A.turnBudget;if(A.turnBudgetExceeded)Y.turnBudgetExceeded=!0;if(A.wrapUpRequested)Y.wrapUpRequested=!0;if(Y.steps[C].model=A.model,Y.steps[C].thinking=O0(A.model,Y.steps[C].thinking),Y.steps[C].attemptedModels=A.attemptedModels,Y.steps[C].modelAttempts=A.modelAttempts,Y.steps[C].totalCost=A.totalCost,Y.steps[C].error=E?p??"Subagent timed out.":A.error,Y.steps[C].transcriptPath=A.transcriptPath??Y.steps[C].transcriptPath,Y.steps[C].transcriptError=A.transcriptError,Y.steps[C].structuredOutput=A.structuredOutput,Y.steps[C].structuredOutputPath=A.structuredOutputPath,Y.steps[C].structuredOutputSchemaPath=A.structuredOutputSchemaPath,Y.steps[C].acceptance=A.acceptance,Y.lastUpdate=I,a(),$$(n,JSON.stringify({type:E?"subagent.step.failed":x$?"subagent.step.paused":A.exitCode===0?"subagent.step.completed":"subagent.step.failed",ts:I,runId:j,stepIndex:C,agent:F.agent,exitCode:E?1:x$?0:A.exitCode,durationMs:G$})),A.completionGuardTriggered){let g=A0({from:Y.steps[C].activityState,to:"needs_attention",runId:j,agent:F.agent,index:C,ts:I,message:`${F.agent} completed without making edits for an implementation task`,reason:"completion_guard"});E0(g)}if(A.exitCode!==0&&z)w=!0;return E?{...A,output:p??"Subagent timed out.",error:p??"Subagent timed out.",exitCode:1,interrupted:!1,timedOut:!0,skipped:!1}:{...A,skipped:!1}},O);R+=K.parallel.length;for(let F=0;F<K.parallel.length;F++){let F$=N+F,z$=($.sessionDir?Fj(r.join($.sessionDir,`parallel-${F}`)):null)??p8(v[F]?.modelAttempts);if(!z$)continue;Y.steps[F$].tokens=z$,Y$={input:Y$.input+z$.input,output:Y$.output+z$.output,total:Y$.total+z$.total}}Y.totalTokens={...Y$},Y.lastUpdate=Date.now(),a();for(let F of v)h.push({agent:F.agent,output:F.output,error:F.error,success:F.interrupted!==!0&&F.exitCode===0,exitCode:F.interrupted===!0?0:F.exitCode,skipped:F.skipped,interrupted:F.interrupted,timedOut:F.timedOut,turnBudget:F.turnBudget,turnBudgetExceeded:F.turnBudgetExceeded,wrapUpRequested:F.wrapUpRequested,toolBudget:F.toolBudget,toolBudgetBlocked:F.toolBudgetBlocked,sessionFile:F.sessionFile,intercomTarget:F.intercomTarget,model:F.model,attemptedModels:F.attemptedModels,modelAttempts:F.modelAttempts,totalCost:F.totalCost,artifactPaths:F.artifactPaths,transcriptPath:F.transcriptPath,transcriptError:F.transcriptError,structuredOutput:F.structuredOutput,structuredOutputPath:F.structuredOutputPath,structuredOutputSchemaPath:F.structuredOutputSchemaPath,acceptance:F.acceptance});for(let F=0;F<K.parallel.length;F++){let F$=K.parallel[F]?.outputName;if(F$)y[F$]=Hj({agent:v[F].agent,output:v[F].output,structuredOutput:v[F].structuredOutput},H)}if(Y.outputs=y,T=e0(v.map((F)=>({agent:F.agent,output:F.output,exitCode:F.exitCode,error:F.error,model:F.model,attemptedModels:F.attemptedModels}))),T=s5(T,d,k,H,K),$$(n,JSON.stringify({type:"subagent.parallel.completed",ts:Date.now(),runId:j,stepIndex:H,success:v.every((F)=>F.exitCode===0||F.exitCode===-1)})),v.some((F)=>F.exitCode!==0&&F.exitCode!==-1))break}finally{if(d)Oj(d)}}else{let K=V,_=Date.now();Y.currentStep=R,Y.steps[R].status="running",Y.steps[R].activityState=void 0,Y.activityState=void 0,yj(Y.steps[R]),Y.steps[R].skills=K.skills,Y.steps[R].startedAt=_,Y.steps[R].lastActivityAt=_,Y.lastActivityAt=_,Y.lastUpdate=_,Y.outputFile=r.join(k,`output-${R}.log`),a(),$$(n,JSON.stringify({type:"subagent.step.started",ts:_,runId:j,stepIndex:R,agent:K.agent})),C1(R);let z=await kj(K,{previousOutput:T,placeholder:X,cwd:Q,sessionEnabled:W0,outputs:y,sessionDir:$.sessionDir,artifactsDir:B,artifactConfig:q,id:j,flatIndex:R,flatStepCount:Math.max(Y.steps.length,1),outputFile:r.join(k,`output-${R}.log`),steerInboxDir:y0(k,R),piPackageRoot:$.piPackageRoot,piArgv1:$.piArgv1,childIntercomTarget:$.childIntercomTargets?.[R],orchestratorIntercomTarget:$.controlIntercomTarget,nestedRoute:$.nestedRoute,registerInterrupt:(v)=>N$(R,v),registerTimeout:(v)=>f$(R,v),registerTurnBudgetAbort:(v)=>S$(R,v),timeoutSignal:q$.signal,timeoutMessage:p,turnBudget:$.turnBudget,onAttemptStart:(v)=>T1(R,v.model,v.thinking),onChildEvent:(v)=>E1(R,v),skipAcceptance:()=>E});if(K.sessionFile)o$=K.sessionFile;if(T=z.output,h.push({agent:z.agent,output:E?p??"Subagent timed out.":z.output,error:E?p??"Subagent timed out.":z.error,success:!E&&z.interrupted!==!0&&z.exitCode===0,exitCode:E?1:z.interrupted===!0?0:z.exitCode,sessionFile:z.sessionFile,intercomTarget:z.intercomTarget,model:z.model,attemptedModels:z.attemptedModels,modelAttempts:z.modelAttempts,totalCost:z.totalCost,artifactPaths:z.artifactPaths,transcriptPath:z.transcriptPath,transcriptError:z.transcriptError,structuredOutput:z.structuredOutput,structuredOutputPath:z.structuredOutputPath,structuredOutputSchemaPath:z.structuredOutputSchemaPath,acceptance:z.acceptance,interrupted:z.interrupted,timedOut:E||z.timedOut?!0:void 0,turnBudget:z.turnBudget,turnBudgetExceeded:z.turnBudgetExceeded,wrapUpRequested:z.wrapUpRequested,toolBudget:z.toolBudget,toolBudgetBlocked:z.toolBudgetBlocked}),K.outputName)y[K.outputName]=Hj({agent:z.agent,output:z.output,structuredOutput:z.structuredOutput},H);Y.outputs=y;let N=$.sessionDir?Fj($.sessionDir):null,w=N?{input:N.input-Y$.input,output:N.output-Y$.output,total:N.total-Y$.total}:null;if(N)Y$=N;else if(w=p8(z.modelAttempts),w)Y$={input:Y$.input+w.input,output:Y$.output+w.output,total:Y$.total+w.total};let d=Date.now(),Z$=z.interrupted===!0;if(Y.steps[R].status=E?"failed":Z$?"paused":z.exitCode===0?"complete":"failed",Y.steps[R].endedAt=d,Y.steps[R].durationMs=d-_,Y.steps[R].exitCode=E?1:Z$?0:z.exitCode,Y.steps[R].timedOut=E||z.timedOut?!0:void 0,Y.steps[R].turnBudget=z.turnBudget,Y.steps[R].turnBudgetExceeded=z.turnBudgetExceeded,Y.steps[R].wrapUpRequested=z.wrapUpRequested,Y.steps[R].toolBudget=z.toolBudget,Y.steps[R].toolBudgetBlocked=z.toolBudgetBlocked,z.toolBudget)Y.toolBudget=z.toolBudget;if(z.toolBudgetBlocked)Y.toolBudgetBlocked=!0;if(z.turnBudget)Y.turnBudget=z.turnBudget;if(z.turnBudgetExceeded)Y.turnBudgetExceeded=!0;if(z.wrapUpRequested)Y.wrapUpRequested=!0;if(Y.steps[R].model=z.model,Y.steps[R].thinking=O0(z.model,Y.steps[R].thinking),Y.steps[R].attemptedModels=z.attemptedModels,Y.steps[R].modelAttempts=z.modelAttempts,Y.steps[R].totalCost=z.totalCost,Y.steps[R].error=E?p??"Subagent timed out.":z.error,Y.steps[R].transcriptPath=z.transcriptPath??Y.steps[R].transcriptPath,Y.steps[R].transcriptError=z.transcriptError,Y.steps[R].structuredOutput=z.structuredOutput,Y.steps[R].structuredOutputPath=z.structuredOutputPath,Y.steps[R].structuredOutputSchemaPath=z.structuredOutputSchemaPath,Y.steps[R].acceptance=z.acceptance,w)Y.steps[R].tokens=w,Y.totalTokens={...Y$};if(Y.lastUpdate=d,a(),$$(n,JSON.stringify({type:E?"subagent.step.failed":Z$?"subagent.step.paused":z.exitCode===0?"subagent.step.completed":"subagent.step.failed",ts:d,runId:j,stepIndex:R,agent:K.agent,exitCode:E?1:Z$?0:z.exitCode,durationMs:d-_,tokens:w})),z.completionGuardTriggered){let v=A0({from:Y.steps[R].activityState,to:"needs_attention",runId:j,agent:K.agent,index:R,ts:d,message:`${K.agent} completed without making edits for an implementation task`,reason:"completion_guard"});E0(v)}if(R++,z.exitCode!==0)break}}let n0=h.map((H)=>{let V=H.output.trim(),K=V?H.error?`${V}
|
|
77
76
|
|
|
78
|
-
|
|
77
|
+
Error: ${H.error}`:V:H.error??"(no output)";return`${H.agent}:
|
|
78
|
+
${K}`}).join(`
|
|
79
|
+
|
|
80
|
+
`),S1=!1;if(G){let H={...nj,...G},V=h[h.length-1]?.artifactPaths?.outputPath,K=sj(n0,H,V);if(K.truncated)n0=K.text,S1=!0}let oj=$.resultMode??Y.mode,i0=h.reduce((H,V)=>({inputTokens:H.inputTokens+(V.totalCost?.inputTokens??0),outputTokens:H.outputTokens+(V.totalCost?.outputTokens??0),costUsd:H.costUsd+(V.totalCost?.costUsd??0)}),{inputTokens:0,outputTokens:0,costUsd:0}),D1=i0.inputTokens>0||i0.outputTokens>0||i0.costUsd>0?i0:void 0,r0=Y.steps.map((H)=>H.agent),$2=r0.length===1?r0[0]:oj==="parallel"?`parallel:${r0.join("+")}`:`chain:${r0.join("->")}`,H0,s0,b1,M0;if(v$){if(H0=$.sessionDir?m5($.sessionDir)??void 0:void 0,!H0&&o$)H0=o$;if(H0)try{let H=$.sessionDir??r.dirname(H0),V=await l5(H0,H,$.piPackageRoot),K=p5(V);if("error"in K)M0=K.error;else s0=K.shareUrl,b1=K.gistUrl}catch(H){M0=String(H)}else M0="Session file not found."}if(X$)clearInterval(X$),X$=void 0;if(_$)clearTimeout(_$),_$=void 0;e8();let R1=H0??o$,V0=Date.now();if(Y.state=E||t?"failed":s?"paused":h.every((H)=>H.success)?"complete":"failed",Y.activityState=void 0,E)Y.timedOut=!0,Y.error=p??"Subagent timed out.";if(t&&!Y.error){let H=Y.turnBudget;Y.error=H?u0(H,H.turnCount):"Subagent exceeded turn budget."}if(Y.endedAt=V0,Y.lastUpdate=V0,Y.sessionFile=R1,Y.totalCost=D1,Y.shareUrl=s0,Y.gistUrl=b1,Y.shareError=M0,Y.state==="failed"&&!Y.error){let H=Y.steps.find((V)=>V.status==="failed");if(H?.agent)Y.error=H.error?`Step failed: ${H.agent}: ${H.error}`:`Step failed: ${H.agent}`}a(),$$(n,JSON.stringify({type:"subagent.run.completed",lifecycleArtifactVersion:S0,ts:V0,runId:j,status:Y.state,durationMs:V0-S,totalTokens:Y.totalTokens,totalCost:D1})),n5(d$,{id:j,mode:Y.mode,cwd:Q,startedAt:S,endedAt:V0,steps:Y.steps.map((H)=>({agent:H.agent,status:H.status,durationMs:H.durationMs})),summary:n0,truncated:S1,artifactsDir:B,sessionFile:R1,shareUrl:s0,shareError:M0});try{D$(Z,{lifecycleArtifactVersion:S0,id:j,agent:$2,mode:oj,success:!E&&!t&&!s&&h.every((H)=>H.success),state:E||t?"failed":s?"paused":h.every((H)=>H.success)?"complete":"failed",summary:E?p??"Subagent timed out.":t?Y.error??"Subagent exceeded turn budget.":s?"Paused after interrupt. Waiting for explicit next action.":n0,...$.timeoutMs!==void 0?{timeoutMs:$.timeoutMs}:{},...$.deadlineAt!==void 0?{deadlineAt:$.deadlineAt}:{},...Y.turnBudget?{turnBudget:Y.turnBudget}:{},...Y.turnBudgetExceeded?{turnBudgetExceeded:!0}:{},...Y.wrapUpRequested?{wrapUpRequested:!0}:{},...Y.toolBudget?{toolBudget:Y.toolBudget}:{},...Y.toolBudgetBlocked?{toolBudgetBlocked:!0}:{},...E?{timedOut:!0,error:p??"Subagent timed out."}:t?{error:Y.error??"Subagent exceeded turn budget."}:{},results:h.map((H)=>({agent:H.agent,output:H.output,error:H.error,success:H.success,skipped:H.skipped||void 0,interrupted:H.interrupted||void 0,timedOut:H.timedOut||void 0,turnBudget:H.turnBudget,turnBudgetExceeded:H.turnBudgetExceeded||void 0,wrapUpRequested:H.wrapUpRequested||void 0,toolBudget:H.toolBudget,toolBudgetBlocked:H.toolBudgetBlocked||void 0,sessionFile:H.sessionFile,intercomTarget:H.intercomTarget,model:H.model,attemptedModels:H.attemptedModels,modelAttempts:H.modelAttempts,totalCost:H.totalCost,artifactPaths:H.artifactPaths,truncated:H.truncated,transcriptPath:H.transcriptPath,transcriptError:H.transcriptError,structuredOutput:H.structuredOutput,structuredOutputPath:H.structuredOutputPath,structuredOutputSchemaPath:H.structuredOutputSchemaPath,acceptance:H.acceptance})),outputs:y,workflowGraph:Y.workflowGraph,exitCode:E||t?1:s||h.every((H)=>H.success)?0:1,timestamp:V0,durationMs:V0-S,totalTokens:Y.totalTokens,totalCost:D1,truncated:S1,artifactsDir:B,cwd:Q,asyncDir:k,sessionId:$.sessionId,sessionFile:R1,intercomTarget:$.controlIntercomTarget,shareUrl:s0,gistUrl:b1,shareError:M0,...W!==void 0&&{taskIndex:W},...U!==void 0&&{totalTasks:U}})}catch(H){console.error(`Failed to write result file ${Z}:`,H)}}var Pj=process.argv[2];if(Pj)try{let $=e.readFileSync(Pj,"utf-8"),j=JSON.parse($);try{e.unlinkSync(Pj)}catch{}r8(j).catch((J)=>{console.error("Subagent runner error:",J),process.exit(1)})}catch($){console.error("Subagent runner error:",$),process.exit(1)}else{let $="";process.stdin.setEncoding("utf-8"),process.stdin.on("data",(j)=>{$+=j}),process.stdin.on("end",()=>{try{let j=JSON.parse($);r8(j).catch((J)=>{console.error("Subagent runner error:",J),process.exit(1)})}catch(j){console.error("Subagent runner error:",j),process.exit(1)}})}
|