@duckmind/dm-darwin-x64 0.43.4 → 0.43.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.
- package/dm +0 -0
- package/extensions/.dm-extensions.json +241 -49
- package/extensions/dm-9router-ext/package.json +2 -19
- package/extensions/dm-9router-ext/src/index.js +5 -0
- package/extensions/dm-ask-user/index.js +10 -0
- package/extensions/dm-ask-user/package.json +1 -21
- package/extensions/dm-cli-anything/package.json +0 -6
- package/extensions/dm-context/package.json +2 -12
- package/extensions/dm-context/src/context.js +1 -0
- package/extensions/dm-context/src/index.js +7 -0
- package/extensions/dm-context/src/utils.js +1 -0
- package/extensions/dm-cua/package.json +0 -7
- package/extensions/dm-fff/package.json +1 -28
- package/extensions/dm-fff/src/index.js +15 -0
- package/extensions/dm-fff/src/query.js +1 -0
- package/extensions/dm-goal/package.json +2 -31
- package/extensions/dm-goal/src/goal.js +43 -0
- package/extensions/dm-grill-me/index.js +174 -0
- package/extensions/dm-grill-me/package.json +1 -26
- package/extensions/dm-image2/package.json +0 -7
- package/extensions/dm-subagents/package.json +1 -32
- package/extensions/dm-subagents/src/agents/agent-management.js +37 -0
- package/extensions/dm-subagents/src/agents/agent-memory.js +6 -0
- package/extensions/dm-subagents/src/agents/agent-scope.js +1 -0
- package/extensions/dm-subagents/src/agents/agent-selection.js +1 -0
- package/extensions/dm-subagents/src/agents/agent-serializer.js +7 -0
- package/extensions/dm-subagents/src/agents/agents.js +11 -0
- package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -0
- package/extensions/dm-subagents/src/agents/frontmatter.js +6 -0
- package/extensions/dm-subagents/src/agents/identity.js +1 -0
- package/extensions/dm-subagents/src/agents/proactive-skills.js +1 -0
- package/extensions/dm-subagents/src/agents/skills.js +6 -0
- package/extensions/dm-subagents/src/extension/config.js +2 -0
- package/extensions/dm-subagents/src/extension/control-notices.js +4 -0
- package/extensions/dm-subagents/src/extension/doctor.js +16 -0
- package/extensions/dm-subagents/src/extension/fanout-child.js +231 -0
- package/extensions/dm-subagents/src/extension/index.js +367 -0
- package/extensions/dm-subagents/src/extension/rpc.js +8 -0
- package/extensions/dm-subagents/src/extension/schemas.js +1 -0
- package/extensions/dm-subagents/src/extension/{tool-description.ts → tool-description.js} +6 -126
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +13 -0
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +5 -0
- package/extensions/dm-subagents/src/intercom/result-intercom.js +3 -0
- package/extensions/dm-subagents/src/profiles/profiles.js +3 -0
- package/extensions/dm-subagents/src/runs/background/async-execution.js +46 -0
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +14 -0
- package/extensions/dm-subagents/src/runs/background/async-resume.js +8 -0
- package/extensions/dm-subagents/src/runs/background/async-status.js +12 -0
- package/extensions/dm-subagents/src/runs/background/chain-append.js +2 -0
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +1 -0
- package/extensions/dm-subagents/src/runs/background/completion-batcher.js +1 -0
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +1 -0
- package/extensions/dm-subagents/src/runs/background/control-channel.js +1 -0
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +17 -0
- package/extensions/dm-subagents/src/runs/background/notify.js +3 -0
- package/extensions/dm-subagents/src/runs/background/parallel-groups.js +1 -0
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +8 -0
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +4 -0
- package/extensions/dm-subagents/src/runs/background/run-status.js +23 -0
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +4 -0
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +11 -0
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +78 -0
- package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -0
- package/extensions/dm-subagents/src/runs/background/wait.js +11 -0
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +12 -0
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +102 -0
- package/extensions/dm-subagents/src/runs/foreground/execution.js +51 -0
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +228 -0
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +3 -0
- package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +3 -0
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/model-fallback.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/model-scope.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +8 -0
- package/extensions/dm-subagents/src/runs/shared/nested-path.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/nested-render.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +5 -0
- package/extensions/dm-subagents/src/runs/shared/run-history.js +5 -0
- package/extensions/dm-subagents/src/runs/shared/single-output.js +14 -0
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +5 -0
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +22 -0
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/turn-budget.js +7 -0
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +1 -0
- package/extensions/dm-subagents/src/runs/shared/worktree.js +3 -0
- package/extensions/dm-subagents/src/shared/artifacts.js +2 -0
- package/extensions/dm-subagents/src/shared/atomic-json.js +1 -0
- package/extensions/dm-subagents/src/shared/child-transcript.js +5 -0
- package/extensions/dm-subagents/src/shared/file-coalescer.js +1 -0
- package/extensions/dm-subagents/src/shared/fork-context.js +6 -0
- package/extensions/dm-subagents/src/shared/formatters.js +9 -0
- package/extensions/dm-subagents/src/shared/jsonl-writer.js +2 -0
- package/extensions/dm-subagents/src/shared/model-info.js +1 -0
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +1 -0
- package/extensions/dm-subagents/src/shared/session-identity.js +1 -0
- package/extensions/dm-subagents/src/shared/session-tokens.js +2 -0
- package/extensions/dm-subagents/src/shared/settings.js +23 -0
- package/extensions/dm-subagents/src/shared/status-format.js +1 -0
- package/extensions/dm-subagents/src/shared/types.js +8 -0
- package/extensions/dm-subagents/src/shared/utils.js +2 -0
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +1 -0
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +7 -0
- package/extensions/dm-subagents/src/slash/slash-bridge.js +1 -0
- package/extensions/dm-subagents/src/slash/slash-commands.js +38 -0
- package/extensions/dm-subagents/src/slash/slash-live-state.js +6 -0
- package/extensions/dm-subagents/src/tui/render-helpers.js +1 -0
- package/extensions/dm-subagents/src/tui/render.js +4 -0
- package/extensions/dm-tasks/package.json +1 -30
- package/extensions/dm-tasks/src/auto-clear.js +1 -0
- package/extensions/dm-tasks/src/index.js +212 -0
- package/extensions/dm-tasks/src/process-tracker.js +1 -0
- package/extensions/dm-tasks/src/task-store.js +1 -0
- package/extensions/dm-tasks/src/tasks-config.js +1 -0
- package/extensions/dm-tasks/src/types.js +0 -0
- package/extensions/dm-tasks/src/ui/settings-menu.js +1 -0
- package/extensions/dm-tasks/src/ui/task-widget.js +1 -0
- package/extensions/dm-usage/index.js +9 -0
- package/extensions/dm-usage/package.json +1 -18
- package/extensions/greedysearch-dm/index.js +20 -0
- package/extensions/greedysearch-dm/package.json +1 -22
- package/extensions/greedysearch-dm/src/formatters/results.js +8 -0
- package/extensions/greedysearch-dm/src/formatters/sources.js +1 -0
- package/extensions/greedysearch-dm/src/formatters/synthesis.js +1 -0
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +20 -0
- package/extensions/greedysearch-dm/src/tools/shared.js +9 -0
- package/extensions/greedysearch-dm/src/types.js +0 -0
- package/extensions/greedysearch-dm/src/utils/helpers.js +1 -0
- package/package.json +1 -1
- package/extensions/dm-9router-ext/src/index.ts +0 -541
- package/extensions/dm-ask-user/index.ts +0 -857
- package/extensions/dm-context/src/context.ts +0 -158
- package/extensions/dm-context/src/index.ts +0 -439
- package/extensions/dm-context/src/utils.ts +0 -6
- package/extensions/dm-fff/src/index.ts +0 -1023
- package/extensions/dm-fff/src/query.ts +0 -87
- package/extensions/dm-goal/src/goal.ts +0 -1073
- package/extensions/dm-grill-me/index.ts +0 -1085
- package/extensions/dm-subagents/src/agents/agent-management.ts +0 -1052
- package/extensions/dm-subagents/src/agents/agent-memory.ts +0 -254
- package/extensions/dm-subagents/src/agents/agent-scope.ts +0 -6
- package/extensions/dm-subagents/src/agents/agent-selection.ts +0 -25
- package/extensions/dm-subagents/src/agents/agent-serializer.ts +0 -121
- package/extensions/dm-subagents/src/agents/agents.ts +0 -1553
- package/extensions/dm-subagents/src/agents/chain-serializer.ts +0 -277
- package/extensions/dm-subagents/src/agents/frontmatter.ts +0 -93
- package/extensions/dm-subagents/src/agents/identity.ts +0 -30
- package/extensions/dm-subagents/src/agents/proactive-skills.ts +0 -191
- package/extensions/dm-subagents/src/agents/skills.ts +0 -729
- package/extensions/dm-subagents/src/extension/config.ts +0 -39
- package/extensions/dm-subagents/src/extension/control-notices.ts +0 -92
- package/extensions/dm-subagents/src/extension/doctor.ts +0 -214
- package/extensions/dm-subagents/src/extension/fanout-child.ts +0 -172
- package/extensions/dm-subagents/src/extension/index.ts +0 -656
- package/extensions/dm-subagents/src/extension/rpc.ts +0 -369
- package/extensions/dm-subagents/src/extension/schemas.ts +0 -309
- package/extensions/dm-subagents/src/intercom/intercom-bridge.ts +0 -180
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.ts +0 -519
- package/extensions/dm-subagents/src/intercom/result-intercom.ts +0 -377
- package/extensions/dm-subagents/src/profiles/profiles.ts +0 -637
- package/extensions/dm-subagents/src/runs/background/async-execution.ts +0 -1065
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.ts +0 -441
- package/extensions/dm-subagents/src/runs/background/async-resume.ts +0 -391
- package/extensions/dm-subagents/src/runs/background/async-status.ts +0 -395
- package/extensions/dm-subagents/src/runs/background/chain-append.ts +0 -282
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.ts +0 -191
- package/extensions/dm-subagents/src/runs/background/completion-batcher.ts +0 -166
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.ts +0 -63
- package/extensions/dm-subagents/src/runs/background/control-channel.ts +0 -332
- package/extensions/dm-subagents/src/runs/background/fleet-view.ts +0 -515
- package/extensions/dm-subagents/src/runs/background/notify.ts +0 -225
- package/extensions/dm-subagents/src/runs/background/parallel-groups.ts +0 -45
- package/extensions/dm-subagents/src/runs/background/result-watcher.ts +0 -315
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.ts +0 -84
- package/extensions/dm-subagents/src/runs/background/run-status.ts +0 -434
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.ts +0 -514
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.ts +0 -368
- package/extensions/dm-subagents/src/runs/background/subagent-runner.ts +0 -3171
- package/extensions/dm-subagents/src/runs/background/top-level-async.ts +0 -13
- package/extensions/dm-subagents/src/runs/background/wait.ts +0 -353
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.ts +0 -1333
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.ts +0 -1313
- package/extensions/dm-subagents/src/runs/foreground/execution.ts +0 -1239
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.ts +0 -3613
- package/extensions/dm-subagents/src/runs/shared/acceptance.ts +0 -879
- package/extensions/dm-subagents/src/runs/shared/chain-outputs.ts +0 -116
- package/extensions/dm-subagents/src/runs/shared/completion-guard.ts +0 -147
- package/extensions/dm-subagents/src/runs/shared/dm-args.ts +0 -271
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.ts +0 -147
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.ts +0 -295
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.ts +0 -175
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +0 -365
- package/extensions/dm-subagents/src/runs/shared/model-fallback.ts +0 -292
- package/extensions/dm-subagents/src/runs/shared/model-scope.ts +0 -128
- package/extensions/dm-subagents/src/runs/shared/nested-events.ts +0 -908
- package/extensions/dm-subagents/src/runs/shared/nested-path.ts +0 -52
- package/extensions/dm-subagents/src/runs/shared/nested-render.ts +0 -115
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.ts +0 -198
- package/extensions/dm-subagents/src/runs/shared/run-history.ts +0 -60
- package/extensions/dm-subagents/src/runs/shared/single-output.ts +0 -180
- package/extensions/dm-subagents/src/runs/shared/structured-output.ts +0 -77
- package/extensions/dm-subagents/src/runs/shared/subagent-control.ts +0 -223
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.ts +0 -342
- package/extensions/dm-subagents/src/runs/shared/tool-budget.ts +0 -74
- package/extensions/dm-subagents/src/runs/shared/turn-budget.ts +0 -52
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.ts +0 -206
- package/extensions/dm-subagents/src/runs/shared/worktree.ts +0 -600
- package/extensions/dm-subagents/src/shared/artifacts.ts +0 -113
- package/extensions/dm-subagents/src/shared/atomic-json.ts +0 -86
- package/extensions/dm-subagents/src/shared/child-transcript.ts +0 -212
- package/extensions/dm-subagents/src/shared/file-coalescer.ts +0 -40
- package/extensions/dm-subagents/src/shared/fork-context.ts +0 -194
- package/extensions/dm-subagents/src/shared/formatters.ts +0 -133
- package/extensions/dm-subagents/src/shared/jsonl-writer.ts +0 -81
- package/extensions/dm-subagents/src/shared/model-info.ts +0 -78
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
- package/extensions/dm-subagents/src/shared/session-identity.ts +0 -10
- package/extensions/dm-subagents/src/shared/session-tokens.ts +0 -44
- package/extensions/dm-subagents/src/shared/settings.ts +0 -450
- package/extensions/dm-subagents/src/shared/status-format.ts +0 -49
- package/extensions/dm-subagents/src/shared/types.ts +0 -1257
- package/extensions/dm-subagents/src/shared/utils.ts +0 -554
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.ts +0 -420
- package/extensions/dm-subagents/src/slash/prompt-workflows.ts +0 -330
- package/extensions/dm-subagents/src/slash/slash-bridge.ts +0 -176
- package/extensions/dm-subagents/src/slash/slash-commands.ts +0 -1296
- package/extensions/dm-subagents/src/slash/slash-live-state.ts +0 -292
- package/extensions/dm-subagents/src/tui/render-helpers.ts +0 -80
- package/extensions/dm-subagents/src/tui/render.ts +0 -1748
- package/extensions/dm-tasks/src/auto-clear.ts +0 -91
- package/extensions/dm-tasks/src/index.ts +0 -1145
- package/extensions/dm-tasks/src/process-tracker.ts +0 -140
- package/extensions/dm-tasks/src/task-store.ts +0 -305
- package/extensions/dm-tasks/src/tasks-config.ts +0 -23
- package/extensions/dm-tasks/src/types.ts +0 -40
- package/extensions/dm-tasks/src/ui/settings-menu.ts +0 -100
- package/extensions/dm-tasks/src/ui/task-widget.ts +0 -265
- package/extensions/dm-usage/index.ts +0 -1718
- package/extensions/greedysearch-dm/index.ts +0 -177
- package/extensions/greedysearch-dm/src/formatters/results.ts +0 -163
- package/extensions/greedysearch-dm/src/formatters/sources.ts +0 -116
- package/extensions/greedysearch-dm/src/formatters/synthesis.ts +0 -87
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.ts +0 -370
- package/extensions/greedysearch-dm/src/tools/shared.ts +0 -187
- package/extensions/greedysearch-dm/src/types.ts +0 -110
- package/extensions/greedysearch-dm/src/utils/helpers.ts +0 -40
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import*as O$ from"node:path";import{Compile as Y0}from"typebox/compile";import*as q from"node:fs";import*as z from"node:path";import*as E from"node:os";import*as y from"node:path";function m($){return $.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function N$($){let J=$?.env??process.env,Q=$&&Object.hasOwn($,"getuid")?$.getuid:process.getuid?.bind(process);if(typeof Q==="function")return`uid-${Q()}`;for(let K of["USERNAME","USER","LOGNAME"]){let Y=J[K];if(Y)return`user-${m(Y)}`}let Z=$&&Object.hasOwn($,"userInfo")?$.userInfo:E.userInfo;try{let K=Z?.().username;if(K)return`user-${m(K)}`}catch{}let X=J.USERPROFILE??J.HOME;if(X)return`home-${m(X)}`;let W=$&&Object.hasOwn($,"homedir")?$.homedir:E.homedir;try{let K=W?.();if(K)return`home-${m(K)}`}catch{}return"shared"}var _=y.join(E.tmpdir(),`dm-subagents-${N$()}`),S=y.join(_,"async-subagent-results"),h=y.join(_,"async-subagent-runs"),b$=y.join(_,"chain-runs"),C0=y.join(_,"artifacts");import*as F from"node:fs";import*as k from"node:path";var D=new Map;function o($){return $ instanceof Error?$.message:String($)}function j$($){return typeof $==="object"&&$!==null&&"code"in $&&$.code==="ENOENT"}function J$($){let J=k.join($,"status.json"),Q;try{Q=F.statSync(J)}catch(K){if(j$(K))return null;throw Error(`Failed to inspect async status file '${J}': ${o(K)}`,{cause:K instanceof Error?K:void 0})}let Z=D.get(J);if(Z&&Z.mtime===Q.mtimeMs)return Z.status;let X;try{X=F.readFileSync(J,"utf-8")}catch(K){if(j$(K))return null;throw Error(`Failed to read async status file '${J}': ${o(K)}`,{cause:K instanceof Error?K:void 0})}let W;try{W=JSON.parse(X)}catch(K){throw Error(`Failed to parse async status file '${J}': ${o(K)}`,{cause:K instanceof Error?K:void 0})}if(D.set(J,{mtime:Q.mtimeMs,status:W}),D.size>50){let K=D.keys().next().value;if(K)D.delete(K)}return W}import*as u from"node:path";import*as y$ from"node:fs";import*as T from"node:path";var S$=[10,25,50,100,200,500,1000,2000,4000],x$=new Set(["EACCES","EBUSY","EPERM"]),Z$=typeof SharedArrayBuffer<"u"?new SharedArrayBuffer(4):void 0,Q$=Z$?new Int32Array(Z$):void 0;function D$($){if($<=0)return;if(Q$)try{Atomics.wait(Q$,0,0,$);return}catch{}let J=Date.now()+$;while(Date.now()<J);}function k$($){let J=$?.code;return typeof J==="string"&&x$.has(J)}function I$($,J,Q,Z,X){for(let W=0;;W++)try{$.renameSync(J,Q);return}catch(K){let Y=Z[W];if(Y===void 0||!k$(K))throw K;X(Y)}}function w$($={}){let J=$.fs??y$,Q=$.now??Date.now,Z=$.pid??process.pid,X=$.random??Math.random,K=$.retryRenameErrors??process.platform==="win32"?$.retryDelaysMs??S$:[],Y=$.wait??D$;return(H,B)=>{J.mkdirSync(T.dirname(H),{recursive:!0});let V=T.join(T.dirname(H),`.${T.basename(H)}.${Z}.${Q()}.${X().toString(36).slice(2)}.tmp`);try{J.writeFileSync(V,JSON.stringify(B,null,2),"utf-8"),I$(J,V,H,K,Y)}finally{J.rmSync(V,{force:!0})}}}var N=w$();var r0=process.platform==="win32"?"SIGBREAK":"SIGUSR2";function R$($){return u.join($,"control")}function P$($){return u.join(R$($),"timeout.json")}function v$($,J={},Q={}){let Z=P$($),X={...J,ts:J.ts??Q.now?.()??Date.now(),type:"timeout"};return N(Z,X),Z}function W$($){v$($.asyncDir,$.source?{source:$.source}:{},{now:$.now})}import*as L from"node:fs";import*as O from"node:path";function g$($,J,Q){if(typeof $!=="object"||$===null)return!1;let{start:Z,count:X,stepIndex:W}=$;return typeof Z==="number"&&typeof X==="number"&&typeof W==="number"&&Number.isInteger(Z)&&Number.isInteger(X)&&Number.isInteger(W)&&Z>=0&&X>0&&W>=0&&W<Q&&Z+X<=J}function X$($,J,Q){if(!Array.isArray($))return[];return $.filter((Z)=>g$(Z,J,Q)).sort((Z,X)=>Z.stepIndex-X.stepIndex||Z.start-X.start)}import*as b from"node:path";import*as x from"node:path";import{fileURLToPath as K$}from"node:url";import*as f from"node:os";import*as C from"node:path";var $j=C.join(f.homedir(),".config","mcp","mcp.json"),jj={cursor:[C.join(f.homedir(),".cursor","mcp.json")],"claude-code":[C.join(f.homedir(),".claude","mcp.json"),C.join(f.homedir(),".claude.json"),C.join(f.homedir(),".claude","claude_desktop_config.json")],"claude-desktop":[C.join(f.homedir(),"Library","Application Support","Claude","claude_desktop_config.json")],codex:[C.join(f.homedir(),".codex","config.json")],windsurf:[C.join(f.homedir(),".windsurf","mcp.json")],vscode:[".vscode/mcp.json"]};import{Compile as Qj}from"typebox/compile";var Cj=x.join(x.dirname(K$(import.meta.url)),"subagent-prompt-runtime.ts"),Aj=x.join(x.dirname(K$(import.meta.url)),"..","..","extension","fanout-child.ts");var Pj=b.join(_,"nested-subagent-events");function l($){return $ instanceof Error?$.message:String($)}function h$($){let J=O.join($,"runner.stderr.log"),Q=65536,Z;try{let W=L.statSync(J);if(W.size<=0)return;let K=L.openSync(J,"r");try{let Y=Math.min(W.size,65536),H=Math.max(0,W.size-Y),B=Buffer.alloc(Y);L.readSync(K,B,0,Y,H),Z=B.toString("utf-8").trim()}finally{L.closeSync(K)}}catch{return}if(!Z)return;let X=Z.split(/\r?\n/).slice(-30).join(`
|
|
2
|
+
`);return X.length>4000?`${X.slice(-4000)}
|
|
3
|
+
[stderr tail truncated]`:X}function H$($){return typeof $==="object"&&$!==null&&"code"in $&&$.code==="ENOENT"}function c$($,J){try{L.mkdirSync(O.dirname($),{recursive:!0}),L.appendFileSync($,`${JSON.stringify(J)}
|
|
4
|
+
`,"utf-8")}catch{}}function d$($){let J=O.join($,"status.json"),Q;try{Q=L.readFileSync(J,"utf-8")}catch(Z){if(H$(Z))return null;throw Error(`Failed to read async status file '${J}': ${l(Z)}`,{cause:Z instanceof Error?Z:void 0})}try{return JSON.parse(Q)}catch(Z){throw Error(`Failed to parse async status file '${J}': ${l(Z)}`,{cause:Z instanceof Error?Z:void 0})}}function p$($){try{let J=JSON.parse(L.readFileSync($,"utf-8"));return{state:J.success?"complete":J.state==="paused"||J.exitCode===0?"paused":"failed",...Array.isArray(J.results)?{results:J.results}:{}}}catch(J){if(H$(J))return;throw Error(`Failed to read async result file '${$}': ${l(J)}`,{cause:J instanceof Error?J:void 0})}}function n$($,J){if(J?.success===!0)return"complete";if(J?.success===!1)return"failed";return $}function o$($,J,Q){let Z=p$(J);if(!Z)return;let X=($.steps??[]).map((W,K)=>{if(W.status!=="running"&&W.status!=="pending")return W;let Y=Z.results?.[K],H=n$(Z.state,Y);return{...W,status:H==="complete"?"complete":H,endedAt:W.endedAt??Q,durationMs:W.startedAt!==void 0&&W.durationMs===void 0?Math.max(0,Q-W.startedAt):W.durationMs,exitCode:W.exitCode??(H==="complete"||H==="paused"?0:1),error:H==="failed"?W.error??Y?.error:W.error,sessionFile:W.sessionFile??Y?.sessionFile,model:W.model??Y?.model,attemptedModels:W.attemptedModels??Y?.attemptedModels,modelAttempts:W.modelAttempts??Y?.modelAttempts}});return{...$,state:Z.state,activityState:void 0,lastUpdate:Q,endedAt:$.endedAt??Q,steps:X}}function u$($,J,Q){let Z=J.startedAt??Q,X=J.agents?.length?J.agents:["subagent"],W=J.chainStepCount,K=W!==void 0?X$(J.parallelGroups,X.length,W):[];return{runId:J.runId||O.basename($),...J.sessionId?{sessionId:J.sessionId}:{},mode:J.mode??"single",state:"running",pid:J.pid,startedAt:Z,lastUpdate:Q,currentStep:0,...W!==void 0?{chainStepCount:W}:{},...K.length?{parallelGroups:K}:{},steps:X.map((Y)=>({agent:Y,status:"running",startedAt:Z})),...J.sessionFile?{sessionFile:J.sessionFile}:{}}}function l$($,J,Q,Z){let X=$.runId||O.basename(J),W=typeof $.pid==="number"?$.pid:"unknown",K=Z??`Async runner process ${W} exited or disappeared before writing a result. Marked run failed by stale-run reconciliation.`,Y=h$(J),H=Y?`${K}
|
|
5
|
+
|
|
6
|
+
Runner stderr tail:
|
|
7
|
+
${Y}`:K,V=(($.steps?.length)?$.steps:[{agent:"subagent",status:"running"}]).map((G)=>G.status==="running"||G.status==="pending"?{...G,status:"failed",activityState:void 0,endedAt:G.endedAt??Q,durationMs:G.startedAt!==void 0&&G.durationMs===void 0?Math.max(0,Q-G.startedAt):G.durationMs,exitCode:G.exitCode??1,error:G.error??H}:G),A={...$,state:"failed",activityState:void 0,lastUpdate:Q,endedAt:Q,steps:V},M=V[$.currentStep??0]?.agent??V[0]?.agent??"subagent";return{status:A,message:H,result:{id:X,agent:M,mode:$.mode,success:!1,state:"failed",summary:H,results:V.map((G)=>({agent:G.agent,output:G.status==="complete"||G.status==="completed"?"":H,error:G.status==="complete"||G.status==="completed"?void 0:G.error??H,success:G.status==="complete"||G.status==="completed",model:G.model,attemptedModels:G.attemptedModels,modelAttempts:G.modelAttempts,sessionFile:G.sessionFile})),exitCode:1,timestamp:Q,durationMs:Math.max(0,Q-$.startedAt),asyncDir:J,sessionId:$.sessionId,sessionFile:$.sessionFile}}}function Y$($,J,Q,Z,X){let W=l$(J,$,Z,X);return N(Q,W.result),N(O.join($,"status.json"),W.status),c$(O.join($,"events.jsonl"),{type:"subagent.run.repaired_stale",ts:Z,runId:W.status.runId,pid:J.pid,resultPath:Q,message:W.message}),{status:W.status,repaired:!0,resultPath:Q,message:W.message}}function i$($,J=process.kill){try{return J($,0),"alive"}catch(Q){let Z=typeof Q==="object"&&Q!==null&&"code"in Q?Q.code:void 0;if(Z==="ESRCH")return"dead";if(Z==="EPERM")return"unknown";return"unknown"}}function i($,J={}){let Q=J.now?.()??Date.now(),Z=d$($),X=!Z&&J.startedRun?u$($,J.startedRun,Q):void 0,W=Z??X;if(!W)return{status:null,repaired:!1};let K=W.runId||O.basename($),Y=O.join(J.resultsDir??S,`${K}.json`);if(L.existsSync(Y)){let B=W.state==="running"||W.state==="queued"?o$(W,Y,Q):void 0;if(B)return N(O.join($,"status.json"),B),{status:B,repaired:!0,resultPath:Y,message:"Existing async result file was used to repair stale running status."};return{status:W,repaired:!1,resultPath:Y}}if(W.state!=="running"||typeof W.pid!=="number")return{status:Z??null,repaired:!1,resultPath:Y};if(!Z){let B=J.startedRun?.startedAt??W.startedAt;if(Q-B<(J.missingStatusGraceMs??1000))return{status:null,repaired:!1,resultPath:Y}}if(i$(W.pid,J.kill)!=="dead"){let B=J.staleAlivePidMs??86400000,V=W.lastUpdate??W.startedAt;if(Q-V<=B)return{status:Z??null,repaired:!1,resultPath:Y};let A=`Async runner process ${W.pid} still has a live PID, but status has not updated for ${Q-V}ms. Marked run failed by stale-run reconciliation because PID ownership cannot be verified.`;return Y$($,W,Y,Q,A)}return Y$($,W,Y,Q)}var ej=process.platform==="win32"?"SIGBREAK":"SIGUSR2";function r($,J){if($===void 0)return;if($.trim()==="")throw Error(`${J} must not be empty.`);if(z.isAbsolute($)||/[\\/]/.test($)||$.includes(".."))throw Error(`${J} must be an async run id or prefix, not a path.`);return $}function c($,J,Q){let Z=z.resolve($),X=z.resolve(J),W=z.relative(Z,X);if(W===""||!W.startsWith("..")&&!z.isAbsolute(W))return;throw Error(`${Q} must be inside ${Z}.`)}function B$($,J,Q=""){if(!q.existsSync($))return[];return q.readdirSync($).filter((Z)=>Z.startsWith(J)&&(!Q||Z.endsWith(Q))).map((Z)=>Q?Z.slice(0,-Q.length):Z).sort()}function s($,J){let Q=z.join($,`${J}.json`);return c($,Q,"Async result file"),q.existsSync(Q)?Q:null}function r$($,J,Q){let Z=r($,"id");if(!Z)return[];let X=z.resolve(J),W=z.resolve(Q);return[...new Set([...B$(X,Z),...B$(W,Z,".json")])].sort().map((Y)=>{let H=z.join(X,Y);return c(X,H,"Async run directory"),{id:Y,location:{asyncDir:q.existsSync(H)?H:null,resultPath:s(W,Y),resolvedId:Y}}})}function G$($,J,Q){let Z=z.resolve(J),X=z.resolve(Q),W=r($.id,"id")??r($.runId,"runId");if($.dir){let B=z.resolve($.dir);c(Z,B,"Async run directory");let V=W??z.basename(B);if(W&&W!==z.basename(B))throw Error(`Async run id '${W}' does not match directory '${z.basename(B)}'.`);return{asyncDir:B,resultPath:s(X,V),resolvedId:V}}if(!W)return{asyncDir:null,resultPath:null};let K=z.join(Z,W);c(Z,K,"Async run directory");let Y=s(X,W);if(q.existsSync(K)||Y)return{asyncDir:q.existsSync(K)?K:null,resultPath:Y,resolvedId:W};let H=r$(W,Z,X);if(H.length===0)return{asyncDir:null,resultPath:null,resolvedId:W};if(H.length>1)throw Error(`Ambiguous async run id prefix '${W}' matched: ${H.map((B)=>B.id).join(", ")}. Provide a longer id.`);return H[0].location}import{Type as j}from"typebox";function U$($){return V$($,[])}function V$($,J){if(!$||typeof $!=="object")return $;let Q=Array.isArray($)?[]:Object.create(Object.getPrototypeOf($));for(let Z of Reflect.ownKeys($)){let X=Object.getOwnPropertyDescriptor($,Z);if(!X)continue;if(Z==="description"&&!s$(J))continue;if("value"in X){let W=typeof Z==="string"?[...J,Z]:J;X.value=V$(X.value,W)}Object.defineProperty(Q,Z,X)}return Q}function s$($){return $.length===2&&$[0]==="properties"}var I=j.Unsafe({anyOf:[{type:"array",items:{type:"string"}},{type:"boolean"},{type:"string"}],description:"Skill name(s) to make available (comma-separated), array of strings, or boolean (false disables, true uses default)"}),d=j.Unsafe({anyOf:[{type:"string"},{type:"boolean"}],description:"Output filename/path (string), or false to disable file output"}),w=j.String({enum:["inline","file-only"],description:"Return saved output inline (default) or only a concise file reference. file-only requires output to be a path."}),p=j.Unsafe({anyOf:[{type:"array",items:{type:"string"}},{type:"boolean"}],description:"Files to read before running (array of filenames), or false to disable"}),n=j.Unsafe({type:"object",additionalProperties:!0,description:"JSON Schema object for strict structured output. Non-object roots are rejected."}),R=j.Unsafe({anyOf:[{type:"string",enum:["auto","none","attested","checked","verified","reviewed"]},{type:"boolean",enum:[!1]},{type:"object",additionalProperties:!0}],description:"Optional acceptance policy. Omitted means auto-inferred; verified requires configured runtime commands."}),a$=j.Object({maxTurns:j.Integer({minimum:1}),graceTurns:j.Optional(j.Integer({minimum:0}))},{additionalProperties:!1,description:"Optional assistant-turn budget. At maxTurns the child is asked to wrap up; after graceTurns additional assistant turns it is aborted and partial output is returned."}),t$=j.Unsafe({anyOf:[{type:"array",minItems:1,items:{type:"string",minLength:1}},{type:"string",enum:["*"]}]}),P=j.Object({soft:j.Optional(j.Integer({minimum:1})),hard:j.Integer({minimum:1}),block:j.Optional(t$)},{additionalProperties:!1,description:"Optional child tool-call budget. soft nudges the child; after hard, block tools (default read/grep/find/ls, or '*' for all tools) are blocked so the child can finalize."}),e$=j.Object({agent:j.String(),task:j.String(),cwd:j.Optional(j.String()),count:j.Optional(j.Integer({minimum:1,description:"Repeat this parallel task N times with the same settings."})),output:j.Optional(d),outputMode:j.Optional(w),reads:j.Optional(p),progress:j.Optional(j.Boolean({description:"Enable progress.md tracking for this task"})),model:j.Optional(j.String({description:"Override model for this task (e.g. 'google/gemini-3-pro')"})),skill:j.Optional(I),toolBudget:j.Optional(P),acceptance:j.Optional(R)}),$0=j.Object({agent:j.String(),task:j.Optional(j.String({description:"Task template with {task}, {previous}, {chain_dir} variables. Defaults to {previous}."})),phase:j.Optional(j.String({description:"Optional phase/group label for status and graph rendering."})),label:j.Optional(j.String({description:"Optional user-facing label for this parallel task."})),as:j.Optional(j.String({description:"Optional safe identifier used as {outputs.name} in later chain steps."})),outputSchema:j.Optional(n),cwd:j.Optional(j.String()),count:j.Optional(j.Integer({minimum:1,description:"Repeat this parallel task N times with the same settings."})),output:j.Optional(d),outputMode:j.Optional(w),reads:j.Optional(p),progress:j.Optional(j.Boolean({description:"Enable progress.md tracking in {chain_dir}"})),skill:j.Optional(I),model:j.Optional(j.String({description:"Override model for this task"})),toolBudget:j.Optional(P),acceptance:j.Optional(R)}),j0=j.Object({from:j.Object({output:j.String({description:"Prior named structured output to expand from."}),path:j.String({description:"JSON Pointer into the structured output, e.g. /items."})},{additionalProperties:!1}),item:j.Optional(j.String({description:"Template variable name for each item. Defaults to item."})),key:j.Optional(j.String({description:"JSON Pointer relative to each item for stable child ids."})),maxItems:j.Optional(j.Integer({minimum:0,description:"Required fanout bound unless configured globally."})),onEmpty:j.Optional(j.String({enum:["skip","fail"],description:"Empty input behavior. Defaults to skip."}))},{additionalProperties:!1}),J0=j.Object({agent:j.String(),task:j.Optional(j.String({description:"Task template with {item}, {item.path}, {task}, {previous}, {chain_dir}, and {outputs.name} variables."})),phase:j.Optional(j.String({description:"Optional phase/group label for status and graph rendering."})),label:j.Optional(j.String({description:"Optional user-facing label; item templates are supported."})),outputSchema:j.Optional(n),cwd:j.Optional(j.String()),output:j.Optional(d),outputMode:j.Optional(w),reads:j.Optional(p),progress:j.Optional(j.Boolean({description:"Enable progress.md tracking in {chain_dir}"})),skill:j.Optional(I),model:j.Optional(j.String({description:"Override model for this task"})),toolBudget:j.Optional(P),acceptance:j.Optional(R)},{additionalProperties:!1}),Z0=j.Object({as:j.String({description:"Safe output name for the ordered collected result array."}),outputSchema:j.Optional(n)},{additionalProperties:!1}),Q0=j.Object({agent:j.Optional(j.String({description:"Sequential step agent name"})),task:j.Optional(j.String({description:"Task template with variables: {task}=original request, {previous}=prior step's text response, {chain_dir}=shared folder, {outputs.name}=prior named output. Required for first step, defaults to '{previous}' for subsequent steps."})),phase:j.Optional(j.String({description:"Optional phase/group label for status and graph rendering."})),label:j.Optional(j.String({description:"Optional user-facing label for this chain step."})),as:j.Optional(j.String({description:"Optional safe identifier used as {outputs.name} in later chain steps."})),outputSchema:j.Optional(n),cwd:j.Optional(j.String()),output:j.Optional(d),outputMode:j.Optional(w),reads:j.Optional(p),progress:j.Optional(j.Boolean({description:"Enable progress.md tracking in {chain_dir}"})),skill:j.Optional(I),model:j.Optional(j.String({description:"Override model for this step"})),toolBudget:j.Optional(P),acceptance:j.Optional(R),parallel:j.Optional(j.Unsafe({anyOf:[j.Array($0,{minItems:1,description:"Tasks to run in parallel"}),J0],description:"Static parallel tasks array, or a single dynamic fanout child template when expand/collect are present."})),expand:j.Optional(j0),collect:j.Optional(Z0),concurrency:j.Optional(j.Number({description:"Max concurrent tasks (default: 4)"})),failFast:j.Optional(j.Boolean({description:"Stop on first failure (default: false)"})),worktree:j.Optional(j.Boolean({description:"Create isolated git worktrees for each parallel task."}))},{description:"Chain step: use {agent, task?, ...} for sequential, {parallel: [...]} for static concurrent execution, or {expand, parallel: {...}, collect} for dynamic fanout.",additionalProperties:!1}),W0=j.Object({enabled:j.Optional(j.Boolean({description:"Enable/disable subagent control attention tracking for this run"})),needsAttentionAfterMs:j.Optional(j.Integer({minimum:1,description:"No-observed-activity window before a run needs attention"})),activeNoticeAfterMs:j.Optional(j.Integer({minimum:1,description:"Active-long-running notice threshold by elapsed ms (default: 240000)"})),activeNoticeAfterTurns:j.Optional(j.Integer({minimum:1,description:"Optional active-long-running notice threshold by assistant turns (disabled by default)"})),activeNoticeAfterTokens:j.Optional(j.Integer({minimum:1,description:"Optional active-long-running notice threshold by total tokens (disabled by default)"})),failedToolAttemptsBeforeAttention:j.Optional(j.Integer({minimum:1,description:"Consecutive mutating-tool failures before escalating to needs_attention (default: 3)"})),notifyOn:j.Optional(j.Array(j.String({enum:["active_long_running","needs_attention"]}),{description:"Control event types that should notify the parent/orchestrator. Defaults to active_long_running and needs_attention."})),notifyChannels:j.Optional(j.Array(j.String({enum:["event","async","intercom"]}),{description:"Notification channels to use when available. Defaults to event, async, and intercom."}))}),X0=j.Object({agent:j.Optional(j.String({description:"Agent name (SINGLE mode) or target for management get/update/delete"})),task:j.Optional(j.String({description:"Task (SINGLE mode, optional for self-contained agents)"})),action:j.Optional(j.String({description:"Management/control action only. Must be omitted for execution mode (single, parallel, or chain)."})),id:j.Optional(j.String({description:"Run id or prefix for action='status', action='interrupt', action='resume', action='steer', or action='append-step'."})),runId:j.Optional(j.String({description:"Target run ID for action='interrupt', action='resume', action='steer', or action='append-step'. Defaults to the most recently active controllable run for interrupt. Prefer id for new calls."})),dir:j.Optional(j.String({description:"Async run directory for action='status', action='resume', or action='steer'."})),index:j.Optional(j.Integer({minimum:0,description:"Zero-based child index for actions that target a specific child or transcript."})),view:j.Optional(j.String({enum:["fleet","transcript"],description:"Optional status view. Use view='fleet' for a read-only active foreground/async fleet surface, or view='transcript' with id/dir (and optional index) to tail a run transcript."})),lines:j.Optional(j.Integer({minimum:1,maximum:500,description:"Maximum transcript lines for action='status', view='transcript'. Defaults to 80."})),message:j.Optional(j.String({description:"Follow-up message for action='resume' or non-terminal guidance for action='steer'. Use index to choose a child from multi-child runs."})),schedule:j.Optional(j.String({description:"Explicit one-shot schedule for action='schedule'. Only honored when scheduledRuns.enabled is true. Use '+10m' or a future ISO timestamp with timezone; scheduled runs always launch async with fresh context."})),scheduleName:j.Optional(j.String({description:"Optional display name for action='schedule'."})),chainName:j.Optional(j.String({description:"Chain name for get/update/delete management actions"})),config:j.Optional(j.Unsafe({anyOf:[{type:"object",additionalProperties:!0},{type:"string"}],description:"Agent/chain config for create/update. Object or JSON string; presence of steps creates a chain."})),tasks:j.Optional(j.Array(e$,{description:"PARALLEL mode: [{agent, task, count?, output?, outputMode?, reads?, progress?}, ...]"})),concurrency:j.Optional(j.Integer({minimum:1,description:"Top-level PARALLEL mode only: max concurrent tasks. Defaults to config.parallel.concurrency or 4."})),worktree:j.Optional(j.Boolean({description:"Create isolated git worktrees for parallel tasks; requires clean git state."})),chain:j.Optional(j.Array(Q0,{description:"CHAIN mode: sequential steps; each result becomes {previous}. append-step takes one tail step and may use {chain_dir}/{outputs.name}."})),context:j.Optional(j.String({enum:["fresh","fork"],description:"'fresh' or 'fork' to branch from parent session. Explicit context overrides every child in the invocation. If omitted, each requested agent uses its own defaultContext; agents without defaultContext: 'fork' run fresh."})),chainDir:j.Optional(j.String({description:"Persistent chain artifact directory; defaults to user-scoped temp storage."})),async:j.Optional(j.Boolean({description:"Run in background (default: false, or per config)"})),timeoutMs:j.Optional(j.Integer({minimum:1,description:"Optional run-level timeout in ms for foreground and async/background runs. Alias of maxRuntimeMs."})),maxRuntimeMs:j.Optional(j.Integer({minimum:1,description:"Alias of timeoutMs for optional run-level timeout in foreground and async/background runs."})),turnBudget:j.Optional(a$),toolBudget:j.Optional(P),agentScope:j.Optional(j.String({description:"Agent discovery scope: 'user', 'project', or 'both' (default: 'both'; project wins on name collisions)"})),cwd:j.Optional(j.String()),artifacts:j.Optional(j.Boolean({description:"Write debug artifacts (default: true)"})),includeProgress:j.Optional(j.Boolean({description:"Include full progress in result (default: false)"})),share:j.Optional(j.Boolean({description:"Upload session to GitHub Gist for sharing (default: false)"})),sessionDir:j.Optional(j.String({description:"Directory to store session logs (default: temp; enables sessions even if share=false)"})),clarify:j.Optional(j.Boolean({description:"Show TUI to preview/edit before execution. Explicit clarify: true keeps the run foreground for the clarify UI; omitted clarify can still run in the background when async: true is set."})),control:j.Optional(W0),output:j.Optional(j.Unsafe({anyOf:[{type:"string"},{type:"boolean"}],description:"Output file for single agent (string), or false to disable. Relative paths resolve against cwd."})),outputMode:j.Optional(w),skill:j.Optional(I),model:j.Optional(j.String({description:"Override model for single agent (e.g. 'anthropic/claude-sonnet-4')"})),acceptance:j.Optional(R)}),z$=U$(X0),K0=j.Object({id:j.Optional(j.String({description:"Run id or prefix to wait for one specific run. Omit to wait across every active async run started in this session."})),all:j.Optional(j.Boolean({description:"Wait for ALL active runs to finish. Default false: return as soon as the first run finishes, so a fleet manager can spawn a replacement and wait again. Ignored when id targets a single run."})),timeoutMs:j.Optional(j.Integer({minimum:1,description:"Give up waiting after this many milliseconds (the runs keep going regardless). Defaults to 1800000 (30 minutes)."}))}),J1=U$(K0);var v=1,F$="subagents:rpc:v1:request",C$="subagents:rpc:v1:ready",A$="subagents:rpc:v1:reply:",e=["ping","status","spawn","interrupt","stop"];class U extends Error{code;constructor($,J){super(J);this.name="SubagentRpcError",this.code=$}}var L$=Y0(z$);function M$($){return`${A$}${$}`}function g($){return Boolean($)&&typeof $==="object"&&!Array.isArray($)}function H0($){if(typeof $!=="string"||$.trim().length===0||/[\r\n]/.test($))throw new U("invalid_request","RPC requestId must be a non-empty string without newlines.");return $}function f$($,J){if($===void 0)return{};if(!g($))throw new U("invalid_params",`RPC ${J} params must be an object.`);return $}function q$($,J){if(L$.Check($))return;let Q=[...L$.Errors($)].slice(0,4).map((Z)=>Z.message);throw new U("invalid_params",`${J}: ${Q.join("; ")||"invalid subagent parameters"}`)}function _$($){return $.content.filter((J)=>J.type==="text").map((J)=>J.text).join(`
|
|
8
|
+
`)}function B0($){return{text:_$($),...$.details?{details:$.details}:{},...$.isError?{isError:!0}:{}}}function G0($){if(!$.isError)return;throw new U("execution_failed",_$($)||"Subagent RPC execution failed.")}function t($,J){let Q=f$($,J),Z={};if(Q.id!==void 0)Z.id=Q.id;if(Q.runId!==void 0)Z.runId=Q.runId;if(Q.dir!==void 0)Z.dir=Q.dir;if(Q.index!==void 0)Z.index=Q.index;return Z}function U0($){if(!$)return{};return{cwd:$.cwd,sessionId:$.sessionManager.getSessionId()??void 0,sessionFile:$.sessionManager.getSessionFile()??null}}function T$($){return{version:v,methods:[...e],capabilities:{status:!0,asyncSpawn:!0,interrupt:!0,stop:!0},events:{ready:C$,request:F$,replyPrefix:A$},session:U0($)}}async function a($,J,Q,Z,X){q$(X,`RPC ${Z} params`);let W=new AbortController,K=await $.execute(`rpc-${Z}-${Q}`,X,W.signal,void 0,J);return G0(K),B0(K)}function V0($){let J=f$($,"spawn");if(J.action!==void 0)throw new U("invalid_params","RPC spawn does not accept management/control actions. Use status or interrupt RPC methods instead.");if(J.async===!1)throw new U("invalid_params","RPC spawn only supports detached async launches; omit async or set async: true.");if(J.clarify===!0)throw new U("invalid_params","RPC spawn cannot open the clarify UI; omit clarify or set clarify: false.");return{...J,async:!0,clarify:!1}}function z0($,J,Q){let Z=t($,"stop");q$({action:"status",...Z},"RPC stop target params");let X=J.asyncDirRoot??h,W=J.resultsDir??S,K;try{K=G$(Z,X,W)}catch(M){throw new U("invalid_params",M instanceof Error?M.message:String(M))}if(!K.asyncDir)throw new U("not_found","Async run not found or already completed; stop requires a live async run directory.");let Y=Q.sessionManager.getSessionId(),H=J$(K.asyncDir),B=H?.runId??K.resolvedId??O$.basename(K.asyncDir);if(!H)throw new U("not_found",`Status file not found for async run '${B}'.`);if(!Y||H.sessionId!==Y)throw new U("not_found",`Async run '${B}' was not found in the active session.`);let V;try{V=i(K.asyncDir,{resultsDir:W,kill:J.kill,now:J.now}).status}catch(M){throw new U("execution_failed",M instanceof Error?M.message:String(M))}let A=V?.runId??B;if(!V)throw new U("not_found",`Status file not found for async run '${A}'.`);if(V.sessionId!==Y)throw new U("not_found",`Async run '${A}' was not found in the active session.`);if(V.state!=="running")throw new U("invalid_state",`Async run ${A} is ${V.state}; stop only supports running async runs.`);try{W$({asyncDir:K.asyncDir,pid:V.pid,kill:J.kill,now:J.now,source:"rpc-stop"})}catch(M){throw new U("execution_failed",M instanceof Error?M.message:String(M))}return{runId:A,asyncDir:K.asyncDir,previousState:V.state,state:"stopping",message:`Stop requested for async run ${A}.`}}async function L0($,J){let Q=J.getContext();if($.method==="ping")return T$(Q);if(!Q)throw new U("no_active_session","No active extension context for subagent RPC.");if($.method==="spawn")return a(J,Q,$.requestId,$.method,V0($.params));if($.method==="status")return a(J,Q,$.requestId,$.method,{action:"status",...t($.params,"status")});if($.method==="interrupt")return a(J,Q,$.requestId,$.method,{action:"interrupt",...t($.params,"interrupt")});if($.method==="stop")return z0($.params,J,Q);throw new U("unsupported_method",`Unsupported subagent RPC method: ${String($.method)}`)}function M0($){if(!g($))throw new U("invalid_request","Subagent RPC request must be an object.");let J=H0($.requestId);if($.version!==v)throw new U("unsupported_version",`Unsupported subagent RPC version: ${String($.version)}.`);if(typeof $.method!=="string"||!e.includes($.method))throw new U("unsupported_method",`Unsupported subagent RPC method: ${String($.method)}.`);return{version:v,requestId:J,method:$.method,...$.params!==void 0?{params:$.params}:{},...g($.source)?{source:$.source}:{}}}function O0($){if(!g($))return"unknown";let J=$.requestId;return typeof J==="string"&&J.trim().length>0&&!/[\r\n]/.test(J)?J:"unknown"}function F0($,J){let Q=O0($),Z=g($)&&typeof $.method==="string"&&e.includes($.method)?$.method:void 0,X=J instanceof U?J:new U("execution_failed",J instanceof Error?J.message:String(J));return{version:v,requestId:Q,...Z?{method:Z}:{},success:!1,error:{code:X.code,message:X.message}}}function G1($){let J=$.events.on(F$,async(Q)=>{let Z;try{Z=M0(Q);let X=await L0(Z,$);$.events.emit(M$(Z.requestId),{version:v,requestId:Z.requestId,method:Z.method,success:!0,data:X})}catch(X){let W=F0(Z??Q,X);$.events.emit(M$(W.requestId),W)}});return{emitReady:(Q)=>{$.events.emit(C$,T$(Q??$.getContext()))},dispose:()=>{if(typeof J==="function")J()}}}export{M$ as subagentRpcReplyEvent,G1 as registerSubagentRpcBridge,F$ as SUBAGENT_RPC_REQUEST_EVENT,A$ as SUBAGENT_RPC_REPLY_EVENT_PREFIX,C$ as SUBAGENT_RPC_READY_EVENT,v as SUBAGENT_RPC_PROTOCOL_VERSION,e as SUBAGENT_RPC_METHODS};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Type as f}from"typebox";function V(q){return X(q,[])}function X(q,R){if(!q||typeof q!=="object")return q;let U=Array.isArray(q)?[]:Object.create(Object.getPrototypeOf(q));for(let w of Reflect.ownKeys(q)){let z=Object.getOwnPropertyDescriptor(q,w);if(!z)continue;if(w==="description"&&!Z(R))continue;if("value"in z){let Y=typeof w==="string"?[...R,w]:R;z.value=X(z.value,Y)}Object.defineProperty(U,w,z)}return U}function Z(q){return q.length===2&&q[0]==="properties"}var E=f.Unsafe({anyOf:[{type:"array",items:{type:"string"}},{type:"boolean"},{type:"string"}],description:"Skill name(s) to make available (comma-separated), array of strings, or boolean (false disables, true uses default)"}),K=f.Unsafe({anyOf:[{type:"string"},{type:"boolean"}],description:"Output filename/path (string), or false to disable file output"}),F=f.String({enum:["inline","file-only"],description:"Return saved output inline (default) or only a concise file reference. file-only requires output to be a path."}),M=f.Unsafe({anyOf:[{type:"array",items:{type:"string"}},{type:"boolean"}],description:"Files to read before running (array of filenames), or false to disable"}),Q=f.Unsafe({type:"object",additionalProperties:!0,description:"JSON Schema object for strict structured output. Non-object roots are rejected."}),G=f.Unsafe({anyOf:[{type:"string",enum:["auto","none","attested","checked","verified","reviewed"]},{type:"boolean",enum:[!1]},{type:"object",additionalProperties:!0}],description:"Optional acceptance policy. Omitted means auto-inferred; verified requires configured runtime commands."}),_=f.Object({maxTurns:f.Integer({minimum:1}),graceTurns:f.Optional(f.Integer({minimum:0}))},{additionalProperties:!1,description:"Optional assistant-turn budget. At maxTurns the child is asked to wrap up; after graceTurns additional assistant turns it is aborted and partial output is returned."}),$=f.Unsafe({anyOf:[{type:"array",minItems:1,items:{type:"string",minLength:1}},{type:"string",enum:["*"]}]}),H=f.Object({soft:f.Optional(f.Integer({minimum:1})),hard:f.Integer({minimum:1}),block:f.Optional($)},{additionalProperties:!1,description:"Optional child tool-call budget. soft nudges the child; after hard, block tools (default read/grep/find/ls, or '*' for all tools) are blocked so the child can finalize."}),g=f.Object({agent:f.String(),task:f.String(),cwd:f.Optional(f.String()),count:f.Optional(f.Integer({minimum:1,description:"Repeat this parallel task N times with the same settings."})),output:f.Optional(K),outputMode:f.Optional(F),reads:f.Optional(M),progress:f.Optional(f.Boolean({description:"Enable progress.md tracking for this task"})),model:f.Optional(f.String({description:"Override model for this task (e.g. 'google/gemini-3-pro')"})),skill:f.Optional(E),toolBudget:f.Optional(H),acceptance:f.Optional(G)}),x=f.Object({agent:f.String(),task:f.Optional(f.String({description:"Task template with {task}, {previous}, {chain_dir} variables. Defaults to {previous}."})),phase:f.Optional(f.String({description:"Optional phase/group label for status and graph rendering."})),label:f.Optional(f.String({description:"Optional user-facing label for this parallel task."})),as:f.Optional(f.String({description:"Optional safe identifier used as {outputs.name} in later chain steps."})),outputSchema:f.Optional(Q),cwd:f.Optional(f.String()),count:f.Optional(f.Integer({minimum:1,description:"Repeat this parallel task N times with the same settings."})),output:f.Optional(K),outputMode:f.Optional(F),reads:f.Optional(M),progress:f.Optional(f.Boolean({description:"Enable progress.md tracking in {chain_dir}"})),skill:f.Optional(E),model:f.Optional(f.String({description:"Override model for this task"})),toolBudget:f.Optional(H),acceptance:f.Optional(G)}),C=f.Object({from:f.Object({output:f.String({description:"Prior named structured output to expand from."}),path:f.String({description:"JSON Pointer into the structured output, e.g. /items."})},{additionalProperties:!1}),item:f.Optional(f.String({description:"Template variable name for each item. Defaults to item."})),key:f.Optional(f.String({description:"JSON Pointer relative to each item for stable child ids."})),maxItems:f.Optional(f.Integer({minimum:0,description:"Required fanout bound unless configured globally."})),onEmpty:f.Optional(f.String({enum:["skip","fail"],description:"Empty input behavior. Defaults to skip."}))},{additionalProperties:!1}),I=f.Object({agent:f.String(),task:f.Optional(f.String({description:"Task template with {item}, {item.path}, {task}, {previous}, {chain_dir}, and {outputs.name} variables."})),phase:f.Optional(f.String({description:"Optional phase/group label for status and graph rendering."})),label:f.Optional(f.String({description:"Optional user-facing label; item templates are supported."})),outputSchema:f.Optional(Q),cwd:f.Optional(f.String()),output:f.Optional(K),outputMode:f.Optional(F),reads:f.Optional(M),progress:f.Optional(f.Boolean({description:"Enable progress.md tracking in {chain_dir}"})),skill:f.Optional(E),model:f.Optional(f.String({description:"Override model for this task"})),toolBudget:f.Optional(H),acceptance:f.Optional(G)},{additionalProperties:!1}),W=f.Object({as:f.String({description:"Safe output name for the ordered collected result array."}),outputSchema:f.Optional(Q)},{additionalProperties:!1}),B=f.Object({agent:f.Optional(f.String({description:"Sequential step agent name"})),task:f.Optional(f.String({description:"Task template with variables: {task}=original request, {previous}=prior step's text response, {chain_dir}=shared folder, {outputs.name}=prior named output. Required for first step, defaults to '{previous}' for subsequent steps."})),phase:f.Optional(f.String({description:"Optional phase/group label for status and graph rendering."})),label:f.Optional(f.String({description:"Optional user-facing label for this chain step."})),as:f.Optional(f.String({description:"Optional safe identifier used as {outputs.name} in later chain steps."})),outputSchema:f.Optional(Q),cwd:f.Optional(f.String()),output:f.Optional(K),outputMode:f.Optional(F),reads:f.Optional(M),progress:f.Optional(f.Boolean({description:"Enable progress.md tracking in {chain_dir}"})),skill:f.Optional(E),model:f.Optional(f.String({description:"Override model for this step"})),toolBudget:f.Optional(H),acceptance:f.Optional(G),parallel:f.Optional(f.Unsafe({anyOf:[f.Array(x,{minItems:1,description:"Tasks to run in parallel"}),I],description:"Static parallel tasks array, or a single dynamic fanout child template when expand/collect are present."})),expand:f.Optional(C),collect:f.Optional(W),concurrency:f.Optional(f.Number({description:"Max concurrent tasks (default: 4)"})),failFast:f.Optional(f.Boolean({description:"Stop on first failure (default: false)"})),worktree:f.Optional(f.Boolean({description:"Create isolated git worktrees for each parallel task."}))},{description:"Chain step: use {agent, task?, ...} for sequential, {parallel: [...]} for static concurrent execution, or {expand, parallel: {...}, collect} for dynamic fanout.",additionalProperties:!1}),L=f.Object({enabled:f.Optional(f.Boolean({description:"Enable/disable subagent control attention tracking for this run"})),needsAttentionAfterMs:f.Optional(f.Integer({minimum:1,description:"No-observed-activity window before a run needs attention"})),activeNoticeAfterMs:f.Optional(f.Integer({minimum:1,description:"Active-long-running notice threshold by elapsed ms (default: 240000)"})),activeNoticeAfterTurns:f.Optional(f.Integer({minimum:1,description:"Optional active-long-running notice threshold by assistant turns (disabled by default)"})),activeNoticeAfterTokens:f.Optional(f.Integer({minimum:1,description:"Optional active-long-running notice threshold by total tokens (disabled by default)"})),failedToolAttemptsBeforeAttention:f.Optional(f.Integer({minimum:1,description:"Consecutive mutating-tool failures before escalating to needs_attention (default: 3)"})),notifyOn:f.Optional(f.Array(f.String({enum:["active_long_running","needs_attention"]}),{description:"Control event types that should notify the parent/orchestrator. Defaults to active_long_running and needs_attention."})),notifyChannels:f.Optional(f.Array(f.String({enum:["event","async","intercom"]}),{description:"Notification channels to use when available. Defaults to event, async, and intercom."}))}),N=f.Object({agent:f.Optional(f.String({description:"Agent name (SINGLE mode) or target for management get/update/delete"})),task:f.Optional(f.String({description:"Task (SINGLE mode, optional for self-contained agents)"})),action:f.Optional(f.String({description:"Management/control action only. Must be omitted for execution mode (single, parallel, or chain)."})),id:f.Optional(f.String({description:"Run id or prefix for action='status', action='interrupt', action='resume', action='steer', or action='append-step'."})),runId:f.Optional(f.String({description:"Target run ID for action='interrupt', action='resume', action='steer', or action='append-step'. Defaults to the most recently active controllable run for interrupt. Prefer id for new calls."})),dir:f.Optional(f.String({description:"Async run directory for action='status', action='resume', or action='steer'."})),index:f.Optional(f.Integer({minimum:0,description:"Zero-based child index for actions that target a specific child or transcript."})),view:f.Optional(f.String({enum:["fleet","transcript"],description:"Optional status view. Use view='fleet' for a read-only active foreground/async fleet surface, or view='transcript' with id/dir (and optional index) to tail a run transcript."})),lines:f.Optional(f.Integer({minimum:1,maximum:500,description:"Maximum transcript lines for action='status', view='transcript'. Defaults to 80."})),message:f.Optional(f.String({description:"Follow-up message for action='resume' or non-terminal guidance for action='steer'. Use index to choose a child from multi-child runs."})),schedule:f.Optional(f.String({description:"Explicit one-shot schedule for action='schedule'. Only honored when scheduledRuns.enabled is true. Use '+10m' or a future ISO timestamp with timezone; scheduled runs always launch async with fresh context."})),scheduleName:f.Optional(f.String({description:"Optional display name for action='schedule'."})),chainName:f.Optional(f.String({description:"Chain name for get/update/delete management actions"})),config:f.Optional(f.Unsafe({anyOf:[{type:"object",additionalProperties:!0},{type:"string"}],description:"Agent/chain config for create/update. Object or JSON string; presence of steps creates a chain."})),tasks:f.Optional(f.Array(g,{description:"PARALLEL mode: [{agent, task, count?, output?, outputMode?, reads?, progress?}, ...]"})),concurrency:f.Optional(f.Integer({minimum:1,description:"Top-level PARALLEL mode only: max concurrent tasks. Defaults to config.parallel.concurrency or 4."})),worktree:f.Optional(f.Boolean({description:"Create isolated git worktrees for parallel tasks; requires clean git state."})),chain:f.Optional(f.Array(B,{description:"CHAIN mode: sequential steps; each result becomes {previous}. append-step takes one tail step and may use {chain_dir}/{outputs.name}."})),context:f.Optional(f.String({enum:["fresh","fork"],description:"'fresh' or 'fork' to branch from parent session. Explicit context overrides every child in the invocation. If omitted, each requested agent uses its own defaultContext; agents without defaultContext: 'fork' run fresh."})),chainDir:f.Optional(f.String({description:"Persistent chain artifact directory; defaults to user-scoped temp storage."})),async:f.Optional(f.Boolean({description:"Run in background (default: false, or per config)"})),timeoutMs:f.Optional(f.Integer({minimum:1,description:"Optional run-level timeout in ms for foreground and async/background runs. Alias of maxRuntimeMs."})),maxRuntimeMs:f.Optional(f.Integer({minimum:1,description:"Alias of timeoutMs for optional run-level timeout in foreground and async/background runs."})),turnBudget:f.Optional(_),toolBudget:f.Optional(H),agentScope:f.Optional(f.String({description:"Agent discovery scope: 'user', 'project', or 'both' (default: 'both'; project wins on name collisions)"})),cwd:f.Optional(f.String()),artifacts:f.Optional(f.Boolean({description:"Write debug artifacts (default: true)"})),includeProgress:f.Optional(f.Boolean({description:"Include full progress in result (default: false)"})),share:f.Optional(f.Boolean({description:"Upload session to GitHub Gist for sharing (default: false)"})),sessionDir:f.Optional(f.String({description:"Directory to store session logs (default: temp; enables sessions even if share=false)"})),clarify:f.Optional(f.Boolean({description:"Show TUI to preview/edit before execution. Explicit clarify: true keeps the run foreground for the clarify UI; omitted clarify can still run in the background when async: true is set."})),control:f.Optional(L),output:f.Optional(f.Unsafe({anyOf:[{type:"string"},{type:"boolean"}],description:"Output file for single agent (string), or false to disable. Relative paths resolve against cwd."})),outputMode:f.Optional(F),skill:f.Optional(E),model:f.Optional(f.String({description:"Override model for single agent (e.g. 'anthropic/claude-sonnet-4')"})),acceptance:f.Optional(G)}),j=V(N),T=f.Object({id:f.Optional(f.String({description:"Run id or prefix to wait for one specific run. Omit to wait across every active async run started in this session."})),all:f.Optional(f.Boolean({description:"Wait for ALL active runs to finish. Default false: return as soon as the first run finishes, so a fleet manager can spawn a replacement and wait again. Ignored when id targets a single run."})),timeoutMs:f.Optional(f.Integer({minimum:1,description:"Give up waiting after this many milliseconds (the runs keep going regardless). Defaults to 1800000 (30 minutes)."}))}),D=V(T);export{D as WaitParams,j as SubagentParams};
|
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
import * as fs from "node:
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import type { ExtensionConfig, ToolDescriptionMode } from "../shared/types.ts";
|
|
4
|
-
import { getAgentDir, getProjectConfigDir } from "../shared/utils.ts";
|
|
5
|
-
|
|
6
|
-
const CUSTOM_TOOL_DESCRIPTION_FILE = "subagent-tool-description.md";
|
|
7
|
-
const CUSTOM_TOOL_DESCRIPTION_MAX_BYTES = 50 * 1024;
|
|
8
|
-
|
|
9
|
-
export const SUBAGENT_SAFETY_GUIDANCE = `SAFETY-CRITICAL SUBAGENT GUIDANCE:
|
|
1
|
+
import*as A from"node:fs";import*as _ from"node:path";import*as W from"node:fs";import*as U from"node:os";import*as q from"node:path";import*as V from"node:os";import*as K from"node:path";function L(Q){return Q.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function w(Q){let Z=Q?.env??process.env,J=Q&&Object.hasOwn(Q,"getuid")?Q.getuid:process.getuid?.bind(process);if(typeof J==="function")return`uid-${J()}`;for(let Y of["USERNAME","USER","LOGNAME"]){let G=Z[Y];if(G)return`user-${L(G)}`}let $=Q&&Object.hasOwn(Q,"userInfo")?Q.userInfo:V.userInfo;try{let Y=$?.().username;if(Y)return`user-${L(Y)}`}catch{}let X=Z.USERPROFILE??Z.HOME;if(X)return`home-${L(X)}`;let R=Q&&Object.hasOwn(Q,"homedir")?Q.homedir:V.homedir;try{let Y=R?.();if(Y)return`home-${L(Y)}`}catch{}return"shared"}var M=K.join(V.tmpdir(),`dm-subagents-${w()}`),p=K.join(M,"async-subagent-results"),n=K.join(M,"async-subagent-runs"),x=K.join(M,"chain-runs"),o=K.join(M,"artifacts");var y=".dm",S="@duckmind/dm-coding-agent",D="DM_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT";function I(Q){return typeof Q==="string"&&Q.trim()?Q:void 0}function T(Q){if(!Q)return;try{let Z=JSON.parse(W.readFileSync(q.join(Q,"package.json"),"utf-8"));if(Z.name!==S)return;return I(Z.piConfig?.configDir)}catch{return}}function v(Q=process.argv[1],Z=process.env[D]){let J=T(Z);if(J)return J;if(!Q)return;try{let $=q.dirname(W.realpathSync(Q));while($!==q.dirname($)){let X=T($);if(X)return X;$=q.dirname($)}}catch{}return}function P(Q,Z,J){return(Q&&typeof Q==="object"?I(Q.CONFIG_DIR_NAME):void 0)??v(Z,J)??y}function C(){return P()}function H(Q){return q.join(Q,C())}function z(){let Q=process.env.DM_CODING_AGENT_DIR;if(Q==="~")return U.homedir();if(Q?.startsWith("~/"))return q.join(U.homedir(),Q.slice(2));return Q||q.join(U.homedir(),C(),"agent")}var F="subagent-tool-description.md",b=51200,j=`SAFETY-CRITICAL SUBAGENT GUIDANCE:
|
|
10
2
|
• Use { action: "list" } before execution and only run executable/non-disabled agents or chains.
|
|
11
3
|
• Keep execution and management separate: omit action for SINGLE/PARALLEL/CHAIN execution; use action only for list/get/models/create/update/delete/status/interrupt/resume/append-step/doctor.
|
|
12
4
|
• Async/background runs: launch with async:true only when work can proceed independently. Do not sleep or poll status just to wait; if this turn must block, use the wait tool. Otherwise continue useful work or respond and let completion notifications arrive.
|
|
13
5
|
• Child-safety boundary: ordinary child subagents are not orchestrators and must not run subagents. Only explicitly configured fanout children may use the child-safe subagent tool, still bounded by depth/session limits.
|
|
14
6
|
• Writing/review safety: keep one writer for the same cwd/worktree. Use fresh-context read-only reviewers/validators for independent review, then have the parent synthesize and apply fixes as the sole writer unless an isolated worktree was intentionally requested.
|
|
15
|
-
• Artifacts/status essentials: chain outputs live under {chain_dir}; async runs expose asyncId/asyncDir with status.json, events.jsonl, output logs, and status via { action: "status", id }. Include output paths and residual risks when reporting results
|
|
16
|
-
|
|
17
|
-
export const FULL_SUBAGENT_TOOL_DESCRIPTION = `Delegate to subagents or manage agent definitions.
|
|
7
|
+
• Artifacts/status essentials: chain outputs live under {chain_dir}; async runs expose asyncId/asyncDir with status.json, events.jsonl, output logs, and status via { action: "status", id }. Include output paths and residual risks when reporting results.`,E=`Delegate to subagents or manage agent definitions.
|
|
18
8
|
|
|
19
9
|
EXECUTION (use exactly ONE mode):
|
|
20
10
|
• Before executing, use { action: "list" } to inspect configured agents/chains. Only execute agents listed as executable/non-disabled.
|
|
@@ -63,9 +53,7 @@ SCHEDULE (opt-in; requires { "scheduledRuns": { "enabled": true } } in config.js
|
|
|
63
53
|
DIAGNOSTICS:
|
|
64
54
|
• { action: "doctor" } - read-only report for runtime paths, discovery, sessions, and intercom
|
|
65
55
|
|
|
66
|
-
${
|
|
67
|
-
|
|
68
|
-
export const COMPACT_SUBAGENT_TOOL_DESCRIPTION = `Delegate to subagents or manage definitions. Use exactly one mode per call.
|
|
56
|
+
${j}`,O=`Delegate to subagents or manage definitions. Use exactly one mode per call.
|
|
69
57
|
|
|
70
58
|
EXECUTE:
|
|
71
59
|
• Before execution, call { action: "list" }; run only executable/non-disabled configured agents/chains.
|
|
@@ -85,116 +73,8 @@ ASYNC / WAIT:
|
|
|
85
73
|
|
|
86
74
|
SAFETY:
|
|
87
75
|
• Ordinary child subagents are not orchestrators and must not run subagents. Only explicit fanout children may use child-safe subagent, still bounded by depth/session limits.
|
|
88
|
-
• Keep one writer per cwd/worktree. Use fresh read-only review/validation fanout, then synthesize and apply fixes from the parent unless isolated worktrees were intentionally requested.`;
|
|
89
|
-
|
|
90
|
-
function isToolDescriptionMode(value: unknown): value is ToolDescriptionMode {
|
|
91
|
-
return value === "full" || value === "compact" || value === "custom";
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function warn(options: ToolDescriptionOptions | undefined, message: string): void {
|
|
95
|
-
(options?.warn ?? console.warn)(`[dm-subagents] ${message}`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export interface ToolDescriptionOptions {
|
|
99
|
-
cwd?: string;
|
|
100
|
-
agentDir?: string;
|
|
101
|
-
warn?: (message: string) => void;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export function resolveToolDescriptionMode(config: Pick<ExtensionConfig, "toolDescriptionMode">, options?: ToolDescriptionOptions): ToolDescriptionMode {
|
|
105
|
-
const mode = config.toolDescriptionMode;
|
|
106
|
-
if (mode === undefined) return "full";
|
|
107
|
-
if (isToolDescriptionMode(mode)) return mode;
|
|
108
|
-
warn(options, `Ignoring invalid toolDescriptionMode ${JSON.stringify(mode)}; expected "full", "compact", or "custom".`);
|
|
109
|
-
return "full";
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function customDescriptionPaths(options?: ToolDescriptionOptions): string[] {
|
|
113
|
-
const cwd = options?.cwd ?? process.cwd();
|
|
114
|
-
const agentDir = options?.agentDir ?? getAgentDir();
|
|
115
|
-
return [
|
|
116
|
-
path.join(getProjectConfigDir(cwd), CUSTOM_TOOL_DESCRIPTION_FILE),
|
|
117
|
-
path.join(agentDir, CUSTOM_TOOL_DESCRIPTION_FILE),
|
|
118
|
-
];
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function renderCustomTemplate(template: string, options?: ToolDescriptionOptions): string {
|
|
122
|
-
const cwd = options?.cwd ?? process.cwd();
|
|
123
|
-
const agentDir = options?.agentDir ?? getAgentDir();
|
|
124
|
-
const projectConfigDir = getProjectConfigDir(cwd);
|
|
125
|
-
const variables: Record<string, () => string> = {
|
|
126
|
-
fullDescription: () => FULL_SUBAGENT_TOOL_DESCRIPTION,
|
|
127
|
-
full: () => FULL_SUBAGENT_TOOL_DESCRIPTION,
|
|
128
|
-
compactDescription: () => COMPACT_SUBAGENT_TOOL_DESCRIPTION,
|
|
129
|
-
compact: () => COMPACT_SUBAGENT_TOOL_DESCRIPTION,
|
|
130
|
-
safetyGuidance: () => SUBAGENT_SAFETY_GUIDANCE,
|
|
131
|
-
safety: () => SUBAGENT_SAFETY_GUIDANCE,
|
|
132
|
-
agentDir: () => agentDir,
|
|
133
|
-
projectConfigDir: () => projectConfigDir,
|
|
134
|
-
};
|
|
135
|
-
return template.replace(/\{\{(\w+)\}\}/g, (raw, name: string) => {
|
|
136
|
-
const replacement = variables[name];
|
|
137
|
-
if (replacement) return replacement();
|
|
138
|
-
warn(options, `${CUSTOM_TOOL_DESCRIPTION_FILE}: unknown placeholder ${raw} left unchanged.`);
|
|
139
|
-
return raw;
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function loadCustomToolDescription(options?: ToolDescriptionOptions): string | undefined {
|
|
144
|
-
for (const filePath of customDescriptionPaths(options)) {
|
|
145
|
-
let stat: fs.Stats;
|
|
146
|
-
try {
|
|
147
|
-
stat = fs.statSync(filePath);
|
|
148
|
-
} catch (error) {
|
|
149
|
-
if (typeof error === "object" && error !== null && "code" in error && (error as NodeJS.ErrnoException).code === "ENOENT") continue;
|
|
150
|
-
warn(options, `Failed to inspect custom tool description '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
if (!stat.isFile()) {
|
|
154
|
-
warn(options, `Ignoring custom tool description '${filePath}' because it is not a file.`);
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
if (stat.size > CUSTOM_TOOL_DESCRIPTION_MAX_BYTES) {
|
|
158
|
-
warn(options, `Ignoring custom tool description '${filePath}' because it is larger than ${CUSTOM_TOOL_DESCRIPTION_MAX_BYTES} bytes.`);
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
try {
|
|
162
|
-
const template = fs.readFileSync(filePath, "utf-8").trim();
|
|
163
|
-
if (!template) {
|
|
164
|
-
warn(options, `Ignoring empty custom tool description '${filePath}'.`);
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
const rendered = renderCustomTemplate(template, options).trim();
|
|
168
|
-
if (!rendered) {
|
|
169
|
-
warn(options, `Ignoring custom tool description '${filePath}' because it rendered empty.`);
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
return rendered;
|
|
173
|
-
} catch (error) {
|
|
174
|
-
warn(options, `Failed to read custom tool description '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return undefined;
|
|
178
|
-
}
|
|
76
|
+
• Keep one writer per cwd/worktree. Use fresh read-only review/validation fanout, then synthesize and apply fixes from the parent unless isolated worktrees were intentionally requested.`;function f(Q){return Q==="full"||Q==="compact"||Q==="custom"}function B(Q,Z){(Q?.warn??console.warn)(`[dm-subagents] ${Z}`)}function k(Q,Z){let J=Q.toolDescriptionMode;if(J===void 0)return"full";if(f(J))return J;return B(Z,`Ignoring invalid toolDescriptionMode ${JSON.stringify(J)}; expected "full", "compact", or "custom".`),"full"}function m(Q){let Z=Q?.cwd??process.cwd(),J=Q?.agentDir??z();return[_.join(H(Z),F),_.join(J,F)]}function h(Q,Z){let J=Z?.cwd??process.cwd(),$=Z?.agentDir??z(),X=H(J),R={fullDescription:()=>E,full:()=>E,compactDescription:()=>O,compact:()=>O,safetyGuidance:()=>j,safety:()=>j,agentDir:()=>$,projectConfigDir:()=>X};return Q.replace(/\{\{(\w+)\}\}/g,(Y,G)=>{let N=R[G];if(N)return N();return B(Z,`${F}: unknown placeholder ${Y} left unchanged.`),Y})}function c(Q){for(let Z of m(Q)){let J;try{J=A.statSync(Z)}catch($){if(typeof $==="object"&&$!==null&&"code"in $&&$.code==="ENOENT")continue;B(Q,`Failed to inspect custom tool description '${Z}': ${$ instanceof Error?$.message:String($)}`);continue}if(!J.isFile()){B(Q,`Ignoring custom tool description '${Z}' because it is not a file.`);continue}if(J.size>b){B(Q,`Ignoring custom tool description '${Z}' because it is larger than ${b} bytes.`);continue}try{let $=A.readFileSync(Z,"utf-8").trim();if(!$){B(Q,`Ignoring empty custom tool description '${Z}'.`);continue}let X=h($,Q).trim();if(!X){B(Q,`Ignoring custom tool description '${Z}' because it rendered empty.`);continue}return X}catch($){B(Q,`Failed to read custom tool description '${Z}': ${$ instanceof Error?$.message:String($)}`)}}return}function u(Q){let Z=Q.split(j).map((J)=>J.trim()).filter(Boolean).join(`
|
|
179
77
|
|
|
180
|
-
|
|
181
|
-
const customDescription = description
|
|
182
|
-
.split(SUBAGENT_SAFETY_GUIDANCE)
|
|
183
|
-
.map((part) => part.trim())
|
|
184
|
-
.filter(Boolean)
|
|
185
|
-
.join("\n\n");
|
|
186
|
-
return customDescription
|
|
187
|
-
? `${customDescription}\n\n${SUBAGENT_SAFETY_GUIDANCE}`
|
|
188
|
-
: SUBAGENT_SAFETY_GUIDANCE;
|
|
189
|
-
}
|
|
78
|
+
`);return Z?`${Z}
|
|
190
79
|
|
|
191
|
-
|
|
192
|
-
const mode = resolveToolDescriptionMode(config, options);
|
|
193
|
-
if (mode === "compact") return COMPACT_SUBAGENT_TOOL_DESCRIPTION;
|
|
194
|
-
if (mode === "custom") {
|
|
195
|
-
const custom = loadCustomToolDescription(options);
|
|
196
|
-
if (custom) return withMandatorySafetyGuidance(custom);
|
|
197
|
-
warn(options, `${CUSTOM_TOOL_DESCRIPTION_FILE} was not found or valid for toolDescriptionMode "custom"; using full description.`);
|
|
198
|
-
}
|
|
199
|
-
return FULL_SUBAGENT_TOOL_DESCRIPTION;
|
|
200
|
-
}
|
|
80
|
+
${j}`:j}function zQ(Q={},Z){let J=k(Q,Z);if(J==="compact")return O;if(J==="custom"){let $=c(Z);if($)return u($);B(Z,`${F} was not found or valid for toolDescriptionMode "custom"; using full description.`)}return E}export{k as resolveToolDescriptionMode,zQ as buildSubagentToolDescription,j as SUBAGENT_SAFETY_GUIDANCE,E as FULL_SUBAGENT_TOOL_DESCRIPTION,O as COMPACT_SUBAGENT_TOOL_DESCRIPTION};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import*as R from"node:fs";import*as T from"node:os";import*as B from"node:path";import*as X from"node:fs";import*as G from"node:os";import*as U from"node:path";import*as V from"node:os";import*as K from"node:path";function H(Q){return Q.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function b(Q){let Z=Q?.env??process.env,Y=Q&&Object.hasOwn(Q,"getuid")?Q.getuid:process.getuid?.bind(process);if(typeof Y==="function")return`uid-${Y()}`;for(let q of["USERNAME","USER","LOGNAME"]){let j=Z[q];if(j)return`user-${H(j)}`}let $=Q&&Object.hasOwn(Q,"userInfo")?Q.userInfo:V.userInfo;try{let q=$?.().username;if(q)return`user-${H(q)}`}catch{}let J=Z.USERPROFILE??Z.HOME;if(J)return`home-${H(J)}`;let W=Q&&Object.hasOwn(Q,"homedir")?Q.homedir:V.homedir;try{let q=W?.();if(q)return`home-${H(q)}`}catch{}return"shared"}var z=K.join(V.tmpdir(),`dm-subagents-${b()}`),n=K.join(z,"async-subagent-results"),o=K.join(z,"async-subagent-runs"),S=K.join(z,"chain-runs"),l=K.join(z,"artifacts");var y=".dm",x="@duckmind/dm-coding-agent",D="DM_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT";function O(Q){return typeof Q==="string"&&Q.trim()?Q:void 0}function _(Q){if(!Q)return;try{let Z=JSON.parse(X.readFileSync(U.join(Q,"package.json"),"utf-8"));if(Z.name!==x)return;return O(Z.piConfig?.configDir)}catch{return}}function P(Q=process.argv[1],Z=process.env[D]){let Y=_(Z);if(Y)return Y;if(!Q)return;try{let $=U.dirname(X.realpathSync(Q));while($!==U.dirname($)){let J=_($);if(J)return J;$=U.dirname($)}}catch{}return}function v(Q,Z,Y){return(Q&&typeof Q==="object"?O(Q.CONFIG_DIR_NAME):void 0)??P(Z,Y)??y}function f(){return v()}function L(){let Q=process.env.DM_CODING_AGENT_DIR;if(Q==="~")return G.homedir();if(Q?.startsWith("~/"))return U.join(G.homedir(),Q.slice(2));return Q||U.join(G.homedir(),f(),"agent")}var F="native:dm-subagents-supervisor-channel";function C(){return L()}function k(Q=C()){return B.join(Q,"extensions","subagent")}var h="subagent-chat",A="Intercom orchestration channel:",M=`The inherited thread is reference-only. Do not continue that conversation or send questions, status updates, or completion handoffs to the supervisor in normal assistant text.
|
|
2
|
+
|
|
3
|
+
Use contact_supervisor first. It resolves the supervisor session "{orchestratorTarget}" and run metadata automatically.
|
|
4
|
+
- Need a decision, blocked, approval, or product/API/scope ambiguity: contact_supervisor({ reason: "need_decision", message: "<question>" })
|
|
5
|
+
- After contact_supervisor with reason "need_decision", stay alive and continue only after the reply arrives. Do not finish your final response with a choose-one question.
|
|
6
|
+
- Do not ask for clarification when the only conflict is review-only/no-edit versus progress-writing or artifact-writing instructions. Review-only/no-edit wins; leave files unchanged and mention the conflict in your final result only if it matters.
|
|
7
|
+
- Meaningful progress or unexpected discoveries that change the plan: contact_supervisor({ reason: "progress_update", message: "UPDATE: <summary>" })
|
|
8
|
+
- Generic intercom is lower-level plumbing/fallback only: intercom({ action: "ask", to: "{orchestratorTarget}", message: "<question>" })
|
|
9
|
+
|
|
10
|
+
Do not use contact_supervisor or intercom for routine completion handoffs. If no coordination is needed, return a focused task result.`;function LQ(Q,Z){let Y=Q?.trim();if(Y)return Y;let $=Z.startsWith("session-")?Z.slice(8):Z;return`${h}-${$.slice(0,8)}`}function E(Q){return Q.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")||"agent"}function FQ(Q,Z,Y){let $=Y!==void 0?`-${Y+1}`:"";return`subagent-${E(Z)}-${E(Q)}${$}`}function m(Q){if(Q==="off"||Q==="always"||Q==="fork-only")return Q;return"always"}function w(Q){if(!Q||typeof Q!=="object"||Array.isArray(Q))return{mode:"always",instructionFile:""};return{mode:m(Q.mode),instructionFile:typeof Q.instructionFile==="string"?Q.instructionFile:""}}function c(Q){return Q.startsWith("~/")?B.join(T.homedir(),Q.slice(2)):Q}function g(Q,Z){if(!Q)return M;let Y=c(Q),$=B.isAbsolute(Y)?Y:B.resolve(Z,Y);try{return R.readFileSync($,"utf-8")}catch(J){return console.warn(`Failed to read intercom bridge instructionFile at '${$}'. Using default instructions.`,J),M}}function N(Q,Z){let Y=Z.replaceAll("{orchestratorTarget}",Q).trim();if(Y.startsWith(A))return Y;return`${A}
|
|
11
|
+
${Y}`}function I(Q,Z,Y){if(Q==="off")return"bridge mode is off";if(Q==="fork-only"&&Z!=="fork")return"bridge mode is fork-only and context is not fork";if(!Y)return"orchestrator target is not available";return}function AQ(Q){let Y=w(Q.config).mode,$=Q.orchestratorTarget?.trim(),J=Y!=="off"&&!(Y==="fork-only"&&Q.context!=="fork"),W=I(Y,Q.context,$);return{active:W===void 0,mode:Y,wantsIntercom:J,supervisorChannelAvailable:!0,extensionDir:F,...$?{orchestratorTarget:$}:{},...W?{reason:W}:{}}}function MQ(Q){let Z=w(Q.config),Y=Z.mode,$=Q.orchestratorTarget?.trim(),J=B.resolve(Q.agentDir??C()),W=B.resolve(Q.settingsDir??k(J)),q=N($||"{orchestratorTarget}",M);if(I(Y,Q.context,$)||!$)return{active:!1,mode:Y,extensionDir:F,instruction:q};return{active:!0,mode:Y,orchestratorTarget:$,extensionDir:F,instruction:N($,g(Z.instructionFile,W))}}function _Q(Q,Z){if(!Z.active||!Z.orchestratorTarget)return Q;let Y=["intercom","contact_supervisor"],$=Q.tools?[...Q.tools,...Y.filter((j)=>!Q.tools?.includes(j))]:Q.tools,J=Z.instruction,W=Q.systemPrompt?.trim()||"",q=W.includes(A)?W:W?`${W}
|
|
12
|
+
|
|
13
|
+
${J}`:J;if($===Q.tools&&q===Q.systemPrompt)return Q;return{...Q,tools:$,systemPrompt:q}}export{FQ as resolveSubagentIntercomTarget,LQ as resolveIntercomSessionTarget,m as resolveIntercomBridgeMode,MQ as resolveIntercomBridge,AQ as diagnoseIntercomBridge,_Q as applyIntercomBridgeToAgent,F as NATIVE_INTERCOM_EXTENSION_DIR,A as INTERCOM_BRIDGE_MARKER};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{randomUUID as fj}from"node:crypto";import*as Y from"node:fs";import*as T from"node:path";import{Type as O}from"typebox";import*as L from"node:path";import{fileURLToPath as c}from"node:url";import*as A from"node:os";import*as W from"node:path";import*as _ from"node:os";import*as C from"node:path";function S(j){return j.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function p(j){let $=j?.env??process.env,f=j&&Object.hasOwn(j,"getuid")?j.getuid:process.getuid?.bind(process);if(typeof f==="function")return`uid-${f()}`;for(let Z of["USERNAME","USER","LOGNAME"]){let X=$[Z];if(X)return`user-${S(X)}`}let J=j&&Object.hasOwn(j,"userInfo")?j.userInfo:_.userInfo;try{let Z=J?.().username;if(Z)return`user-${S(Z)}`}catch{}let B=$.USERPROFILE??$.HOME;if(B)return`home-${S(B)}`;let U=j&&Object.hasOwn(j,"homedir")?j.homedir:_.homedir;try{let Z=U?.();if(Z)return`home-${S(Z)}`}catch{}return"shared"}var H=C.join(_.tmpdir(),`dm-subagents-${p()}`),Rj=C.join(H,"async-subagent-results"),Nj=C.join(H,"async-subagent-runs"),l=C.join(H,"chain-runs"),yj=C.join(H,"artifacts");var w=250;var aj=W.join(A.homedir(),".config","mcp","mcp.json"),ej={cursor:[W.join(A.homedir(),".cursor","mcp.json")],"claude-code":[W.join(A.homedir(),".claude","mcp.json"),W.join(A.homedir(),".claude.json"),W.join(A.homedir(),".claude","claude_desktop_config.json")],"claude-desktop":[W.join(A.homedir(),"Library","Application Support","Claude","claude_desktop_config.json")],codex:[W.join(A.homedir(),".codex","config.json")],windsurf:[W.join(A.homedir(),".windsurf","mcp.json")],vscode:[".vscode/mcp.json"]};import{Compile as f$}from"typebox/compile";var M$=L.join(L.dirname(c(import.meta.url)),"subagent-prompt-runtime.ts"),_$=L.join(L.dirname(c(import.meta.url)),"..","..","extension","fanout-child.ts");var q="DM_SUBAGENT_ORCHESTRATOR_TARGET",I="DM_SUBAGENT_ORCHESTRATOR_SESSION_ID",x="DM_SUBAGENT_SUPERVISOR_CHANNEL_DIR",v="DM_SUBAGENT_RUN_ID",D="DM_SUBAGENT_CHILD_AGENT",P="DM_SUBAGENT_CHILD_INDEX";import*as t from"node:fs";import*as V from"node:path";var s=[10,25,50,100,200,500,1000,2000,4000],i=new Set(["EACCES","EBUSY","EPERM"]),o=typeof SharedArrayBuffer<"u"?new SharedArrayBuffer(4):void 0,k=o?new Int32Array(o):void 0;function a(j){if(j<=0)return;if(k)try{Atomics.wait(k,0,0,j);return}catch{}let $=Date.now()+j;while(Date.now()<$);}function e(j){let $=j?.code;return typeof $==="string"&&i.has($)}function jj(j,$,f,J,B){for(let U=0;;U++)try{j.renameSync($,f);return}catch(Z){let X=J[U];if(X===void 0||!e(Z))throw Z;B(X)}}function $j(j={}){let $=j.fs??t,f=j.now??Date.now,J=j.pid??process.pid,B=j.random??Math.random,Z=j.retryRenameErrors??process.platform==="win32"?j.retryDelaysMs??s:[],X=j.wait??a;return(K,G)=>{$.mkdirSync(V.dirname(K),{recursive:!0});let Q=V.join(V.dirname(K),`.${V.basename(K)}.${J}.${f()}.${B().toString(36).slice(2)}.tmp`);try{$.writeFileSync(Q,JSON.stringify(G,null,2),"utf-8"),jj($,Q,K,Z,X)}finally{$.rmSync(Q,{force:!0})}}}var R=$j();var z=T.join(H,"supervisor-channels"),y="requests",m="replies",E="subagent_supervisor",Jj=65536,Bj=600000,Uj=Math.min(w,500),Zj=O.Object({reason:O.String({enum:["need_decision","interview_request","progress_update"]}),message:O.Optional(O.String()),interview:O.Optional(O.Unsafe({type:"object",additionalProperties:!0}))},{additionalProperties:!1}),g=O.Object({action:O.String({enum:["list","send","ask","reply","pending","status"]}),to:O.Optional(O.String()),message:O.Optional(O.String()),replyTo:O.Optional(O.String())},{additionalProperties:!1});function b(j){return j.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function R$(j,$,f){return T.join(z,`${b(j)}-${b($)}-${f}`)}function Qj(j){Y.mkdirSync(T.join(j,y),{recursive:!0,mode:448}),Y.mkdirSync(T.join(j,m),{recursive:!0,mode:448})}function Xj(j,$){return T.join(j,y,`${b($)}.json`)}function n(j,$){return T.join(j,m,`${b($)}.json`)}function M(j){let $=process.env[j]?.trim();return $?$:void 0}function d(){let j=M(x),$=M(v),f=M(D),J=M(P),B=M(I);if(!j||!$||!f||!B||J===void 0||!/^\d+$/.test(J))return;return{channelDir:j,runId:$,agent:f,childIndex:Number(J),orchestratorTarget:M(q),orchestratorSessionId:B,childTarget:M("DM_SUBAGENT_INTERCOM_SESSION_NAME")}}function Oj(j){if(j==="interview_request")return"Subagent requests a structured supervisor interview.";if(j==="progress_update")return"Subagent progress update.";return"Subagent needs a supervisor decision."}function Yj(j){let $=[Oj(j.reason),`Run: ${j.runId}`,`Agent: ${j.agent}`,`Child index: ${j.childIndex}`];if(j.childTarget)$.push(`Child intercom target: ${j.childTarget}`);if($.push(""),j.message?.trim())$.push(j.message.trim());if(j.reason==="interview_request"){if($.push("","Structured response requested. Reply with JSON, optionally fenced in ```json, matching the requested interview shape."),j.interview!==void 0)$.push(JSON.stringify(j.interview,null,"\t"))}return $.join(`
|
|
2
|
+
`).trimEnd()}function Wj(j){let $=j.trim(),f=$.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i)?.[1]?.trim();try{return{value:JSON.parse(f??$)}}catch(J){return{error:J instanceof Error?`${J.name}: ${J.message}`:String(J)}}}function Tj(){let j=Number(process.env.PI_INTERCOM_ASK_TIMEOUT_MS);return Number.isFinite(j)&&j>0?j:Bj}function Kj(j,$){return new Promise((f,J)=>{if($?.aborted){J(Error("Supervisor request cancelled."));return}let B,U=()=>{if(B)clearTimeout(B);$?.removeEventListener("abort",Z)},Z=()=>{U(),J(Error("Supervisor request cancelled."))};B=setTimeout(()=>{U(),f()},j),$?.addEventListener("abort",Z,{once:!0})})}async function Gj(j,$,f){let J=n(j,$),B=Date.now()+Tj();while(Date.now()<=B){if(f?.aborted)throw Error("Supervisor request cancelled.");if(Y.existsSync(J)){let U=JSON.parse(Y.readFileSync(J,"utf-8"));if(U.type==="subagent.supervisor.reply"&&U.requestId===$&&typeof U.message==="string")return U}await Kj(250,f)}throw Error("Timed out waiting for supervisor reply.")}async function N(j,$){let f=d();if(!f)throw Error("Native supervisor channel is not available for this subagent.");if(j.reason!=="progress_update"&&!j.message?.trim()&&j.reason!=="interview_request")throw Error("message is required for supervisor decisions.");Qj(f.channelDir);let J=fj(),B=j.reason!=="progress_update",U=Yj({...f,reason:j.reason,message:j.message,interview:j.interview}),Z={type:"subagent.supervisor.request",id:J,createdAt:Date.now(),reason:j.reason,message:U,expectsReply:B,...f.orchestratorTarget?{orchestratorTarget:f.orchestratorTarget}:{},...f.orchestratorSessionId?{orchestratorSessionId:f.orchestratorSessionId}:{},runId:f.runId,agent:f.agent,childIndex:f.childIndex,...f.childTarget?{childTarget:f.childTarget}:{},...j.interview!==void 0?{interview:j.interview}:{}},X=JSON.stringify(Z,null,"\t");if(Buffer.byteLength(X,"utf-8")>Jj)throw Error("Supervisor request is too large.");if(R(Xj(f.channelDir,J),Z),!B)return{content:[{type:"text",text:"Supervisor progress update queued."}],details:{delivered:!0,requestId:J,reason:j.reason}};let K=await Gj(f.channelDir,J,$),G={requestId:J,reason:j.reason};if(j.reason==="interview_request"){let Q=Wj(K.message);if(Q.error)G.structuredReplyParseError=Q.error;else G.structuredReply=Q.value}return{content:[{type:"text",text:`**Reply from supervisor:**
|
|
3
|
+
${K.message}`}],details:G}}function F(j,$){try{return j.getAllTools?.().some((f)=>f.name===$)===!0}catch{return!1}}function N$(j,$={}){if(!d())return;let f=$.includeIntercomFallback!==!1;if(!F(j,"contact_supervisor")){let J={name:"contact_supervisor",label:"Contact Supervisor",description:"Contact the parent/supervisor session for a blocking decision, structured interview, or progress update.",parameters:Zj,execute(B,U,Z){return N(U,Z)}};j.registerTool(J)}if(f&&!F(j,"intercom")){let J={name:"intercom",label:"Intercom",description:"Native supervisor-channel intercom fallback for subagents. Prefer contact_supervisor when available.",parameters:g,async execute(B,U,Z){let X=U.action;if(X==="status")return{content:[{type:"text",text:"Native supervisor channel is active."}],details:{active:!0}};if(X==="list")return{content:[{type:"text",text:"Supervisor session available through contact_supervisor."}],details:{sessions:[]}};if(X==="send")return N({reason:"progress_update",message:U.message??""},Z);if(X==="ask")return N({reason:"need_decision",message:U.message??""},Z);throw Error("Native child intercom supports status, list, send, and ask. Use parent intercom reply from the supervisor session.")}};j.registerTool(J)}}function Aj(j,$){try{let f=JSON.parse(Y.readFileSync(j,"utf-8"));if(f.type!=="subagent.supervisor.request")return;if(typeof f.id!=="string"||!f.id)return;if(f.reason!=="need_decision"&&f.reason!=="interview_request"&&f.reason!=="progress_update")return;if(typeof f.message!=="string"||!f.message)return;if(typeof f.runId!=="string"||typeof f.agent!=="string"||typeof f.childIndex!=="number")return;return{...f,channelDir:$,requestFile:j}}catch{return}}function Hj(){let j;try{j=Y.readdirSync(z,{withFileTypes:!0})}catch(f){if(f.code==="ENOENT")return[];throw f}let $=[];for(let f of j){if(!f.isDirectory())continue;let J=T.join(z,f.name),B=T.join(J,y),U;try{U=Y.readdirSync(B,{withFileTypes:!0})}catch{continue}for(let Z of U)if(Z.isFile()&&Z.name.endsWith(".json"))$.push({channelDir:J,file:T.join(B,Z.name)})}return $}function Vj(j,$){try{let f=$.sessionManager.getSessionId();if(f)return f}catch{}return j.currentSessionId??void 0}function Mj(j,$,f){let J=Vj($,f);return Boolean(J&&j.orchestratorSessionId===J)}function _j(j){let $=j.expectsReply?` Reply: ${E}({ action: "reply", replyTo: "${j.id}", message: "..." })`:"";return`- ${j.id}: ${j.agent} [${j.runId}#${j.childIndex}] ${j.reason}.${$}`}function Cj(j){let $=[j.message];if(j.expectsReply)$.push("",`Reply with: ${E}({ action: "reply", replyTo: "${j.id}", message: "..." })`);return $.join(`
|
|
4
|
+
`)}function Lj(j,$){if(!$.trim())throw Error("message is required for supervisor replies.");let f={type:"subagent.supervisor.reply",requestId:j.id,createdAt:Date.now(),message:$.trim()};R(n(j.channelDir,j.id),f);try{Y.rmSync(j.requestFile,{force:!0})}catch{}}function Sj(j,$){if($.replyTo){let J=j.get($.replyTo);if(!J)throw Error(`No pending supervisor request found for replyTo '${$.replyTo}'.`);return J}let f=[...j.values()].filter((J)=>J.expectsReply);if($.to){let J=$.to.toLowerCase(),B=f.filter((U)=>U.id.toLowerCase().startsWith(J)||U.agent.toLowerCase()===J||U.childTarget?.toLowerCase()===J);if(B.length===1)return B[0];if(B.length>1)throw Error(`Multiple pending supervisor requests match '${$.to}'. Use replyTo.`)}if(f.length===1)return f[0];if(f.length===0)throw Error("No pending supervisor requests need a reply.");throw Error("Multiple pending supervisor requests need replies. Use replyTo.")}function zj(j){return[...j.values()].map(($)=>({id:$.id,runId:$.runId,agent:$.agent,childIndex:$.childIndex,reason:$.reason,expectsReply:$.expectsReply}))}function h(j,$="intercom"){return{name:$,label:$==="intercom"?"Intercom":"Subagent Supervisor",description:$==="intercom"?"Native dm-subagents supervisor channel. Use reply/pending/status to answer child subagent requests.":"Native dm-subagents supervisor channel. Use reply/pending/status to answer child subagent requests without overriding the optional intercom compatibility extension.",parameters:g,async execute(f,J){let B=J;if(B.action==="status")return{content:[{type:"text",text:`Native supervisor channel active. Pending replies: ${j.size}.`}],details:{active:!0,pending:j.size,root:z}};if(B.action==="pending"||B.action==="list"){let U=[...j.values()].filter((Z)=>Z.expectsReply).map(_j);return{content:[{type:"text",text:U.length?U.join(`
|
|
5
|
+
`):"No pending supervisor requests."}],details:{pending:zj(j)}}}if(B.action==="reply"){let U=Sj(j,B);return Lj(U,B.message??""),j.delete(U.id),{content:[{type:"text",text:`Replied to supervisor request ${U.id}.`}],details:{replyTo:U.id,runId:U.runId,agent:U.agent}}}if(B.action==="send"||B.action==="ask")throw Error("Native dm-subagents intercom currently handles supervisor replies. Child agents initiate asks with contact_supervisor.");throw Error(`Unsupported intercom action: ${B.action}`)}}}function y$(j,$){let f=new Map,J=new Set,B,U=()=>{if(!F(j,E))j.registerTool(h(f,E));if(!F(j,"intercom"))j.registerTool(h(f))},Z=()=>{let X=$.lastUiContext;if(!X)return;for(let{channelDir:K,file:G}of Hj()){if(J.has(G))continue;let Q=Aj(G,K);if(!Q||!Mj(Q,$,X))continue;if(J.add(G),Q.expectsReply)f.set(Q.id,Q);else try{Y.rmSync(Q.requestFile,{force:!0})}catch{}j.sendMessage({customType:"subagent_supervisor_request",content:Cj(Q),display:!0,details:{id:Q.id,reason:Q.reason,expectsReply:Q.expectsReply,runId:Q.runId,agent:Q.agent,childIndex:Q.childIndex}})}};return{start:()=>{if(B)return;U(),Z(),B=setInterval(Z,Uj),B.unref?.()},dispose:()=>{if(B)clearInterval(B);B=void 0,f.clear(),J.clear()},pending:f}}export{R$ as resolveSupervisorChannelDir,N$ as registerNativeSupervisorClient,Qj as ensureSupervisorChannelDir,y$ as createNativeSupervisorChannel,E as NATIVE_SUPERVISOR_TOOL_NAME};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{randomUUID as k}from"node:crypto";import*as E from"node:fs";import*as B from"node:os";import*as O from"node:path";var _="subagent:result-intercom",A="subagent:result-intercom-delivery";function V(j){return j.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function N(j){let K=j?.env??process.env,J=j&&Object.hasOwn(j,"getuid")?j.getuid:process.getuid?.bind(process);if(typeof J==="function")return`uid-${J()}`;for(let Z of["USERNAME","USER","LOGNAME"]){let $=K[Z];if($)return`user-${V($)}`}let F=j&&Object.hasOwn(j,"userInfo")?j.userInfo:B.userInfo;try{let Z=F?.().username;if(Z)return`user-${V(Z)}`}catch{}let Q=K.USERPROFILE??K.HOME;if(Q)return`home-${V(Q)}`;let Y=j&&Object.hasOwn(j,"homedir")?j.homedir:B.homedir;try{let Z=Y?.();if(Z)return`home-${V(Z)}`}catch{}return"shared"}var L=O.join(B.tmpdir(),`dm-subagents-${N()}`),S=O.join(L,"async-subagent-results"),y=O.join(L,"async-subagent-runs"),b=O.join(L,"chain-runs"),x=O.join(L,"artifacts");function m(j){if(j.detached)return"detached";if(j.interrupted||j.state==="paused")return"paused";if(typeof j.success==="boolean")return j.success?"completed":"failed";if(j.state==="complete")return"completed";if(j.state==="failed")return"failed";if(typeof j.exitCode==="number")return j.exitCode===0?"completed":"failed";return"failed"}function G(j){let K={completed:0,failed:0,paused:0,detached:0};for(let J of j)K[J.status]+=1;return K}function z(j){let K=[j.completed?`${j.completed} completed`:void 0,j.failed?`${j.failed} failed`:void 0,j.paused?`${j.paused} paused`:void 0,j.detached?`${j.detached} detached`:void 0].filter((J)=>Boolean(J));return K.length?K.join(", "):"0 results"}function P(j){let K=G(j);if(K.failed>0)return"failed";if(K.paused>0)return"paused";if(K.completed>0)return"completed";if(K.detached>0)return"detached";return"failed"}function w(j,K=0){return{id:j.id,parentRunId:j.parentRunId,...j.parentStepIndex!==void 0?{parentStepIndex:j.parentStepIndex}:{},...j.parentAgent?{parentAgent:j.parentAgent}:{},depth:j.depth,path:j.path.slice(0,4).map((J)=>({runId:J.runId,...J.stepIndex!==void 0?{stepIndex:J.stepIndex}:{},...J.agent?{agent:J.agent}:{}})),...j.asyncDir?{asyncDir:j.asyncDir}:{},...j.sessionId?{sessionId:j.sessionId}:{},...j.sessionFile?{sessionFile:j.sessionFile}:{},...j.intercomTarget?{intercomTarget:j.intercomTarget}:{},...j.ownerIntercomTarget?{ownerIntercomTarget:j.ownerIntercomTarget}:{},...j.leafIntercomTarget?{leafIntercomTarget:j.leafIntercomTarget}:{},...j.ownerState?{ownerState:j.ownerState}:{},...j.mode?{mode:j.mode}:{},state:j.state,...j.agent?{agent:j.agent}:{},...j.agents?.length?{agents:j.agents.slice(0,12)}:{},...j.currentStep!==void 0?{currentStep:j.currentStep}:{},...j.chainStepCount!==void 0?{chainStepCount:j.chainStepCount}:{},...j.parallelGroups?.length?{parallelGroups:j.parallelGroups.slice(0,8)}:{},...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.totalTokens?{totalTokens:j.totalTokens}:{},...j.startedAt!==void 0?{startedAt:j.startedAt}:{},...j.endedAt!==void 0?{endedAt:j.endedAt}:{},...j.lastUpdate!==void 0?{lastUpdate:j.lastUpdate}:{},...j.error?{error:j.error}:{},...j.steps?.length?{steps:j.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}:{},...K<2&&J.children?.length?{children:J.children.slice(0,8).map((F)=>w(F,K+1))}:{}}))}:{},...K<2&&j.children?.length?{children:j.children.slice(0,8).map((J)=>w(J,K+1))}:{}}}function U(j){if(!j?.length)return;return j.slice(0,16).map((K)=>w(K))}function h(j,K,J){let F=U(J);if(!F?.length)return K.map((Q)=>({...Q,children:U(Q.children)}));return K.map((Q,Y)=>{let Z=Q.index??Y,$=new Set(Q.children?.map((W)=>W.id)??[]),X=F.filter((W)=>W.parentRunId===j&&W.parentStepIndex===Z&&!$.has(W.id)),H=K.length===1?F.filter((W)=>W.parentRunId===j&&W.parentStepIndex===void 0&&!$.has(W.id)):[],q=U([...Q.children??[],...X,...H]);return q?.length?{...Q,children:q}:{...Q,children:void 0}})}function T(j){if(!j?.length)return[];let K=["Nested subagents:"],J=10,F=(Q,Y)=>{for(let Z of Q??[]){if(J<=0){K.push(`${Y}↳ +more nested runs; inspect status for full tree`);return}J--;let $=Z.agent??Z.agents?.join("+")??Z.id;if(K.push(`${Y}↳ ${$} — ${Z.state} [${Z.id}]`),Z.sessionFile)K.push(`${Y} Session: ${Z.sessionFile}`);F(Z.children,`${Y} `);for(let X of Z.steps??[])F(X.children,`${Y} `)}};return F(j,""),K}function I(j){if(j.source!=="async"||!j.asyncId)return;let K=j.children.filter((J)=>typeof J.sessionPath==="string"&&E.existsSync(J.sessionPath));if(j.children.length===1&&K.length===1)return`Revive: subagent({ action: "resume", id: "${j.asyncId}", message: "..." })`;if(K.length>0){let J=K[0]?.index??j.children.indexOf(K[0]);return`Revive child: subagent({ action: "resume", id: "${j.asyncId}", index: ${J}, message: "..." })`}return"Resume: unavailable; no child session file was persisted."}function C(j){let K=G(j.children),J=["subagent results","",`Run: ${j.runId}`,`Mode: ${j.mode}`,`Status: ${j.status}`,`Children: ${z(K)}`];if(j.mode==="chain"&&typeof j.chainSteps==="number")J.push(`Chain steps: ${j.chainSteps}`);if(j.asyncId)J.push(`Async id: ${j.asyncId}`);if(j.asyncDir)J.push(`Async dir: ${j.asyncDir}`);let F=I(j);if(F)J.push(F);if(j.children.some((Q)=>Q.intercomTarget))J.push(""),J.push(j.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<j.children.length;Q++){let Y=j.children[Q];if(J.push(""),J.push(`${Q+1}. ${Y.agent} — ${Y.status}`),Y.intercomTarget)J.push(`${j.source==="async"?"Previous intercom target":"Run intercom target"}: ${Y.intercomTarget}`);if(Y.artifactPath)J.push(`Output artifact: ${Y.artifactPath}`);if(Y.sessionPath)J.push(`Session: ${Y.sessionPath}`);J.push(...T(Y.children)),J.push("Summary:"),J.push(Y.summary)}return J.join(`
|
|
2
|
+
`)}function o(j){let K=j.children.map((Z)=>({...Z,summary:Z.summary.trim()||"(no output)",children:U(Z.children)})),J=P(K),F=z(G(K)),Q=K[0],Y={to:j.to,runId:j.runId,mode:j.mode,status:J,summary:F,source:j.source,children:K,...j.asyncId?{asyncId:j.asyncId}:{},...j.asyncDir?{asyncDir:j.asyncDir}:{},...typeof j.chainSteps==="number"?{chainSteps:j.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 Y.message=C(Y),Y}async function c(j,K,J=500){return D(j,K.to,K.message,J,K)}async function D(j,K,J,F=500,Q={}){if(typeof j.on!=="function"||typeof j.emit!=="function")return!1;let Y=typeof Q.requestId==="string"?Q.requestId:k();return new Promise((Z)=>{let $=!1,X,H,q=(W)=>{if($)return;if($=!0,H)clearTimeout(H);X?.(),Z(W)};X=j.on(A,(W)=>{if(!W||typeof W!=="object")return;let R=W;if(R.requestId!==Y)return;q(R.delivered===!0)}),H=setTimeout(()=>q(!1),F);try{j.emit(_,{...Q,to:K,message:J,requestId:Y})}catch{q(!1)}})}function M(j){return{...j,messages:void 0,finalOutput:void 0,truncation:void 0}}function a(j){return{...j,results:j.results.map(M)}}function l(j){let K=G(j.payload.children),F=[`Delivered ${j.mode==="single"?"single subagent result":j.mode==="parallel"?"parallel subagent results":"chain subagent results"} via intercom.`,`Run: ${j.runId}`,`Children: ${z(K)}`],Q=j.payload.children.filter(($)=>typeof $.artifactPath==="string");if(Q.length>0){F.push("Artifacts:");for(let $ of Q)F.push(`- ${$.agent} [${$.status}]: ${$.artifactPath}`)}let Y=j.payload.children.filter(($)=>typeof $.intercomTarget==="string");if(Y.length>0){F.push("Run intercom targets (may be inactive after completion):");for(let $ of Y)F.push(`- ${$.agent} [${$.status}]: ${$.intercomTarget}`)}let Z=j.payload.children.filter(($)=>typeof $.sessionPath==="string");if(Z.length>0){F.push("Sessions:");for(let $ of Z)F.push(`- ${$.agent} [${$.status}]: ${$.sessionPath}`)}return F.push("Full grouped output was sent over intercom."),F.join(`
|
|
3
|
+
`)}export{a as stripDetailsOutputsForIntercomReceipt,m as resolveSubagentResultStatus,l as formatSubagentResultReceipt,c as deliverSubagentResultIntercomEvent,D as deliverSubagentIntercomMessageEvent,U as compactNestedResultChildren,o as buildSubagentResultIntercomPayload,h as attachNestedChildrenToResultChildren};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import*as j from"node:fs";import*as r from"node:os";import*as z from"node:path";var N=["off","minimal","low","medium","high","xhigh"];function y(Q){return{provider:Q.provider,id:Q.id,fullId:`${Q.provider}/${Q.id}`,reasoning:Q.reasoning,thinkingLevelMap:Q.thinkingLevelMap}}function C(Q){let Y=Q.lastIndexOf(":");if(Y===-1)return{baseModel:Q,thinkingSuffix:""};let Z=N.find(($)=>$===Q.substring(Y+1));if(!Z)return{baseModel:Q,thinkingSuffix:""};return{baseModel:Q.substring(0,Y),thinkingSuffix:`:${Z}`}}function u(Q,Y,Z){if(!Q||!Y||Y.length===0)return;let{baseModel:$}=C(Q),W=Y.find((B)=>B.fullId===$);if(W)return W;let U=Y.filter((B)=>B.id===$);if(Z){let B=U.find((G)=>G.provider===Z);if(B)return B}return U.length===1?U[0]:void 0}function c(Q){if(!Q)return[...N];if(Q.reasoning===!1)return["off"];if(!Q.thinkingLevelMap)return[...N];return N.filter((Z)=>{let $=Q.thinkingLevelMap?.[Z];if($===null)return!1;if(Z==="xhigh")return $!==void 0;return!0})}import*as L from"node:fs";import*as I from"node:os";import*as H from"node:path";import*as T from"node:os";import*as M from"node:path";function w(Q){return Q.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"unknown"}function BQ(Q){let Y=Q?.env??process.env,Z=Q&&Object.hasOwn(Q,"getuid")?Q.getuid:process.getuid?.bind(process);if(typeof Z==="function")return`uid-${Z()}`;for(let B of["USERNAME","USER","LOGNAME"]){let G=Y[B];if(G)return`user-${w(G)}`}let $=Q&&Object.hasOwn(Q,"userInfo")?Q.userInfo:T.userInfo;try{let B=$?.().username;if(B)return`user-${w(B)}`}catch{}let W=Y.USERPROFILE??Y.HOME;if(W)return`home-${w(W)}`;let U=Q&&Object.hasOwn(Q,"homedir")?Q.homedir:T.homedir;try{let B=U?.();if(B)return`home-${w(B)}`}catch{}return"shared"}var D=M.join(T.tmpdir(),`dm-subagents-${BQ()}`),oQ=M.join(D,"async-subagent-results"),lQ=M.join(D,"async-subagent-runs"),UQ=M.join(D,"chain-runs"),iQ=M.join(D,"artifacts");var VQ=".dm",GQ="@duckmind/dm-coding-agent",KQ="DM_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT";function d(Q){return typeof Q==="string"&&Q.trim()?Q:void 0}function p(Q){if(!Q)return;try{let Y=JSON.parse(L.readFileSync(H.join(Q,"package.json"),"utf-8"));if(Y.name!==GQ)return;return d(Y.piConfig?.configDir)}catch{return}}function jQ(Q=process.argv[1],Y=process.env[KQ]){let Z=p(Y);if(Z)return Z;if(!Q)return;try{let $=H.dirname(L.realpathSync(Q));while($!==H.dirname($)){let W=p($);if(W)return W;$=H.dirname($)}}catch{}return}function qQ(Q,Y,Z){return(Q&&typeof Q==="object"?d(Q.CONFIG_DIR_NAME):void 0)??jQ(Y,Z)??VQ}function _Q(){return qQ()}function R(){let Q=process.env.DM_CODING_AGENT_DIR;if(Q==="~")return I.homedir();if(Q?.startsWith("~/"))return H.join(I.homedir(),Q.slice(2));return Q||H.join(I.homedir(),_Q(),"agent")}var a=7;function f(Q){let Y=j.readFileSync(Q,"utf-8"),Z=JSON.parse(Y);if(!Z||typeof Z!=="object"||Array.isArray(Z))throw Error(`File '${Q}' must contain a JSON object.`);return Z}function S(Q,Y){j.mkdirSync(z.dirname(Q),{recursive:!0}),j.writeFileSync(Q,`${JSON.stringify(Y,null,2)}
|
|
2
|
+
`,"utf-8")}var LQ=/^[A-Za-z0-9][A-Za-z0-9._-]*$/;function s(Q,Y){let Z=Q.trim();if(!Z)throw Error(`${Y} is required.`);if(!LQ.test(Z)||Z==="."||Z===".."||Z.includes("/")||Z.includes("\\"))throw Error(`${Y} must be a safe file name using only letters, numbers, dots, underscores, and hyphens.`);return Z}function EQ(Q){let Y=Q.trim(),Z=Y.endsWith(".json")?Y.slice(0,-5):Y;return s(Z,"Profile name")}function k(Q){return s(Q,"Provider")}function HQ(Q,Y){let Z=Y.subagents;if(!Z||typeof Z!=="object"||Array.isArray(Z))throw Error(`Profile '${Q}' must contain a 'subagents' object.`);let $=Z.agentOverrides;if(!$||typeof $!=="object"||Array.isArray($))throw Error(`Profile '${Q}' must contain 'subagents.agentOverrides' as an object.`);for(let[W,U]of Object.entries($)){if(!U||typeof U!=="object"||Array.isArray(U))throw Error(`Profile '${Q}' has invalid override '${W}'; expected an object.`);let B=U.model;if(B!==void 0&&typeof B!=="string")throw Error(`Profile '${Q}' has invalid model for '${W}'; expected a string.`)}return Y}function zQ(){return z.join(R(),"settings.json")}function FQ(Q){if(!j.existsSync(Q))return{};return f(Q)}function AQ(Q){let Y=Q.match(/(\d+(?:\.\d+)?)/g);if(!Y||Y.length===0)return 0;return Math.max(...Y.map((Z)=>Number.parseFloat(Z)).filter((Z)=>Number.isFinite(Z)))}function t(Q){return Q.toLowerCase().replace(/([a-z])([0-9])/g,"$1 $2").replace(/([0-9])([a-z])/g,"$1 $2").split(/[^a-z0-9.]+/).filter(Boolean)}function OQ(Q){let Y=new Set(t(Q));if(["spark","flash","nano","tiny","instant"].some((Z)=>Y.has(Z)))return 0;if(["mini","haiku","small"].some((Z)=>Y.has(Z)))return 1;if(["opus","max","ultra","pro"].some((Z)=>Y.has(Z)))return 4;if(["sonnet","turbo","plus"].some((Z)=>Y.has(Z)))return 3;return 2}function h(Q){if(!Q)return;let Y=[Q.input,Q.output,Q.cacheRead,Q.cacheWrite].filter((Z)=>typeof Z==="number"&&Number.isFinite(Z));if(Y.length===0)return;return Y.reduce((Z,$)=>Z+$,0)}function x(Q){let Y=Q.filter((Z)=>typeof Z==="number"&&Number.isFinite(Z));if(Y.length===0)return;return{min:Math.min(...Y),max:Math.max(...Y)}}function P(Q,Y){if(Q===void 0||!Y)return;if(Y.max<=Y.min)return 0.5;return(Q-Y.min)/(Y.max-Y.min)}function TQ(Q){return{cost:x(Q.map((Y)=>h(Y.cost))),contextWindow:x(Q.map((Y)=>Y.contextWindow)),maxTokens:x(Q.map((Y)=>Y.maxTokens))}}function MQ(Q){if(Q<=0.33)return"cheap";if(Q<=0.66)return"medium";return"expensive"}function NQ(Q){if(Q<=0.33)return"weak";if(Q<=0.66)return"medium";return"strong"}function IQ(Q,Y){if(Q==="strong")return"strong";if(Q==="medium")return Y==="cheap"?"cheap":"medium";return"cheap"}function CQ(Q){if(Q==="cheap")return["scout","delegate"];if(Q==="medium")return["planner","context-builder","researcher"];return["worker","reviewer","oracle"]}function RQ(Q,Y){let Z=Q.name?.trim()||Q.id,$=new Set(t(Z)),W=OQ(Z),U=AQ(Q.id),B=P(h(Q.cost),Y.cost),G=P(Q.contextWindow,Y.contextWindow),_=P(Q.maxTokens,Y.maxTokens),K=B!==void 0||G!==void 0||_!==void 0?["official-metadata","heuristic-name"]:["heuristic-name"],X=[W/4,...G!==void 0?[G]:[],..._!==void 0?[_]:[],...Q.reasoning===!0?[1]:[],...Q.reasoning===!1?[0]:[]],J=$.has("highspeed")||$.has("flash")||$.has("instant")||$.has("turbo"),F=$.has("pro")||$.has("ultra")||$.has("opus")||$.has("max"),q=X.reduce((WQ,XQ)=>WQ+XQ,0)/X.length;if(J)q-=0.2;q=Math.max(0,Math.min(1,q));let A=B!==void 0?MQ(B):W===0?"cheap":W>=3?"expensive":"medium",O=NQ(q),b=J?"fast":F?"slow":B!==void 0?B<=0.33?"fast":B<=0.66?"medium":"slow":W<=1?"fast":W>=3?"slow":"medium",m=IQ(O,A),JQ=J?125:0;return{profileRank:Math.round(q*100*10)+Math.round(U*25)-JQ,costTier:A,qualityTier:O,latencyTier:b,recommendedRoleTier:m,recommendedAgents:CQ(m),classificationSources:K}}function wQ(Q,Y){if(Y)return"timeout";if(!Q)return"error";if(/(unauthori[sz]ed|forbidden|api key|auth|billing|credit|quota)/i.test(Q))return"auth";if(/(not found|unknown model|model unavailable|model disabled|unsupported model|unavailable)/i.test(Q))return"unavailable";return"error"}async function e(Q,Y,Z){if(typeof Q.exec!=="function")return{status:"skipped",message:"DM exec is unavailable in this runtime."};let $=await Q.exec("dm",["-p","--model",Z,"--no-tools",'Reply with exactly "OK".'],{cwd:r.tmpdir(),timeout:45000}),W=typeof $.stdout==="string"?$.stdout.trim():"",B=[typeof $.stderr==="string"?$.stderr.trim():"",W].filter(Boolean).join(`
|
|
3
|
+
`).trim();if($.code===0)return{status:"ok",message:W||"Probe succeeded."};return{status:wQ(B,$.killed===!0),message:B||`Probe exited with code ${$.code??"unknown"}.`}}function v(Q,Y){if(Q<=1)return 0;return Math.max(0,Math.min(Q-1,Math.round((Q-1)*Y)))}function DQ(Q){return Q==="quota"?{cheap:0,medium:0.3333333333333333,strong:0.6666666666666666}:{cheap:0.3333333333333333,medium:0.6666666666666666,strong:1}}function n(Q,Y){if(Q.length===0)throw Error("No provider models are available for profile generation.");let Z=Y==="quota"&&Q.length>1?Q.slice(0,-1):Q,$=DQ(Y);return{cheap:Z[v(Z.length,$.cheap)].fullId,medium:Z[v(Z.length,$.medium)].fullId,strong:Z[v(Z.length,$.strong)].fullId}}function o(Q){return h(Q.observed.cost)}function SQ(Q,Y){let Z=o(Q),$=o(Y);if(Z===void 0||$===void 0)return!1;if(Z>$)return!1;if(Q.derived.profileRank<Y.derived.profileRank)return!1;if((Q.observed.reasoning===!0?1:0)<(Y.observed.reasoning===!0?1:0))return!1;if((Q.observed.contextWindow??0)<(Y.observed.contextWindow??0))return!1;if((Q.observed.maxTokens??0)<(Y.observed.maxTokens??0))return!1;return Z<$||Q.derived.profileRank>Y.derived.profileRank||Q.observed.reasoning===!0&&Y.observed.reasoning!==!0||(Q.observed.contextWindow??0)>(Y.observed.contextWindow??0)||(Q.observed.maxTokens??0)>(Y.observed.maxTokens??0)}function bQ(Q){return Q.filter((Y,Z)=>!Q.some(($,W)=>W!==Z&&SQ($,Y)))}function l(Q,Y){return{subagents:{agentOverrides:{scout:{model:Y.cheap},delegate:{model:Y.cheap},planner:{model:Y.medium},"context-builder":{model:Y.medium},researcher:{model:Y.medium},worker:{model:Y.strong},reviewer:{model:Y.strong},oracle:{model:Y.strong}}}}}function yQ(Q){return Q.observed.availableInRegistry&&Q.observed.probe.status!=="unavailable"&&Q.observed.probe.status!=="auth"&&Q.observed.probe.status!=="timeout"&&Q.observed.probe.status!=="error"}function QQ(Q){return Q.derived.classificationSources.includes("heuristic-name")&&!Q.derived.classificationSources.includes("official-metadata")}function xQ(){return"Classification fell back to name heuristics."}function i(Q){return Q.models.filter(QQ).length}function PQ(Q){let Y=g();return z.join(Y,`${EQ(Q)}.json`)}function YQ(){return z.join(R(),"profiles","dm-subagents")}function vQ(){return YQ()}function g(){let Q=vQ();return j.mkdirSync(Q,{recursive:!0}),Q}function fQ(){return z.join(YQ(),"providers")}function kQ(){let Q=fQ();return j.mkdirSync(Q,{recursive:!0}),Q}function ZQ(Q){return z.join(kQ(),`${k(Q)}.models.json`)}function LY(){let Q=g();return j.readdirSync(Q,{withFileTypes:!0}).filter((Y)=>Y.isFile()&&Y.name.endsWith(".json")).map((Y)=>Y.name.slice(0,-5)).sort((Y,Z)=>Y.localeCompare(Z))}function $Q(Q){let Y=PQ(Q);if(!j.existsSync(Y))throw Error(`Profile not found: ${Q}`);let Z=f(Y);return{filePath:Y,profile:HQ(Y,Z)}}function EY(Q){let{filePath:Y,profile:Z}=$Q(Q),$=zQ(),W=FQ($);return W.subagents=Z.subagents,S($,W),{filePath:Y,settingsPath:$}}function hQ(Q){let Y=ZQ(Q);if(!j.existsSync(Y))return null;return f(Y)}function gQ(Q,Y=a){let Z=Date.parse(Q.refreshedAt);if(!Number.isFinite(Z))return!0;let $=Y*24*60*60*1000;return Date.now()-Z>$}async function mQ(Q,Y,Z,$={}){let W=k(Z),U=$.maxAgeDays??a,B=ZQ(W);if(!$.force){let X=hQ(W);if(X&&!gQ(X,U))return{filePath:B,catalog:X,reused:!0,heuristicFallbackCount:i(X)}}let G=Y.modelRegistry.getAvailable().filter((X)=>X.provider===W);if(G.length===0)throw Error(`No models found in the current registry for provider '${W}'.`);let _=[];for(let X of G){let J=X,F=`${J.provider}/${J.id}`,q=$.probe===!1?{status:"skipped",message:"Live probing disabled."}:await e(Q,Y,F);_.push({rawModel:X,modelRecord:J,fullId:F,probe:q})}let V=TQ(_.map(({modelRecord:X})=>({id:X.id,...typeof X.name==="string"?{name:X.name}:{},...typeof X.reasoning==="boolean"?{reasoning:X.reasoning}:{},...typeof X.contextWindow==="number"?{contextWindow:X.contextWindow}:{},...typeof X.maxTokens==="number"?{maxTokens:X.maxTokens}:{},...X.cost&&typeof X.cost==="object"?{cost:X.cost}:{}}))),K=[];for(let{rawModel:X,modelRecord:J,fullId:F,probe:q}of _){let A=RQ({id:J.id,...typeof J.name==="string"?{name:J.name}:{},...typeof J.reasoning==="boolean"?{reasoning:J.reasoning}:{},...typeof J.contextWindow==="number"?{contextWindow:J.contextWindow}:{},...typeof J.maxTokens==="number"?{maxTokens:J.maxTokens}:{},...J.cost&&typeof J.cost==="object"?{cost:J.cost}:{}},V),O=A.classificationSources.includes("heuristic-name")&&!A.classificationSources.includes("official-metadata")?[xQ()]:[];K.push({id:J.id,fullId:F,observed:{availableInRegistry:!0,...typeof J.name==="string"?{name:J.name}:{},...typeof J.reasoning==="boolean"?{reasoning:J.reasoning}:{},thinkingLevels:c(y(X)).map((b)=>b),...typeof J.contextWindow==="number"?{contextWindow:J.contextWindow}:{},...typeof J.maxTokens==="number"?{maxTokens:J.maxTokens}:{},...J.cost&&typeof J.cost==="object"?{cost:J.cost}:{},probe:{status:q.status,checkedAt:new Date().toISOString(),...q.message?{message:q.message}:{}}},derived:A,warnings:O,notes:[]})}K.sort((X,J)=>X.derived.profileRank-J.derived.profileRank||X.fullId.localeCompare(J.fullId));let E={provider:W,refreshedAt:new Date().toISOString(),maxAgeDays:U,sources:["runtime-registry",...$.probe===!1?[]:["live-probe"],"heuristic-classifier"],models:K};return S(B,E),{filePath:B,catalog:E,reused:!1,heuristicFallbackCount:i(E)}}async function HY(Q,Y,Z,$={}){let W=k(Z),{filePath:U,catalog:B,heuristicFallbackCount:G}=await mQ(Q,Y,W,{maxAgeDays:$.maxAgeDays,force:$.forceRefresh,probe:$.probe}),_=B.models.filter(yQ),V=bQ(_);if(V.length===0)throw Error(`Provider '${W}' has no usable models after filtering.`);let K=n(V,"quota"),E=n(V,"quality"),X=g(),J=z.join(X,`${W}.quota.json`),F=z.join(X,`${W}.quality.json`);S(J,l("quota",K)),S(F,l("quality",E));let q=new Set([...Object.values(K),...Object.values(E)]),A=V.filter((O)=>q.has(O.fullId)&&QQ(O)).length;return{quotaPath:J,qualityPath:F,catalogPath:U,quotaModels:K,qualityModels:E,heuristicFallbackCount:G,selectedHeuristicFallbackCount:A}}async function zY(Q,Y,Z){let{filePath:$,profile:W}=$Q(Z),U=Y.modelRegistry.getAvailable().map(y),B=Object.entries(W.subagents.agentOverrides).filter(([,V])=>typeof V?.model==="string"&&V.model.trim()).map(([V,K])=>({agent:V,model:K.model.trim()})),G=new Map,_=[];for(let V of B){let K=u(V.model,U),{thinkingSuffix:E}=C(V.model),X=K?`${K.fullId}${E}`:V.model,J=G.get(X);if(!J)J=await e(Q,Y,X),G.set(X,J);_.push({agent:V.agent,model:V.model,inRegistry:K!==void 0,probe:J})}return{profileName:Z,filePath:$,results:_}}export{mQ as refreshProviderModelCatalog,$Q as readSubagentProfile,hQ as readProviderModelCatalog,LY as listSubagentProfiles,gQ as isProviderModelCatalogStale,YQ as getSubagentProfilesRootDir,vQ as getSubagentProfilesDir,ZQ as getProviderModelsPath,fQ as getProviderModelsDir,HY as generateProfilesForProvider,g as ensureSubagentProfilesDir,kQ as ensureProviderModelsDir,i as countHeuristicFallbackModels,zY as checkSubagentProfile,EY as applySubagentProfile,a as DEFAULT_PROVIDER_MODELS_MAX_AGE_DAYS};
|