@duckmind/dm-windows-x64 0.60.6 → 0.60.9

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 +1,282 @@
1
- import*as j from"node:os";import*as V from"node:path";function z(J){return J.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function w(J){let Q=J?.env??process.env,U=J&&Object.hasOwn(J,"getuid")?J.getuid:process.getuid?.bind(process);if(typeof U==="function")return`uid-${U()}`;for(let q of["USERNAME","USER","LOGNAME"]){let B=Q[q];if(B)return`user-${z(B)}`}let $=J&&Object.hasOwn(J,"userInfo")?J.userInfo:j.userInfo;try{let q=$?.().username;if(q)return`user-${z(q)}`}catch{}let X=Q.USERPROFILE??Q.HOME;if(X)return`home-${z(X)}`;let Z=J&&Object.hasOwn(J,"homedir")?J.homedir:j.homedir;try{let q=Z?.();if(q)return`home-${z(q)}`}catch{}return"shared"}var A=V.join(j.tmpdir(),`dm-subagents-${w()}`),e=V.join(A,"async-subagent-results"),JJ=V.join(A,"async-subagent-runs"),b=V.join(A,"chain-runs"),UJ=V.join(A,"artifacts");function D(J){let Q=[];for(let U=J.length-1;U>=0;U--){let $=J[U];if($.role!=="assistant")continue;if("errorMessage"in $&&typeof $.errorMessage==="string"&&$.errorMessage.length>0||"stopReason"in $&&$.stopReason==="error")continue;for(let Z=$.content.length-1;Z>=0;Z--){let q=$.content[Z];if(q.type!=="text"||q.text.trim().length===0)continue;if(Q.push(q.text),/```acceptance-report\s*\n[\s\S]*?```/i.test(q.text))return q.text;for(let B of q.text.matchAll(/```(?:json|jsonc|json5)\s*\n([\s\S]*?)```/gi)){let Y=B[1]??"";if(/"criteriaSatisfied"/.test(Y)&&/"(?:changedFiles|testsAddedOrUpdated|commandsRun|validationOutput|residualRisks|noStagedFiles|diffSummary|reviewFindings|manualNotes)"/.test(Y))return q.text}if(/ACCEPTANCE_REPORT\s*:/i.test(q.text))return q.text}}return Q[0]??""}function E(J){return J.finalOutput??D(J.messages??[])}import{Compile as x}from"typebox/compile";function C(J,Q){let U;try{U=x(J)}catch(X){return{status:"invalid",message:`invalid outputSchema: ${X instanceof Error?X.message:String(X)}`}}if(U.Check(Q))return{status:"valid"};return{status:"invalid",message:[...U.Errors(Q)].slice(0,8).map((X)=>{return`${X.instancePath?X.instancePath.replace(/^\//,"").replace(/\//g,"."):"root"}: ${X.message}`}).join("; ")||"schema validation failed"}}class W extends Error{}var y=/^[A-Za-z_][A-Za-z0-9_]*$/,P=/^[A-Za-z_][A-Za-z0-9_]*$/,H=/\{([A-Za-z_][A-Za-z0-9_]*)(?:\.([^{}]+))?\}/g,v=new Set(["task","previous","chain_dir","outputs"]),S=new Set(["expand","parallel","collect","concurrency","failFast","phase","label","acceptance"]),f=new Set([...S,"effectiveAcceptance","sessionFiles","thinkingOverrides"]),k=new Set(["from","item","key","maxItems","onEmpty"]),h=new Set(["output","path"]),I=new Set(["agent","task","phase","label","outputSchema","cwd","output","outputMode","reads","progress","skill","model","toolBudget","acceptance"]),m=new Set([...I,"outputName","structured","inheritProjectContext","inheritSkills","skills","outputPath","maxSubagentDepth","structuredOutput","structuredOutputSchema","tools","extensions","subagentOnlyExtensions","mcpDirectTools","completionGuard","systemPrompt","systemPromptMode","thinking","modelCandidates","sessionFile","effectiveAcceptance","parentSessionId"]),c=new Set(["as","outputSchema"]);function F(J){return y.test(J)}function L(J,Q){if(J==="")return;if(!J.startsWith("/"))throw new W(`${Q} must be a JSON Pointer starting with '/'.`);for(let U of J.slice(1).split("/"))if(/~(?![01])/.test(U))throw new W(`${Q} contains invalid JSON Pointer escape.`)}function g(J){return J.replace(/~1/g,"/").replace(/~0/g,"~")}function M(J,Q,U){if(L(Q,U),Q==="")return J;let $=J;for(let X of Q.slice(1).split("/")){let Z=g(X);if(Array.isArray($)){if(!/^(0|[1-9][0-9]*)$/.test(Z))throw new W(`${U} segment '${Z}' does not address an array index.`);let B=Number(Z);if(B>=$.length)throw new W(`${U} does not exist.`);$=$[B];continue}if(!$||typeof $!=="object")throw new W(`${U} does not exist.`);let q=$;if(!Object.prototype.hasOwnProperty.call(q,Z))throw new W(`${U} does not exist.`);$=q[Z]}return $}function u(J,Q){if(typeof J==="string"||typeof J==="number"||typeof J==="boolean"){let U=String(J);if(!U.trim())throw new W(`${Q} resolved to an empty key.`);if(/[\u0000-\u001F\u007F]/.test(U))throw new W(`${Q} resolved to an unsafe key.`);if(U.length>200)throw new W(`${Q} resolved to a key longer than 200 characters.`);return U}throw new W(`${Q} must resolve to a string, number, or boolean.`)}function d(J){return J.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"item"}function p(J,Q){if(J===void 0)throw new W(`Unresolved item reference '${Q}'.`);if(typeof J==="string")return J;if(typeof J==="number"||typeof J==="boolean"||J===null)return String(J);return JSON.stringify(J)}function n(J,Q,U){if(!Q)return J;let $=`/${Q.split(".").map((X)=>X.replace(/~/g,"~0").replace(/\//g,"~1")).join("/")}`;return M(J,$,U)}function N(J,Q,U){return J.replace(H,($,X,Z)=>{if(X!==Q)return $;if(Z!==void 0&&(!Z.trim()||Z.includes("..")))throw new W(`Invalid item reference '${$}'.`);return p(n(U,Z,$),$)})}function K(J,Q,U){if(!J||typeof J!=="object"||Array.isArray(J))throw new W(`${U} must be an object.`);for(let $ of Object.keys(J))if(!Q.has($))throw new W(`${U} does not support field '${$}'.`)}function o(J,Q,U){for(let $ of J.matchAll(/\{([^{}]*)\}/g)){let X=$[0],Z=$[1];if(Z===Q||Z.startsWith(`${Q}.`)){if(!H.test(X)||Z===`${Q}.`||Z.includes(".."))throw new W(`Invalid item reference '${X}' in ${U}.`);H.lastIndex=0;continue}H.lastIndex=0;let q=Z.match(/^[A-Za-z_][A-Za-z0-9_]*/)?.[0];if(q===Q)throw new W(`Invalid item reference '${X}' in ${U}.`);if(q&&v.has(q))continue;if(q)throw new W(`Unsupported template reference '${X}' in ${U}.`)}if(H.lastIndex=0,J.includes(`{${Q}.}`)||new RegExp(`\\{${Q}(?:\\.|$)[^}]*$`).test(J))throw new W(`Invalid item reference in ${U}.`)}function SJ(J){return!!J&&typeof J==="object"&&!Array.isArray(J)&&(Object.prototype.hasOwnProperty.call(J,"expand")||Object.prototype.hasOwnProperty.call(J,"collect"))}function l(J,Q,U={}){let $=`Dynamic chain step ${Q+1}`;if(K(J,U.allowRunnerFields?f:S,$),!J.expand||!J.expand.from)throw new W(`${$} requires expand.from.`);if(K(J.expand,k,`${$} expand`),K(J.expand.from,h,`${$} expand.from`),!F(J.expand.from.output))throw new W(`${$} has invalid expand.from.output '${J.expand.from.output}'.`);if(L(J.expand.from.path,`${$} expand.from.path`),J.expand.key!==void 0)L(J.expand.key,`${$} expand.key`);let X=J.expand.item??"item";if(!P.test(X))throw new W(`${$} has invalid expand.item '${X}'.`);if(J.expand.maxItems===void 0&&U.maxItems===void 0)throw new W(`${$} requires expand.maxItems or config.chain.dynamicFanout.maxItems.`);if(J.expand.maxItems!==void 0&&(!Number.isInteger(J.expand.maxItems)||J.expand.maxItems<0))throw new W(`${$} expand.maxItems must be an integer >= 0.`);if(U.maxItems!==void 0&&(!Number.isInteger(U.maxItems)||U.maxItems<0))throw new W("config.chain.dynamicFanout.maxItems must be an integer >= 0.");if(!J.parallel||Array.isArray(J.parallel))throw new W(`${$} requires a single parallel template object and cannot mix dynamic expand/collect with static parallel arrays.`);if(K(J.parallel,U.allowRunnerFields?m:I,`${$} parallel`),"expand"in J.parallel)throw new W(`${$} does not support nested dynamic fanout.`);if(!J.parallel.agent)throw new W(`${$} parallel.agent is required.`);if(!J.collect?.as||!F(J.collect.as))throw new W(`${$} requires collect.as with a safe output name.`);K(J.collect,c,`${$} collect`);for(let[Z,q]of[["parallel.task",J.parallel.task],["parallel.label",J.parallel.label]])if(q)o(q,X,`${$} ${Z}`)}function i(J,Q,U,$={}){l(J,U,$);let X=J.expand.from.output,Z=Q[X];if(!Z)throw new W(`Dynamic chain step ${U+1} references unknown output '${X}'.`);if(Z.structured===void 0)throw new W(`Dynamic chain step ${U+1} requires structured output '${X}'.`);let q=M(Z.structured,J.expand.from.path,`Dynamic chain step ${U+1} expand.from.path`);if(!Array.isArray(q))throw new W(`Dynamic chain step ${U+1} expand.from.path must resolve to an array.`);let B=J.expand.maxItems??$.maxItems;if(B===void 0)throw new W(`Dynamic chain step ${U+1} requires an effective maxItems.`);if(q.length>B)throw new W(`Dynamic chain step ${U+1} resolved ${q.length} items, exceeding maxItems ${B}.`);let Y=new Set,G=new Set;return q.map((R,T)=>{let _=J.expand.key===void 0?String(T):u(M(R,J.expand.key,`Dynamic chain step ${U+1} expand.key`),`Dynamic chain step ${U+1} expand.key`);if(Y.has(_))throw new W(`Dynamic chain step ${U+1} produced duplicate item key '${_}'.`);Y.add(_);let O=d(_);if(G.has(O))throw new W(`Dynamic chain step ${U+1} produced colliding item id '${O}'.`);return G.add(O),{index:T,key:_,idKey:O,item:R}})}function IJ(J,Q,U,$={}){let X=i(J,Q,U,$);if(X.length===0){if((J.expand.onEmpty??"skip")==="fail")throw new W(`Dynamic chain step ${U+1} source array is empty.`);return{items:X,parallel:[],collectedOnEmpty:[]}}let Z=J.expand.item??"item",q=X.map((B)=>{let Y=N(J.parallel.task??"{previous}",Z,B.item),G=J.parallel.label?N(J.parallel.label,Z,B.item):void 0;return{...J.parallel,task:Y,...G!==void 0?{label:G}:{}}});return{items:X,parallel:q}}function wJ(J,Q,U){return Q.map(($,X)=>{let Z=U[X],q=Z?"output"in Z&&typeof Z.output==="string"?Z.output:E(Z):"";return{key:$.key,index:$.index,item:$.item,agent:Z?.agent??J.parallel.agent,exitCode:Z?.exitCode??null,text:q,...Z?.structuredOutput!==void 0?{structured:Z.structuredOutput}:{},...Z?.error?{error:Z.error}:{},...Z?.timedOut?{timedOut:!0}:{},...Z?.savedOutputPath?{outputPath:Z.savedOutputPath}:{},...Z?.artifactPaths?{artifactPaths:Z.artifactPaths}:{}}})}function bJ(J,Q){if(!J)return;let U=C(J,Q);if(U.status==="invalid")throw new W(`Collected output validation failed: ${U.message}`)}export{l as validateDynamicStepShape,bJ as validateDynamicCollection,M as resolveJsonPointer,N as resolveItemTemplate,i as resolveDynamicFanoutItems,d as normalizeItemKeyForId,IJ as materializeDynamicParallelStep,F as isSafeOutputName,SJ as hasDynamicFanoutFields,wJ as collectDynamicResults,o as assertNoUnresolvedItemReferences,L as assertJsonPointer,W as DynamicFanoutError};
1
+ import { getSingleResultOutput } from "../../shared/utils.js";
2
+ import { validateStructuredOutputValue } from "./structured-output.js";
3
+
4
+ export class DynamicFanoutError extends Error {
5
+ }
6
+ const SAFE_OUTPUT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
7
+ const ITEM_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
8
+ const ITEM_REF_PATTERN = /\{([A-Za-z_][A-Za-z0-9_]*)(?:\.([^{}]+))?\}/g;
9
+ const RESERVED_TEMPLATE_NAMES = new Set(["task", "previous", "chain_dir", "outputs"]);
10
+ const DYNAMIC_STEP_KEYS = new Set(["expand", "parallel", "collect", "concurrency", "failFast", "phase", "label", "acceptance"]);
11
+ const RUNNER_DYNAMIC_STEP_KEYS = new Set([...DYNAMIC_STEP_KEYS, "effectiveAcceptance", "sessionFiles", "thinkingOverrides"]);
12
+ const DYNAMIC_EXPAND_KEYS = new Set(["from", "item", "key", "maxItems", "onEmpty"]);
13
+ const DYNAMIC_EXPAND_FROM_KEYS = new Set(["output", "path"]);
14
+ const DYNAMIC_PARALLEL_KEYS = new Set(["agent", "task", "phase", "label", "outputSchema", "cwd", "output", "outputMode", "reads", "progress", "skill", "model", "toolBudget", "acceptance"]);
15
+ const RUNNER_DYNAMIC_PARALLEL_KEYS = new Set([
16
+ ...DYNAMIC_PARALLEL_KEYS,
17
+ "outputName",
18
+ "structured",
19
+ "inheritProjectContext",
20
+ "inheritSkills",
21
+ "skills",
22
+ "outputPath",
23
+ "maxSubagentDepth",
24
+ "structuredOutput",
25
+ "structuredOutputSchema",
26
+ "tools",
27
+ "extensions",
28
+ "subagentOnlyExtensions",
29
+ "mcpDirectTools",
30
+ "completionGuard",
31
+ "systemPrompt",
32
+ "systemPromptMode",
33
+ "thinking",
34
+ "modelCandidates",
35
+ "sessionFile",
36
+ "effectiveAcceptance",
37
+ "parentSessionId"
38
+ ]);
39
+ const DYNAMIC_COLLECT_KEYS = new Set(["as", "outputSchema"]);
40
+ export function isSafeOutputName(name) {
41
+ return SAFE_OUTPUT_NAME_PATTERN.test(name);
42
+ }
43
+ export function assertJsonPointer(pointer, label) {
44
+ if (pointer === "")
45
+ return;
46
+ if (!pointer.startsWith("/")) {
47
+ throw new DynamicFanoutError(`${label} must be a JSON Pointer starting with '/'.`);
48
+ }
49
+ for (const segment of pointer.slice(1).split("/")) {
50
+ if (/~(?![01])/.test(segment)) {
51
+ throw new DynamicFanoutError(`${label} contains invalid JSON Pointer escape.`);
52
+ }
53
+ }
54
+ }
55
+ function decodePointerSegment(segment) {
56
+ return segment.replace(/~1/g, "/").replace(/~0/g, "~");
57
+ }
58
+ export function resolveJsonPointer(value, pointer, label) {
59
+ assertJsonPointer(pointer, label);
60
+ if (pointer === "")
61
+ return value;
62
+ let current = value;
63
+ for (const rawSegment of pointer.slice(1).split("/")) {
64
+ const segment = decodePointerSegment(rawSegment);
65
+ if (Array.isArray(current)) {
66
+ if (!/^(0|[1-9][0-9]*)$/.test(segment)) {
67
+ throw new DynamicFanoutError(`${label} segment '${segment}' does not address an array index.`);
68
+ }
69
+ const index = Number(segment);
70
+ if (index >= current.length)
71
+ throw new DynamicFanoutError(`${label} does not exist.`);
72
+ current = current[index];
73
+ continue;
74
+ }
75
+ if (!current || typeof current !== "object") {
76
+ throw new DynamicFanoutError(`${label} does not exist.`);
77
+ }
78
+ const record = current;
79
+ if (!Object.prototype.hasOwnProperty.call(record, segment)) {
80
+ throw new DynamicFanoutError(`${label} does not exist.`);
81
+ }
82
+ current = record[segment];
83
+ }
84
+ return current;
85
+ }
86
+ function scalarToKey(value, label) {
87
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
88
+ const key = String(value);
89
+ if (!key.trim())
90
+ throw new DynamicFanoutError(`${label} resolved to an empty key.`);
91
+ if (/[\u0000-\u001F\u007F]/.test(key))
92
+ throw new DynamicFanoutError(`${label} resolved to an unsafe key.`);
93
+ if (key.length > 200)
94
+ throw new DynamicFanoutError(`${label} resolved to a key longer than 200 characters.`);
95
+ return key;
96
+ }
97
+ throw new DynamicFanoutError(`${label} must resolve to a string, number, or boolean.`);
98
+ }
99
+ export function normalizeItemKeyForId(key) {
100
+ const normalized = key.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
101
+ return normalized || "item";
102
+ }
103
+ function valueToTemplateText(value, reference) {
104
+ if (value === undefined)
105
+ throw new DynamicFanoutError(`Unresolved item reference '${reference}'.`);
106
+ if (typeof value === "string")
107
+ return value;
108
+ if (typeof value === "number" || typeof value === "boolean" || value === null)
109
+ return String(value);
110
+ return JSON.stringify(value);
111
+ }
112
+ function resolveItemPath(item, pathText, reference) {
113
+ if (!pathText)
114
+ return item;
115
+ const pointer = `/${pathText.split(".").map((segment) => segment.replace(/~/g, "~0").replace(/\//g, "~1")).join("/")}`;
116
+ return resolveJsonPointer(item, pointer, reference);
117
+ }
118
+ export function resolveItemTemplate(template, itemName, item) {
119
+ return template.replace(ITEM_REF_PATTERN, (raw, name, pathText) => {
120
+ if (name !== itemName)
121
+ return raw;
122
+ if (pathText !== undefined && (!pathText.trim() || pathText.includes(".."))) {
123
+ throw new DynamicFanoutError(`Invalid item reference '${raw}'.`);
124
+ }
125
+ return valueToTemplateText(resolveItemPath(item, pathText, raw), raw);
126
+ });
127
+ }
128
+ function assertOnlyKeys(value, allowed, label) {
129
+ if (!value || typeof value !== "object" || Array.isArray(value))
130
+ throw new DynamicFanoutError(`${label} must be an object.`);
131
+ for (const key of Object.keys(value)) {
132
+ if (!allowed.has(key))
133
+ throw new DynamicFanoutError(`${label} does not support field '${key}'.`);
134
+ }
135
+ }
136
+ export function assertNoUnresolvedItemReferences(template, itemName, label) {
137
+ for (const match of template.matchAll(/\{([^{}]*)\}/g)) {
138
+ const raw = match[0];
139
+ const reference = match[1];
140
+ if (reference === itemName || reference.startsWith(`${itemName}.`)) {
141
+ if (!ITEM_REF_PATTERN.test(raw) || reference === `${itemName}.` || reference.includes("..")) {
142
+ throw new DynamicFanoutError(`Invalid item reference '${raw}' in ${label}.`);
143
+ }
144
+ ITEM_REF_PATTERN.lastIndex = 0;
145
+ continue;
146
+ }
147
+ ITEM_REF_PATTERN.lastIndex = 0;
148
+ const name = reference.match(/^[A-Za-z_][A-Za-z0-9_]*/)?.[0];
149
+ if (name === itemName)
150
+ throw new DynamicFanoutError(`Invalid item reference '${raw}' in ${label}.`);
151
+ if (name && RESERVED_TEMPLATE_NAMES.has(name))
152
+ continue;
153
+ if (name)
154
+ throw new DynamicFanoutError(`Unsupported template reference '${raw}' in ${label}.`);
155
+ }
156
+ ITEM_REF_PATTERN.lastIndex = 0;
157
+ if (template.includes(`{${itemName}.}`) || new RegExp(`\\{${itemName}(?:\\.|$)[^}]*$`).test(template)) {
158
+ throw new DynamicFanoutError(`Invalid item reference in ${label}.`);
159
+ }
160
+ }
161
+ export function hasDynamicFanoutFields(step) {
162
+ return !!step && typeof step === "object" && !Array.isArray(step) && (Object.prototype.hasOwnProperty.call(step, "expand") || Object.prototype.hasOwnProperty.call(step, "collect"));
163
+ }
164
+ export function validateDynamicStepShape(step, stepIndex, config = {}) {
165
+ const prefix = `Dynamic chain step ${stepIndex + 1}`;
166
+ assertOnlyKeys(step, config.allowRunnerFields ? RUNNER_DYNAMIC_STEP_KEYS : DYNAMIC_STEP_KEYS, prefix);
167
+ if (!step.expand || !step.expand.from)
168
+ throw new DynamicFanoutError(`${prefix} requires expand.from.`);
169
+ assertOnlyKeys(step.expand, DYNAMIC_EXPAND_KEYS, `${prefix} expand`);
170
+ assertOnlyKeys(step.expand.from, DYNAMIC_EXPAND_FROM_KEYS, `${prefix} expand.from`);
171
+ if (!isSafeOutputName(step.expand.from.output))
172
+ throw new DynamicFanoutError(`${prefix} has invalid expand.from.output '${step.expand.from.output}'.`);
173
+ assertJsonPointer(step.expand.from.path, `${prefix} expand.from.path`);
174
+ if (step.expand.key !== undefined)
175
+ assertJsonPointer(step.expand.key, `${prefix} expand.key`);
176
+ const itemName = step.expand.item ?? "item";
177
+ if (!ITEM_NAME_PATTERN.test(itemName))
178
+ throw new DynamicFanoutError(`${prefix} has invalid expand.item '${itemName}'.`);
179
+ if (step.expand.maxItems === undefined && config.maxItems === undefined) {
180
+ throw new DynamicFanoutError(`${prefix} requires expand.maxItems or config.chain.dynamicFanout.maxItems.`);
181
+ }
182
+ if (step.expand.maxItems !== undefined && (!Number.isInteger(step.expand.maxItems) || step.expand.maxItems < 0)) {
183
+ throw new DynamicFanoutError(`${prefix} expand.maxItems must be an integer >= 0.`);
184
+ }
185
+ if (config.maxItems !== undefined && (!Number.isInteger(config.maxItems) || config.maxItems < 0)) {
186
+ throw new DynamicFanoutError("config.chain.dynamicFanout.maxItems must be an integer >= 0.");
187
+ }
188
+ if (!step.parallel || Array.isArray(step.parallel))
189
+ throw new DynamicFanoutError(`${prefix} requires a single parallel template object and cannot mix dynamic expand/collect with static parallel arrays.`);
190
+ assertOnlyKeys(step.parallel, config.allowRunnerFields ? RUNNER_DYNAMIC_PARALLEL_KEYS : DYNAMIC_PARALLEL_KEYS, `${prefix} parallel`);
191
+ if ("expand" in step.parallel)
192
+ throw new DynamicFanoutError(`${prefix} does not support nested dynamic fanout.`);
193
+ if (!step.parallel.agent)
194
+ throw new DynamicFanoutError(`${prefix} parallel.agent is required.`);
195
+ if (!step.collect?.as || !isSafeOutputName(step.collect.as))
196
+ throw new DynamicFanoutError(`${prefix} requires collect.as with a safe output name.`);
197
+ assertOnlyKeys(step.collect, DYNAMIC_COLLECT_KEYS, `${prefix} collect`);
198
+ for (const [label, template] of [
199
+ ["parallel.task", step.parallel.task],
200
+ ["parallel.label", step.parallel.label]
201
+ ]) {
202
+ if (template)
203
+ assertNoUnresolvedItemReferences(template, itemName, `${prefix} ${label}`);
204
+ }
205
+ }
206
+ export function resolveDynamicFanoutItems(step, outputs, stepIndex, config = {}) {
207
+ validateDynamicStepShape(step, stepIndex, config);
208
+ const sourceName = step.expand.from.output;
209
+ const source = outputs[sourceName];
210
+ if (!source)
211
+ throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} references unknown output '${sourceName}'.`);
212
+ if (source.structured === undefined)
213
+ throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} requires structured output '${sourceName}'.`);
214
+ const value = resolveJsonPointer(source.structured, step.expand.from.path, `Dynamic chain step ${stepIndex + 1} expand.from.path`);
215
+ if (!Array.isArray(value))
216
+ throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} expand.from.path must resolve to an array.`);
217
+ const maxItems = step.expand.maxItems ?? config.maxItems;
218
+ if (maxItems === undefined)
219
+ throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} requires an effective maxItems.`);
220
+ if (value.length > maxItems)
221
+ throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} resolved ${value.length} items, exceeding maxItems ${maxItems}.`);
222
+ const seen = new Set;
223
+ const seenIds = new Set;
224
+ return value.map((item, index) => {
225
+ const key = step.expand.key === undefined ? String(index) : scalarToKey(resolveJsonPointer(item, step.expand.key, `Dynamic chain step ${stepIndex + 1} expand.key`), `Dynamic chain step ${stepIndex + 1} expand.key`);
226
+ if (seen.has(key))
227
+ throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} produced duplicate item key '${key}'.`);
228
+ seen.add(key);
229
+ const idKey = normalizeItemKeyForId(key);
230
+ if (seenIds.has(idKey))
231
+ throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} produced colliding item id '${idKey}'.`);
232
+ seenIds.add(idKey);
233
+ return { index, key, idKey, item };
234
+ });
235
+ }
236
+ export function materializeDynamicParallelStep(step, outputs, stepIndex, config = {}) {
237
+ const items = resolveDynamicFanoutItems(step, outputs, stepIndex, config);
238
+ if (items.length === 0) {
239
+ if ((step.expand.onEmpty ?? "skip") === "fail") {
240
+ throw new DynamicFanoutError(`Dynamic chain step ${stepIndex + 1} source array is empty.`);
241
+ }
242
+ return { items, parallel: [], collectedOnEmpty: [] };
243
+ }
244
+ const itemName = step.expand.item ?? "item";
245
+ const parallel = items.map((entry) => {
246
+ const task = resolveItemTemplate(step.parallel.task ?? "{previous}", itemName, entry.item);
247
+ const label = step.parallel.label ? resolveItemTemplate(step.parallel.label, itemName, entry.item) : undefined;
248
+ return {
249
+ ...step.parallel,
250
+ task,
251
+ ...label !== undefined ? { label } : {}
252
+ };
253
+ });
254
+ return { items, parallel };
255
+ }
256
+ export function collectDynamicResults(step, items, results) {
257
+ return items.map((entry, index) => {
258
+ const result = results[index];
259
+ const text = result ? "output" in result && typeof result.output === "string" ? result.output : getSingleResultOutput(result) : "";
260
+ return {
261
+ key: entry.key,
262
+ index: entry.index,
263
+ item: entry.item,
264
+ agent: result?.agent ?? step.parallel.agent,
265
+ exitCode: result?.exitCode ?? null,
266
+ text,
267
+ ...result?.structuredOutput !== undefined ? { structured: result.structuredOutput } : {},
268
+ ...result?.error ? { error: result.error } : {},
269
+ ...result?.timedOut ? { timedOut: true } : {},
270
+ ...result?.savedOutputPath ? { outputPath: result.savedOutputPath } : {},
271
+ ...result?.artifactPaths ? { artifactPaths: result.artifactPaths } : {}
272
+ };
273
+ });
274
+ }
275
+ export function validateDynamicCollection(schema, value) {
276
+ if (!schema)
277
+ return;
278
+ const validation = validateStructuredOutputValue(schema, value);
279
+ if (validation.status === "invalid") {
280
+ throw new DynamicFanoutError(`Collected output validation failed: ${validation.message}`);
281
+ }
282
+ }
@@ -1 +1,148 @@
1
- var s=[/(^|[;&|()\s])rm\s+/,/(^|[;&|()\s])mv\s+/,/(^|[;&|()\s])cp\s+/,/(^|[;&|()\s])mkdir\s+/,/(^|[;&|()\s])touch\s+/,/(^|[;&|()\s])git\s+apply\b/,/(^|[;&|()\s])patch\s+/,/(^|[;&|()\s])sed\s+[^\n;&|]*\s-i\b/,/(^|[;&|()\s])perl\s+[^\n;&|]*\s-pi\b/,/(^|[;&|()]|\n)\s*tee\s+[^|&;]+/,/\b(writeFile|writeFileSync|appendFile|appendFileSync)\b/,/\bwrite_text\s*\(/,/\bopen\s*\([^)]*,\s*["'][wa]/],l=["failed","error","no exact match","did not match","malformed","rejected","unable","cannot","could not"];function f(e,t){if(!e||!t)return;let n=["path","file","filename","target","cwd"];for(let i of n){let r=t[i];if(typeof r==="string"&&r.trim())return r.trim()}if(e==="bash"){let i=typeof t.command==="string"?t.command:void 0;if(!i)return;let r=i.match(/(?:>|>>|tee\s+)(\S+)/);if(r?.[1])return r[1]}return}function c(e){let t=!1,n=!1;for(let i=0;i<e.length;i++){let r=e[i];if(r==="'"&&!n){t=!t;continue}if(r==='"'&&!t){n=!n;continue}if(t||n)continue;if(r!==">")continue;if(e[i-1]==="-")continue;let o=e[i+1]===">",u=i+(o?2:1);while(u<e.length&&/\s/.test(e[u]))u++;if(u>=e.length)continue;let a=e[u];if(a==="&"||a==="|"||a===";")continue;if(a==="("||a===")")continue;return!0}return!1}function d(e){return c(e)||s.some((t)=>t.test(e))}function g(e,t){if(!e)return!1;if(e==="edit"||e==="write")return!0;if(e!=="bash")return!1;let n=typeof t?.command==="string"?t.command:"";if(!n.trim())return!1;return d(n)}function h(e){let t=e.toLowerCase();return l.some((n)=>t.includes(n))}function F(e,t){if(t.now-t.startedAt>=e.activeNoticeAfterMs)return"time_threshold";if(e.activeNoticeAfterTurns!==void 0&&t.turns>=e.activeNoticeAfterTurns)return"turn_threshold";if(e.activeNoticeAfterTokens!==void 0&&t.tokens>=e.activeNoticeAfterTokens)return"token_threshold";return}function p(e){e.consecutiveFailures=0,e.lastFailureAt=void 0,e.recentFailures=[],e.lastMutatingPath=void 0,e.repeatedPathFailures=0}function b(){return{consecutiveFailures:0,recentFailures:[],repeatedPathFailures:0}}function M(e,t,n){if(e.lastFailureAt===void 0||t.ts-e.lastFailureAt>n)e.consecutiveFailures=0,e.recentFailures=[],e.repeatedPathFailures=0,e.lastMutatingPath=void 0;if(e.lastFailureAt=t.ts,e.consecutiveFailures+=1,t.path&&e.lastMutatingPath===t.path)e.repeatedPathFailures+=1;else if(t.path)e.lastMutatingPath=t.path,e.repeatedPathFailures=1;if(e.recentFailures.push(t),e.recentFailures.length>3)e.recentFailures.shift()}function m(e,t){return e.consecutiveFailures>=t||e.repeatedPathFailures>=t}function A(e){if(e.recentFailures.length===0)return;return e.recentFailures.map((t)=>`${t.tool}${t.path?`(${t.path})`:""}: ${t.error}`).join(" | ")}export{A as summarizeRecentMutatingFailures,m as shouldEscalateMutatingFailures,f as resolveCurrentPath,p as resetMutatingFailureState,M as recordMutatingFailure,F as nextLongRunningTrigger,g as isMutatingTool,d as isMutatingBashCommand,h as didMutatingToolFail,b as createMutatingFailureState};
1
+ const MUTATING_BASH_PATTERNS = [
2
+ /(^|[;&|()\s])rm\s+/,
3
+ /(^|[;&|()\s])mv\s+/,
4
+ /(^|[;&|()\s])cp\s+/,
5
+ /(^|[;&|()\s])mkdir\s+/,
6
+ /(^|[;&|()\s])touch\s+/,
7
+ /(^|[;&|()\s])git\s+apply\b/,
8
+ /(^|[;&|()\s])patch\s+/,
9
+ /(^|[;&|()\s])sed\s+[^\n;&|]*\s-i\b/,
10
+ /(^|[;&|()\s])perl\s+[^\n;&|]*\s-pi\b/,
11
+ /(^|[;&|()]|\n)\s*tee\s+[^|&;]+/,
12
+ /\b(writeFile|writeFileSync|appendFile|appendFileSync)\b/,
13
+ /\bwrite_text\s*\(/,
14
+ /\bopen\s*\([^)]*,\s*["'][wa]/
15
+ ];
16
+ const MUTATING_FAILURE_HINTS = [
17
+ "failed",
18
+ "error",
19
+ "no exact match",
20
+ "did not match",
21
+ "malformed",
22
+ "rejected",
23
+ "unable",
24
+ "cannot",
25
+ "could not"
26
+ ];
27
+ export function resolveCurrentPath(toolName, args) {
28
+ if (!toolName || !args)
29
+ return;
30
+ const direct = ["path", "file", "filename", "target", "cwd"];
31
+ for (const key of direct) {
32
+ const value = args[key];
33
+ if (typeof value === "string" && value.trim())
34
+ return value.trim();
35
+ }
36
+ if (toolName === "bash") {
37
+ const command = typeof args.command === "string" ? args.command : undefined;
38
+ if (!command)
39
+ return;
40
+ const redirect = command.match(/(?:>|>>|tee\s+)(\S+)/);
41
+ if (redirect?.[1])
42
+ return redirect[1];
43
+ }
44
+ return;
45
+ }
46
+ function hasUnquotedFileRedirection(command) {
47
+ let inSingle = false;
48
+ let inDouble = false;
49
+ for (let i = 0;i < command.length; i++) {
50
+ const char = command[i];
51
+ if (char === "'" && !inDouble) {
52
+ inSingle = !inSingle;
53
+ continue;
54
+ }
55
+ if (char === '"' && !inSingle) {
56
+ inDouble = !inDouble;
57
+ continue;
58
+ }
59
+ if (inSingle || inDouble)
60
+ continue;
61
+ if (char !== ">")
62
+ continue;
63
+ if (command[i - 1] === "-")
64
+ continue;
65
+ const isDouble = command[i + 1] === ">";
66
+ let cursor = i + (isDouble ? 2 : 1);
67
+ while (cursor < command.length && /\s/.test(command[cursor]))
68
+ cursor++;
69
+ if (cursor >= command.length)
70
+ continue;
71
+ const targetStart = command[cursor];
72
+ if (targetStart === "&" || targetStart === "|" || targetStart === ";")
73
+ continue;
74
+ if (targetStart === "(" || targetStart === ")")
75
+ continue;
76
+ return true;
77
+ }
78
+ return false;
79
+ }
80
+ export function isMutatingBashCommand(command) {
81
+ return hasUnquotedFileRedirection(command) || MUTATING_BASH_PATTERNS.some((pattern) => pattern.test(command));
82
+ }
83
+ export function isMutatingTool(toolName, args) {
84
+ if (!toolName)
85
+ return false;
86
+ if (toolName === "edit" || toolName === "write")
87
+ return true;
88
+ if (toolName !== "bash")
89
+ return false;
90
+ const command = typeof args?.command === "string" ? args.command : "";
91
+ if (!command.trim())
92
+ return false;
93
+ return isMutatingBashCommand(command);
94
+ }
95
+ export function didMutatingToolFail(text) {
96
+ const lowered = text.toLowerCase();
97
+ return MUTATING_FAILURE_HINTS.some((hint) => lowered.includes(hint));
98
+ }
99
+ export function nextLongRunningTrigger(config, metrics) {
100
+ if (metrics.now - metrics.startedAt >= config.activeNoticeAfterMs)
101
+ return "time_threshold";
102
+ if (config.activeNoticeAfterTurns !== undefined && metrics.turns >= config.activeNoticeAfterTurns)
103
+ return "turn_threshold";
104
+ if (config.activeNoticeAfterTokens !== undefined && metrics.tokens >= config.activeNoticeAfterTokens)
105
+ return "token_threshold";
106
+ return;
107
+ }
108
+ export function resetMutatingFailureState(state) {
109
+ state.consecutiveFailures = 0;
110
+ state.lastFailureAt = undefined;
111
+ state.recentFailures = [];
112
+ state.lastMutatingPath = undefined;
113
+ state.repeatedPathFailures = 0;
114
+ }
115
+ export function createMutatingFailureState() {
116
+ return {
117
+ consecutiveFailures: 0,
118
+ recentFailures: [],
119
+ repeatedPathFailures: 0
120
+ };
121
+ }
122
+ export function recordMutatingFailure(state, input, windowMs) {
123
+ if (state.lastFailureAt === undefined || input.ts - state.lastFailureAt > windowMs) {
124
+ state.consecutiveFailures = 0;
125
+ state.recentFailures = [];
126
+ state.repeatedPathFailures = 0;
127
+ state.lastMutatingPath = undefined;
128
+ }
129
+ state.lastFailureAt = input.ts;
130
+ state.consecutiveFailures += 1;
131
+ if (input.path && state.lastMutatingPath === input.path) {
132
+ state.repeatedPathFailures += 1;
133
+ } else if (input.path) {
134
+ state.lastMutatingPath = input.path;
135
+ state.repeatedPathFailures = 1;
136
+ }
137
+ state.recentFailures.push(input);
138
+ if (state.recentFailures.length > 3)
139
+ state.recentFailures.shift();
140
+ }
141
+ export function shouldEscalateMutatingFailures(state, threshold) {
142
+ return state.consecutiveFailures >= threshold || state.repeatedPathFailures >= threshold;
143
+ }
144
+ export function summarizeRecentMutatingFailures(state) {
145
+ if (state.recentFailures.length === 0)
146
+ return;
147
+ return state.recentFailures.map((entry) => `${entry.tool}${entry.path ? `(${entry.path})` : ""}: ${entry.error}`).join(" | ");
148
+ }