@duckmind/dm-windows-x64 0.60.6 → 0.60.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dm.exe +0 -0
- package/extensions/.dm-extensions.json +70 -123
- package/extensions/dm-9router-ext/src/index.js +410 -5
- package/extensions/dm-caveman/extensions/caveman.js +283 -12
- package/extensions/dm-cliproxy/index.js +182 -2
- package/extensions/dm-cliproxy/scripts/check-config-migration.js +66 -8
- package/extensions/dm-cliproxy/src/apply.js +228 -1
- package/extensions/dm-cliproxy/src/cache.js +42 -1
- package/extensions/dm-cliproxy/src/commands.js +50 -2
- package/extensions/dm-cliproxy/src/compat.js +81 -1
- package/extensions/dm-cliproxy/src/config.js +192 -2
- package/extensions/dm-cliproxy/src/conflicts.js +46 -1
- package/extensions/dm-cliproxy/src/fetch-models.js +190 -1
- package/extensions/dm-cliproxy/src/fetch-usage.js +41 -1
- package/extensions/dm-cliproxy/src/log.js +23 -1
- package/extensions/dm-cliproxy/src/status-quota.js +77 -1
- package/extensions/dm-cliproxy/src/ui-frame.js +50 -1
- package/extensions/dm-cliproxy/src/ui-hub/hub.js +199 -2
- package/extensions/dm-cliproxy/src/ui-hub/index.js +26 -2
- package/extensions/dm-cliproxy/src/ui-hub/shell.js +46 -1
- package/extensions/dm-cliproxy/src/ui-hub/view-diagnostics.js +69 -1
- package/extensions/dm-cliproxy/src/ui-hub/view-models.js +379 -1
- package/extensions/dm-cliproxy/src/ui-hub/view-usage.js +106 -1
- package/extensions/dm-cliproxy/src/ui-picker/catalog.js +41 -1
- package/extensions/dm-cliproxy/src/ui-picker/mutate.js +115 -1
- package/extensions/dm-cliproxy/src/ui-picker/prompt-confirm.js +35 -1
- package/extensions/dm-cliproxy/src/ui-picker/prompt-name.js +62 -1
- package/extensions/dm-cliproxy/src/ui-picker/providers.js +45 -1
- package/extensions/dm-cliproxy/src/ui-picker/render-text.js +34 -1
- package/extensions/dm-cliproxy/src/ui-picker/rows.js +57 -1
- package/extensions/dm-cliproxy/src/ui-setup.js +260 -2
- package/extensions/dm-cliproxy/src/ui-usage.js +151 -1
- package/extensions/dm-cliproxy/src/usage-shared-cache.js +97 -1
- package/extensions/dm-context/src/context.js +144 -1
- package/extensions/dm-context/src/index.js +339 -7
- package/extensions/dm-context/src/utils.js +9 -1
- package/extensions/dm-cua/bin/browser-cua.mjs +73 -8
- package/extensions/dm-cua/index.js +75 -6
- package/extensions/dm-cua/src/browser-cua-lib.mjs +490 -6
- package/extensions/dm-cua/src/browser-install.mjs +331 -2
- package/extensions/dm-fff/src/index.js +688 -12
- package/extensions/dm-fff/src/query.js +60 -1
- package/extensions/dm-goal/src/goal.js +894 -23
- package/extensions/dm-image2/index.js +103 -9
- package/extensions/dm-image2/src/image-lib.mjs +1275 -8
- package/extensions/dm-subagents/install.mjs +62 -8
- package/extensions/dm-subagents/src/agents/agent-management.js +1190 -36
- package/extensions/dm-subagents/src/agents/agent-memory.js +216 -6
- package/extensions/dm-subagents/src/agents/agent-scope.js +5 -1
- package/extensions/dm-subagents/src/agents/agent-selection.js +20 -1
- package/extensions/dm-subagents/src/agents/agent-serializer.js +120 -5
- package/extensions/dm-subagents/src/agents/agents.js +1139 -11
- package/extensions/dm-subagents/src/agents/chain-serializer.js +299 -11
- package/extensions/dm-subagents/src/agents/frontmatter.js +65 -6
- package/extensions/dm-subagents/src/agents/identity.js +29 -1
- package/extensions/dm-subagents/src/agents/proactive-skills.js +141 -1
- package/extensions/dm-subagents/src/agents/skills.js +614 -6
- package/extensions/dm-subagents/src/extension/config.js +35 -2
- package/extensions/dm-subagents/src/extension/control-notices.js +69 -4
- package/extensions/dm-subagents/src/extension/doctor.js +172 -15
- package/extensions/dm-subagents/src/extension/fanout-child.js +158 -231
- package/extensions/dm-subagents/src/extension/index.js +521 -359
- package/extensions/dm-subagents/src/extension/rpc.js +266 -7
- package/extensions/dm-subagents/src/extension/schemas.js +275 -1
- package/extensions/dm-subagents/src/extension/tool-description.js +111 -6
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +126 -4
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +452 -5
- package/extensions/dm-subagents/src/intercom/result-intercom.js +319 -3
- package/extensions/dm-subagents/src/profiles/profiles.js +458 -3
- package/extensions/dm-subagents/src/runs/background/async-execution.js +834 -40
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +435 -14
- package/extensions/dm-subagents/src/runs/background/async-resume.js +334 -8
- package/extensions/dm-subagents/src/runs/background/async-status.js +313 -12
- package/extensions/dm-subagents/src/runs/background/chain-append.js +245 -2
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +136 -1
- package/extensions/dm-subagents/src/runs/background/completion-batcher.js +94 -1
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +54 -1
- package/extensions/dm-subagents/src/runs/background/control-channel.js +190 -1
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +483 -17
- package/extensions/dm-subagents/src/runs/background/notify.js +129 -3
- package/extensions/dm-subagents/src/runs/background/parallel-groups.js +34 -1
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +236 -6
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +76 -4
- package/extensions/dm-subagents/src/runs/background/run-status.js +427 -23
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +487 -4
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +306 -9
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +2849 -73
- package/extensions/dm-subagents/src/runs/background/top-level-async.js +5 -1
- package/extensions/dm-subagents/src/runs/background/wait.js +206 -11
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +1013 -12
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +980 -101
- package/extensions/dm-subagents/src/runs/foreground/execution.js +1165 -45
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +3157 -222
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +835 -3
- package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +104 -1
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +116 -3
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +208 -1
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +90 -1
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +282 -1
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +148 -1
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +305 -1
- package/extensions/dm-subagents/src/runs/shared/model-fallback.js +194 -1
- package/extensions/dm-subagents/src/runs/shared/model-scope.js +65 -1
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +851 -8
- package/extensions/dm-subagents/src/runs/shared/nested-path.js +41 -1
- package/extensions/dm-subagents/src/runs/shared/nested-render.js +105 -1
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +81 -4
- package/extensions/dm-subagents/src/runs/shared/run-history.js +51 -4
- package/extensions/dm-subagents/src/runs/shared/single-output.js +149 -8
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +58 -1
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +166 -5
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +329 -13
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +73 -1
- package/extensions/dm-subagents/src/runs/shared/turn-budget.js +47 -4
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +196 -1
- package/extensions/dm-subagents/src/runs/shared/worktree.js +435 -3
- package/extensions/dm-subagents/src/shared/artifacts.js +92 -2
- package/extensions/dm-subagents/src/shared/atomic-json.js +55 -1
- package/extensions/dm-subagents/src/shared/child-transcript.js +167 -5
- package/extensions/dm-subagents/src/shared/file-coalescer.js +25 -1
- package/extensions/dm-subagents/src/shared/fork-context.js +147 -4
- package/extensions/dm-subagents/src/shared/formatters.js +98 -7
- package/extensions/dm-subagents/src/shared/jsonl-writer.js +56 -2
- package/extensions/dm-subagents/src/shared/model-info.js +62 -1
- package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +68 -1
- package/extensions/dm-subagents/src/shared/session-identity.js +6 -1
- package/extensions/dm-subagents/src/shared/session-tokens.js +39 -2
- package/extensions/dm-subagents/src/shared/settings.js +198 -11
- package/extensions/dm-subagents/src/shared/status-format.js +53 -1
- package/extensions/dm-subagents/src/shared/types.js +184 -6
- package/extensions/dm-subagents/src/shared/utils.js +462 -2
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +288 -1
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +297 -7
- package/extensions/dm-subagents/src/slash/slash-bridge.js +118 -1
- package/extensions/dm-subagents/src/slash/slash-commands.js +1287 -31
- package/extensions/dm-subagents/src/slash/slash-live-state.js +240 -4
- package/extensions/dm-subagents/src/tui/render-helpers.js +64 -1
- package/extensions/dm-subagents/src/tui/render.js +1542 -4
- package/extensions/dm-usage/index.js +1294 -9
- package/extensions/greedysearch-dm/bin/cdp-greedy.mjs +40 -9
- package/extensions/greedysearch-dm/bin/cdp-headless.mjs +5 -2
- package/extensions/greedysearch-dm/bin/cdp-visible.mjs +5 -2
- package/extensions/greedysearch-dm/bin/cdp.mjs +896 -30
- package/extensions/greedysearch-dm/bin/gschrome.mjs +30 -2
- package/extensions/greedysearch-dm/bin/kill-visible.mjs +7 -2
- package/extensions/greedysearch-dm/bin/launch-visible.mjs +13 -2
- package/extensions/greedysearch-dm/bin/launch.mjs +282 -10
- package/extensions/greedysearch-dm/bin/mcp.mjs +386 -361
- package/extensions/greedysearch-dm/bin/search.mjs +620 -540
- package/extensions/greedysearch-dm/bin/visible.mjs +22 -2
- package/extensions/greedysearch-dm/extractors/bing-copilot.mjs +329 -579
- package/extensions/greedysearch-dm/extractors/chatgpt.mjs +301 -583
- package/extensions/greedysearch-dm/extractors/common.mjs +408 -32
- package/extensions/greedysearch-dm/extractors/consensus.mjs +376 -365
- package/extensions/greedysearch-dm/extractors/consent.mjs +303 -14
- package/extensions/greedysearch-dm/extractors/gemini.mjs +228 -592
- package/extensions/greedysearch-dm/extractors/google-ai.mjs +78 -499
- package/extensions/greedysearch-dm/extractors/logically.mjs +270 -347
- package/extensions/greedysearch-dm/extractors/perplexity.mjs +243 -581
- package/extensions/greedysearch-dm/extractors/selectors.mjs +32 -1
- package/extensions/greedysearch-dm/extractors/semantic-scholar.mjs +130 -317
- package/extensions/greedysearch-dm/index.js +123 -23
- package/extensions/greedysearch-dm/src/fetcher.mjs +576 -2
- package/extensions/greedysearch-dm/src/formatters/results.js +95 -10
- package/extensions/greedysearch-dm/src/formatters/sources.js +57 -1
- package/extensions/greedysearch-dm/src/formatters/synthesis.js +49 -1
- package/extensions/greedysearch-dm/src/github.mjs +222 -7
- package/extensions/greedysearch-dm/src/reddit.mjs +145 -14
- package/extensions/greedysearch-dm/src/search/browser-lifecycle.mjs +340 -9
- package/extensions/greedysearch-dm/src/search/challenge-detect.mjs +112 -4
- package/extensions/greedysearch-dm/src/search/chrome.mjs +486 -285
- package/extensions/greedysearch-dm/src/search/constants.mjs +109 -8
- package/extensions/greedysearch-dm/src/search/defaults.mjs +10 -1
- package/extensions/greedysearch-dm/src/search/engines.mjs +79 -9
- package/extensions/greedysearch-dm/src/search/fetch-source.mjs +441 -349
- package/extensions/greedysearch-dm/src/search/file-sources.mjs +29 -7
- package/extensions/greedysearch-dm/src/search/minimize.mjs +86 -1
- package/extensions/greedysearch-dm/src/search/output.mjs +51 -5
- package/extensions/greedysearch-dm/src/search/paths.mjs +48 -1
- package/extensions/greedysearch-dm/src/search/pdf.mjs +63 -2
- package/extensions/greedysearch-dm/src/search/port-pid.mjs +69 -1
- package/extensions/greedysearch-dm/src/search/progress.mjs +109 -2
- package/extensions/greedysearch-dm/src/search/query.mjs +21 -1
- package/extensions/greedysearch-dm/src/search/recovery.mjs +49 -1
- package/extensions/greedysearch-dm/src/search/research.mjs +2227 -458
- package/extensions/greedysearch-dm/src/search/scale-aware.mjs +61 -11
- package/extensions/greedysearch-dm/src/search/simple-research.mjs +396 -805
- package/extensions/greedysearch-dm/src/search/sources.mjs +412 -1
- package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +127 -12
- package/extensions/greedysearch-dm/src/search/synthesis.mjs +202 -12
- package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +209 -23
- package/extensions/greedysearch-dm/src/tools/shared.js +226 -10
- package/extensions/greedysearch-dm/src/utils/content.mjs +35 -4
- package/extensions/greedysearch-dm/src/utils/helpers.js +22 -1
- package/extensions/greedysearch-dm/src/utils/node-runtime.mjs +10 -1
- package/extensions/greedysearch-dm/src/utils/system-cmds.mjs +61 -1
- package/package.json +1 -1
|
@@ -1 +1,275 @@
|
|
|
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
|
+
import { Type } from "typebox";
|
|
2
|
+
function keepTopLevelParameterDescriptions(schema) {
|
|
3
|
+
return pruneNestedDescriptions(schema, []);
|
|
4
|
+
}
|
|
5
|
+
function pruneNestedDescriptions(value, path) {
|
|
6
|
+
if (!value || typeof value !== "object")
|
|
7
|
+
return value;
|
|
8
|
+
const result = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value));
|
|
9
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
10
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
11
|
+
if (!descriptor)
|
|
12
|
+
continue;
|
|
13
|
+
if (key === "description" && !isTopLevelParameterDescription(path))
|
|
14
|
+
continue;
|
|
15
|
+
if ("value" in descriptor) {
|
|
16
|
+
const nextPath = typeof key === "string" ? [...path, key] : path;
|
|
17
|
+
descriptor.value = pruneNestedDescriptions(descriptor.value, nextPath);
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(result, key, descriptor);
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
function isTopLevelParameterDescription(path) {
|
|
24
|
+
return path.length === 2 && path[0] === "properties";
|
|
25
|
+
}
|
|
26
|
+
const SkillOverride = Type.Unsafe({
|
|
27
|
+
anyOf: [
|
|
28
|
+
{ type: "array", items: { type: "string" } },
|
|
29
|
+
{ type: "boolean" },
|
|
30
|
+
{ type: "string" }
|
|
31
|
+
],
|
|
32
|
+
description: "Skill name(s) to make available (comma-separated), array of strings, or boolean (false disables, true uses default)"
|
|
33
|
+
});
|
|
34
|
+
const OutputOverride = Type.Unsafe({
|
|
35
|
+
anyOf: [
|
|
36
|
+
{ type: "string" },
|
|
37
|
+
{ type: "boolean" }
|
|
38
|
+
],
|
|
39
|
+
description: "Output filename/path (string), or false to disable file output"
|
|
40
|
+
});
|
|
41
|
+
const OutputModeOverride = Type.String({
|
|
42
|
+
enum: ["inline", "file-only"],
|
|
43
|
+
description: "Return saved output inline (default) or only a concise file reference. file-only requires output to be a path."
|
|
44
|
+
});
|
|
45
|
+
const ReadsOverride = Type.Unsafe({
|
|
46
|
+
anyOf: [
|
|
47
|
+
{ type: "array", items: { type: "string" } },
|
|
48
|
+
{ type: "boolean" }
|
|
49
|
+
],
|
|
50
|
+
description: "Files to read before running (array of filenames), or false to disable"
|
|
51
|
+
});
|
|
52
|
+
const JsonSchemaObject = Type.Unsafe({
|
|
53
|
+
type: "object",
|
|
54
|
+
additionalProperties: true,
|
|
55
|
+
description: "JSON Schema object for strict structured output. Non-object roots are rejected."
|
|
56
|
+
});
|
|
57
|
+
const AcceptanceOverride = Type.Unsafe({
|
|
58
|
+
anyOf: [
|
|
59
|
+
{ type: "string", enum: ["auto", "none", "attested", "checked", "verified", "reviewed"] },
|
|
60
|
+
{ type: "boolean", enum: [false] },
|
|
61
|
+
{ type: "object", additionalProperties: true }
|
|
62
|
+
],
|
|
63
|
+
description: "Optional acceptance policy. Omitted means auto-inferred; verified requires configured runtime commands."
|
|
64
|
+
});
|
|
65
|
+
const TurnBudgetOverride = Type.Object({
|
|
66
|
+
maxTurns: Type.Integer({ minimum: 1 }),
|
|
67
|
+
graceTurns: Type.Optional(Type.Integer({ minimum: 0 }))
|
|
68
|
+
}, { additionalProperties: false, 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." });
|
|
69
|
+
const ToolBudgetBlock = Type.Unsafe({
|
|
70
|
+
anyOf: [
|
|
71
|
+
{ type: "array", minItems: 1, items: { type: "string", minLength: 1 } },
|
|
72
|
+
{ type: "string", enum: ["*"] }
|
|
73
|
+
]
|
|
74
|
+
});
|
|
75
|
+
const ToolBudgetOverride = Type.Object({
|
|
76
|
+
soft: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
77
|
+
hard: Type.Integer({ minimum: 1 }),
|
|
78
|
+
block: Type.Optional(ToolBudgetBlock)
|
|
79
|
+
}, { additionalProperties: false, 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." });
|
|
80
|
+
const TaskItem = Type.Object({
|
|
81
|
+
agent: Type.String(),
|
|
82
|
+
task: Type.String(),
|
|
83
|
+
cwd: Type.Optional(Type.String()),
|
|
84
|
+
count: Type.Optional(Type.Integer({ minimum: 1, description: "Repeat this parallel task N times with the same settings." })),
|
|
85
|
+
output: Type.Optional(OutputOverride),
|
|
86
|
+
outputMode: Type.Optional(OutputModeOverride),
|
|
87
|
+
reads: Type.Optional(ReadsOverride),
|
|
88
|
+
progress: Type.Optional(Type.Boolean({ description: "Enable progress.md tracking for this task" })),
|
|
89
|
+
model: Type.Optional(Type.String({ description: "Override model for this task (e.g. 'google/gemini-3-pro')" })),
|
|
90
|
+
skill: Type.Optional(SkillOverride),
|
|
91
|
+
toolBudget: Type.Optional(ToolBudgetOverride),
|
|
92
|
+
acceptance: Type.Optional(AcceptanceOverride)
|
|
93
|
+
});
|
|
94
|
+
const ParallelTaskSchema = Type.Object({
|
|
95
|
+
agent: Type.String(),
|
|
96
|
+
task: Type.Optional(Type.String({ description: "Task template with {task}, {previous}, {chain_dir} variables. Defaults to {previous}." })),
|
|
97
|
+
phase: Type.Optional(Type.String({ description: "Optional phase/group label for status and graph rendering." })),
|
|
98
|
+
label: Type.Optional(Type.String({ description: "Optional user-facing label for this parallel task." })),
|
|
99
|
+
as: Type.Optional(Type.String({ description: "Optional safe identifier used as {outputs.name} in later chain steps." })),
|
|
100
|
+
outputSchema: Type.Optional(JsonSchemaObject),
|
|
101
|
+
cwd: Type.Optional(Type.String()),
|
|
102
|
+
count: Type.Optional(Type.Integer({ minimum: 1, description: "Repeat this parallel task N times with the same settings." })),
|
|
103
|
+
output: Type.Optional(OutputOverride),
|
|
104
|
+
outputMode: Type.Optional(OutputModeOverride),
|
|
105
|
+
reads: Type.Optional(ReadsOverride),
|
|
106
|
+
progress: Type.Optional(Type.Boolean({ description: "Enable progress.md tracking in {chain_dir}" })),
|
|
107
|
+
skill: Type.Optional(SkillOverride),
|
|
108
|
+
model: Type.Optional(Type.String({ description: "Override model for this task" })),
|
|
109
|
+
toolBudget: Type.Optional(ToolBudgetOverride),
|
|
110
|
+
acceptance: Type.Optional(AcceptanceOverride)
|
|
111
|
+
});
|
|
112
|
+
const DynamicExpandSchema = Type.Object({
|
|
113
|
+
from: Type.Object({
|
|
114
|
+
output: Type.String({ description: "Prior named structured output to expand from." }),
|
|
115
|
+
path: Type.String({ description: "JSON Pointer into the structured output, e.g. /items." })
|
|
116
|
+
}, { additionalProperties: false }),
|
|
117
|
+
item: Type.Optional(Type.String({ description: "Template variable name for each item. Defaults to item." })),
|
|
118
|
+
key: Type.Optional(Type.String({ description: "JSON Pointer relative to each item for stable child ids." })),
|
|
119
|
+
maxItems: Type.Optional(Type.Integer({ minimum: 0, description: "Required fanout bound unless configured globally." })),
|
|
120
|
+
onEmpty: Type.Optional(Type.String({ enum: ["skip", "fail"], description: "Empty input behavior. Defaults to skip." }))
|
|
121
|
+
}, { additionalProperties: false });
|
|
122
|
+
const DynamicParallelTemplateSchema = Type.Object({
|
|
123
|
+
agent: Type.String(),
|
|
124
|
+
task: Type.Optional(Type.String({ description: "Task template with {item}, {item.path}, {task}, {previous}, {chain_dir}, and {outputs.name} variables." })),
|
|
125
|
+
phase: Type.Optional(Type.String({ description: "Optional phase/group label for status and graph rendering." })),
|
|
126
|
+
label: Type.Optional(Type.String({ description: "Optional user-facing label; item templates are supported." })),
|
|
127
|
+
outputSchema: Type.Optional(JsonSchemaObject),
|
|
128
|
+
cwd: Type.Optional(Type.String()),
|
|
129
|
+
output: Type.Optional(OutputOverride),
|
|
130
|
+
outputMode: Type.Optional(OutputModeOverride),
|
|
131
|
+
reads: Type.Optional(ReadsOverride),
|
|
132
|
+
progress: Type.Optional(Type.Boolean({ description: "Enable progress.md tracking in {chain_dir}" })),
|
|
133
|
+
skill: Type.Optional(SkillOverride),
|
|
134
|
+
model: Type.Optional(Type.String({ description: "Override model for this task" })),
|
|
135
|
+
toolBudget: Type.Optional(ToolBudgetOverride),
|
|
136
|
+
acceptance: Type.Optional(AcceptanceOverride)
|
|
137
|
+
}, { additionalProperties: false });
|
|
138
|
+
const DynamicCollectSchema = Type.Object({
|
|
139
|
+
as: Type.String({ description: "Safe output name for the ordered collected result array." }),
|
|
140
|
+
outputSchema: Type.Optional(JsonSchemaObject)
|
|
141
|
+
}, { additionalProperties: false });
|
|
142
|
+
const ChainItem = Type.Object({
|
|
143
|
+
agent: Type.Optional(Type.String({ description: "Sequential step agent name" })),
|
|
144
|
+
task: Type.Optional(Type.String({
|
|
145
|
+
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."
|
|
146
|
+
})),
|
|
147
|
+
phase: Type.Optional(Type.String({ description: "Optional phase/group label for status and graph rendering." })),
|
|
148
|
+
label: Type.Optional(Type.String({ description: "Optional user-facing label for this chain step." })),
|
|
149
|
+
as: Type.Optional(Type.String({ description: "Optional safe identifier used as {outputs.name} in later chain steps." })),
|
|
150
|
+
outputSchema: Type.Optional(JsonSchemaObject),
|
|
151
|
+
cwd: Type.Optional(Type.String()),
|
|
152
|
+
output: Type.Optional(OutputOverride),
|
|
153
|
+
outputMode: Type.Optional(OutputModeOverride),
|
|
154
|
+
reads: Type.Optional(ReadsOverride),
|
|
155
|
+
progress: Type.Optional(Type.Boolean({ description: "Enable progress.md tracking in {chain_dir}" })),
|
|
156
|
+
skill: Type.Optional(SkillOverride),
|
|
157
|
+
model: Type.Optional(Type.String({ description: "Override model for this step" })),
|
|
158
|
+
toolBudget: Type.Optional(ToolBudgetOverride),
|
|
159
|
+
acceptance: Type.Optional(AcceptanceOverride),
|
|
160
|
+
parallel: Type.Optional(Type.Unsafe({
|
|
161
|
+
anyOf: [
|
|
162
|
+
Type.Array(ParallelTaskSchema, { minItems: 1, description: "Tasks to run in parallel" }),
|
|
163
|
+
DynamicParallelTemplateSchema
|
|
164
|
+
],
|
|
165
|
+
description: "Static parallel tasks array, or a single dynamic fanout child template when expand/collect are present."
|
|
166
|
+
})),
|
|
167
|
+
expand: Type.Optional(DynamicExpandSchema),
|
|
168
|
+
collect: Type.Optional(DynamicCollectSchema),
|
|
169
|
+
concurrency: Type.Optional(Type.Number({ description: "Max concurrent tasks (default: 4)" })),
|
|
170
|
+
failFast: Type.Optional(Type.Boolean({ description: "Stop on first failure (default: false)" })),
|
|
171
|
+
worktree: Type.Optional(Type.Boolean({
|
|
172
|
+
description: "Create isolated git worktrees for each parallel task."
|
|
173
|
+
}))
|
|
174
|
+
}, {
|
|
175
|
+
description: "Chain step: use {agent, task?, ...} for sequential, {parallel: [...]} for static concurrent execution, or {expand, parallel: {...}, collect} for dynamic fanout.",
|
|
176
|
+
additionalProperties: false
|
|
177
|
+
});
|
|
178
|
+
const ControlOverrides = Type.Object({
|
|
179
|
+
enabled: Type.Optional(Type.Boolean({ description: "Enable/disable subagent control attention tracking for this run" })),
|
|
180
|
+
needsAttentionAfterMs: Type.Optional(Type.Integer({ minimum: 1, description: "No-observed-activity window before a run needs attention" })),
|
|
181
|
+
activeNoticeAfterMs: Type.Optional(Type.Integer({ minimum: 1, description: "Active-long-running notice threshold by elapsed ms (default: 240000)" })),
|
|
182
|
+
activeNoticeAfterTurns: Type.Optional(Type.Integer({ minimum: 1, description: "Optional active-long-running notice threshold by assistant turns (disabled by default)" })),
|
|
183
|
+
activeNoticeAfterTokens: Type.Optional(Type.Integer({ minimum: 1, description: "Optional active-long-running notice threshold by total tokens (disabled by default)" })),
|
|
184
|
+
failedToolAttemptsBeforeAttention: Type.Optional(Type.Integer({ minimum: 1, description: "Consecutive mutating-tool failures before escalating to needs_attention (default: 3)" })),
|
|
185
|
+
notifyOn: Type.Optional(Type.Array(Type.String({ enum: ["active_long_running", "needs_attention"] }), {
|
|
186
|
+
description: "Control event types that should notify the parent/orchestrator. Defaults to active_long_running and needs_attention."
|
|
187
|
+
})),
|
|
188
|
+
notifyChannels: Type.Optional(Type.Array(Type.String({ enum: ["event", "async", "intercom"] }), {
|
|
189
|
+
description: "Notification channels to use when available. Defaults to event, async, and intercom."
|
|
190
|
+
}))
|
|
191
|
+
});
|
|
192
|
+
const SubagentParamsSchema = Type.Object({
|
|
193
|
+
agent: Type.Optional(Type.String({ description: "Agent name (SINGLE mode) or target for management get/update/delete" })),
|
|
194
|
+
task: Type.Optional(Type.String({ description: "Task (SINGLE mode, optional for self-contained agents)" })),
|
|
195
|
+
action: Type.Optional(Type.String({
|
|
196
|
+
description: "Management/control action only. Must be omitted for execution mode (single, parallel, or chain)."
|
|
197
|
+
})),
|
|
198
|
+
id: Type.Optional(Type.String({
|
|
199
|
+
description: "Run id or prefix for action='status', action='interrupt', action='resume', action='steer', or action='append-step'."
|
|
200
|
+
})),
|
|
201
|
+
runId: Type.Optional(Type.String({
|
|
202
|
+
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."
|
|
203
|
+
})),
|
|
204
|
+
dir: Type.Optional(Type.String({
|
|
205
|
+
description: "Async run directory for action='status', action='resume', or action='steer'."
|
|
206
|
+
})),
|
|
207
|
+
index: Type.Optional(Type.Integer({ minimum: 0, description: "Zero-based child index for actions that target a specific child or transcript." })),
|
|
208
|
+
view: Type.Optional(Type.String({
|
|
209
|
+
enum: ["fleet", "transcript"],
|
|
210
|
+
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."
|
|
211
|
+
})),
|
|
212
|
+
lines: Type.Optional(Type.Integer({ minimum: 1, maximum: 500, description: "Maximum transcript lines for action='status', view='transcript'. Defaults to 80." })),
|
|
213
|
+
message: Type.Optional(Type.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." })),
|
|
214
|
+
schedule: Type.Optional(Type.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." })),
|
|
215
|
+
scheduleName: Type.Optional(Type.String({ description: "Optional display name for action='schedule'." })),
|
|
216
|
+
chainName: Type.Optional(Type.String({
|
|
217
|
+
description: "Chain name for get/update/delete management actions"
|
|
218
|
+
})),
|
|
219
|
+
config: Type.Optional(Type.Unsafe({
|
|
220
|
+
anyOf: [
|
|
221
|
+
{ type: "object", additionalProperties: true },
|
|
222
|
+
{ type: "string" }
|
|
223
|
+
],
|
|
224
|
+
description: "Agent/chain config for create/update. Object or JSON string; presence of steps creates a chain."
|
|
225
|
+
})),
|
|
226
|
+
tasks: Type.Optional(Type.Array(TaskItem, { description: "PARALLEL mode: [{agent, task, count?, output?, outputMode?, reads?, progress?}, ...]" })),
|
|
227
|
+
concurrency: Type.Optional(Type.Integer({ minimum: 1, description: "Top-level PARALLEL mode only: max concurrent tasks. Defaults to config.parallel.concurrency or 4." })),
|
|
228
|
+
worktree: Type.Optional(Type.Boolean({
|
|
229
|
+
description: "Create isolated git worktrees for parallel tasks; requires clean git state."
|
|
230
|
+
})),
|
|
231
|
+
chain: Type.Optional(Type.Array(ChainItem, { description: "CHAIN mode: sequential steps; each result becomes {previous}. append-step takes one tail step and may use {chain_dir}/{outputs.name}." })),
|
|
232
|
+
context: Type.Optional(Type.String({
|
|
233
|
+
enum: ["fresh", "fork"],
|
|
234
|
+
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."
|
|
235
|
+
})),
|
|
236
|
+
chainDir: Type.Optional(Type.String({ description: "Persistent chain artifact directory; defaults to user-scoped temp storage." })),
|
|
237
|
+
async: Type.Optional(Type.Boolean({ description: "Run in background (default: false, or per config)" })),
|
|
238
|
+
timeoutMs: Type.Optional(Type.Integer({ minimum: 1, description: "Optional run-level timeout in ms for foreground and async/background runs. Alias of maxRuntimeMs." })),
|
|
239
|
+
maxRuntimeMs: Type.Optional(Type.Integer({ minimum: 1, description: "Alias of timeoutMs for optional run-level timeout in foreground and async/background runs." })),
|
|
240
|
+
turnBudget: Type.Optional(TurnBudgetOverride),
|
|
241
|
+
toolBudget: Type.Optional(ToolBudgetOverride),
|
|
242
|
+
agentScope: Type.Optional(Type.String({ description: "Agent discovery scope: 'user', 'project', or 'both' (default: 'both'; project wins on name collisions)" })),
|
|
243
|
+
cwd: Type.Optional(Type.String()),
|
|
244
|
+
artifacts: Type.Optional(Type.Boolean({ description: "Write debug artifacts (default: true)" })),
|
|
245
|
+
includeProgress: Type.Optional(Type.Boolean({ description: "Include full progress in result (default: false)" })),
|
|
246
|
+
share: Type.Optional(Type.Boolean({ description: "Upload session to GitHub Gist for sharing (default: false)" })),
|
|
247
|
+
sessionDir: Type.Optional(Type.String({ description: "Directory to store session logs (default: temp; enables sessions even if share=false)" })),
|
|
248
|
+
clarify: Type.Optional(Type.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." })),
|
|
249
|
+
control: Type.Optional(ControlOverrides),
|
|
250
|
+
output: Type.Optional(Type.Unsafe({
|
|
251
|
+
anyOf: [
|
|
252
|
+
{ type: "string" },
|
|
253
|
+
{ type: "boolean" }
|
|
254
|
+
],
|
|
255
|
+
description: "Output file for single agent (string), or false to disable. Relative paths resolve against cwd."
|
|
256
|
+
})),
|
|
257
|
+
outputMode: Type.Optional(OutputModeOverride),
|
|
258
|
+
skill: Type.Optional(SkillOverride),
|
|
259
|
+
model: Type.Optional(Type.String({ description: "Override model for single agent (e.g. 'anthropic/claude-sonnet-4')" })),
|
|
260
|
+
acceptance: Type.Optional(AcceptanceOverride)
|
|
261
|
+
});
|
|
262
|
+
export const SubagentParams = keepTopLevelParameterDescriptions(SubagentParamsSchema);
|
|
263
|
+
const WaitParamsSchema = Type.Object({
|
|
264
|
+
id: Type.Optional(Type.String({
|
|
265
|
+
description: "Run id or prefix to wait for one specific run. Omit to wait across every active async run started in this session."
|
|
266
|
+
})),
|
|
267
|
+
all: Type.Optional(Type.Boolean({
|
|
268
|
+
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."
|
|
269
|
+
})),
|
|
270
|
+
timeoutMs: Type.Optional(Type.Integer({
|
|
271
|
+
minimum: 1,
|
|
272
|
+
description: "Give up waiting after this many milliseconds (the runs keep going regardless). Defaults to 1800000 (30 minutes)."
|
|
273
|
+
}))
|
|
274
|
+
});
|
|
275
|
+
export const WaitParams = keepTopLevelParameterDescriptions(WaitParamsSchema);
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { getAgentDir, getProjectConfigDir } from "../shared/utils.js";
|
|
4
|
+
const CUSTOM_TOOL_DESCRIPTION_FILE = "subagent-tool-description.md";
|
|
5
|
+
const CUSTOM_TOOL_DESCRIPTION_MAX_BYTES = 50 * 1024;
|
|
6
|
+
export const SUBAGENT_SAFETY_GUIDANCE = `SAFETY-CRITICAL SUBAGENT GUIDANCE:
|
|
2
7
|
• Use { action: "list" } before execution and only run executable/non-disabled agents or chains.
|
|
3
8
|
• 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.
|
|
4
9
|
• 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.
|
|
5
10
|
• 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.
|
|
6
11
|
• 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.
|
|
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
|
|
12
|
+
• 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.`;
|
|
13
|
+
export const FULL_SUBAGENT_TOOL_DESCRIPTION = `Delegate to subagents or manage agent definitions.
|
|
8
14
|
|
|
9
15
|
EXECUTION (use exactly ONE mode):
|
|
10
16
|
• Before executing, use { action: "list" } to inspect configured agents/chains. Only execute agents listed as executable/non-disabled.
|
|
@@ -53,7 +59,8 @@ SCHEDULE (opt-in; requires { "scheduledRuns": { "enabled": true } } in config.js
|
|
|
53
59
|
DIAGNOSTICS:
|
|
54
60
|
• { action: "doctor" } - read-only report for runtime paths, discovery, sessions, and intercom
|
|
55
61
|
|
|
56
|
-
${
|
|
62
|
+
${SUBAGENT_SAFETY_GUIDANCE}`;
|
|
63
|
+
export const COMPACT_SUBAGENT_TOOL_DESCRIPTION = `Delegate to subagents or manage definitions. Use exactly one mode per call.
|
|
57
64
|
|
|
58
65
|
EXECUTE:
|
|
59
66
|
• Before execution, call { action: "list" }; run only executable/non-disabled configured agents/chains.
|
|
@@ -73,8 +80,106 @@ ASYNC / WAIT:
|
|
|
73
80
|
|
|
74
81
|
SAFETY:
|
|
75
82
|
• 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.
|
|
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.`;
|
|
83
|
+
• 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.`;
|
|
84
|
+
function isToolDescriptionMode(value) {
|
|
85
|
+
return value === "full" || value === "compact" || value === "custom";
|
|
86
|
+
}
|
|
87
|
+
function warn(options, message) {
|
|
88
|
+
(options?.warn ?? console.warn)(`[dm-subagents] ${message}`);
|
|
89
|
+
}
|
|
90
|
+
export function resolveToolDescriptionMode(config, options) {
|
|
91
|
+
const mode = config.toolDescriptionMode;
|
|
92
|
+
if (mode === undefined)
|
|
93
|
+
return "full";
|
|
94
|
+
if (isToolDescriptionMode(mode))
|
|
95
|
+
return mode;
|
|
96
|
+
warn(options, `Ignoring invalid toolDescriptionMode ${JSON.stringify(mode)}; expected "full", "compact", or "custom".`);
|
|
97
|
+
return "full";
|
|
98
|
+
}
|
|
99
|
+
function customDescriptionPaths(options) {
|
|
100
|
+
const cwd = options?.cwd ?? process.cwd();
|
|
101
|
+
const agentDir = options?.agentDir ?? getAgentDir();
|
|
102
|
+
return [
|
|
103
|
+
path.join(getProjectConfigDir(cwd), CUSTOM_TOOL_DESCRIPTION_FILE),
|
|
104
|
+
path.join(agentDir, CUSTOM_TOOL_DESCRIPTION_FILE)
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
function renderCustomTemplate(template, options) {
|
|
108
|
+
const cwd = options?.cwd ?? process.cwd();
|
|
109
|
+
const agentDir = options?.agentDir ?? getAgentDir();
|
|
110
|
+
const projectConfigDir = getProjectConfigDir(cwd);
|
|
111
|
+
const variables = {
|
|
112
|
+
fullDescription: () => FULL_SUBAGENT_TOOL_DESCRIPTION,
|
|
113
|
+
full: () => FULL_SUBAGENT_TOOL_DESCRIPTION,
|
|
114
|
+
compactDescription: () => COMPACT_SUBAGENT_TOOL_DESCRIPTION,
|
|
115
|
+
compact: () => COMPACT_SUBAGENT_TOOL_DESCRIPTION,
|
|
116
|
+
safetyGuidance: () => SUBAGENT_SAFETY_GUIDANCE,
|
|
117
|
+
safety: () => SUBAGENT_SAFETY_GUIDANCE,
|
|
118
|
+
agentDir: () => agentDir,
|
|
119
|
+
projectConfigDir: () => projectConfigDir
|
|
120
|
+
};
|
|
121
|
+
return template.replace(/\{\{(\w+)\}\}/g, (raw, name) => {
|
|
122
|
+
const replacement = variables[name];
|
|
123
|
+
if (replacement)
|
|
124
|
+
return replacement();
|
|
125
|
+
warn(options, `${CUSTOM_TOOL_DESCRIPTION_FILE}: unknown placeholder ${raw} left unchanged.`);
|
|
126
|
+
return raw;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function loadCustomToolDescription(options) {
|
|
130
|
+
for (const filePath of customDescriptionPaths(options)) {
|
|
131
|
+
let stat;
|
|
132
|
+
try {
|
|
133
|
+
stat = fs.statSync(filePath);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
|
|
136
|
+
continue;
|
|
137
|
+
warn(options, `Failed to inspect custom tool description '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (!stat.isFile()) {
|
|
141
|
+
warn(options, `Ignoring custom tool description '${filePath}' because it is not a file.`);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (stat.size > CUSTOM_TOOL_DESCRIPTION_MAX_BYTES) {
|
|
145
|
+
warn(options, `Ignoring custom tool description '${filePath}' because it is larger than ${CUSTOM_TOOL_DESCRIPTION_MAX_BYTES} bytes.`);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
const template = fs.readFileSync(filePath, "utf-8").trim();
|
|
150
|
+
if (!template) {
|
|
151
|
+
warn(options, `Ignoring empty custom tool description '${filePath}'.`);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const rendered = renderCustomTemplate(template, options).trim();
|
|
155
|
+
if (!rendered) {
|
|
156
|
+
warn(options, `Ignoring custom tool description '${filePath}' because it rendered empty.`);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
return rendered;
|
|
160
|
+
} catch (error) {
|
|
161
|
+
warn(options, `Failed to read custom tool description '${filePath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
function withMandatorySafetyGuidance(description) {
|
|
167
|
+
const customDescription = description.split(SUBAGENT_SAFETY_GUIDANCE).map((part) => part.trim()).filter(Boolean).join(`
|
|
77
168
|
|
|
78
|
-
`);
|
|
169
|
+
`);
|
|
170
|
+
return customDescription ? `${customDescription}
|
|
79
171
|
|
|
80
|
-
${
|
|
172
|
+
${SUBAGENT_SAFETY_GUIDANCE}` : SUBAGENT_SAFETY_GUIDANCE;
|
|
173
|
+
}
|
|
174
|
+
export function buildSubagentToolDescription(config = {}, options) {
|
|
175
|
+
const mode = resolveToolDescriptionMode(config, options);
|
|
176
|
+
if (mode === "compact")
|
|
177
|
+
return COMPACT_SUBAGENT_TOOL_DESCRIPTION;
|
|
178
|
+
if (mode === "custom") {
|
|
179
|
+
const custom = loadCustomToolDescription(options);
|
|
180
|
+
if (custom)
|
|
181
|
+
return withMandatorySafetyGuidance(custom);
|
|
182
|
+
warn(options, `${CUSTOM_TOOL_DESCRIPTION_FILE} was not found or valid for toolDescriptionMode "custom"; using full description.`);
|
|
183
|
+
}
|
|
184
|
+
return FULL_SUBAGENT_TOOL_DESCRIPTION;
|
|
185
|
+
}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { getAgentDir } from "../shared/utils.js";
|
|
5
|
+
export const NATIVE_INTERCOM_EXTENSION_DIR = "native:dm-subagents-supervisor-channel";
|
|
6
|
+
function defaultAgentDir() {
|
|
7
|
+
return getAgentDir();
|
|
8
|
+
}
|
|
9
|
+
function defaultSubagentConfigDir(agentDir = defaultAgentDir()) {
|
|
10
|
+
return path.join(agentDir, "extensions", "subagent");
|
|
11
|
+
}
|
|
12
|
+
const DEFAULT_INTERCOM_TARGET_PREFIX = "subagent-chat";
|
|
13
|
+
export const INTERCOM_BRIDGE_MARKER = "Intercom orchestration channel:";
|
|
14
|
+
const DEFAULT_INTERCOM_BRIDGE_TEMPLATE = `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
15
|
|
|
3
16
|
Use contact_supervisor first. It resolves the supervisor session "{orchestratorTarget}" and run metadata automatically.
|
|
4
17
|
- Need a decision, blocked, approval, or product/API/scope ambiguity: contact_supervisor({ reason: "need_decision", message: "<question>" })
|
|
@@ -7,7 +20,116 @@ Use contact_supervisor first. It resolves the supervisor session "{orchestratorT
|
|
|
7
20
|
- Meaningful progress or unexpected discoveries that change the plan: contact_supervisor({ reason: "progress_update", message: "UPDATE: <summary>" })
|
|
8
21
|
- Generic intercom is lower-level plumbing/fallback only: intercom({ action: "ask", to: "{orchestratorTarget}", message: "<question>" })
|
|
9
22
|
|
|
10
|
-
Do not use contact_supervisor or intercom for routine completion handoffs. If no coordination is needed, return a focused task result.`;
|
|
11
|
-
|
|
23
|
+
Do not use contact_supervisor or intercom for routine completion handoffs. If no coordination is needed, return a focused task result.`;
|
|
24
|
+
export function resolveIntercomSessionTarget(sessionName, sessionId) {
|
|
25
|
+
const trimmedName = sessionName?.trim();
|
|
26
|
+
if (trimmedName)
|
|
27
|
+
return trimmedName;
|
|
28
|
+
const normalizedSessionId = sessionId.startsWith("session-") ? sessionId.slice("session-".length) : sessionId;
|
|
29
|
+
return `${DEFAULT_INTERCOM_TARGET_PREFIX}-${normalizedSessionId.slice(0, 8)}`;
|
|
30
|
+
}
|
|
31
|
+
function sanitizeIntercomTargetPart(value) {
|
|
32
|
+
return value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "agent";
|
|
33
|
+
}
|
|
34
|
+
export function resolveSubagentIntercomTarget(runId, agent, index) {
|
|
35
|
+
const stepSuffix = index !== undefined ? `-${index + 1}` : "";
|
|
36
|
+
return `subagent-${sanitizeIntercomTargetPart(agent)}-${sanitizeIntercomTargetPart(runId)}${stepSuffix}`;
|
|
37
|
+
}
|
|
38
|
+
export function resolveIntercomBridgeMode(value) {
|
|
39
|
+
if (value === "off" || value === "always" || value === "fork-only")
|
|
40
|
+
return value;
|
|
41
|
+
return "always";
|
|
42
|
+
}
|
|
43
|
+
function resolveIntercomBridgeConfig(value) {
|
|
44
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
45
|
+
return { mode: "always", instructionFile: "" };
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
mode: resolveIntercomBridgeMode(value.mode),
|
|
49
|
+
instructionFile: typeof value.instructionFile === "string" ? value.instructionFile : ""
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function expandTilde(filePath) {
|
|
53
|
+
return filePath.startsWith("~/") ? path.join(os.homedir(), filePath.slice(2)) : filePath;
|
|
54
|
+
}
|
|
55
|
+
function resolveInstructionTemplate(instructionFile, settingsDir) {
|
|
56
|
+
if (!instructionFile)
|
|
57
|
+
return DEFAULT_INTERCOM_BRIDGE_TEMPLATE;
|
|
58
|
+
const expandedPath = expandTilde(instructionFile);
|
|
59
|
+
const resolvedPath = path.isAbsolute(expandedPath) ? expandedPath : path.resolve(settingsDir, expandedPath);
|
|
60
|
+
try {
|
|
61
|
+
return fs.readFileSync(resolvedPath, "utf-8");
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.warn(`Failed to read intercom bridge instructionFile at '${resolvedPath}'. Using default instructions.`, error);
|
|
64
|
+
return DEFAULT_INTERCOM_BRIDGE_TEMPLATE;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function buildIntercomBridgeInstruction(orchestratorTarget, template) {
|
|
68
|
+
const instruction = template.replaceAll("{orchestratorTarget}", orchestratorTarget).trim();
|
|
69
|
+
if (instruction.startsWith(INTERCOM_BRIDGE_MARKER))
|
|
70
|
+
return instruction;
|
|
71
|
+
return `${INTERCOM_BRIDGE_MARKER}
|
|
72
|
+
${instruction}`;
|
|
73
|
+
}
|
|
74
|
+
function inactiveReason(mode, context, orchestratorTarget) {
|
|
75
|
+
if (mode === "off")
|
|
76
|
+
return "bridge mode is off";
|
|
77
|
+
if (mode === "fork-only" && context !== "fork")
|
|
78
|
+
return "bridge mode is fork-only and context is not fork";
|
|
79
|
+
if (!orchestratorTarget)
|
|
80
|
+
return "orchestrator target is not available";
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
export function diagnoseIntercomBridge(input) {
|
|
84
|
+
const config = resolveIntercomBridgeConfig(input.config);
|
|
85
|
+
const mode = config.mode;
|
|
86
|
+
const orchestratorTarget = input.orchestratorTarget?.trim();
|
|
87
|
+
const wantsIntercom = mode !== "off" && !(mode === "fork-only" && input.context !== "fork");
|
|
88
|
+
const reason = inactiveReason(mode, input.context, orchestratorTarget);
|
|
89
|
+
return {
|
|
90
|
+
active: reason === undefined,
|
|
91
|
+
mode,
|
|
92
|
+
wantsIntercom,
|
|
93
|
+
supervisorChannelAvailable: true,
|
|
94
|
+
extensionDir: NATIVE_INTERCOM_EXTENSION_DIR,
|
|
95
|
+
...orchestratorTarget ? { orchestratorTarget } : {},
|
|
96
|
+
...reason ? { reason } : {}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export function resolveIntercomBridge(input) {
|
|
100
|
+
const config = resolveIntercomBridgeConfig(input.config);
|
|
101
|
+
const mode = config.mode;
|
|
102
|
+
const orchestratorTarget = input.orchestratorTarget?.trim();
|
|
103
|
+
const agentDir = path.resolve(input.agentDir ?? defaultAgentDir());
|
|
104
|
+
const settingsDir = path.resolve(input.settingsDir ?? defaultSubagentConfigDir(agentDir));
|
|
105
|
+
const defaultInstruction = buildIntercomBridgeInstruction(orchestratorTarget || "{orchestratorTarget}", DEFAULT_INTERCOM_BRIDGE_TEMPLATE);
|
|
106
|
+
const reason = inactiveReason(mode, input.context, orchestratorTarget);
|
|
107
|
+
if (reason || !orchestratorTarget) {
|
|
108
|
+
return { active: false, mode, extensionDir: NATIVE_INTERCOM_EXTENSION_DIR, instruction: defaultInstruction };
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
active: true,
|
|
112
|
+
mode,
|
|
113
|
+
orchestratorTarget,
|
|
114
|
+
extensionDir: NATIVE_INTERCOM_EXTENSION_DIR,
|
|
115
|
+
instruction: buildIntercomBridgeInstruction(orchestratorTarget, resolveInstructionTemplate(config.instructionFile, settingsDir))
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export function applyIntercomBridgeToAgent(agent, bridge) {
|
|
119
|
+
if (!bridge.active || !bridge.orchestratorTarget)
|
|
120
|
+
return agent;
|
|
121
|
+
const bridgeTools = ["intercom", "contact_supervisor"];
|
|
122
|
+
const tools = agent.tools ? [...agent.tools, ...bridgeTools.filter((tool) => !agent.tools?.includes(tool))] : agent.tools;
|
|
123
|
+
const instruction = bridge.instruction;
|
|
124
|
+
const trimmedPrompt = agent.systemPrompt?.trim() || "";
|
|
125
|
+
const systemPrompt = trimmedPrompt.includes(INTERCOM_BRIDGE_MARKER) ? trimmedPrompt : trimmedPrompt ? `${trimmedPrompt}
|
|
12
126
|
|
|
13
|
-
${
|
|
127
|
+
${instruction}` : instruction;
|
|
128
|
+
if (tools === agent.tools && systemPrompt === agent.systemPrompt)
|
|
129
|
+
return agent;
|
|
130
|
+
return {
|
|
131
|
+
...agent,
|
|
132
|
+
tools,
|
|
133
|
+
systemPrompt
|
|
134
|
+
};
|
|
135
|
+
}
|