@duckmind/dm-windows-x64 0.60.4 → 0.60.8

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.
Files changed (197) hide show
  1. package/dm.exe +0 -0
  2. package/extensions/.dm-extensions.json +70 -123
  3. package/extensions/dm-9router-ext/src/index.js +410 -5
  4. package/extensions/dm-caveman/extensions/caveman.js +283 -12
  5. package/extensions/dm-cliproxy/index.js +182 -2
  6. package/extensions/dm-cliproxy/scripts/check-config-migration.js +66 -8
  7. package/extensions/dm-cliproxy/src/apply.js +228 -1
  8. package/extensions/dm-cliproxy/src/cache.js +42 -1
  9. package/extensions/dm-cliproxy/src/commands.js +50 -2
  10. package/extensions/dm-cliproxy/src/compat.js +81 -1
  11. package/extensions/dm-cliproxy/src/config.js +192 -2
  12. package/extensions/dm-cliproxy/src/conflicts.js +46 -1
  13. package/extensions/dm-cliproxy/src/fetch-models.js +190 -1
  14. package/extensions/dm-cliproxy/src/fetch-usage.js +41 -1
  15. package/extensions/dm-cliproxy/src/log.js +23 -1
  16. package/extensions/dm-cliproxy/src/status-quota.js +77 -1
  17. package/extensions/dm-cliproxy/src/ui-frame.js +50 -1
  18. package/extensions/dm-cliproxy/src/ui-hub/hub.js +199 -2
  19. package/extensions/dm-cliproxy/src/ui-hub/index.js +26 -2
  20. package/extensions/dm-cliproxy/src/ui-hub/shell.js +46 -1
  21. package/extensions/dm-cliproxy/src/ui-hub/view-diagnostics.js +69 -1
  22. package/extensions/dm-cliproxy/src/ui-hub/view-models.js +379 -1
  23. package/extensions/dm-cliproxy/src/ui-hub/view-usage.js +106 -1
  24. package/extensions/dm-cliproxy/src/ui-picker/catalog.js +41 -1
  25. package/extensions/dm-cliproxy/src/ui-picker/mutate.js +115 -1
  26. package/extensions/dm-cliproxy/src/ui-picker/prompt-confirm.js +35 -1
  27. package/extensions/dm-cliproxy/src/ui-picker/prompt-name.js +62 -1
  28. package/extensions/dm-cliproxy/src/ui-picker/providers.js +45 -1
  29. package/extensions/dm-cliproxy/src/ui-picker/render-text.js +34 -1
  30. package/extensions/dm-cliproxy/src/ui-picker/rows.js +57 -1
  31. package/extensions/dm-cliproxy/src/ui-setup.js +260 -2
  32. package/extensions/dm-cliproxy/src/ui-usage.js +151 -1
  33. package/extensions/dm-cliproxy/src/usage-shared-cache.js +97 -1
  34. package/extensions/dm-context/src/context.js +144 -1
  35. package/extensions/dm-context/src/index.js +339 -7
  36. package/extensions/dm-context/src/utils.js +9 -1
  37. package/extensions/dm-cua/bin/browser-cua.mjs +73 -8
  38. package/extensions/dm-cua/index.js +75 -6
  39. package/extensions/dm-cua/src/browser-cua-lib.mjs +490 -6
  40. package/extensions/dm-cua/src/browser-install.mjs +331 -2
  41. package/extensions/dm-fff/src/index.js +688 -12
  42. package/extensions/dm-fff/src/query.js +60 -1
  43. package/extensions/dm-goal/src/goal.js +894 -23
  44. package/extensions/dm-image2/index.js +103 -9
  45. package/extensions/dm-image2/src/image-lib.mjs +1275 -8
  46. package/extensions/dm-subagents/install.mjs +62 -8
  47. package/extensions/dm-subagents/src/agents/agent-management.js +1190 -36
  48. package/extensions/dm-subagents/src/agents/agent-memory.js +216 -6
  49. package/extensions/dm-subagents/src/agents/agent-scope.js +5 -1
  50. package/extensions/dm-subagents/src/agents/agent-selection.js +20 -1
  51. package/extensions/dm-subagents/src/agents/agent-serializer.js +120 -5
  52. package/extensions/dm-subagents/src/agents/agents.js +1139 -11
  53. package/extensions/dm-subagents/src/agents/chain-serializer.js +299 -11
  54. package/extensions/dm-subagents/src/agents/frontmatter.js +65 -6
  55. package/extensions/dm-subagents/src/agents/identity.js +29 -1
  56. package/extensions/dm-subagents/src/agents/proactive-skills.js +141 -1
  57. package/extensions/dm-subagents/src/agents/skills.js +614 -6
  58. package/extensions/dm-subagents/src/extension/config.js +35 -2
  59. package/extensions/dm-subagents/src/extension/control-notices.js +69 -4
  60. package/extensions/dm-subagents/src/extension/doctor.js +172 -15
  61. package/extensions/dm-subagents/src/extension/fanout-child.js +158 -231
  62. package/extensions/dm-subagents/src/extension/index.js +521 -359
  63. package/extensions/dm-subagents/src/extension/rpc.js +266 -7
  64. package/extensions/dm-subagents/src/extension/schemas.js +275 -1
  65. package/extensions/dm-subagents/src/extension/tool-description.js +111 -6
  66. package/extensions/dm-subagents/src/intercom/intercom-bridge.js +126 -4
  67. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +452 -5
  68. package/extensions/dm-subagents/src/intercom/result-intercom.js +319 -3
  69. package/extensions/dm-subagents/src/profiles/profiles.js +458 -3
  70. package/extensions/dm-subagents/src/runs/background/async-execution.js +834 -40
  71. package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +435 -14
  72. package/extensions/dm-subagents/src/runs/background/async-resume.js +334 -8
  73. package/extensions/dm-subagents/src/runs/background/async-status.js +313 -12
  74. package/extensions/dm-subagents/src/runs/background/chain-append.js +245 -2
  75. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +136 -1
  76. package/extensions/dm-subagents/src/runs/background/completion-batcher.js +94 -1
  77. package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +54 -1
  78. package/extensions/dm-subagents/src/runs/background/control-channel.js +190 -1
  79. package/extensions/dm-subagents/src/runs/background/fleet-view.js +483 -17
  80. package/extensions/dm-subagents/src/runs/background/notify.js +129 -3
  81. package/extensions/dm-subagents/src/runs/background/parallel-groups.js +34 -1
  82. package/extensions/dm-subagents/src/runs/background/result-watcher.js +236 -6
  83. package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +76 -4
  84. package/extensions/dm-subagents/src/runs/background/run-status.js +427 -23
  85. package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +487 -4
  86. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +306 -9
  87. package/extensions/dm-subagents/src/runs/background/subagent-runner.js +2849 -73
  88. package/extensions/dm-subagents/src/runs/background/top-level-async.js +5 -1
  89. package/extensions/dm-subagents/src/runs/background/wait.js +206 -11
  90. package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +1013 -12
  91. package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +980 -101
  92. package/extensions/dm-subagents/src/runs/foreground/execution.js +1165 -45
  93. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +3157 -222
  94. package/extensions/dm-subagents/src/runs/shared/acceptance.js +835 -3
  95. package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +104 -1
  96. package/extensions/dm-subagents/src/runs/shared/completion-guard.js +116 -3
  97. package/extensions/dm-subagents/src/runs/shared/dm-args.js +208 -1
  98. package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +90 -1
  99. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +282 -1
  100. package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +148 -1
  101. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +305 -1
  102. package/extensions/dm-subagents/src/runs/shared/model-fallback.js +194 -1
  103. package/extensions/dm-subagents/src/runs/shared/model-scope.js +65 -1
  104. package/extensions/dm-subagents/src/runs/shared/nested-events.js +851 -8
  105. package/extensions/dm-subagents/src/runs/shared/nested-path.js +41 -1
  106. package/extensions/dm-subagents/src/runs/shared/nested-render.js +105 -1
  107. package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +81 -4
  108. package/extensions/dm-subagents/src/runs/shared/run-history.js +51 -4
  109. package/extensions/dm-subagents/src/runs/shared/single-output.js +149 -8
  110. package/extensions/dm-subagents/src/runs/shared/structured-output.js +58 -1
  111. package/extensions/dm-subagents/src/runs/shared/subagent-control.js +166 -5
  112. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +329 -13
  113. package/extensions/dm-subagents/src/runs/shared/tool-budget.js +73 -1
  114. package/extensions/dm-subagents/src/runs/shared/turn-budget.js +47 -4
  115. package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +196 -1
  116. package/extensions/dm-subagents/src/runs/shared/worktree.js +435 -3
  117. package/extensions/dm-subagents/src/shared/artifacts.js +92 -2
  118. package/extensions/dm-subagents/src/shared/atomic-json.js +55 -1
  119. package/extensions/dm-subagents/src/shared/child-transcript.js +167 -5
  120. package/extensions/dm-subagents/src/shared/file-coalescer.js +25 -1
  121. package/extensions/dm-subagents/src/shared/fork-context.js +147 -4
  122. package/extensions/dm-subagents/src/shared/formatters.js +98 -7
  123. package/extensions/dm-subagents/src/shared/jsonl-writer.js +56 -2
  124. package/extensions/dm-subagents/src/shared/model-info.js +62 -1
  125. package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +68 -1
  126. package/extensions/dm-subagents/src/shared/session-identity.js +6 -1
  127. package/extensions/dm-subagents/src/shared/session-tokens.js +39 -2
  128. package/extensions/dm-subagents/src/shared/settings.js +198 -11
  129. package/extensions/dm-subagents/src/shared/status-format.js +53 -1
  130. package/extensions/dm-subagents/src/shared/types.js +184 -6
  131. package/extensions/dm-subagents/src/shared/utils.js +462 -2
  132. package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +288 -1
  133. package/extensions/dm-subagents/src/slash/prompt-workflows.js +297 -7
  134. package/extensions/dm-subagents/src/slash/slash-bridge.js +118 -1
  135. package/extensions/dm-subagents/src/slash/slash-commands.js +1287 -31
  136. package/extensions/dm-subagents/src/slash/slash-live-state.js +240 -4
  137. package/extensions/dm-subagents/src/tui/render-helpers.js +64 -1
  138. package/extensions/dm-subagents/src/tui/render.js +1542 -4
  139. package/extensions/dm-usage/index.js +1294 -9
  140. package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +40 -9
  141. package/extensions/greedysearch-dm/bin/cdp-headless.mjs +5 -2
  142. package/extensions/greedysearch-dm/bin/cdp-visible.mjs +5 -2
  143. package/extensions/greedysearch-dm/bin/cdp.mjs +896 -30
  144. package/extensions/greedysearch-dm/bin/gschrome.mjs +30 -2
  145. package/extensions/greedysearch-dm/bin/kill-visible.mjs +7 -2
  146. package/extensions/greedysearch-dm/bin/launch-visible.mjs +13 -2
  147. package/extensions/greedysearch-dm/bin/launch.mjs +282 -10
  148. package/extensions/greedysearch-dm/bin/mcp.mjs +386 -361
  149. package/extensions/greedysearch-dm/bin/search.mjs +620 -540
  150. package/extensions/greedysearch-dm/bin/visible.mjs +22 -2
  151. package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +329 -579
  152. package/extensions/greedysearch-dm/extractors/chatgpt.mjs +301 -583
  153. package/extensions/greedysearch-dm/extractors/common.mjs +408 -32
  154. package/extensions/greedysearch-dm/extractors/consensus.mjs +376 -365
  155. package/extensions/greedysearch-dm/extractors/consent.mjs +303 -14
  156. package/extensions/greedysearch-dm/extractors/gemini.mjs +228 -592
  157. package/extensions/greedysearch-dm/extractors/google-ai.mjs +78 -499
  158. package/extensions/greedysearch-dm/extractors/logically.mjs +270 -347
  159. package/extensions/greedysearch-dm/extractors/perplexity.mjs +243 -581
  160. package/extensions/greedysearch-dm/extractors/selectors.mjs +32 -1
  161. package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +130 -317
  162. package/extensions/greedysearch-dm/index.js +123 -23
  163. package/extensions/greedysearch-dm/src/fetcher.mjs +576 -2
  164. package/extensions/greedysearch-dm/src/formatters/results.js +95 -10
  165. package/extensions/greedysearch-dm/src/formatters/sources.js +57 -1
  166. package/extensions/greedysearch-dm/src/formatters/synthesis.js +49 -1
  167. package/extensions/greedysearch-dm/src/github.mjs +222 -7
  168. package/extensions/greedysearch-dm/src/reddit.mjs +145 -14
  169. package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +340 -9
  170. package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +112 -4
  171. package/extensions/greedysearch-dm/src/search/chrome.mjs +486 -285
  172. package/extensions/greedysearch-dm/src/search/constants.mjs +109 -8
  173. package/extensions/greedysearch-dm/src/search/defaults.mjs +10 -1
  174. package/extensions/greedysearch-dm/src/search/engines.mjs +79 -9
  175. package/extensions/greedysearch-dm/src/search/fetch-source.mjs +441 -349
  176. package/extensions/greedysearch-dm/src/search/file-sources.mjs +29 -7
  177. package/extensions/greedysearch-dm/src/search/minimize.mjs +86 -1
  178. package/extensions/greedysearch-dm/src/search/output.mjs +51 -5
  179. package/extensions/greedysearch-dm/src/search/paths.mjs +48 -1
  180. package/extensions/greedysearch-dm/src/search/pdf.mjs +63 -2
  181. package/extensions/greedysearch-dm/src/search/port-pid.mjs +69 -1
  182. package/extensions/greedysearch-dm/src/search/progress.mjs +109 -2
  183. package/extensions/greedysearch-dm/src/search/query.mjs +21 -1
  184. package/extensions/greedysearch-dm/src/search/recovery.mjs +49 -1
  185. package/extensions/greedysearch-dm/src/search/research.mjs +2227 -458
  186. package/extensions/greedysearch-dm/src/search/scale-aware.mjs +61 -11
  187. package/extensions/greedysearch-dm/src/search/simple-research.mjs +396 -805
  188. package/extensions/greedysearch-dm/src/search/sources.mjs +412 -1
  189. package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +127 -12
  190. package/extensions/greedysearch-dm/src/search/synthesis.mjs +202 -12
  191. package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +209 -23
  192. package/extensions/greedysearch-dm/src/tools/shared.js +226 -10
  193. package/extensions/greedysearch-dm/src/utils/content.mjs +35 -4
  194. package/extensions/greedysearch-dm/src/utils/helpers.js +22 -1
  195. package/extensions/greedysearch-dm/src/utils/node-runtime.mjs +10 -1
  196. package/extensions/greedysearch-dm/src/utils/system-cmds.mjs +61 -1
  197. package/package.json +1 -1
@@ -1,3 +1,129 @@
1
- function O(j){if(typeof j!=="string")return;let $=j.trim();return $.length>0?$:void 0}function I(j){if(typeof j!=="number")return;return Number.isFinite(j)?j:void 0}function y(j,$){let k=O(j.id);if(k)return`id:${k}`;let q=O(j.sessionId)??"no-session",Q=O(j.agent)??"unknown",R=I(j.timestamp),J=I(j.taskIndex),Z=I(j.totalTasks),Y=typeof j.success==="boolean"?j.success?"1":"0":"?";return["meta",q,Q,R!==void 0?String(R):"no-ts",J!==void 0?String(J):"-",Z!==void 0?String(Z):"-",Y,$].join(":")}function m(j,$,k){for(let[q,Q]of j.entries())if($-Q>k)j.delete(q)}function A(j,$,k,q){if(m(j,k,q),j.has($))return!0;return j.set($,k),!1}function D(j){let $=globalThis,k=$[j];if(k instanceof Map)return k;let q=new Map;return $[j]=q,q}var z={enabled:!0,debounceMs:150,maxWaitMs:1000,stragglerDebounceMs:75,stragglerMaxWaitMs:400,stragglerWindowMs:2000};function X(j){if(typeof j!=="number"||!Number.isFinite(j)||!Number.isInteger(j)||j<1)return;return j}function _(j,$){return{enabled:typeof $?.enabled==="boolean"?$.enabled:typeof j?.enabled==="boolean"?j.enabled:z.enabled,debounceMs:X($?.debounceMs)??X(j?.debounceMs)??z.debounceMs,maxWaitMs:X($?.maxWaitMs)??X(j?.maxWaitMs)??z.maxWaitMs,stragglerDebounceMs:X($?.stragglerDebounceMs)??X(j?.stragglerDebounceMs)??z.stragglerDebounceMs,stragglerMaxWaitMs:X($?.stragglerMaxWaitMs)??X(j?.stragglerMaxWaitMs)??z.stragglerMaxWaitMs,stragglerWindowMs:X($?.stragglerWindowMs)??X(j?.stragglerWindowMs)??z.stragglerWindowMs}}var v={setTimeout:(j,$)=>setTimeout(j,$),clearTimeout:(j)=>clearTimeout(j)};function E(j){if(j&&typeof j==="object"&&"unref"in j&&typeof j.unref==="function")j.unref()}function P(j){let $=j.timers??v,k=j.now??Date.now,q=j.config;if(!q.enabled)return{push(V){j.emit([V])},flush(){},dispose(){}};let Q=[],R=null,J=null,Z=!1,Y=null,F=()=>{if(R)$.clearTimeout(R),R=null;if(J)$.clearTimeout(J),J=null},K=()=>{if(F(),Q.length===0)return;let V=Q;Q=[],Y=k(),j.emit(V)};return{push(V){if(Q.length===0)Z=Y!==null&&k()-Y<q.stragglerWindowMs;if(Q.push(V),R)$.clearTimeout(R);let w=Z?q.stragglerDebounceMs:q.debounceMs;if(R=$.setTimeout(K,w),E(R),!J){let N=Z?q.stragglerMaxWaitMs:q.maxWaitMs;J=$.setTimeout(K,N),E(J)}},flush:K,dispose(){F(),Q=[]}}}import*as W from"node:os";import*as H from"node:path";var f="subagent:async-complete";function B(j){return j.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function h(j){let $=j?.env??process.env,k=j&&Object.hasOwn(j,"getuid")?j.getuid:process.getuid?.bind(process);if(typeof k==="function")return`uid-${k()}`;for(let J of["USERNAME","USER","LOGNAME"]){let Z=$[J];if(Z)return`user-${B(Z)}`}let q=j&&Object.hasOwn(j,"userInfo")?j.userInfo:W.userInfo;try{let J=q?.().username;if(J)return`user-${B(J)}`}catch{}let Q=$.USERPROFILE??$.HOME;if(Q)return`home-${B(Q)}`;let R=j&&Object.hasOwn(j,"homedir")?j.homedir:W.homedir;try{let J=R?.();if(J)return`home-${B(J)}`}catch{}return"shared"}var M=H.join(W.tmpdir(),`dm-subagents-${h()}`),l=H.join(M,"async-subagent-results"),i=H.join(M,"async-subagent-runs"),a=H.join(M,"chain-runs"),t=H.join(M,"artifacts");function C(j){if(!j.sessionValue)return;return j.sessionLabel?`${j.sessionLabel}: ${j.sessionValue}`:j.sessionValue}function n(j){let $=C(j);return[`Background task ${j.status}: **${j.agent}**${j.taskInfo??""}`,"",j.resultPreview.trim()?j.resultPreview:"(no output)",$?"":void 0,$].filter((k)=>k!==void 0).join(`
2
- `)}function u(j){let k=[`Background tasks completed (${j.length}): ${j.map((q)=>`**${q.agent}**${q.taskInfo??""}`).join(", ")}`,""];for(let q=0;q<j.length;q++){let Q=j[q];if(!Q)continue;let R=C(Q);if(k.push(`${q+1}. ${Q.agent}${Q.taskInfo??""}`),k.push(Q.resultPreview.trim()?Q.resultPreview:"(no output)"),R)k.push(R);k.push("")}return k.join(`
3
- `).trimEnd()}function T(j,$){if($.length===0)return;let k=$.length===1?n($[0]):u($);j.sendMessage({customType:"subagent-notify",content:k,display:!0},{triggerTurn:!0})}function p(j){let $=typeof j.sessionId==="string"?j.sessionId.trim():"";if($)return`session:${$}`;let k=typeof j.cwd==="string"?j.cwd.trim():"";return k?`cwd:${k}`:"unknown"}function d(j){let $=j.agent??"unknown",k=typeof j.summary==="string"?j.summary:"",Q=!j.success&&(j.exitCode===0||j.state==="paused"||k.startsWith("Paused after interrupt."))?"paused":j.success?"completed":"failed",R=j.taskIndex!==void 0&&j.totalTasks!==void 0?` (${j.taskIndex+1}/${j.totalTasks})`:void 0,J=j.shareUrl?{label:"Session",value:j.shareUrl}:j.shareError?{label:"Session share error",value:j.shareError}:j.sessionFile?{label:"Session file",value:j.sessionFile}:void 0;return{agent:$,status:Q,...R?{taskInfo:R}:{},resultPreview:k,...typeof j.durationMs==="number"?{durationMs:j.durationMs}:{},...J?{sessionLabel:J.label,sessionValue:J.value}:{}}}function r(j,$,k={}){let R=globalThis,J=R.__pi_subagents_notify_unsubscribe__;if(typeof J==="function")try{J()}catch{}let Z=R.__pi_subagents_notify_batcher__;if(Z&&typeof Z.dispose==="function")try{Z.dispose()}catch{}let Y=D("__pi_subagents_notify_seen__"),F=600000,K=k.now??Date.now,V=_(k.batchConfig),w=new Map;R.__pi_subagents_notify_batcher__={dispose(){for(let S of w.values())S.dispose();w.clear()}};let N=(S)=>{let U=S;if(typeof U.sessionId!=="string"||U.sessionId!==$.currentSessionId)return;let b=K(),c=y(U,"notify");if(A(Y,c,b,F))return;let L=d(U),x=p(U),G=w.get(x);if(!G)G=P({config:V,emit:(g)=>T(j,g),...k.timers?{timers:k.timers}:{},now:K}),w.set(x,G);if(L.status!=="completed"){G.flush(),T(j,[L]);return}G.push(L)};R.__pi_subagents_notify_unsubscribe__=j.events.on(f,N)}export{n as formatSingleCompletion,u as formatGroupedCompletion,r as default,d as buildCompletionDetails};
1
+ import { buildCompletionKey, getGlobalSeenMap, markSeenWithTtl } from "./completion-dedupe.js";
2
+ import {
3
+ createCompletionBatcher,
4
+ resolveCompletionBatchConfig
5
+ } from "./completion-batcher.js";
6
+ import { SUBAGENT_ASYNC_COMPLETE_EVENT } from "../../shared/types.js";
7
+ function formatSessionLine(details) {
8
+ if (!details.sessionValue)
9
+ return;
10
+ return details.sessionLabel ? `${details.sessionLabel}: ${details.sessionValue}` : details.sessionValue;
11
+ }
12
+ export function formatSingleCompletion(details) {
13
+ const sessionLine = formatSessionLine(details);
14
+ return [
15
+ `Background task ${details.status}: **${details.agent}**${details.taskInfo ?? ""}`,
16
+ "",
17
+ details.resultPreview.trim() ? details.resultPreview : "(no output)",
18
+ sessionLine ? "" : undefined,
19
+ sessionLine
20
+ ].filter((line) => line !== undefined).join(`
21
+ `);
22
+ }
23
+ export function formatGroupedCompletion(details) {
24
+ const header = `Background tasks completed (${details.length}): ${details.map((d) => `**${d.agent}**${d.taskInfo ?? ""}`).join(", ")}`;
25
+ const blocks = [header, ""];
26
+ for (let index = 0;index < details.length; index++) {
27
+ const detail = details[index];
28
+ if (!detail)
29
+ continue;
30
+ const sessionLine = formatSessionLine(detail);
31
+ blocks.push(`${index + 1}. ${detail.agent}${detail.taskInfo ?? ""}`);
32
+ blocks.push(detail.resultPreview.trim() ? detail.resultPreview : "(no output)");
33
+ if (sessionLine)
34
+ blocks.push(sessionLine);
35
+ blocks.push("");
36
+ }
37
+ return blocks.join(`
38
+ `).trimEnd();
39
+ }
40
+ function sendCompletion(pi, details) {
41
+ if (details.length === 0)
42
+ return;
43
+ const content = details.length === 1 ? formatSingleCompletion(details[0]) : formatGroupedCompletion(details);
44
+ pi.sendMessage({
45
+ customType: "subagent-notify",
46
+ content,
47
+ display: true
48
+ }, { triggerTurn: true });
49
+ }
50
+ function completionBatchKey(result) {
51
+ const sessionId = typeof result.sessionId === "string" ? result.sessionId.trim() : "";
52
+ if (sessionId)
53
+ return `session:${sessionId}`;
54
+ const cwd = typeof result.cwd === "string" ? result.cwd.trim() : "";
55
+ return cwd ? `cwd:${cwd}` : "unknown";
56
+ }
57
+ export function buildCompletionDetails(result) {
58
+ const agent = result.agent ?? "unknown";
59
+ const summary = typeof result.summary === "string" ? result.summary : "";
60
+ const paused = !result.success && (result.exitCode === 0 || result.state === "paused" || summary.startsWith("Paused after interrupt."));
61
+ const status = paused ? "paused" : result.success ? "completed" : "failed";
62
+ const taskInfo = result.taskIndex !== undefined && result.totalTasks !== undefined ? ` (${result.taskIndex + 1}/${result.totalTasks})` : undefined;
63
+ const session = result.shareUrl ? { label: "Session", value: result.shareUrl } : result.shareError ? { label: "Session share error", value: result.shareError } : result.sessionFile ? { label: "Session file", value: result.sessionFile } : undefined;
64
+ return {
65
+ agent,
66
+ status,
67
+ ...taskInfo ? { taskInfo } : {},
68
+ resultPreview: summary,
69
+ ...typeof result.durationMs === "number" ? { durationMs: result.durationMs } : {},
70
+ ...session ? { sessionLabel: session.label, sessionValue: session.value } : {}
71
+ };
72
+ }
73
+ export default function registerSubagentNotify(pi, state, options = {}) {
74
+ const unsubscribeStoreKey = "__pi_subagents_notify_unsubscribe__";
75
+ const batcherStoreKey = "__pi_subagents_notify_batcher__";
76
+ const globalStore = globalThis;
77
+ const previousUnsubscribe = globalStore[unsubscribeStoreKey];
78
+ if (typeof previousUnsubscribe === "function") {
79
+ try {
80
+ previousUnsubscribe();
81
+ } catch {}
82
+ }
83
+ const previousBatcher = globalStore[batcherStoreKey];
84
+ if (previousBatcher && typeof previousBatcher.dispose === "function") {
85
+ try {
86
+ previousBatcher.dispose();
87
+ } catch {}
88
+ }
89
+ const seen = getGlobalSeenMap("__pi_subagents_notify_seen__");
90
+ const ttlMs = 10 * 60 * 1000;
91
+ const nowFn = options.now ?? Date.now;
92
+ const batchConfig = resolveCompletionBatchConfig(options.batchConfig);
93
+ const batchers = new Map;
94
+ globalStore[batcherStoreKey] = {
95
+ dispose() {
96
+ for (const batcher of batchers.values())
97
+ batcher.dispose();
98
+ batchers.clear();
99
+ }
100
+ };
101
+ const handleComplete = (data) => {
102
+ const result = data;
103
+ if (typeof result.sessionId !== "string" || result.sessionId !== state.currentSessionId)
104
+ return;
105
+ const now = nowFn();
106
+ const key = buildCompletionKey(result, "notify");
107
+ if (markSeenWithTtl(seen, key, now, ttlMs))
108
+ return;
109
+ const details = buildCompletionDetails(result);
110
+ const batchKey = completionBatchKey(result);
111
+ let batcher = batchers.get(batchKey);
112
+ if (!batcher) {
113
+ batcher = createCompletionBatcher({
114
+ config: batchConfig,
115
+ emit: (items) => sendCompletion(pi, items),
116
+ ...options.timers ? { timers: options.timers } : {},
117
+ now: nowFn
118
+ });
119
+ batchers.set(batchKey, batcher);
120
+ }
121
+ if (details.status !== "completed") {
122
+ batcher.flush();
123
+ sendCompletion(pi, [details]);
124
+ return;
125
+ }
126
+ batcher.push(details);
127
+ };
128
+ globalStore[unsubscribeStoreKey] = pi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete);
129
+ }
@@ -1 +1,34 @@
1
- function a(n,u,s){if(typeof n!=="object"||n===null)return!1;let{start:r,count:t,stepIndex:e}=n;return typeof r==="number"&&typeof t==="number"&&typeof e==="number"&&Number.isInteger(r)&&Number.isInteger(t)&&Number.isInteger(e)&&r>=0&&t>0&&e>=0&&e<s&&r+t<=u}function l(n,u,s){if(!Array.isArray(n))return[];return n.filter((r)=>a(r,u,s)).sort((r,t)=>r.stepIndex-t.stepIndex||r.start-t.start)}function o(n,u,s){let r=0,t=0;for(let e of s){while(t<e.start&&r<u){if(t===n)return r;t++,r++}if(n>=e.start&&n<e.start+e.count)return e.stepIndex;t=e.start+e.count,r=e.stepIndex+1}while(t<=n&&r<u){if(t===n)return r;t++,r++}return Math.max(0,u-1)}export{l as normalizeParallelGroups,o as flatToLogicalStepIndex};
1
+ function isValidParallelGroup(group, stepCount, chainStepCount) {
2
+ if (typeof group !== "object" || group === null)
3
+ return false;
4
+ const { start, count, stepIndex } = group;
5
+ return typeof start === "number" && typeof count === "number" && typeof stepIndex === "number" && Number.isInteger(start) && Number.isInteger(count) && Number.isInteger(stepIndex) && start >= 0 && count > 0 && stepIndex >= 0 && stepIndex < chainStepCount && start + count <= stepCount;
6
+ }
7
+ export function normalizeParallelGroups(groups, stepCount, chainStepCount) {
8
+ if (!Array.isArray(groups))
9
+ return [];
10
+ return groups.filter((group) => isValidParallelGroup(group, stepCount, chainStepCount)).sort((left, right) => left.stepIndex - right.stepIndex || left.start - right.start);
11
+ }
12
+ export function flatToLogicalStepIndex(flatIndex, chainStepCount, groups) {
13
+ let logicalIndex = 0;
14
+ let cursor = 0;
15
+ for (const group of groups) {
16
+ while (cursor < group.start && logicalIndex < chainStepCount) {
17
+ if (cursor === flatIndex)
18
+ return logicalIndex;
19
+ cursor++;
20
+ logicalIndex++;
21
+ }
22
+ if (flatIndex >= group.start && flatIndex < group.start + group.count)
23
+ return group.stepIndex;
24
+ cursor = group.start + group.count;
25
+ logicalIndex = group.stepIndex + 1;
26
+ }
27
+ while (cursor <= flatIndex && logicalIndex < chainStepCount) {
28
+ if (cursor === flatIndex)
29
+ return logicalIndex;
30
+ cursor++;
31
+ logicalIndex++;
32
+ }
33
+ return Math.max(0, chainStepCount - 1);
34
+ }
@@ -1,8 +1,238 @@
1
- import*as Ej from"node:fs";import*as P$ from"node:path";function o($){if(typeof $!=="string")return;let J=$.trim();return J.length>0?J:void 0}function n($){if(typeof $!=="number")return;return Number.isFinite($)?$:void 0}function Q$($,J){let j=o($.id);if(j)return`id:${j}`;let Z=o($.sessionId)??"no-session",Q=o($.agent)??"unknown",X=n($.timestamp),W=n($.taskIndex),Y=n($.totalTasks),O=typeof $.success==="boolean"?$.success?"1":"0":"?";return["meta",Z,Q,X!==void 0?String(X):"no-ts",W!==void 0?String(W):"-",Y!==void 0?String(Y):"-",O,J].join(":")}function h$($,J,j){for(let[Z,Q]of $.entries())if(J-Q>j)$.delete(Z)}function X$($,J,j,Z){if(h$($,j,Z),$.has(J))return!0;return $.set(J,j),!1}var o$={setTimeout:($,J)=>setTimeout($,J),clearTimeout:($)=>clearTimeout($)};function B$($,J,j=o$){let Z=new Map;return{schedule(Q,X=J){if(Z.has(Q))return!1;let W=j.setTimeout(()=>{Z.delete(Q),$(Q)},X);return Z.set(Q,W),!0},clear(){for(let Q of Z.values())j.clearTimeout(Q);Z.clear()}}}import*as R from"node:os";import*as I from"node:path";var W$="subagent:async-complete";var Y$="subagent:result-intercom",f$="subagent:result-intercom-delivery";function w($){return $.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function n$($){let J=$?.env??process.env,j=$&&Object.hasOwn($,"getuid")?$.getuid:process.getuid?.bind(process);if(typeof j==="function")return`uid-${j()}`;for(let W of["USERNAME","USER","LOGNAME"]){let Y=J[W];if(Y)return`user-${w(Y)}`}let Z=$&&Object.hasOwn($,"userInfo")?$.userInfo:R.userInfo;try{let W=Z?.().username;if(W)return`user-${w(W)}`}catch{}let Q=J.USERPROFILE??J.HOME;if(Q)return`home-${w(Q)}`;let X=$&&Object.hasOwn($,"homedir")?$.homedir:R.homedir;try{let W=X?.();if(W)return`home-${w(W)}`}catch{}return"shared"}var S=I.join(R.tmpdir(),`dm-subagents-${n$()}`),d$=I.join(S,"async-subagent-results"),p$=I.join(S,"async-subagent-runs"),u$=I.join(S,"chain-runs"),Nj=I.join(S,"artifacts");import{randomUUID as r$}from"node:crypto";import*as K$ from"node:fs";function O$($){if($.detached)return"detached";if($.interrupted||$.state==="paused")return"paused";if(typeof $.success==="boolean")return $.success?"completed":"failed";if($.state==="complete")return"completed";if($.state==="failed")return"failed";if(typeof $.exitCode==="number")return $.exitCode===0?"completed":"failed";return"failed"}function p($){let J={completed:0,failed:0,paused:0,detached:0};for(let j of $)J[j.status]+=1;return J}function q$($){let J=[$.completed?`${$.completed} completed`:void 0,$.failed?`${$.failed} failed`:void 0,$.paused?`${$.paused} paused`:void 0,$.detached?`${$.detached} detached`:void 0].filter((j)=>Boolean(j));return J.length?J.join(", "):"0 results"}function l$($){let J=p($);if(J.failed>0)return"failed";if(J.paused>0)return"paused";if(J.completed>0)return"completed";if(J.detached>0)return"detached";return"failed"}function d($,J=0){return{id:$.id,parentRunId:$.parentRunId,...$.parentStepIndex!==void 0?{parentStepIndex:$.parentStepIndex}:{},...$.parentAgent?{parentAgent:$.parentAgent}:{},depth:$.depth,path:$.path.slice(0,4).map((j)=>({runId:j.runId,...j.stepIndex!==void 0?{stepIndex:j.stepIndex}:{},...j.agent?{agent:j.agent}:{}})),...$.asyncDir?{asyncDir:$.asyncDir}:{},...$.sessionId?{sessionId:$.sessionId}:{},...$.sessionFile?{sessionFile:$.sessionFile}:{},...$.intercomTarget?{intercomTarget:$.intercomTarget}:{},...$.ownerIntercomTarget?{ownerIntercomTarget:$.ownerIntercomTarget}:{},...$.leafIntercomTarget?{leafIntercomTarget:$.leafIntercomTarget}:{},...$.ownerState?{ownerState:$.ownerState}:{},...$.mode?{mode:$.mode}:{},state:$.state,...$.agent?{agent:$.agent}:{},...$.agents?.length?{agents:$.agents.slice(0,12)}:{},...$.currentStep!==void 0?{currentStep:$.currentStep}:{},...$.chainStepCount!==void 0?{chainStepCount:$.chainStepCount}:{},...$.parallelGroups?.length?{parallelGroups:$.parallelGroups.slice(0,8)}:{},...$.activityState?{activityState:$.activityState}:{},...$.lastActivityAt!==void 0?{lastActivityAt:$.lastActivityAt}:{},...$.currentTool?{currentTool:$.currentTool}:{},...$.currentToolStartedAt!==void 0?{currentToolStartedAt:$.currentToolStartedAt}:{},...$.currentPath?{currentPath:$.currentPath}:{},...$.turnCount!==void 0?{turnCount:$.turnCount}:{},...$.toolCount!==void 0?{toolCount:$.toolCount}:{},...$.totalTokens?{totalTokens:$.totalTokens}:{},...$.startedAt!==void 0?{startedAt:$.startedAt}:{},...$.endedAt!==void 0?{endedAt:$.endedAt}:{},...$.lastUpdate!==void 0?{lastUpdate:$.lastUpdate}:{},...$.error?{error:$.error}:{},...$.steps?.length?{steps:$.steps.slice(0,12).map((j)=>({agent:j.agent,status:j.status,...j.sessionFile?{sessionFile:j.sessionFile}:{},...j.activityState?{activityState:j.activityState}:{},...j.lastActivityAt!==void 0?{lastActivityAt:j.lastActivityAt}:{},...j.currentTool?{currentTool:j.currentTool}:{},...j.currentToolStartedAt!==void 0?{currentToolStartedAt:j.currentToolStartedAt}:{},...j.currentPath?{currentPath:j.currentPath}:{},...j.turnCount!==void 0?{turnCount:j.turnCount}:{},...j.toolCount!==void 0?{toolCount:j.toolCount}:{},...j.startedAt!==void 0?{startedAt:j.startedAt}:{},...j.endedAt!==void 0?{endedAt:j.endedAt}:{},...j.error?{error:j.error}:{},...J<2&&j.children?.length?{children:j.children.slice(0,8).map((Z)=>d(Z,J+1))}:{}}))}:{},...J<2&&$.children?.length?{children:$.children.slice(0,8).map((j)=>d(j,J+1))}:{}}}function E($){if(!$?.length)return;return $.slice(0,16).map((J)=>d(J))}function H$($,J,j){let Z=E(j);if(!Z?.length)return J.map((Q)=>({...Q,children:E(Q.children)}));return J.map((Q,X)=>{let W=Q.index??X,Y=new Set(Q.children?.map((G)=>G.id)??[]),O=Z.filter((G)=>G.parentRunId===$&&G.parentStepIndex===W&&!Y.has(G.id)),L=J.length===1?Z.filter((G)=>G.parentRunId===$&&G.parentStepIndex===void 0&&!Y.has(G.id)):[],U=E([...Q.children??[],...O,...L]);return U?.length?{...Q,children:U}:{...Q,children:void 0}})}function i$($){if(!$?.length)return[];let J=["Nested subagents:"],j=10,Z=(Q,X)=>{for(let W of Q??[]){if(j<=0){J.push(`${X}↳ +more nested runs; inspect status for full tree`);return}j--;let Y=W.agent??W.agents?.join("+")??W.id;if(J.push(`${X}↳ ${Y} — ${W.state} [${W.id}]`),W.sessionFile)J.push(`${X} Session: ${W.sessionFile}`);Z(W.children,`${X} `);for(let O of W.steps??[])Z(O.children,`${X} `)}};return Z($,""),J}function s$($){if($.source!=="async"||!$.asyncId)return;let J=$.children.filter((j)=>typeof j.sessionPath==="string"&&K$.existsSync(j.sessionPath));if($.children.length===1&&J.length===1)return`Revive: subagent({ action: "resume", id: "${$.asyncId}", message: "..." })`;if(J.length>0){let j=J[0]?.index??$.children.indexOf(J[0]);return`Revive child: subagent({ action: "resume", id: "${$.asyncId}", index: ${j}, message: "..." })`}return"Resume: unavailable; no child session file was persisted."}function a$($){let J=p($.children),j=["subagent results","",`Run: ${$.runId}`,`Mode: ${$.mode}`,`Status: ${$.status}`,`Children: ${q$(J)}`];if($.mode==="chain"&&typeof $.chainSteps==="number")j.push(`Chain steps: ${$.chainSteps}`);if($.asyncId)j.push(`Async id: ${$.asyncId}`);if($.asyncDir)j.push(`Async dir: ${$.asyncDir}`);let Z=s$($);if(Z)j.push(Z);if($.children.some((Q)=>Q.intercomTarget))j.push(""),j.push($.source==="async"?"Previous intercom targets below identify child sessions used while they were running. Inspect artifacts or session logs if resume is unavailable.":"Intercom targets below identify child sessions used while they were running; completed child sessions may no longer be reachable. Inspect artifacts or session logs for follow-up.");for(let Q=0;Q<$.children.length;Q++){let X=$.children[Q];if(j.push(""),j.push(`${Q+1}. ${X.agent} — ${X.status}`),X.intercomTarget)j.push(`${$.source==="async"?"Previous intercom target":"Run intercom target"}: ${X.intercomTarget}`);if(X.artifactPath)j.push(`Output artifact: ${X.artifactPath}`);if(X.sessionPath)j.push(`Session: ${X.sessionPath}`);j.push(...i$(X.children)),j.push("Summary:"),j.push(X.summary)}return j.join(`
2
- `)}function G$($){let J=$.children.map((W)=>({...W,summary:W.summary.trim()||"(no output)",children:E(W.children)})),j=l$(J),Z=q$(p(J)),Q=J[0],X={to:$.to,runId:$.runId,mode:$.mode,status:j,summary:Z,source:$.source,children:J,...$.asyncId?{asyncId:$.asyncId}:{},...$.asyncDir?{asyncDir:$.asyncDir}:{},...typeof $.chainSteps==="number"?{chainSteps:$.chainSteps}:{},...Q?.agent?{agent:Q.agent}:{},...Q?.index!==void 0?{index:Q.index}:{},...Q?.artifactPath?{artifactPath:Q.artifactPath}:{},...Q?.sessionPath?{sessionPath:Q.sessionPath}:{},message:""};return X.message=a$(X),X}async function M$($,J,j=500){return t$($,J.to,J.message,j,J)}async function t$($,J,j,Z=500,Q={}){if(typeof $.on!=="function"||typeof $.emit!=="function")return!1;let X=typeof Q.requestId==="string"?Q.requestId:r$();return new Promise((W)=>{let Y=!1,O,L,U=(G)=>{if(Y)return;if(Y=!0,L)clearTimeout(L);O?.(),W(G)};O=$.on(f$,(G)=>{if(!G||typeof G!=="object")return;let b=G;if(b.requestId!==X)return;U(b.delivered===!0)}),L=setTimeout(()=>U(!1),Z);try{$.emit(Y$,{...Q,to:J,message:j,requestId:X})}catch{U(!1)}})}import*as F from"node:fs";import*as M from"node:path";import*as L$ from"node:path";var e$=128,$j=4;function u($){return typeof $==="string"&&$.length>0&&$.length<=e$&&!L$.isAbsolute($)&&!$.includes("/")&&!$.includes("\\")&&!$.includes("..")}function U$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function V$($,J){return typeof $==="string"&&$.length>0?$.slice(0,J):void 0}function F$($){if(!Array.isArray($))return[];return $.map((J)=>{if(!J||typeof J!=="object")return;let j=J;if(!u(j.runId))return;return{runId:j.runId,...U$(j.stepIndex)!==void 0?{stepIndex:U$(j.stepIndex)}:{},...V$(j.agent,128)?{agent:V$(j.agent,128)}:{}}}).filter((J)=>Boolean(J)).slice(0,$j)}import*as z from"node:path";import{fileURLToPath as T$}from"node:url";import*as A from"node:os";import*as T from"node:path";var W0=T.join(A.homedir(),".config","mcp","mcp.json"),Y0={cursor:[T.join(A.homedir(),".cursor","mcp.json")],"claude-code":[T.join(A.homedir(),".claude","mcp.json"),T.join(A.homedir(),".claude.json"),T.join(A.homedir(),".claude","claude_desktop_config.json")],"claude-desktop":[T.join(A.homedir(),"Library","Application Support","Claude","claude_desktop_config.json")],codex:[T.join(A.homedir(),".codex","config.json")],windsurf:[T.join(A.homedir(),".windsurf","mcp.json")],vscode:[".vscode/mcp.json"]};import{Compile as O0}from"typebox/compile";function z$($,J){let j=T$($),Z=z.extname(j),Q=[".js",".mjs",".cjs",".ts",".mts",".cts"].includes(Z)?Z:".ts";return z.join(z.dirname(j),`${J}${Q}`)}function A$($){return z.basename(T$($)).startsWith("dm-args.")}function Qj($=import.meta.url){let J=A$($)?"subagent-prompt-runtime":z.join("..","runs","shared","subagent-prompt-runtime");return z$($,J)}function Xj($=import.meta.url){let J=A$($)?z.join("..","..","extension","fanout-child"):"fanout-child";return z$($,J)}var E0=Qj(),y0=Xj();import*as Bj from"node:fs";import*as y from"node:path";var Wj=[10,25,50,100,200,500,1000,2000,4000],Yj=new Set(["EACCES","EBUSY","EPERM"]),_$=typeof SharedArrayBuffer<"u"?new SharedArrayBuffer(4):void 0,C$=_$?new Int32Array(_$):void 0;function fj($){if($<=0)return;if(C$)try{Atomics.wait(C$,0,0,$);return}catch{}let J=Date.now()+$;while(Date.now()<J);}function Kj($){let J=$?.code;return typeof J==="string"&&Yj.has(J)}function Oj($,J,j,Z,Q){for(let X=0;;X++)try{$.renameSync(J,j);return}catch(W){let Y=Z[X];if(Y===void 0||!Kj(W))throw W;Q(Y)}}function qj($={}){let J=$.fs??Bj,j=$.now??Date.now,Z=$.pid??process.pid,Q=$.random??Math.random,W=$.retryRenameErrors??process.platform==="win32"?$.retryDelaysMs??Wj:[],Y=$.wait??fj;return(O,L)=>{J.mkdirSync(y.dirname(O),{recursive:!0});let U=y.join(y.dirname(O),`.${y.basename(O)}.${Z}.${j()}.${Q().toString(36).slice(2)}.tmp`);try{J.writeFileSync(U,JSON.stringify(L,null,2),"utf-8"),Oj(J,U,O,W,Y)}finally{J.rmSync(U,{force:!0})}}}var S$=qj();var k=M.join(S,"nested-subagent-events"),Hj="route.json",Gj="registry.json",R$=65536,E$=12,g=16,r=3;function v($){return u($)}function Mj($,J){if(!v(J))throw Error(`${$} must be a non-empty safe id token.`)}function l($,J){Mj($,J)}function i($,J){let j=M.resolve($),Z=M.resolve(J);return Z===j||Z.startsWith(`${j}${M.sep}`)}function I$($){return M.dirname(M.resolve($.eventSink))}function s($){if(l("rootRunId",$.rootRunId),l("capabilityToken",$.capabilityToken),!i(k,$.eventSink))throw Error("Nested event sink is outside the subagent nested event root.");if(!i(k,$.controlInbox))throw Error("Nested control inbox is outside the subagent nested event root.");if(I$($)!==M.dirname(M.resolve($.controlInbox)))throw Error("Nested event sink and control inbox must share one route root.")}function B($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function K($,J=512){return typeof $==="string"&&$.length>0?$.slice(0,J):void 0}function Uj($){if(!$||typeof $!=="object")return;let J=$,j=B(J.input),Z=B(J.output),Q=B(J.total);return j!==void 0&&Z!==void 0&&Q!==void 0?{input:j,output:Z,total:Q}:void 0}function Vj($){if(!$||typeof $!=="object")return;let J=$,j=B(J.inputTokens),Z=B(J.outputTokens),Q=B(J.costUsd);return j!==void 0&&Z!==void 0&&Q!==void 0?{inputTokens:j,outputTokens:Z,costUsd:Q}:void 0}function m($){if(!$||typeof $!=="object")return;let J=$,j=B(J.maxTurns),Z=B(J.graceTurns),Q=B(J.turnCount),X=J.outcome==="within-budget"||J.outcome==="wrap-up-requested"||J.outcome==="exceeded"?J.outcome:void 0;if(j===void 0||Z===void 0||Q===void 0||!X)return;return{maxTurns:j,graceTurns:Z,turnCount:Q,outcome:X,...B(J.wrapUpRequestedAtTurn)!==void 0?{wrapUpRequestedAtTurn:B(J.wrapUpRequestedAtTurn)}:{},...B(J.exceededAtTurn)!==void 0?{exceededAtTurn:B(J.exceededAtTurn)}:{}}}function Lj($,J){return $==="queued"||$==="running"||$==="complete"||$==="failed"||$==="paused"?$:J}function Fj($,J){if(!$||typeof $!=="object")return;let j=$,Z=K(j.agent,128);if(!Z)return;let Q=j.status==="pending"||j.status==="running"||j.status==="complete"||j.status==="completed"||j.status==="failed"||j.status==="paused"?j.status:"pending";return{agent:Z,status:Q,...K(j.sessionFile,2048)?{sessionFile:K(j.sessionFile,2048)}:{},...j.activityState==="active_long_running"||j.activityState==="needs_attention"?{activityState:j.activityState}:{},...B(j.lastActivityAt)!==void 0?{lastActivityAt:B(j.lastActivityAt)}:{},...K(j.currentTool,128)?{currentTool:K(j.currentTool,128)}:{},...B(j.currentToolStartedAt)!==void 0?{currentToolStartedAt:B(j.currentToolStartedAt)}:{},...K(j.currentPath,2048)?{currentPath:K(j.currentPath,2048)}:{},...B(j.turnCount)!==void 0?{turnCount:B(j.turnCount)}:{},...B(j.toolCount)!==void 0?{toolCount:B(j.toolCount)}:{},...B(j.startedAt)!==void 0?{startedAt:B(j.startedAt)}:{},...B(j.endedAt)!==void 0?{endedAt:B(j.endedAt)}:{},...K(j.error,1024)?{error:K(j.error,1024)}:{},...j.timedOut===!0?{timedOut:!0}:{},...m(j.turnBudget)?{turnBudget:m(j.turnBudget)}:{},...j.turnBudgetExceeded===!0?{turnBudgetExceeded:!0}:{},...j.wrapUpRequested===!0?{wrapUpRequested:!0}:{},...J<r&&Array.isArray(j.children)?{children:j.children.map((X)=>D(X,J+1)).filter((X)=>Boolean(X)).slice(0,g)}:{}}}function D($,J=0){if(!$||typeof $!=="object")return;let j=$;if(!v(j.id)||!v(j.parentRunId))return;let Z=F$(j.path),Q=Array.isArray(j.steps)?j.steps.map((Y)=>Fj(Y,J+1)).filter((Y)=>Boolean(Y)).slice(0,E$):void 0,X=Uj(j.totalTokens),W=Vj(j.totalCost);return{id:j.id,parentRunId:j.parentRunId,...B(j.parentStepIndex)!==void 0?{parentStepIndex:B(j.parentStepIndex)}:{},...K(j.parentAgent,128)?{parentAgent:K(j.parentAgent,128)}:{},depth:Math.min(Math.max(0,B(j.depth)??0),r),path:Z,state:Lj(j.state,"running"),...K(j.asyncDir,2048)?{asyncDir:K(j.asyncDir,2048)}:{},...B(j.pid)!==void 0&&B(j.pid)>0&&Number.isInteger(B(j.pid))?{pid:B(j.pid)}:{},...K(j.sessionId,256)?{sessionId:K(j.sessionId,256)}:{},...K(j.sessionFile,2048)?{sessionFile:K(j.sessionFile,2048)}:{},...K(j.intercomTarget,256)?{intercomTarget:K(j.intercomTarget,256)}:{},...K(j.ownerIntercomTarget,256)?{ownerIntercomTarget:K(j.ownerIntercomTarget,256)}:{},...K(j.leafIntercomTarget,256)?{leafIntercomTarget:K(j.leafIntercomTarget,256)}:{},...j.ownerState==="live"||j.ownerState==="gone"||j.ownerState==="unknown"?{ownerState:j.ownerState}:{},...K(j.controlInbox,2048)?{controlInbox:K(j.controlInbox,2048)}:{},...K(j.capabilityToken,128)?{capabilityToken:K(j.capabilityToken,128)}:{},...j.mode==="single"||j.mode==="parallel"||j.mode==="chain"?{mode:j.mode}:{},...K(j.agent,128)?{agent:K(j.agent,128)}:{},...Array.isArray(j.agents)?{agents:j.agents.map((Y)=>K(Y,128)).filter((Y)=>Boolean(Y)).slice(0,E$)}:{},...B(j.currentStep)!==void 0?{currentStep:B(j.currentStep)}:{},...B(j.chainStepCount)!==void 0?{chainStepCount:B(j.chainStepCount)}:{},...j.activityState==="active_long_running"||j.activityState==="needs_attention"?{activityState:j.activityState}:{},...B(j.lastActivityAt)!==void 0?{lastActivityAt:B(j.lastActivityAt)}:{},...K(j.currentTool,128)?{currentTool:K(j.currentTool,128)}:{},...B(j.currentToolStartedAt)!==void 0?{currentToolStartedAt:B(j.currentToolStartedAt)}:{},...K(j.currentPath,2048)?{currentPath:K(j.currentPath,2048)}:{},...B(j.turnCount)!==void 0?{turnCount:B(j.turnCount)}:{},...B(j.toolCount)!==void 0?{toolCount:B(j.toolCount)}:{},...X?{totalTokens:X}:{},...W?{totalCost:W}:{},...B(j.startedAt)!==void 0?{startedAt:B(j.startedAt)}:{},...B(j.endedAt)!==void 0?{endedAt:B(j.endedAt)}:{},...B(j.lastUpdate)!==void 0?{lastUpdate:B(j.lastUpdate)}:{},...B(j.timeoutMs)!==void 0?{timeoutMs:B(j.timeoutMs)}:{},...B(j.deadlineAt)!==void 0?{deadlineAt:B(j.deadlineAt)}:{},...j.timedOut===!0?{timedOut:!0}:{},...m(j.turnBudget)?{turnBudget:m(j.turnBudget)}:{},...j.turnBudgetExceeded===!0?{turnBudgetExceeded:!0}:{},...j.wrapUpRequested===!0?{wrapUpRequested:!0}:{},...K(j.error,1024)?{error:K(j.error,1024)}:{},...Q&&Q.length>0?{steps:Q}:{},...J<r&&Array.isArray(j.children)?{children:j.children.map((Y)=>D(Y,J+1)).filter((Y)=>Boolean(Y)).slice(0,g)}:{}}}function y$($,J){if(Buffer.byteLength($,"utf-8")>R$)return;let j;try{j=JSON.parse($)}catch{return}if(!j||typeof j!=="object")return;let Z=j;if(Z.type!=="subagent.nested.started"&&Z.type!=="subagent.nested.updated"&&Z.type!=="subagent.nested.completed")return;if(Z.rootRunId!==J.rootRunId||Z.capabilityToken!==J.capabilityToken)return;if(!v(Z.parentRunId))return;let Q=B(Z.ts);if(Q===void 0)return;let X=D(Z.child);if(!X||X.id===J.rootRunId)return;let W={...X,controlInbox:J.controlInbox,capabilityToken:J.capabilityToken,ownerState:X.ownerState??"unknown"};return{type:Z.type,ts:Q,rootRunId:J.rootRunId,parentRunId:Z.parentRunId,...B(Z.parentStepIndex)!==void 0?{parentStepIndex:B(Z.parentStepIndex)}:{},capabilityToken:J.capabilityToken,child:W}}function Tj($,J){if(!$.includes(`
3
- `)){let j=y$($.trim(),J);return j?[j]:[]}return $.split(`
4
- `).slice(0,$.endsWith(`
5
- `)?void 0:-1).map((j)=>j.trim()?y$(j,J):void 0).filter((j)=>Boolean(j))}function P($){return $==="complete"||$==="failed"||$==="paused"}function b$($,J){let j=J.type==="subagent.nested.completed"&&J.child.state==="running"?"complete":J.child.state,Z={...J.child,state:j,lastUpdate:J.child.lastUpdate??J.ts};if(!$)return Z;let Q=$.lastUpdate??0,X=Z.lastUpdate??J.ts;if(X<Q)return $;if(P($.state)&&!P(Z.state))return $;if(P($.state)&&P(Z.state)&&X===Q)return $;return{...$,...Z,state:Z.state,lastUpdate:Math.max(Q,X)}}function zj($,J){let j=!1,Z=(Y)=>Y.map((O)=>{if(O.id===J.parentRunId){let U=O.children??[],G=U.findIndex((V)=>V.id===J.child.id),b=b$(G>=0?U[G]:void 0,J),q=G>=0?U.map((V,f)=>f===G?b:V):[...U,b];return j=!0,{...O,children:q.slice(0,g),lastUpdate:Math.max(O.lastUpdate??0,J.ts)}}if(!O.children?.length)return O;let L=Z(O.children);return L===O.children?O:{...O,children:L}}),Q=Z($);if(j)return Q;let X=Q.findIndex((Y)=>Y.id===J.child.id),W=b$(X>=0?Q[X]:void 0,J);return X>=0?Q.map((Y,O)=>O===X?W:Y):[...Q,W].slice(0,g)}function Aj($,J){return{...$,updatedAt:Math.max($.updatedAt,J.ts),children:zj($.children,J)}}function D$($){return M.join(I$($),Gj)}function _j($){l("rootRunId",$);let J;try{J=F.readdirSync(k)}catch(j){if(j.code==="ENOENT")return;throw j}for(let j of J){if(!j.startsWith(`${$}-`))continue;let Z=M.join(k,j);try{let Q=JSON.parse(F.readFileSync(M.join(Z,Hj),"utf-8"));if(Q.rootRunId!==$||typeof Q.capabilityToken!=="string")continue;let X={rootRunId:$,eventSink:M.join(Z,"events"),controlInbox:M.join(Z,"controls"),capabilityToken:Q.capabilityToken};return s(X),X}catch{continue}}return}function N$($){let J=_j($);return J?Sj(J):void 0}function Cj($){s($);try{let J=JSON.parse(F.readFileSync(D$($),"utf-8"));return{rootRunId:$.rootRunId,updatedAt:typeof J.updatedAt==="number"?J.updatedAt:0,children:Array.isArray(J.children)?J.children.map((j)=>D(j)).filter((j)=>Boolean(j)):[],processedEvents:Array.isArray(J.processedEvents)?J.processedEvents.filter((j)=>typeof j==="string"):[]}}catch(J){if(J.code!=="ENOENT")throw J;return{rootRunId:$.rootRunId,updatedAt:0,children:[],processedEvents:[]}}}function Sj($){s($);let J=Cj($),j=new Set(J.processedEvents),Z=!1,Q=[];try{Q=F.readdirSync($.eventSink).filter((X)=>X.endsWith(".json")||X.endsWith(".jsonl")).sort()}catch(X){if(X.code!=="ENOENT")throw X}for(let X of Q){if(j.has(X))continue;let W=M.join($.eventSink,X);if(!i($.eventSink,W))continue;let Y;try{let O=F.statSync(W);if(!O.isFile()||O.size>R$)continue;Y=F.readFileSync(W,"utf-8")}catch{continue}for(let O of Tj(Y,$))J=Aj(J,O),Z=!0;j.add(X),Z=!0}if(Z)J={...J,processedEvents:[...j].slice(-1000)},S$(D$($),J);return J}var yj=3000,bj=3000;function x$($,J,j){if($===void 0)return;if(!Array.isArray($)){console.error(`Ignoring invalid nested children in subagent result file '${J}' at ${j}: expected an array.`);return}let Z=$.map((Q)=>D(Q)).filter((Q)=>Boolean(Q));if(Z.length!==$.length)console.error(`Ignoring ${$.length-Z.length} invalid nested child record(s) in subagent result file '${J}' at ${j}.`);return Z.length?Z:void 0}function t($){return typeof $==="object"&&$!==null&&"code"in $?$.code:void 0}function w$($){return t($)==="ENOENT"}function a($){let J=t($);return J==="EMFILE"||J==="ENOSPC"}function Rj($,J){try{return $.realpathSync.native(J)}catch{return J}}function l0($,J,j,Z,Q={}){let X=Q.fs??Ej,W=Q.timers??{setTimeout,clearTimeout,setInterval,clearInterval},Y=async(q)=>{let V=P$.join(j,q);if(!X.existsSync(V))return;try{let f=JSON.parse(X.readFileSync(V,"utf-8"));if(typeof f.sessionId!=="string"||f.sessionId!==J.currentSessionId)return;let _=f.runId??f.id??q.replace(/\.json$/i,""),k$=f.nestedChildren!==void 0,N=E(x$(f.nestedChildren,V,"nestedChildren"));if(!N?.length&&!k$)try{N=E(N$(_)?.children)}catch(H){console.error(`Failed to enrich subagent result file '${V}' with nested registry children; will retry later:`,H);return}let g$=Date.now(),v$=Q$(f,`result:${q}`);if(X$(J.completionSeen,v$,g$,Z)){X.unlinkSync(V);return}let e=Array.isArray(f.results)&&f.results.length>0,c=e?f.results:[{agent:f.agent,output:f.summary,success:f.success}],$$=H$(_,c.map((H={},C)=>{let x=H.output??f.summary,J$=typeof x==="string"&&x.trim().length>0,m$=J$?x:"(no output)",c$=H.success===!1&&H.error?`${H.error}${J$?`
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { buildCompletionKey, markSeenWithTtl } from "./completion-dedupe.js";
4
+ import { createFileCoalescer } from "../../shared/file-coalescer.js";
5
+ import {
6
+ SUBAGENT_ASYNC_COMPLETE_EVENT
7
+ } from "../../shared/types.js";
8
+ import {
9
+ attachNestedChildrenToResultChildren,
10
+ buildSubagentResultIntercomPayload,
11
+ compactNestedResultChildren,
12
+ deliverSubagentResultIntercomEvent,
13
+ resolveSubagentResultStatus
14
+ } from "../../intercom/result-intercom.js";
15
+ import { projectNestedRegistryForRoot, sanitizeSummary } from "../shared/nested-events.js";
16
+ const WATCHER_RESTART_DELAY_MS = 3000;
17
+ const POLL_INTERVAL_MS = 3000;
18
+ function sanitizeNestedResultChildren(value, resultPath, label) {
19
+ if (value === undefined)
20
+ return;
21
+ if (!Array.isArray(value)) {
22
+ console.error(`Ignoring invalid nested children in subagent result file '${resultPath}' at ${label}: expected an array.`);
23
+ return;
24
+ }
25
+ const children = value.map((child) => sanitizeSummary(child)).filter((child) => Boolean(child));
26
+ if (children.length !== value.length) {
27
+ console.error(`Ignoring ${value.length - children.length} invalid nested child record(s) in subagent result file '${resultPath}' at ${label}.`);
28
+ }
29
+ return children.length ? children : undefined;
30
+ }
31
+ function getErrorCode(error) {
32
+ return typeof error === "object" && error !== null && "code" in error ? error.code : undefined;
33
+ }
34
+ function isNotFoundError(error) {
35
+ return getErrorCode(error) === "ENOENT";
36
+ }
37
+ function shouldFallBackToPolling(error) {
38
+ const code = getErrorCode(error);
39
+ return code === "EMFILE" || code === "ENOSPC";
40
+ }
41
+ function resolveNativeWatchDir(fsApi, resultsDir) {
42
+ try {
43
+ return fsApi.realpathSync.native(resultsDir);
44
+ } catch {
45
+ return resultsDir;
46
+ }
47
+ }
48
+ export function createResultWatcher(pi, state, resultsDir, completionTtlMs, deps = {}) {
49
+ const fsApi = deps.fs ?? fs;
50
+ const timers = deps.timers ?? { setTimeout, clearTimeout, setInterval, clearInterval };
51
+ const handleResult = async (file) => {
52
+ const resultPath = path.join(resultsDir, file);
53
+ if (!fsApi.existsSync(resultPath))
54
+ return;
55
+ try {
56
+ const data = JSON.parse(fsApi.readFileSync(resultPath, "utf-8"));
57
+ if (typeof data.sessionId !== "string" || data.sessionId !== state.currentSessionId)
58
+ return;
59
+ const runId = data.runId ?? data.id ?? file.replace(/\.json$/i, "");
60
+ const hasExplicitNestedChildren = data.nestedChildren !== undefined;
61
+ let nestedChildren = compactNestedResultChildren(sanitizeNestedResultChildren(data.nestedChildren, resultPath, "nestedChildren"));
62
+ if (!nestedChildren?.length && !hasExplicitNestedChildren) {
63
+ try {
64
+ nestedChildren = compactNestedResultChildren(projectNestedRegistryForRoot(runId)?.children);
65
+ } catch (error) {
66
+ console.error(`Failed to enrich subagent result file '${resultPath}' with nested registry children; will retry later:`, error);
67
+ return;
68
+ }
69
+ }
70
+ const now = Date.now();
71
+ const completionKey = buildCompletionKey(data, `result:${file}`);
72
+ if (markSeenWithTtl(state.completionSeen, completionKey, now, completionTtlMs)) {
73
+ fsApi.unlinkSync(resultPath);
74
+ return;
75
+ }
76
+ const hasResultChildren = Array.isArray(data.results) && data.results.length > 0;
77
+ const resultChildren = hasResultChildren ? data.results : [{
78
+ agent: data.agent,
79
+ output: data.summary,
80
+ success: data.success
81
+ }];
82
+ const normalizedChildren = attachNestedChildrenToResultChildren(runId, resultChildren.map((result = {}, index) => {
83
+ const baseOutput = result.output ?? data.summary;
84
+ const hasRealOutput = typeof baseOutput === "string" && baseOutput.trim().length > 0;
85
+ const output = hasRealOutput ? baseOutput : "(no output)";
86
+ const summary = result.success === false && result.error ? `${result.error}${hasRealOutput ? `
6
87
 
7
88
  Output:
8
- ${x}`:""}`:m$,h=H.sessionFile??(c.length===1?f.sessionFile:void 0),Z$=x$(H.children,V,`results[${C}].children`);return{agent:H.agent??f.agent??`step-${C+1}`,status:O$({success:H.success,state:f.state==="paused"||typeof H.success!=="boolean"?f.state:void 0}),summary:c$,index:C,artifactPath:H.artifactPaths?.outputPath,...typeof h==="string"&&X.existsSync(h)?{sessionPath:h}:{},...H.intercomTarget?{intercomTarget:H.intercomTarget}:{},...Z$?{children:Z$}:{}}}),N),j$=f.intercomTarget?.trim();if(j$){let H=f.mode==="single"||f.mode==="parallel"||f.mode==="chain"?f.mode:c.length>1?"chain":"single",C=G$({to:j$,runId:_,mode:H,source:"async",children:$$,asyncId:f.id,asyncDir:f.asyncDir});if(!await M$($.events,C))console.error(`Subagent async grouped result intercom delivery was not acknowledged for '${V}'.`)}$.events.emit(W$,{...f,runId:_,...N?.length?{nestedChildren:N}:{},...Array.isArray(f.results)?{results:e?$$.map((H,C)=>({...f.results[C],agent:H.agent,status:H.status,summary:H.summary,index:H.index,artifactPath:H.artifactPath,sessionPath:H.sessionPath,children:H.children})):[]}:{}}),X.unlinkSync(V)}catch(f){if(w$(f))return;console.error(`Failed to process subagent result file '${V}':`,f)}};J.resultFileCoalescer=B$((q)=>{Y(q)},50);let O=()=>{try{X.readdirSync(j).filter((q)=>q.endsWith(".json")).forEach((q)=>J.resultFileCoalescer.schedule(q,0))}catch(q){if(w$(q))return;console.error(`Failed to scan subagent result directory '${j}':`,q)}},L=(q)=>{if(J.watcher?.close(),J.watcher=null,J.watcherRestartTimer)return;console.error(`Subagent result watcher for '${j}' fell back to polling because native fs.watch is unavailable (${t(q)??"unknown error"}).`),O(),J.watcherRestartTimer=W.setInterval(O,bj),J.watcherRestartTimer.unref?.()},U=()=>{if(J.watcherRestartTimer)return;J.watcherRestartTimer=W.setTimeout(()=>{J.watcherRestartTimer=null;try{X.mkdirSync(j,{recursive:!0}),G()}catch(q){if(a(q)){L(q);return}console.error(`Failed to restart subagent result watcher for '${j}':`,q),U()}},yj),J.watcherRestartTimer.unref?.()},G=()=>{if(J.watcher)return;if(J.watcherRestartTimer)W.clearTimeout(J.watcherRestartTimer),W.clearInterval(J.watcherRestartTimer),J.watcherRestartTimer=null;try{let q=Rj(X,j);J.watcher=X.watch(q,(V,f)=>{if(V!=="rename"||!f)return;let _=f.toString();if(!_.endsWith(".json"))return;J.resultFileCoalescer.schedule(_)}),J.watcher.on("error",(V)=>{if(a(V)){L(V);return}console.error(`Subagent result watcher failed for '${j}':`,V),J.watcher?.close(),J.watcher=null,U()}),J.watcher.unref?.()}catch(q){if(a(q)){L(q);return}console.error(`Failed to start subagent result watcher for '${j}':`,q),J.watcher=null,U()}};return{startResultWatcher:G,primeExistingResults:O,stopResultWatcher:()=>{if(J.watcher?.close(),J.watcher=null,J.watcherRestartTimer)W.clearTimeout(J.watcherRestartTimer),W.clearInterval(J.watcherRestartTimer);J.watcherRestartTimer=null,J.resultFileCoalescer.clear()}}}export{l0 as createResultWatcher};
89
+ ${baseOutput}` : ""}` : output;
90
+ const sessionPath = result.sessionFile ?? (resultChildren.length === 1 ? data.sessionFile : undefined);
91
+ const childNestedChildren = sanitizeNestedResultChildren(result.children, resultPath, `results[${index}].children`);
92
+ return {
93
+ agent: result.agent ?? data.agent ?? `step-${index + 1}`,
94
+ status: resolveSubagentResultStatus({
95
+ success: result.success,
96
+ state: data.state === "paused" || typeof result.success !== "boolean" ? data.state : undefined
97
+ }),
98
+ summary,
99
+ index,
100
+ artifactPath: result.artifactPaths?.outputPath,
101
+ ...typeof sessionPath === "string" && fsApi.existsSync(sessionPath) ? { sessionPath } : {},
102
+ ...result.intercomTarget ? { intercomTarget: result.intercomTarget } : {},
103
+ ...childNestedChildren ? { children: childNestedChildren } : {}
104
+ };
105
+ }), nestedChildren);
106
+ const intercomTarget = data.intercomTarget?.trim();
107
+ if (intercomTarget) {
108
+ const mode = data.mode === "single" || data.mode === "parallel" || data.mode === "chain" ? data.mode : resultChildren.length > 1 ? "chain" : "single";
109
+ const payload = buildSubagentResultIntercomPayload({
110
+ to: intercomTarget,
111
+ runId,
112
+ mode,
113
+ source: "async",
114
+ children: normalizedChildren,
115
+ asyncId: data.id,
116
+ asyncDir: data.asyncDir
117
+ });
118
+ const delivered = await deliverSubagentResultIntercomEvent(pi.events, payload);
119
+ if (!delivered) {
120
+ console.error(`Subagent async grouped result intercom delivery was not acknowledged for '${resultPath}'.`);
121
+ }
122
+ }
123
+ pi.events.emit(SUBAGENT_ASYNC_COMPLETE_EVENT, {
124
+ ...data,
125
+ runId,
126
+ ...nestedChildren?.length ? { nestedChildren } : {},
127
+ ...Array.isArray(data.results) ? {
128
+ results: hasResultChildren ? normalizedChildren.map((child, index) => ({
129
+ ...data.results[index],
130
+ agent: child.agent,
131
+ status: child.status,
132
+ summary: child.summary,
133
+ index: child.index,
134
+ artifactPath: child.artifactPath,
135
+ sessionPath: child.sessionPath,
136
+ children: child.children
137
+ })) : []
138
+ } : {}
139
+ });
140
+ fsApi.unlinkSync(resultPath);
141
+ } catch (error) {
142
+ if (isNotFoundError(error))
143
+ return;
144
+ console.error(`Failed to process subagent result file '${resultPath}':`, error);
145
+ }
146
+ };
147
+ state.resultFileCoalescer = createFileCoalescer((file) => {
148
+ handleResult(file);
149
+ }, 50);
150
+ const primeExistingResults = () => {
151
+ try {
152
+ fsApi.readdirSync(resultsDir).filter((f) => f.endsWith(".json")).forEach((file) => state.resultFileCoalescer.schedule(file, 0));
153
+ } catch (error) {
154
+ if (isNotFoundError(error))
155
+ return;
156
+ console.error(`Failed to scan subagent result directory '${resultsDir}':`, error);
157
+ }
158
+ };
159
+ const startPollingFallback = (reason) => {
160
+ state.watcher?.close();
161
+ state.watcher = null;
162
+ if (state.watcherRestartTimer)
163
+ return;
164
+ console.error(`Subagent result watcher for '${resultsDir}' fell back to polling because native fs.watch is unavailable (${getErrorCode(reason) ?? "unknown error"}).`);
165
+ primeExistingResults();
166
+ state.watcherRestartTimer = timers.setInterval(primeExistingResults, POLL_INTERVAL_MS);
167
+ state.watcherRestartTimer.unref?.();
168
+ };
169
+ const scheduleRestart = () => {
170
+ if (state.watcherRestartTimer)
171
+ return;
172
+ state.watcherRestartTimer = timers.setTimeout(() => {
173
+ state.watcherRestartTimer = null;
174
+ try {
175
+ fsApi.mkdirSync(resultsDir, { recursive: true });
176
+ startResultWatcher();
177
+ } catch (error) {
178
+ if (shouldFallBackToPolling(error)) {
179
+ startPollingFallback(error);
180
+ return;
181
+ }
182
+ console.error(`Failed to restart subagent result watcher for '${resultsDir}':`, error);
183
+ scheduleRestart();
184
+ }
185
+ }, WATCHER_RESTART_DELAY_MS);
186
+ state.watcherRestartTimer.unref?.();
187
+ };
188
+ const startResultWatcher = () => {
189
+ if (state.watcher)
190
+ return;
191
+ if (state.watcherRestartTimer) {
192
+ timers.clearTimeout(state.watcherRestartTimer);
193
+ timers.clearInterval(state.watcherRestartTimer);
194
+ state.watcherRestartTimer = null;
195
+ }
196
+ try {
197
+ const watchDir = resolveNativeWatchDir(fsApi, resultsDir);
198
+ state.watcher = fsApi.watch(watchDir, (ev, file) => {
199
+ if (ev !== "rename" || !file)
200
+ return;
201
+ const fileName = file.toString();
202
+ if (!fileName.endsWith(".json"))
203
+ return;
204
+ state.resultFileCoalescer.schedule(fileName);
205
+ });
206
+ state.watcher.on("error", (error) => {
207
+ if (shouldFallBackToPolling(error)) {
208
+ startPollingFallback(error);
209
+ return;
210
+ }
211
+ console.error(`Subagent result watcher failed for '${resultsDir}':`, error);
212
+ state.watcher?.close();
213
+ state.watcher = null;
214
+ scheduleRestart();
215
+ });
216
+ state.watcher.unref?.();
217
+ } catch (error) {
218
+ if (shouldFallBackToPolling(error)) {
219
+ startPollingFallback(error);
220
+ return;
221
+ }
222
+ console.error(`Failed to start subagent result watcher for '${resultsDir}':`, error);
223
+ state.watcher = null;
224
+ scheduleRestart();
225
+ }
226
+ };
227
+ const stopResultWatcher = () => {
228
+ state.watcher?.close();
229
+ state.watcher = null;
230
+ if (state.watcherRestartTimer) {
231
+ timers.clearTimeout(state.watcherRestartTimer);
232
+ timers.clearInterval(state.watcherRestartTimer);
233
+ }
234
+ state.watcherRestartTimer = null;
235
+ state.resultFileCoalescer.clear();
236
+ };
237
+ return { startResultWatcher, primeExistingResults, stopResultWatcher };
238
+ }
@@ -1,4 +1,76 @@
1
- import*as b from"node:fs";import*as u from"node:path";import*as _ from"node:os";import*as T from"node:path";function S(j){return j.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function z$(j){let J=j?.env??process.env,$=j&&Object.hasOwn(j,"getuid")?j.getuid:process.getuid?.bind(process);if(typeof $==="function")return`uid-${$()}`;for(let H of["USERNAME","USER","LOGNAME"]){let Y=J[H];if(Y)return`user-${S(Y)}`}let Z=j&&Object.hasOwn(j,"userInfo")?j.userInfo:_.userInfo;try{let H=Z?.().username;if(H)return`user-${S(H)}`}catch{}let Q=J.USERPROFILE??J.HOME;if(Q)return`home-${S(Q)}`;let W=j&&Object.hasOwn(j,"homedir")?j.homedir:_.homedir;try{let H=W?.();if(H)return`home-${S(H)}`}catch{}return"shared"}var A=T.join(_.tmpdir(),`dm-subagents-${z$()}`),E=T.join(A,"async-subagent-results"),N=T.join(A,"async-subagent-runs"),M$=T.join(A,"chain-runs"),r$=T.join(A,"artifacts");import*as F from"node:fs";import*as V from"node:path";import*as A$ from"node:fs";import*as C from"node:path";var C$=[10,25,50,100,200,500,1000,2000,4000],F$=new Set(["EACCES","EBUSY","EPERM"]),i=typeof SharedArrayBuffer<"u"?new SharedArrayBuffer(4):void 0,s=i?new Int32Array(i):void 0;function q$(j){if(j<=0)return;if(s)try{Atomics.wait(s,0,0,j);return}catch{}let J=Date.now()+j;while(Date.now()<J);}function _$(j){let J=j?.code;return typeof J==="string"&&F$.has(J)}function T$(j,J,$,Z,Q){for(let W=0;;W++)try{j.renameSync(J,$);return}catch(H){let Y=Z[W];if(Y===void 0||!_$(H))throw H;Q(Y)}}function E$(j={}){let J=j.fs??A$,$=j.now??Date.now,Z=j.pid??process.pid,Q=j.random??Math.random,H=j.retryRenameErrors??process.platform==="win32"?j.retryDelaysMs??C$:[],Y=j.wait??q$;return(B,f)=>{J.mkdirSync(C.dirname(B),{recursive:!0});let G=C.join(C.dirname(B),`.${C.basename(B)}.${Z}.${$()}.${Q().toString(36).slice(2)}.tmp`);try{J.writeFileSync(G,JSON.stringify(f,null,2),"utf-8"),T$(J,G,B,H,Y)}finally{J.rmSync(G,{force:!0})}}}var y=E$();var Tj=process.platform==="win32"?"SIGBREAK":"SIGUSR2";import*as L from"node:fs";import*as O from"node:path";import*as e from"node:path";var b$=128,S$=4;function g(j){return typeof j==="string"&&j.length>0&&j.length<=b$&&!e.isAbsolute(j)&&!j.includes("/")&&!j.includes("\\")&&!j.includes("..")}function a(j){return typeof j==="number"&&Number.isFinite(j)?j:void 0}function t(j,J){return typeof j==="string"&&j.length>0?j.slice(0,J):void 0}function $$(j){if(!Array.isArray(j))return[];return j.map((J)=>{if(!J||typeof J!=="object")return;let $=J;if(!g($.runId))return;return{runId:$.runId,...a($.stepIndex)!==void 0?{stepIndex:a($.stepIndex)}:{},...t($.agent,128)?{agent:t($.agent,128)}:{}}}).filter((J)=>Boolean(J)).slice(0,S$)}import*as z from"node:path";import{fileURLToPath as j$}from"node:url";import*as M from"node:os";import*as U from"node:path";var yj=U.join(M.homedir(),".config","mcp","mcp.json"),Rj={cursor:[U.join(M.homedir(),".cursor","mcp.json")],"claude-code":[U.join(M.homedir(),".claude","mcp.json"),U.join(M.homedir(),".claude.json"),U.join(M.homedir(),".claude","claude_desktop_config.json")],"claude-desktop":[U.join(M.homedir(),"Library","Application Support","Claude","claude_desktop_config.json")],codex:[U.join(M.homedir(),".codex","config.json")],windsurf:[U.join(M.homedir(),".windsurf","mcp.json")],vscode:[".vscode/mcp.json"]};import{Compile as kj}from"typebox/compile";function J$(j,J){let $=j$(j),Z=z.extname($),Q=[".js",".mjs",".cjs",".ts",".mts",".cts"].includes(Z)?Z:".ts";return z.join(z.dirname($),`${J}${Q}`)}function Z$(j){return z.basename(j$(j)).startsWith("dm-args.")}function y$(j=import.meta.url){let J=Z$(j)?"subagent-prompt-runtime":z.join("..","runs","shared","subagent-prompt-runtime");return J$(j,J)}function R$(j=import.meta.url){let J=Z$(j)?z.join("..","..","extension","fanout-child"):"fanout-child";return J$(j,J)}var rj=y$(),ij=R$();var x=O.join(A,"nested-subagent-events"),x$="route.json",D$="registry.json",Y$=65536,Q$=12,D=16,m=3;function k(j){return g(j)}function n(j,J){if(!k(J))throw Error(`${j} must be a non-empty safe id token.`)}function h(j,J){n(j,J)}function c(j,J){let $=O.resolve(j),Z=O.resolve(J);return Z===$||Z.startsWith(`${$}${O.sep}`)}function K$(j){return O.dirname(O.resolve(j.eventSink))}function o(j){if(h("rootRunId",j.rootRunId),h("capabilityToken",j.capabilityToken),!c(x,j.eventSink))throw Error("Nested event sink is outside the subagent nested event root.");if(!c(x,j.controlInbox))throw Error("Nested control inbox is outside the subagent nested event root.");if(K$(j)!==O.dirname(O.resolve(j.controlInbox)))throw Error("Nested event sink and control inbox must share one route root.")}function X(j){return typeof j==="number"&&Number.isFinite(j)?j:void 0}function K(j,J=512){return typeof j==="string"&&j.length>0?j.slice(0,J):void 0}function k$(j){if(!j||typeof j!=="object")return;let J=j,$=X(J.input),Z=X(J.output),Q=X(J.total);return $!==void 0&&Z!==void 0&&Q!==void 0?{input:$,output:Z,total:Q}:void 0}function I$(j){if(!j||typeof j!=="object")return;let J=j,$=X(J.inputTokens),Z=X(J.outputTokens),Q=X(J.costUsd);return $!==void 0&&Z!==void 0&&Q!==void 0?{inputTokens:$,outputTokens:Z,costUsd:Q}:void 0}function I(j){if(!j||typeof j!=="object")return;let J=j,$=X(J.maxTurns),Z=X(J.graceTurns),Q=X(J.turnCount),W=J.outcome==="within-budget"||J.outcome==="wrap-up-requested"||J.outcome==="exceeded"?J.outcome:void 0;if($===void 0||Z===void 0||Q===void 0||!W)return;return{maxTurns:$,graceTurns:Z,turnCount:Q,outcome:W,...X(J.wrapUpRequestedAtTurn)!==void 0?{wrapUpRequestedAtTurn:X(J.wrapUpRequestedAtTurn)}:{},...X(J.exceededAtTurn)!==void 0?{exceededAtTurn:X(J.exceededAtTurn)}:{}}}function w$(j,J){return j==="queued"||j==="running"||j==="complete"||j==="failed"||j==="paused"?j:J}function P$(j,J){if(!j||typeof j!=="object")return;let $=j,Z=K($.agent,128);if(!Z)return;let Q=$.status==="pending"||$.status==="running"||$.status==="complete"||$.status==="completed"||$.status==="failed"||$.status==="paused"?$.status:"pending";return{agent:Z,status:Q,...K($.sessionFile,2048)?{sessionFile:K($.sessionFile,2048)}:{},...$.activityState==="active_long_running"||$.activityState==="needs_attention"?{activityState:$.activityState}:{},...X($.lastActivityAt)!==void 0?{lastActivityAt:X($.lastActivityAt)}:{},...K($.currentTool,128)?{currentTool:K($.currentTool,128)}:{},...X($.currentToolStartedAt)!==void 0?{currentToolStartedAt:X($.currentToolStartedAt)}:{},...K($.currentPath,2048)?{currentPath:K($.currentPath,2048)}:{},...X($.turnCount)!==void 0?{turnCount:X($.turnCount)}:{},...X($.toolCount)!==void 0?{toolCount:X($.toolCount)}:{},...X($.startedAt)!==void 0?{startedAt:X($.startedAt)}:{},...X($.endedAt)!==void 0?{endedAt:X($.endedAt)}:{},...K($.error,1024)?{error:K($.error,1024)}:{},...$.timedOut===!0?{timedOut:!0}:{},...I($.turnBudget)?{turnBudget:I($.turnBudget)}:{},...$.turnBudgetExceeded===!0?{turnBudgetExceeded:!0}:{},...$.wrapUpRequested===!0?{wrapUpRequested:!0}:{},...J<m&&Array.isArray($.children)?{children:$.children.map((W)=>P(W,J+1)).filter((W)=>Boolean(W)).slice(0,D)}:{}}}function P(j,J=0){if(!j||typeof j!=="object")return;let $=j;if(!k($.id)||!k($.parentRunId))return;let Z=$$($.path),Q=Array.isArray($.steps)?$.steps.map((Y)=>P$(Y,J+1)).filter((Y)=>Boolean(Y)).slice(0,Q$):void 0,W=k$($.totalTokens),H=I$($.totalCost);return{id:$.id,parentRunId:$.parentRunId,...X($.parentStepIndex)!==void 0?{parentStepIndex:X($.parentStepIndex)}:{},...K($.parentAgent,128)?{parentAgent:K($.parentAgent,128)}:{},depth:Math.min(Math.max(0,X($.depth)??0),m),path:Z,state:w$($.state,"running"),...K($.asyncDir,2048)?{asyncDir:K($.asyncDir,2048)}:{},...X($.pid)!==void 0&&X($.pid)>0&&Number.isInteger(X($.pid))?{pid:X($.pid)}:{},...K($.sessionId,256)?{sessionId:K($.sessionId,256)}:{},...K($.sessionFile,2048)?{sessionFile:K($.sessionFile,2048)}:{},...K($.intercomTarget,256)?{intercomTarget:K($.intercomTarget,256)}:{},...K($.ownerIntercomTarget,256)?{ownerIntercomTarget:K($.ownerIntercomTarget,256)}:{},...K($.leafIntercomTarget,256)?{leafIntercomTarget:K($.leafIntercomTarget,256)}:{},...$.ownerState==="live"||$.ownerState==="gone"||$.ownerState==="unknown"?{ownerState:$.ownerState}:{},...K($.controlInbox,2048)?{controlInbox:K($.controlInbox,2048)}:{},...K($.capabilityToken,128)?{capabilityToken:K($.capabilityToken,128)}:{},...$.mode==="single"||$.mode==="parallel"||$.mode==="chain"?{mode:$.mode}:{},...K($.agent,128)?{agent:K($.agent,128)}:{},...Array.isArray($.agents)?{agents:$.agents.map((Y)=>K(Y,128)).filter((Y)=>Boolean(Y)).slice(0,Q$)}:{},...X($.currentStep)!==void 0?{currentStep:X($.currentStep)}:{},...X($.chainStepCount)!==void 0?{chainStepCount:X($.chainStepCount)}:{},...$.activityState==="active_long_running"||$.activityState==="needs_attention"?{activityState:$.activityState}:{},...X($.lastActivityAt)!==void 0?{lastActivityAt:X($.lastActivityAt)}:{},...K($.currentTool,128)?{currentTool:K($.currentTool,128)}:{},...X($.currentToolStartedAt)!==void 0?{currentToolStartedAt:X($.currentToolStartedAt)}:{},...K($.currentPath,2048)?{currentPath:K($.currentPath,2048)}:{},...X($.turnCount)!==void 0?{turnCount:X($.turnCount)}:{},...X($.toolCount)!==void 0?{toolCount:X($.toolCount)}:{},...W?{totalTokens:W}:{},...H?{totalCost:H}:{},...X($.startedAt)!==void 0?{startedAt:X($.startedAt)}:{},...X($.endedAt)!==void 0?{endedAt:X($.endedAt)}:{},...X($.lastUpdate)!==void 0?{lastUpdate:X($.lastUpdate)}:{},...X($.timeoutMs)!==void 0?{timeoutMs:X($.timeoutMs)}:{},...X($.deadlineAt)!==void 0?{deadlineAt:X($.deadlineAt)}:{},...$.timedOut===!0?{timedOut:!0}:{},...I($.turnBudget)?{turnBudget:I($.turnBudget)}:{},...$.turnBudgetExceeded===!0?{turnBudgetExceeded:!0}:{},...$.wrapUpRequested===!0?{wrapUpRequested:!0}:{},...K($.error,1024)?{error:K($.error,1024)}:{},...Q&&Q.length>0?{steps:Q}:{},...J<m&&Array.isArray($.children)?{children:$.children.map((Y)=>P(Y,J+1)).filter((Y)=>Boolean(Y)).slice(0,D)}:{}}}function W$(j,J){if(Buffer.byteLength(j,"utf-8")>Y$)return;let $;try{$=JSON.parse(j)}catch{return}if(!$||typeof $!=="object")return;let Z=$;if(Z.type!=="subagent.nested.started"&&Z.type!=="subagent.nested.updated"&&Z.type!=="subagent.nested.completed")return;if(Z.rootRunId!==J.rootRunId||Z.capabilityToken!==J.capabilityToken)return;if(!k(Z.parentRunId))return;let Q=X(Z.ts);if(Q===void 0)return;let W=P(Z.child);if(!W||W.id===J.rootRunId)return;let H={...W,controlInbox:J.controlInbox,capabilityToken:J.capabilityToken,ownerState:W.ownerState??"unknown"};return{type:Z.type,ts:Q,rootRunId:J.rootRunId,parentRunId:Z.parentRunId,...X(Z.parentStepIndex)!==void 0?{parentStepIndex:X(Z.parentStepIndex)}:{},capabilityToken:J.capabilityToken,child:H}}function v$(j,J){if(!j.includes(`
2
- `)){let $=W$(j.trim(),J);return $?[$]:[]}return j.split(`
3
- `).slice(0,j.endsWith(`
4
- `)?void 0:-1).map(($)=>$.trim()?W$($,J):void 0).filter(($)=>Boolean($))}function R(j){return j==="complete"||j==="failed"||j==="paused"}function X$(j,J){let $=J.type==="subagent.nested.completed"&&J.child.state==="running"?"complete":J.child.state,Z={...J.child,state:$,lastUpdate:J.child.lastUpdate??J.ts};if(!j)return Z;let Q=j.lastUpdate??0,W=Z.lastUpdate??J.ts;if(W<Q)return j;if(R(j.state)&&!R(Z.state))return j;if(R(j.state)&&R(Z.state)&&W===Q)return j;return{...j,...Z,state:Z.state,lastUpdate:Math.max(Q,W)}}function g$(j,J){let $=!1,Z=(Y)=>Y.map((B)=>{if(B.id===J.parentRunId){let G=B.children??[],q=G.findIndex((v)=>v.id===J.child.id),l=X$(q>=0?G[q]:void 0,J),L$=q>=0?G.map((v,U$)=>U$===q?l:v):[...G,l];return $=!0,{...B,children:L$.slice(0,D),lastUpdate:Math.max(B.lastUpdate??0,J.ts)}}if(!B.children?.length)return B;let f=Z(B.children);return f===B.children?B:{...B,children:f}}),Q=Z(j);if($)return Q;let W=Q.findIndex((Y)=>Y.id===J.child.id),H=X$(W>=0?Q[W]:void 0,J);return W>=0?Q.map((Y,B)=>B===W?H:Y):[...Q,H].slice(0,D)}function m$(j,J){return{...j,updatedAt:Math.max(j.updatedAt,J.ts),children:g$(j.children,J)}}function H$(j){return O.join(K$(j),D$)}function w(j,J=[]){for(let $ of j??[])J.push($),w($.children,J),w($.steps?.flatMap((Z)=>Z.children??[]),J);return J}function d(j,J,$=[]){if(!J)return w(j,$);for(let Z of j??[]){if(Z.parentRunId===J.parentRunId&&(J.parentStepIndex===void 0||Z.parentStepIndex===J.parentStepIndex)){w([Z],$);continue}d(Z.children,J,$),d(Z.steps?.flatMap((Q)=>Q.children??[]),J,$)}return $}function h$(){let j;try{j=L.readdirSync(x)}catch($){if($.code==="ENOENT")return[];throw $}let J=[];for(let $ of j){let Z=O.join(x,$);try{let Q=JSON.parse(L.readFileSync(O.join(Z,x$),"utf-8"));if(typeof Q.rootRunId!=="string"||typeof Q.capabilityToken!=="string")continue;let W={rootRunId:Q.rootRunId,eventSink:O.join(Z,"events"),controlInbox:O.join(Z,"controls"),capabilityToken:Q.capabilityToken};o(W),J.push(W)}catch{continue}}return J}function p(j,J={}){h("id",j);let $=[];for(let Z of J.scope?.routes??h$())try{let Q=B$(Z);for(let W of d(Q.children,J.scope?.descendantOf))if(J.prefix?W.id.startsWith(j):W.id===j)$.push({rootRunId:Z.rootRunId,route:Z,run:W})}catch{continue}return $}function c$(j){o(j);try{let J=JSON.parse(L.readFileSync(H$(j),"utf-8"));return{rootRunId:j.rootRunId,updatedAt:typeof J.updatedAt==="number"?J.updatedAt:0,children:Array.isArray(J.children)?J.children.map(($)=>P($)).filter(($)=>Boolean($)):[],processedEvents:Array.isArray(J.processedEvents)?J.processedEvents.filter(($)=>typeof $==="string"):[]}}catch(J){if(J.code!=="ENOENT")throw J;return{rootRunId:j.rootRunId,updatedAt:0,children:[],processedEvents:[]}}}function B$(j){o(j);let J=c$(j),$=new Set(J.processedEvents),Z=!1,Q=[];try{Q=L.readdirSync(j.eventSink).filter((W)=>W.endsWith(".json")||W.endsWith(".jsonl")).sort()}catch(W){if(W.code!=="ENOENT")throw W}for(let W of Q){if($.has(W))continue;let H=O.join(j.eventSink,W);if(!c(j.eventSink,H))continue;let Y;try{let B=L.statSync(H);if(!B.isFile()||B.size>Y$)continue;Y=L.readFileSync(H,"utf-8")}catch{continue}for(let B of v$(Y,j))J=m$(J,B),Z=!0;$.add(W),Z=!0}if(Z)J={...J,processedEvents:[...$].slice(-1000)},y(H$(j),J);return J}var b0=process.platform==="win32"?"SIGBREAK":"SIGUSR2";function d$(j,J){if(j===void 0)return;if(j.trim()==="")throw Error(`${J} must not be empty.`);if(V.isAbsolute(j)||/[\\/]/.test(j)||j.includes(".."))throw Error(`${J} must be an async run id or prefix, not a path.`);return j}function O$(j,J,$){let Z=V.resolve(j),Q=V.resolve(J),W=V.relative(Z,Q);if(W===""||!W.startsWith("..")&&!V.isAbsolute(W))return;throw Error(`${$} must be inside ${Z}.`)}function G$(j,J,$=""){if(!F.existsSync(j))return[];return F.readdirSync(j).filter((Z)=>Z.startsWith(J)&&(!$||Z.endsWith($))).map((Z)=>$?Z.slice(0,-$.length):Z).sort()}function n$(j,J){let $=V.join(j,`${J}.json`);return O$(j,$,"Async result file"),F.existsSync($)?$:null}function V$(j,J,$){let Z=d$(j,"id");if(!Z)return[];let Q=V.resolve(J),W=V.resolve($);return[...new Set([...G$(Q,Z),...G$(W,Z,".json")])].sort().map((Y)=>{let B=V.join(Q,Y);return O$(Q,B,"Async run directory"),{id:Y,location:{asyncDir:F.existsSync(B)?B:null,resultPath:n$(W,Y),resolvedId:Y}}})}function o$(j,J,$){let Z=u.join(J,j),Q=u.join($,`${j}.json`);if(!b.existsSync(Z)&&!b.existsSync(Q))return;return{asyncDir:b.existsSync(Z)?Z:null,resultPath:b.existsSync(Q)?Q:null,resolvedId:j}}function p$(j){if(!j)return[];return[...new Set([...j.foregroundControls.keys(),...j.foregroundRuns?.keys()??[]])]}function u$(j){if(!j)return;let J=[],$=new Set,Z=(Q)=>{if(!Q)return;let W=`${Q.rootRunId}:${Q.eventSink}:${Q.controlInbox}`;if($.has(W))return;$.add(W),J.push(Q)};for(let Q of j.foregroundControls.values())Z(Q.nestedRoute);for(let Q of j.asyncJobs.values())Z(Q.nestedRoute);return{routes:J}}function l$(j,J,$){return V$(j,J,$)}function x0(j,J={}){n("id",j);let $=J.asyncDirRoot??N,Z=J.resultsDir??E,Q=J.nested??u$(J.state);if(J.state?.foregroundControls.has(j)||J.state?.foregroundRuns?.has(j))return{kind:"foreground",id:j};let W=o$(j,$,Z);if(W)return{kind:"async",id:j,location:W};let H=p(j,Q?{scope:Q}:{});if(H.length>1)throw Error(`Nested run id '${j}' is ambiguous across authorized registries. Provide the full id after stale registries are cleaned up.`);if(H[0])return{kind:"nested",id:j,match:H[0]};let Y=[];for(let G of p$(J.state).filter((q)=>q.startsWith(j)))Y.push({kind:"foreground",id:G});for(let G of l$(j,$,Z))Y.push({kind:"async",id:G.id,location:G.location});for(let G of p(j,Q?{prefix:!0,scope:Q}:{prefix:!0}))Y.push({kind:"nested",id:G.run.id,match:G});let f=[...new Map(Y.map((G)=>[`${G.kind}:${G.id}`,G])).values()];if(f.length>1)throw Error(`Ambiguous subagent run id prefix '${j}' matched: ${f.map((G)=>`${G.kind}:${G.id}`).join(", ")}. Provide a longer id.`);return f[0]}export{x0 as resolveSubagentRunId};
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { ASYNC_DIR, RESULTS_DIR } from "../../shared/types.js";
4
+ import { findAsyncRunPrefixMatches } from "./async-resume.js";
5
+ import { assertSafeNestedId, findNestedRunMatchesById } from "../shared/nested-events.js";
6
+ function exactAsyncLocation(id, asyncDirRoot, resultsDir) {
7
+ const asyncDir = path.join(asyncDirRoot, id);
8
+ const resultPath = path.join(resultsDir, `${id}.json`);
9
+ if (!fs.existsSync(asyncDir) && !fs.existsSync(resultPath))
10
+ return;
11
+ return {
12
+ asyncDir: fs.existsSync(asyncDir) ? asyncDir : null,
13
+ resultPath: fs.existsSync(resultPath) ? resultPath : null,
14
+ resolvedId: id
15
+ };
16
+ }
17
+ function foregroundIds(state) {
18
+ if (!state)
19
+ return [];
20
+ return [...new Set([...state.foregroundControls.keys(), ...state.foregroundRuns?.keys() ?? []])];
21
+ }
22
+ function nestedScopeFromState(state) {
23
+ if (!state)
24
+ return;
25
+ const routes = [];
26
+ const seen = new Set;
27
+ const add = (route) => {
28
+ if (!route)
29
+ return;
30
+ const key = `${route.rootRunId}:${route.eventSink}:${route.controlInbox}`;
31
+ if (seen.has(key))
32
+ return;
33
+ seen.add(key);
34
+ routes.push(route);
35
+ };
36
+ for (const control of state.foregroundControls.values())
37
+ add(control.nestedRoute);
38
+ for (const job of state.asyncJobs.values())
39
+ add(job.nestedRoute);
40
+ return { routes };
41
+ }
42
+ function asyncPrefixMatches(prefix, asyncDirRoot, resultsDir) {
43
+ return findAsyncRunPrefixMatches(prefix, asyncDirRoot, resultsDir);
44
+ }
45
+ export function resolveSubagentRunId(id, deps = {}) {
46
+ assertSafeNestedId("id", id);
47
+ const asyncDirRoot = deps.asyncDirRoot ?? ASYNC_DIR;
48
+ const resultsDir = deps.resultsDir ?? RESULTS_DIR;
49
+ const nestedScope = deps.nested ?? nestedScopeFromState(deps.state);
50
+ if (deps.state?.foregroundControls.has(id) || deps.state?.foregroundRuns?.has(id))
51
+ return { kind: "foreground", id };
52
+ const exactAsync = exactAsyncLocation(id, asyncDirRoot, resultsDir);
53
+ if (exactAsync)
54
+ return { kind: "async", id, location: exactAsync };
55
+ const exactNested = findNestedRunMatchesById(id, nestedScope ? { scope: nestedScope } : {});
56
+ if (exactNested.length > 1)
57
+ throw new Error(`Nested run id '${id}' is ambiguous across authorized registries. Provide the full id after stale registries are cleaned up.`);
58
+ if (exactNested[0])
59
+ return { kind: "nested", id, match: exactNested[0] };
60
+ const matches = [];
61
+ for (const foregroundId of foregroundIds(deps.state).filter((candidate) => candidate.startsWith(id))) {
62
+ matches.push({ kind: "foreground", id: foregroundId });
63
+ }
64
+ for (const match of asyncPrefixMatches(id, asyncDirRoot, resultsDir)) {
65
+ matches.push({ kind: "async", id: match.id, location: match.location });
66
+ }
67
+ for (const match of findNestedRunMatchesById(id, nestedScope ? { prefix: true, scope: nestedScope } : { prefix: true })) {
68
+ matches.push({ kind: "nested", id: match.run.id, match });
69
+ }
70
+ const unique = new Map(matches.map((match) => [`${match.kind}:${match.id}`, match]));
71
+ const values = [...unique.values()];
72
+ if (values.length > 1) {
73
+ throw new Error(`Ambiguous subagent run id prefix '${id}' matched: ${values.map((match) => `${match.kind}:${match.id}`).join(", ")}. Provide a longer id.`);
74
+ }
75
+ return values[0];
76
+ }