@duckmind/dm-darwin-x64 0.43.4 → 0.48.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/dm +0 -0
  2. package/extensions/.dm-extensions.json +242 -50
  3. package/extensions/dm-9router-ext/package.json +2 -19
  4. package/extensions/dm-9router-ext/src/index.js +5 -0
  5. package/extensions/dm-ask-user/index.js +10 -0
  6. package/extensions/dm-ask-user/package.json +1 -21
  7. package/extensions/dm-cli-anything/package.json +0 -6
  8. package/extensions/dm-context/package.json +2 -12
  9. package/extensions/dm-context/src/context.js +1 -0
  10. package/extensions/dm-context/src/index.js +7 -0
  11. package/extensions/dm-context/src/utils.js +1 -0
  12. package/extensions/dm-cua/package.json +0 -7
  13. package/extensions/dm-fff/package.json +1 -28
  14. package/extensions/dm-fff/src/index.js +15 -0
  15. package/extensions/dm-fff/src/query.js +1 -0
  16. package/extensions/dm-goal/package.json +2 -31
  17. package/extensions/dm-goal/src/goal.js +43 -0
  18. package/extensions/dm-grill-me/index.js +174 -0
  19. package/extensions/dm-grill-me/package.json +1 -26
  20. package/extensions/dm-image2/package.json +0 -7
  21. package/extensions/dm-subagents/package.json +1 -32
  22. package/extensions/dm-subagents/src/agents/agent-management.js +37 -0
  23. package/extensions/dm-subagents/src/agents/agent-memory.js +6 -0
  24. package/extensions/dm-subagents/src/agents/agent-scope.js +1 -0
  25. package/extensions/dm-subagents/src/agents/agent-selection.js +1 -0
  26. package/extensions/dm-subagents/src/agents/agent-serializer.js +7 -0
  27. package/extensions/dm-subagents/src/agents/agents.js +11 -0
  28. package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -0
  29. package/extensions/dm-subagents/src/agents/frontmatter.js +6 -0
  30. package/extensions/dm-subagents/src/agents/identity.js +1 -0
  31. package/extensions/dm-subagents/src/agents/proactive-skills.js +1 -0
  32. package/extensions/dm-subagents/src/agents/skills.js +6 -0
  33. package/extensions/dm-subagents/src/extension/config.js +2 -0
  34. package/extensions/dm-subagents/src/extension/control-notices.js +4 -0
  35. package/extensions/dm-subagents/src/extension/doctor.js +16 -0
  36. package/extensions/dm-subagents/src/extension/fanout-child.js +231 -0
  37. package/extensions/dm-subagents/src/extension/index.js +367 -0
  38. package/extensions/dm-subagents/src/extension/rpc.js +8 -0
  39. package/extensions/dm-subagents/src/extension/schemas.js +1 -0
  40. package/extensions/dm-subagents/src/extension/{tool-description.ts → tool-description.js} +6 -126
  41. package/extensions/dm-subagents/src/intercom/intercom-bridge.js +13 -0
  42. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +5 -0
  43. package/extensions/dm-subagents/src/intercom/result-intercom.js +3 -0
  44. package/extensions/dm-subagents/src/profiles/profiles.js +3 -0
  45. package/extensions/dm-subagents/src/runs/background/async-execution.js +46 -0
  46. package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +14 -0
  47. package/extensions/dm-subagents/src/runs/background/async-resume.js +8 -0
  48. package/extensions/dm-subagents/src/runs/background/async-status.js +12 -0
  49. package/extensions/dm-subagents/src/runs/background/chain-append.js +2 -0
  50. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +1 -0
  51. package/extensions/dm-subagents/src/runs/background/completion-batcher.js +1 -0
  52. package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +1 -0
  53. package/extensions/dm-subagents/src/runs/background/control-channel.js +1 -0
  54. package/extensions/dm-subagents/src/runs/background/fleet-view.js +17 -0
  55. package/extensions/dm-subagents/src/runs/background/notify.js +3 -0
  56. package/extensions/dm-subagents/src/runs/background/parallel-groups.js +1 -0
  57. package/extensions/dm-subagents/src/runs/background/result-watcher.js +8 -0
  58. package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +4 -0
  59. package/extensions/dm-subagents/src/runs/background/run-status.js +23 -0
  60. package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +4 -0
  61. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +11 -0
  62. package/extensions/dm-subagents/src/runs/background/subagent-runner.js +78 -0
  63. package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -0
  64. package/extensions/dm-subagents/src/runs/background/wait.js +11 -0
  65. package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +12 -0
  66. package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +102 -0
  67. package/extensions/dm-subagents/src/runs/foreground/execution.js +51 -0
  68. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +228 -0
  69. package/extensions/dm-subagents/src/runs/shared/acceptance.js +3 -0
  70. package/extensions/dm-subagents/src/runs/shared/chain-outputs.js +1 -0
  71. package/extensions/dm-subagents/src/runs/shared/completion-guard.js +3 -0
  72. package/extensions/dm-subagents/src/runs/shared/dm-args.js +1 -0
  73. package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +1 -0
  74. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +1 -0
  75. package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +1 -0
  76. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +1 -0
  77. package/extensions/dm-subagents/src/runs/shared/model-fallback.js +1 -0
  78. package/extensions/dm-subagents/src/runs/shared/model-scope.js +1 -0
  79. package/extensions/dm-subagents/src/runs/shared/nested-events.js +8 -0
  80. package/extensions/dm-subagents/src/runs/shared/nested-path.js +1 -0
  81. package/extensions/dm-subagents/src/runs/shared/nested-render.js +1 -0
  82. package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +5 -0
  83. package/extensions/dm-subagents/src/runs/shared/run-history.js +5 -0
  84. package/extensions/dm-subagents/src/runs/shared/single-output.js +14 -0
  85. package/extensions/dm-subagents/src/runs/shared/structured-output.js +1 -0
  86. package/extensions/dm-subagents/src/runs/shared/subagent-control.js +5 -0
  87. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +22 -0
  88. package/extensions/dm-subagents/src/runs/shared/tool-budget.js +1 -0
  89. package/extensions/dm-subagents/src/runs/shared/turn-budget.js +7 -0
  90. package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +1 -0
  91. package/extensions/dm-subagents/src/runs/shared/worktree.js +3 -0
  92. package/extensions/dm-subagents/src/shared/artifacts.js +2 -0
  93. package/extensions/dm-subagents/src/shared/atomic-json.js +1 -0
  94. package/extensions/dm-subagents/src/shared/child-transcript.js +5 -0
  95. package/extensions/dm-subagents/src/shared/file-coalescer.js +1 -0
  96. package/extensions/dm-subagents/src/shared/fork-context.js +6 -0
  97. package/extensions/dm-subagents/src/shared/formatters.js +9 -0
  98. package/extensions/dm-subagents/src/shared/jsonl-writer.js +2 -0
  99. package/extensions/dm-subagents/src/shared/model-info.js +1 -0
  100. package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.js +1 -0
  101. package/extensions/dm-subagents/src/shared/session-identity.js +1 -0
  102. package/extensions/dm-subagents/src/shared/session-tokens.js +2 -0
  103. package/extensions/dm-subagents/src/shared/settings.js +23 -0
  104. package/extensions/dm-subagents/src/shared/status-format.js +1 -0
  105. package/extensions/dm-subagents/src/shared/types.js +8 -0
  106. package/extensions/dm-subagents/src/shared/utils.js +2 -0
  107. package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +1 -0
  108. package/extensions/dm-subagents/src/slash/prompt-workflows.js +7 -0
  109. package/extensions/dm-subagents/src/slash/slash-bridge.js +1 -0
  110. package/extensions/dm-subagents/src/slash/slash-commands.js +38 -0
  111. package/extensions/dm-subagents/src/slash/slash-live-state.js +6 -0
  112. package/extensions/dm-subagents/src/tui/render-helpers.js +1 -0
  113. package/extensions/dm-subagents/src/tui/render.js +4 -0
  114. package/extensions/dm-tasks/package.json +1 -30
  115. package/extensions/dm-tasks/src/auto-clear.js +1 -0
  116. package/extensions/dm-tasks/src/index.js +212 -0
  117. package/extensions/dm-tasks/src/process-tracker.js +1 -0
  118. package/extensions/dm-tasks/src/task-store.js +1 -0
  119. package/extensions/dm-tasks/src/tasks-config.js +1 -0
  120. package/extensions/dm-tasks/src/types.js +0 -0
  121. package/extensions/dm-tasks/src/ui/settings-menu.js +1 -0
  122. package/extensions/dm-tasks/src/ui/task-widget.js +1 -0
  123. package/extensions/dm-usage/index.js +9 -0
  124. package/extensions/dm-usage/package.json +1 -18
  125. package/extensions/greedysearch-dm/bin/search.mjs +51 -51
  126. package/extensions/greedysearch-dm/index.js +20 -0
  127. package/extensions/greedysearch-dm/package.json +1 -22
  128. package/extensions/greedysearch-dm/src/formatters/results.js +8 -0
  129. package/extensions/greedysearch-dm/src/formatters/sources.js +1 -0
  130. package/extensions/greedysearch-dm/src/formatters/synthesis.js +1 -0
  131. package/extensions/greedysearch-dm/src/search/research.mjs +59 -59
  132. package/extensions/greedysearch-dm/src/search/synthesis-runner.mjs +10 -10
  133. package/extensions/greedysearch-dm/src/tools/greedy-search-handler.js +20 -0
  134. package/extensions/greedysearch-dm/src/tools/shared.js +9 -0
  135. package/extensions/greedysearch-dm/src/types.js +0 -0
  136. package/extensions/greedysearch-dm/src/utils/helpers.js +1 -0
  137. package/package.json +1 -1
  138. package/extensions/dm-9router-ext/src/index.ts +0 -541
  139. package/extensions/dm-ask-user/index.ts +0 -857
  140. package/extensions/dm-context/src/context.ts +0 -158
  141. package/extensions/dm-context/src/index.ts +0 -439
  142. package/extensions/dm-context/src/utils.ts +0 -6
  143. package/extensions/dm-fff/src/index.ts +0 -1023
  144. package/extensions/dm-fff/src/query.ts +0 -87
  145. package/extensions/dm-goal/src/goal.ts +0 -1073
  146. package/extensions/dm-grill-me/index.ts +0 -1085
  147. package/extensions/dm-subagents/src/agents/agent-management.ts +0 -1052
  148. package/extensions/dm-subagents/src/agents/agent-memory.ts +0 -254
  149. package/extensions/dm-subagents/src/agents/agent-scope.ts +0 -6
  150. package/extensions/dm-subagents/src/agents/agent-selection.ts +0 -25
  151. package/extensions/dm-subagents/src/agents/agent-serializer.ts +0 -121
  152. package/extensions/dm-subagents/src/agents/agents.ts +0 -1553
  153. package/extensions/dm-subagents/src/agents/chain-serializer.ts +0 -277
  154. package/extensions/dm-subagents/src/agents/frontmatter.ts +0 -93
  155. package/extensions/dm-subagents/src/agents/identity.ts +0 -30
  156. package/extensions/dm-subagents/src/agents/proactive-skills.ts +0 -191
  157. package/extensions/dm-subagents/src/agents/skills.ts +0 -729
  158. package/extensions/dm-subagents/src/extension/config.ts +0 -39
  159. package/extensions/dm-subagents/src/extension/control-notices.ts +0 -92
  160. package/extensions/dm-subagents/src/extension/doctor.ts +0 -214
  161. package/extensions/dm-subagents/src/extension/fanout-child.ts +0 -172
  162. package/extensions/dm-subagents/src/extension/index.ts +0 -656
  163. package/extensions/dm-subagents/src/extension/rpc.ts +0 -369
  164. package/extensions/dm-subagents/src/extension/schemas.ts +0 -309
  165. package/extensions/dm-subagents/src/intercom/intercom-bridge.ts +0 -180
  166. package/extensions/dm-subagents/src/intercom/native-supervisor-channel.ts +0 -519
  167. package/extensions/dm-subagents/src/intercom/result-intercom.ts +0 -377
  168. package/extensions/dm-subagents/src/profiles/profiles.ts +0 -637
  169. package/extensions/dm-subagents/src/runs/background/async-execution.ts +0 -1065
  170. package/extensions/dm-subagents/src/runs/background/async-job-tracker.ts +0 -441
  171. package/extensions/dm-subagents/src/runs/background/async-resume.ts +0 -391
  172. package/extensions/dm-subagents/src/runs/background/async-status.ts +0 -395
  173. package/extensions/dm-subagents/src/runs/background/chain-append.ts +0 -282
  174. package/extensions/dm-subagents/src/runs/background/chain-root-attachment.ts +0 -191
  175. package/extensions/dm-subagents/src/runs/background/completion-batcher.ts +0 -166
  176. package/extensions/dm-subagents/src/runs/background/completion-dedupe.ts +0 -63
  177. package/extensions/dm-subagents/src/runs/background/control-channel.ts +0 -332
  178. package/extensions/dm-subagents/src/runs/background/fleet-view.ts +0 -515
  179. package/extensions/dm-subagents/src/runs/background/notify.ts +0 -225
  180. package/extensions/dm-subagents/src/runs/background/parallel-groups.ts +0 -45
  181. package/extensions/dm-subagents/src/runs/background/result-watcher.ts +0 -315
  182. package/extensions/dm-subagents/src/runs/background/run-id-resolver.ts +0 -84
  183. package/extensions/dm-subagents/src/runs/background/run-status.ts +0 -434
  184. package/extensions/dm-subagents/src/runs/background/scheduled-runs.ts +0 -514
  185. package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.ts +0 -368
  186. package/extensions/dm-subagents/src/runs/background/subagent-runner.ts +0 -3171
  187. package/extensions/dm-subagents/src/runs/background/top-level-async.ts +0 -13
  188. package/extensions/dm-subagents/src/runs/background/wait.ts +0 -353
  189. package/extensions/dm-subagents/src/runs/foreground/chain-clarify.ts +0 -1333
  190. package/extensions/dm-subagents/src/runs/foreground/chain-execution.ts +0 -1313
  191. package/extensions/dm-subagents/src/runs/foreground/execution.ts +0 -1239
  192. package/extensions/dm-subagents/src/runs/foreground/subagent-executor.ts +0 -3613
  193. package/extensions/dm-subagents/src/runs/shared/acceptance.ts +0 -879
  194. package/extensions/dm-subagents/src/runs/shared/chain-outputs.ts +0 -116
  195. package/extensions/dm-subagents/src/runs/shared/completion-guard.ts +0 -147
  196. package/extensions/dm-subagents/src/runs/shared/dm-args.ts +0 -271
  197. package/extensions/dm-subagents/src/runs/shared/dm-spawn.ts +0 -147
  198. package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.ts +0 -295
  199. package/extensions/dm-subagents/src/runs/shared/long-running-guard.ts +0 -175
  200. package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +0 -365
  201. package/extensions/dm-subagents/src/runs/shared/model-fallback.ts +0 -292
  202. package/extensions/dm-subagents/src/runs/shared/model-scope.ts +0 -128
  203. package/extensions/dm-subagents/src/runs/shared/nested-events.ts +0 -908
  204. package/extensions/dm-subagents/src/runs/shared/nested-path.ts +0 -52
  205. package/extensions/dm-subagents/src/runs/shared/nested-render.ts +0 -115
  206. package/extensions/dm-subagents/src/runs/shared/parallel-utils.ts +0 -198
  207. package/extensions/dm-subagents/src/runs/shared/run-history.ts +0 -60
  208. package/extensions/dm-subagents/src/runs/shared/single-output.ts +0 -180
  209. package/extensions/dm-subagents/src/runs/shared/structured-output.ts +0 -77
  210. package/extensions/dm-subagents/src/runs/shared/subagent-control.ts +0 -223
  211. package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.ts +0 -342
  212. package/extensions/dm-subagents/src/runs/shared/tool-budget.ts +0 -74
  213. package/extensions/dm-subagents/src/runs/shared/turn-budget.ts +0 -52
  214. package/extensions/dm-subagents/src/runs/shared/workflow-graph.ts +0 -206
  215. package/extensions/dm-subagents/src/runs/shared/worktree.ts +0 -600
  216. package/extensions/dm-subagents/src/shared/artifacts.ts +0 -113
  217. package/extensions/dm-subagents/src/shared/atomic-json.ts +0 -86
  218. package/extensions/dm-subagents/src/shared/child-transcript.ts +0 -212
  219. package/extensions/dm-subagents/src/shared/file-coalescer.ts +0 -40
  220. package/extensions/dm-subagents/src/shared/fork-context.ts +0 -194
  221. package/extensions/dm-subagents/src/shared/formatters.ts +0 -133
  222. package/extensions/dm-subagents/src/shared/jsonl-writer.ts +0 -81
  223. package/extensions/dm-subagents/src/shared/model-info.ts +0 -78
  224. package/extensions/dm-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
  225. package/extensions/dm-subagents/src/shared/session-identity.ts +0 -10
  226. package/extensions/dm-subagents/src/shared/session-tokens.ts +0 -44
  227. package/extensions/dm-subagents/src/shared/settings.ts +0 -450
  228. package/extensions/dm-subagents/src/shared/status-format.ts +0 -49
  229. package/extensions/dm-subagents/src/shared/types.ts +0 -1257
  230. package/extensions/dm-subagents/src/shared/utils.ts +0 -554
  231. package/extensions/dm-subagents/src/slash/prompt-template-bridge.ts +0 -420
  232. package/extensions/dm-subagents/src/slash/prompt-workflows.ts +0 -330
  233. package/extensions/dm-subagents/src/slash/slash-bridge.ts +0 -176
  234. package/extensions/dm-subagents/src/slash/slash-commands.ts +0 -1296
  235. package/extensions/dm-subagents/src/slash/slash-live-state.ts +0 -292
  236. package/extensions/dm-subagents/src/tui/render-helpers.ts +0 -80
  237. package/extensions/dm-subagents/src/tui/render.ts +0 -1748
  238. package/extensions/dm-tasks/src/auto-clear.ts +0 -91
  239. package/extensions/dm-tasks/src/index.ts +0 -1145
  240. package/extensions/dm-tasks/src/process-tracker.ts +0 -140
  241. package/extensions/dm-tasks/src/task-store.ts +0 -305
  242. package/extensions/dm-tasks/src/tasks-config.ts +0 -23
  243. package/extensions/dm-tasks/src/types.ts +0 -40
  244. package/extensions/dm-tasks/src/ui/settings-menu.ts +0 -100
  245. package/extensions/dm-tasks/src/ui/task-widget.ts +0 -265
  246. package/extensions/dm-usage/index.ts +0 -1718
  247. package/extensions/greedysearch-dm/index.ts +0 -177
  248. package/extensions/greedysearch-dm/src/formatters/results.ts +0 -163
  249. package/extensions/greedysearch-dm/src/formatters/sources.ts +0 -116
  250. package/extensions/greedysearch-dm/src/formatters/synthesis.ts +0 -87
  251. package/extensions/greedysearch-dm/src/tools/greedy-search-handler.ts +0 -370
  252. package/extensions/greedysearch-dm/src/tools/shared.ts +0 -187
  253. package/extensions/greedysearch-dm/src/types.ts +0 -110
  254. package/extensions/greedysearch-dm/src/utils/helpers.ts +0 -40
@@ -1,1257 +0,0 @@
1
- /**
2
- * Type definitions for the subagent extension
3
- */
4
-
5
- import * as os from "node:os";
6
- import * as path from "node:path";
7
- import type { Message } from "@duckmind/dm-ai";
8
- import type { FSWatcher } from "node:fs";
9
- import type { ExtensionContext } from "@duckmind/dm-coding-agent";
10
- import type { ModelScopeConfig } from "../runs/shared/model-scope.ts";
11
-
12
- // ============================================================================
13
- // Basic Types
14
- // ============================================================================
15
-
16
- export interface MaxOutputConfig {
17
- bytes?: number;
18
- lines?: number;
19
- }
20
-
21
- export type OutputMode = "inline" | "file-only";
22
-
23
- export type JsonSchemaObject = Record<string, unknown>;
24
-
25
- export interface ChainOutputMapEntry {
26
- text: string;
27
- structured?: unknown;
28
- agent: string;
29
- stepIndex: number;
30
- }
31
-
32
- export type ChainOutputMap = Record<string, ChainOutputMapEntry>;
33
-
34
- export type WorkflowNodeStatus = "pending" | "running" | "completed" | "failed" | "paused" | "detached";
35
-
36
- export interface WorkflowGraphNode {
37
- id: string;
38
- kind: "step" | "parallel-group" | "dynamic-parallel-group" | "agent";
39
- agent?: string;
40
- phase?: string;
41
- label: string;
42
- status: WorkflowNodeStatus;
43
- flatIndex?: number;
44
- stepIndex?: number;
45
- children?: WorkflowGraphNode[];
46
- dynamic?: {
47
- sourceOutput: string;
48
- sourcePath: string;
49
- itemName: string;
50
- maxItems?: number;
51
- collectAs?: string;
52
- };
53
- itemKey?: string;
54
- outputName?: string;
55
- structured?: boolean;
56
- acceptanceStatus?: AcceptanceLedgerStatus;
57
- error?: string;
58
- }
59
-
60
- export interface WorkflowGraphSnapshot {
61
- runId: string;
62
- mode: "chain" | "parallel" | "single";
63
- phases: Array<{ title: string; nodeIds: string[] }>;
64
- nodes: WorkflowGraphNode[];
65
- currentNodeId?: string;
66
- }
67
-
68
- export interface SavedOutputReference {
69
- path: string;
70
- bytes: number;
71
- lines: number;
72
- message: string;
73
- }
74
-
75
- interface TruncationResult {
76
- text: string;
77
- truncated: boolean;
78
- originalBytes?: number;
79
- originalLines?: number;
80
- artifactPath?: string;
81
- }
82
-
83
- export interface Usage {
84
- input: number;
85
- output: number;
86
- cacheRead: number;
87
- cacheWrite: number;
88
- cost: number;
89
- turns: number;
90
- }
91
-
92
- export interface TurnBudgetConfig {
93
- maxTurns: number;
94
- graceTurns?: number;
95
- }
96
-
97
- export interface ResolvedTurnBudget {
98
- maxTurns: number;
99
- graceTurns: number;
100
- }
101
-
102
- export interface ToolBudgetConfig {
103
- soft?: number;
104
- hard: number;
105
- block?: string[] | "*";
106
- }
107
-
108
- export interface ResolvedToolBudget {
109
- soft?: number;
110
- hard: number;
111
- block: string[] | "*";
112
- }
113
-
114
- export type ToolBudgetOutcome = "within-budget" | "soft-reached" | "hard-blocked";
115
-
116
- export interface ToolBudgetState extends ResolvedToolBudget {
117
- outcome: ToolBudgetOutcome;
118
- toolCount: number;
119
- softReachedAt?: number;
120
- hardReachedAt?: number;
121
- blockedTool?: string;
122
- }
123
-
124
- export type TurnBudgetOutcome = "within-budget" | "wrap-up-requested" | "exceeded";
125
-
126
- export interface TurnBudgetState extends ResolvedTurnBudget {
127
- outcome: TurnBudgetOutcome;
128
- turnCount: number;
129
- wrapUpRequestedAtTurn?: number;
130
- exceededAtTurn?: number;
131
- }
132
-
133
- export interface TokenUsage {
134
- input: number;
135
- output: number;
136
- total: number;
137
- }
138
-
139
- export type ActivityState = "active_long_running" | "needs_attention";
140
- export type ControlEventType = "active_long_running" | "needs_attention";
141
- export type ControlNotificationChannel = "event" | "async" | "intercom";
142
-
143
- export interface ControlConfig {
144
- enabled?: boolean;
145
- needsAttentionAfterMs?: number;
146
- activeNoticeAfterMs?: number;
147
- activeNoticeAfterTurns?: number;
148
- activeNoticeAfterTokens?: number;
149
- failedToolAttemptsBeforeAttention?: number;
150
- notifyOn?: ControlEventType[];
151
- notifyChannels?: ControlNotificationChannel[];
152
- }
153
-
154
- export interface ResolvedControlConfig {
155
- enabled: boolean;
156
- needsAttentionAfterMs: number;
157
- activeNoticeAfterMs: number;
158
- activeNoticeAfterTurns?: number;
159
- activeNoticeAfterTokens?: number;
160
- failedToolAttemptsBeforeAttention: number;
161
- notifyOn: ControlEventType[];
162
- notifyChannels: ControlNotificationChannel[];
163
- }
164
-
165
- /**
166
- * Smart completion batching for async-completion notifications. Successful
167
- * sibling completions are held briefly so they arrive as one grouped message;
168
- * failure and attention signals bypass grouping and always fire immediately.
169
- */
170
- export interface CompletionBatchConfig {
171
- enabled?: boolean;
172
- /** Idle window after each arrival; resets on every new item. */
173
- debounceMs?: number;
174
- /** Hard cap measured from the first item in a group. */
175
- maxWaitMs?: number;
176
- /** Shorter idle window for straggler groups. */
177
- stragglerDebounceMs?: number;
178
- /** Shorter hard cap for straggler groups. */
179
- stragglerMaxWaitMs?: number;
180
- /** Arrivals within this window after an emit join a straggler group. */
181
- stragglerWindowMs?: number;
182
- }
183
-
184
- export interface ControlEvent {
185
- type: ControlEventType;
186
- from?: ActivityState;
187
- to: ActivityState;
188
- ts: number;
189
- agent: string;
190
- index?: number;
191
- runId: string;
192
- nestedRunId?: string;
193
- nestingPath?: NestedRunAddress["path"];
194
- message: string;
195
- reason?: "idle" | "completion_guard" | "active_long_running" | "tool_failures" | "time_threshold" | "turn_threshold" | "token_threshold";
196
- turns?: number;
197
- tokens?: number;
198
- toolCount?: number;
199
- currentTool?: string;
200
- currentToolDurationMs?: number;
201
- currentPath?: string;
202
- elapsedMs?: number;
203
- recentFailureSummary?: string;
204
- }
205
-
206
- export type SubagentResultStatus = "completed" | "failed" | "paused" | "detached";
207
- export type SubagentRunMode = "single" | "parallel" | "chain";
208
- export const SUBAGENT_LIFECYCLE_ARTIFACT_VERSION = 1;
209
- export type SubagentLifecycleArtifactVersion = typeof SUBAGENT_LIFECYCLE_ARTIFACT_VERSION;
210
-
211
- export type PublicNestedStepSummary = Pick<
212
- NestedStepSummary,
213
- "agent" | "status" | "sessionFile" | "transcriptPath" | "transcriptError" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "toolBudget" | "toolBudgetBlocked" | "startedAt" | "endedAt" | "error" | "timedOut"
214
- > & {
215
- children?: PublicNestedRunSummary[];
216
- };
217
-
218
- export type CostSummary = {
219
- inputTokens: number;
220
- outputTokens: number;
221
- costUsd: number;
222
- };
223
-
224
- export type PublicNestedRunSummary = Pick<
225
- NestedRunSummary,
226
- "id" | "parentRunId" | "parentStepIndex" | "parentAgent" | "depth" | "path" | "asyncDir" | "sessionId" | "sessionFile" | "intercomTarget" | "ownerIntercomTarget" | "leafIntercomTarget" | "ownerState" | "mode" | "state" | "agent" | "agents" | "currentStep" | "chainStepCount" | "parallelGroups" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "toolBudget" | "toolBudgetBlocked" | "totalTokens" | "totalCost" | "startedAt" | "endedAt" | "lastUpdate" | "error" | "timeoutMs" | "deadlineAt" | "timedOut" | "turnBudget" | "turnBudgetExceeded" | "wrapUpRequested"
227
- > & {
228
- steps?: PublicNestedStepSummary[];
229
- children?: PublicNestedRunSummary[];
230
- };
231
-
232
- export interface SubagentResultIntercomChild {
233
- agent: string;
234
- status: SubagentResultStatus;
235
- summary: string;
236
- index?: number;
237
- artifactPath?: string;
238
- sessionPath?: string;
239
- intercomTarget?: string;
240
- children?: PublicNestedRunSummary[];
241
- }
242
-
243
- export interface SubagentResultIntercomPayload {
244
- to: string;
245
- message: string;
246
- requestId?: string;
247
- runId: string;
248
- mode: SubagentRunMode;
249
- status: SubagentResultStatus;
250
- summary: string;
251
- source: "foreground" | "async";
252
- children: SubagentResultIntercomChild[];
253
- asyncId?: string;
254
- asyncDir?: string;
255
- chainSteps?: number;
256
- agent?: string;
257
- index?: number;
258
- artifactPath?: string;
259
- sessionPath?: string;
260
- }
261
-
262
- // ============================================================================
263
- // Progress Tracking
264
- // ============================================================================
265
-
266
- export interface AgentProgress {
267
- index: number;
268
- agent: string;
269
- status: "pending" | "running" | "completed" | "failed" | "detached";
270
- activityState?: ActivityState;
271
- task: string;
272
- skills?: string[];
273
- lastActivityAt?: number;
274
- currentTool?: string;
275
- currentToolArgs?: string;
276
- currentToolStartedAt?: number;
277
- currentPath?: string;
278
- recentTools: Array<{ tool: string; args: string; endMs: number }>;
279
- recentOutput: string[];
280
- toolCount: number;
281
- turnCount?: number;
282
- tokens: number;
283
- durationMs: number;
284
- error?: string;
285
- failedTool?: string;
286
- }
287
-
288
- export interface ToolCallSummary {
289
- text: string;
290
- expandedText: string;
291
- }
292
-
293
- interface ProgressSummary {
294
- toolCount: number;
295
- tokens: number;
296
- durationMs: number;
297
- }
298
-
299
- // ============================================================================
300
- // Results
301
- // ============================================================================
302
-
303
- export interface ModelAttempt {
304
- model: string;
305
- success: boolean;
306
- exitCode?: number | null;
307
- error?: string;
308
- usage?: Usage;
309
- }
310
-
311
- export type AcceptanceLevel = "auto" | "none" | "attested" | "checked" | "verified" | "reviewed";
312
-
313
- export type AcceptanceEvidenceKind =
314
- | "changed-files"
315
- | "tests-added"
316
- | "commands-run"
317
- | "validation-output"
318
- | "residual-risks"
319
- | "no-staged-files"
320
- | "diff-summary"
321
- | "review-findings"
322
- | "manual-notes";
323
-
324
- export interface AcceptanceGate {
325
- id: string;
326
- must: string;
327
- evidence?: AcceptanceEvidenceKind[];
328
- severity?: "required" | "recommended";
329
- }
330
-
331
- export interface AcceptanceVerifyCommand {
332
- id: string;
333
- command: string;
334
- timeoutMs?: number;
335
- cwd?: string;
336
- env?: Record<string, string>;
337
- allowFailure?: boolean;
338
- }
339
-
340
- export interface AcceptanceReviewGate {
341
- agent?: string;
342
- focus?: string;
343
- required?: boolean;
344
- }
345
-
346
- export interface AcceptanceConfig {
347
- level?: AcceptanceLevel;
348
- criteria?: Array<string | AcceptanceGate>;
349
- evidence?: AcceptanceEvidenceKind[];
350
- verify?: AcceptanceVerifyCommand[];
351
- review?: AcceptanceReviewGate | false;
352
- stopRules?: string[];
353
- reason?: string;
354
- }
355
-
356
- export type AcceptanceInput = AcceptanceLevel | false | AcceptanceConfig;
357
-
358
- export interface ResolvedAcceptanceGate extends AcceptanceGate {
359
- id: string;
360
- must: string;
361
- evidence: AcceptanceEvidenceKind[];
362
- severity: "required" | "recommended";
363
- }
364
-
365
- export interface ResolvedAcceptanceConfig {
366
- level: Exclude<AcceptanceLevel, "auto">;
367
- explicit: boolean;
368
- inferredReason: string[];
369
- criteria: ResolvedAcceptanceGate[];
370
- evidence: AcceptanceEvidenceKind[];
371
- verify: AcceptanceVerifyCommand[];
372
- review?: AcceptanceReviewGate | false;
373
- stopRules: string[];
374
- reason?: string;
375
- }
376
-
377
- export interface AcceptanceReport {
378
- criteriaSatisfied?: Array<{
379
- id?: string;
380
- status: "satisfied" | "not-satisfied" | "not-applicable";
381
- evidence: string;
382
- }>;
383
- changedFiles?: string[];
384
- testsAddedOrUpdated?: string[];
385
- commandsRun?: Array<{
386
- command: string;
387
- result: "passed" | "failed" | "not-run";
388
- summary: string;
389
- }>;
390
- validationOutput?: string[];
391
- residualRisks?: string[];
392
- noStagedFiles?: boolean;
393
- diffSummary?: string;
394
- reviewFindings?: string[];
395
- manualNotes?: string;
396
- notes?: string;
397
- }
398
-
399
- export type AcceptanceRuntimeCheckStatus = "passed" | "failed" | "not-applicable";
400
-
401
- export interface AcceptanceRuntimeCheck {
402
- id: string;
403
- status: AcceptanceRuntimeCheckStatus;
404
- message: string;
405
- }
406
-
407
- export interface AcceptanceVerifyResult {
408
- id: string;
409
- command: string;
410
- cwd?: string;
411
- exitCode: number | null;
412
- status: "passed" | "failed" | "timed-out" | "allowed-failure";
413
- stdout?: string;
414
- stderr?: string;
415
- durationMs: number;
416
- }
417
-
418
- export interface AcceptanceReviewResult {
419
- status: "no-blockers" | "blockers" | "needs-parent-decision";
420
- findings: Array<{
421
- severity: "blocker" | "non-blocking";
422
- file?: string;
423
- issue: string;
424
- rationale: string;
425
- }>;
426
- }
427
-
428
- export type AcceptanceLedgerStatus =
429
- | "not-required"
430
- | "claimed"
431
- | "attested"
432
- | "checked"
433
- | "verified"
434
- | "reviewed"
435
- | "accepted"
436
- | "rejected";
437
-
438
- export interface AcceptanceLedger {
439
- status: AcceptanceLedgerStatus;
440
- explicit: boolean;
441
- effectiveAcceptance: ResolvedAcceptanceConfig;
442
- inferredReason: string[];
443
- criteria: ResolvedAcceptanceGate[];
444
- childReport?: AcceptanceReport;
445
- childReportParseError?: string;
446
- runtimeChecks: AcceptanceRuntimeCheck[];
447
- verifyRuns: AcceptanceVerifyResult[];
448
- reviewResult?: AcceptanceReviewResult;
449
- parentDecision?: {
450
- status: "accepted" | "rejected";
451
- at: string;
452
- reason?: string;
453
- };
454
- }
455
-
456
- export interface SingleResult {
457
- agent: string;
458
- task: string;
459
- exitCode: number;
460
- detached?: boolean;
461
- detachedReason?: string;
462
- interrupted?: boolean;
463
- timedOut?: boolean;
464
- turnBudget?: TurnBudgetState;
465
- turnBudgetExceeded?: boolean;
466
- wrapUpRequested?: boolean;
467
- toolBudget?: ToolBudgetState;
468
- toolBudgetBlocked?: boolean;
469
- messages?: Message[];
470
- usage: Usage;
471
- model?: string;
472
- attemptedModels?: string[];
473
- modelAttempts?: ModelAttempt[];
474
- controlEvents?: ControlEvent[];
475
- error?: string;
476
- sessionFile?: string;
477
- skills?: string[];
478
- skillsWarning?: string;
479
- progress?: AgentProgress;
480
- progressSummary?: ProgressSummary;
481
- toolCalls?: ToolCallSummary[];
482
- artifactPaths?: ArtifactPaths;
483
- truncation?: TruncationResult;
484
- finalOutput?: string;
485
- outputMode?: OutputMode;
486
- savedOutputPath?: string;
487
- outputReference?: SavedOutputReference;
488
- outputSaveError?: string;
489
- structuredOutput?: unknown;
490
- structuredOutputPath?: string;
491
- structuredOutputSchemaPath?: string;
492
- acceptance?: AcceptanceLedger;
493
- transcriptPath?: string;
494
- transcriptError?: string;
495
- children?: NestedRunSummary[];
496
- }
497
-
498
- export interface Details {
499
- mode: SubagentRunMode | "management";
500
- runId?: string;
501
- context?: "fresh" | "fork";
502
- results: SingleResult[];
503
- controlEvents?: ControlEvent[];
504
- asyncId?: string;
505
- asyncDir?: string;
506
- timeoutMs?: number;
507
- deadlineAt?: number;
508
- timedOut?: boolean;
509
- turnBudget?: ResolvedTurnBudget;
510
- toolBudget?: ResolvedToolBudget;
511
- progress?: AgentProgress[];
512
- progressSummary?: ProgressSummary;
513
- artifacts?: {
514
- dir: string;
515
- files: ArtifactPaths[];
516
- };
517
- truncation?: {
518
- truncated: boolean;
519
- originalBytes?: number;
520
- originalLines?: number;
521
- artifactPath?: string;
522
- };
523
- // Chain metadata for observability
524
- chainAgents?: string[]; // Agent names in order, e.g., ["scout", "planner"]
525
- totalSteps?: number; // Total steps in chain
526
- currentStepIndex?: number; // 0-indexed current step (for running chains)
527
- workflowGraph?: WorkflowGraphSnapshot;
528
- outputs?: ChainOutputMap;
529
- // Aggregated child usage across all agents in the run
530
- totalChildUsage?: Usage;
531
- // Aggregated cost across all agents in the run
532
- totalCost?: CostSummary;
533
- }
534
-
535
- // ============================================================================
536
- // Artifacts
537
- // ============================================================================
538
-
539
- export interface ArtifactPaths {
540
- inputPath: string;
541
- outputPath: string;
542
- jsonlPath: string;
543
- transcriptPath: string;
544
- metadataPath: string;
545
- }
546
-
547
- export interface ArtifactConfig {
548
- enabled: boolean;
549
- includeInput: boolean;
550
- includeOutput: boolean;
551
- includeJsonl: boolean;
552
- includeTranscript?: boolean;
553
- includeMetadata: boolean;
554
- cleanupDays: number;
555
- }
556
-
557
- // ============================================================================
558
- // Async Execution
559
- // ============================================================================
560
-
561
- export interface AsyncParallelGroupStatus {
562
- start: number;
563
- count: number;
564
- stepIndex: number;
565
- }
566
-
567
- export type NestedRunState = "queued" | "running" | "complete" | "failed" | "paused";
568
- export type NestedOwnerState = "live" | "gone" | "unknown";
569
-
570
- export interface NestedRunAddress {
571
- id: string;
572
- parentRunId: string;
573
- parentStepIndex?: number;
574
- parentAgent?: string;
575
- depth: number;
576
- path: Array<{ runId: string; stepIndex?: number; agent?: string }>;
577
- }
578
-
579
- export interface NestedStepSummary {
580
- agent: string;
581
- status: "pending" | "running" | "complete" | "completed" | "failed" | "paused";
582
- sessionFile?: string;
583
- transcriptPath?: string;
584
- transcriptError?: string;
585
- activityState?: ActivityState;
586
- lastActivityAt?: number;
587
- currentTool?: string;
588
- currentToolStartedAt?: number;
589
- currentPath?: string;
590
- turnCount?: number;
591
- toolCount?: number;
592
- startedAt?: number;
593
- endedAt?: number;
594
- error?: string;
595
- timedOut?: boolean;
596
- turnBudget?: TurnBudgetState;
597
- turnBudgetExceeded?: boolean;
598
- wrapUpRequested?: boolean;
599
- toolBudget?: ToolBudgetState;
600
- toolBudgetBlocked?: boolean;
601
- children?: NestedRunSummary[];
602
- }
603
-
604
- export interface NestedRunSummary extends NestedRunAddress {
605
- asyncDir?: string;
606
- pid?: number;
607
- sessionId?: string;
608
- sessionFile?: string;
609
- intercomTarget?: string;
610
- ownerIntercomTarget?: string;
611
- leafIntercomTarget?: string;
612
- ownerState?: NestedOwnerState;
613
- controlInbox?: string;
614
- capabilityToken?: string;
615
- mode?: SubagentRunMode;
616
- state: NestedRunState;
617
- agent?: string;
618
- agents?: string[];
619
- currentStep?: number;
620
- chainStepCount?: number;
621
- parallelGroups?: AsyncParallelGroupStatus[];
622
- steps?: NestedStepSummary[];
623
- children?: NestedRunSummary[];
624
- activityState?: ActivityState;
625
- lastActivityAt?: number;
626
- currentTool?: string;
627
- currentToolStartedAt?: number;
628
- currentPath?: string;
629
- turnCount?: number;
630
- toolCount?: number;
631
- totalTokens?: TokenUsage;
632
- totalCost?: CostSummary;
633
- startedAt?: number;
634
- endedAt?: number;
635
- lastUpdate?: number;
636
- timeoutMs?: number;
637
- deadlineAt?: number;
638
- timedOut?: boolean;
639
- turnBudget?: TurnBudgetState;
640
- turnBudgetExceeded?: boolean;
641
- wrapUpRequested?: boolean;
642
- toolBudget?: ToolBudgetState;
643
- toolBudgetBlocked?: boolean;
644
- error?: string;
645
- }
646
-
647
- export interface NestedRouteInfo {
648
- rootRunId: string;
649
- eventSink: string;
650
- controlInbox: string;
651
- capabilityToken: string;
652
- }
653
-
654
- export interface AsyncStartedEvent {
655
- lifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;
656
- id?: string;
657
- asyncDir?: string;
658
- pid?: number;
659
- sessionId?: string;
660
- mode?: SubagentRunMode;
661
- agent?: string;
662
- agents?: string[];
663
- chain?: string[];
664
- chainStepCount?: number;
665
- parallelGroups?: AsyncParallelGroupStatus[];
666
- workflowGraph?: WorkflowGraphSnapshot;
667
- timeoutMs?: number;
668
- deadlineAt?: number;
669
- turnBudget?: TurnBudgetState;
670
- nestedRoute?: NestedRouteInfo;
671
- }
672
-
673
- export interface AsyncStatus {
674
- lifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;
675
- runId: string;
676
- sessionId?: string;
677
- mode: SubagentRunMode;
678
- state: "queued" | "running" | "complete" | "failed" | "paused";
679
- error?: string;
680
- activityState?: ActivityState;
681
- lastActivityAt?: number;
682
- currentTool?: string;
683
- currentToolStartedAt?: number;
684
- currentPath?: string;
685
- turnCount?: number;
686
- toolCount?: number;
687
- steerCount?: number;
688
- lastSteerAt?: number;
689
- startedAt: number;
690
- endedAt?: number;
691
- lastUpdate?: number;
692
- timeoutMs?: number;
693
- deadlineAt?: number;
694
- timedOut?: boolean;
695
- turnBudget?: TurnBudgetState;
696
- turnBudgetExceeded?: boolean;
697
- wrapUpRequested?: boolean;
698
- toolBudget?: ToolBudgetState;
699
- toolBudgetBlocked?: boolean;
700
- pid?: number;
701
- cwd?: string;
702
- currentStep?: number;
703
- chainStepCount?: number;
704
- pendingAppends?: number;
705
- parallelGroups?: AsyncParallelGroupStatus[];
706
- workflowGraph?: WorkflowGraphSnapshot;
707
- steps?: Array<{
708
- agent: string;
709
- phase?: string;
710
- label?: string;
711
- outputName?: string;
712
- structured?: boolean;
713
- status: "pending" | "running" | "complete" | "completed" | "failed" | "paused";
714
- children?: NestedRunSummary[];
715
- sessionFile?: string;
716
- transcriptPath?: string;
717
- transcriptError?: string;
718
- activityState?: ActivityState;
719
- lastActivityAt?: number;
720
- currentTool?: string;
721
- currentToolArgs?: string;
722
- currentToolStartedAt?: number;
723
- currentPath?: string;
724
- recentTools?: Array<{ tool: string; args: string; endMs: number }>;
725
- recentOutput?: string[];
726
- turnCount?: number;
727
- toolCount?: number;
728
- startedAt?: number;
729
- endedAt?: number;
730
- durationMs?: number;
731
- exitCode?: number | null;
732
- timedOut?: boolean;
733
- turnBudget?: TurnBudgetState;
734
- turnBudgetExceeded?: boolean;
735
- wrapUpRequested?: boolean;
736
- toolBudget?: ToolBudgetState;
737
- toolBudgetBlocked?: boolean;
738
- tokens?: TokenUsage;
739
- skills?: string[];
740
- model?: string;
741
- thinking?: string;
742
- attemptedModels?: string[];
743
- modelAttempts?: ModelAttempt[];
744
- totalCost?: CostSummary;
745
- steerCount?: number;
746
- lastSteerAt?: number;
747
- error?: string;
748
- structuredOutput?: unknown;
749
- structuredOutputPath?: string;
750
- structuredOutputSchemaPath?: string;
751
- acceptance?: AcceptanceLedger;
752
- }>;
753
- sessionDir?: string;
754
- outputFile?: string;
755
- totalTokens?: TokenUsage;
756
- totalCost?: CostSummary;
757
- sessionFile?: string;
758
- outputs?: ChainOutputMap;
759
- }
760
-
761
- export type AsyncJobStep = NonNullable<AsyncStatus["steps"]>[number] & {
762
- index?: number;
763
- };
764
-
765
- export interface AsyncJobState {
766
- asyncId: string;
767
- asyncDir: string;
768
- status: "queued" | "running" | "complete" | "failed" | "paused";
769
- pid?: number;
770
- sessionId?: string;
771
- activityState?: ActivityState;
772
- lastActivityAt?: number;
773
- currentTool?: string;
774
- currentToolStartedAt?: number;
775
- currentPath?: string;
776
- turnCount?: number;
777
- toolCount?: number;
778
- steerCount?: number;
779
- lastSteerAt?: number;
780
- mode?: SubagentRunMode;
781
- agents?: string[];
782
- currentStep?: number;
783
- chainStepCount?: number;
784
- parallelGroups?: AsyncParallelGroupStatus[];
785
- steps?: AsyncJobStep[];
786
- stepsTotal?: number;
787
- runningSteps?: number;
788
- completedSteps?: number;
789
- hasParallelGroups?: boolean;
790
- activeParallelGroup?: boolean;
791
- startedAt?: number;
792
- updatedAt?: number;
793
- timeoutMs?: number;
794
- deadlineAt?: number;
795
- timedOut?: boolean;
796
- turnBudget?: TurnBudgetState;
797
- turnBudgetExceeded?: boolean;
798
- wrapUpRequested?: boolean;
799
- toolBudget?: ToolBudgetState;
800
- toolBudgetBlocked?: boolean;
801
- sessionDir?: string;
802
- outputFile?: string;
803
- totalTokens?: TokenUsage;
804
- sessionFile?: string;
805
- controlEventCursor?: number;
806
- nestedRoute?: NestedRouteInfo;
807
- nestedChildren?: NestedRunSummary[];
808
- }
809
-
810
- export interface ForegroundResumeChild {
811
- agent: string;
812
- index: number;
813
- sessionFile?: string;
814
- status: SubagentResultStatus;
815
- exitCode?: number;
816
- finalOutput?: string;
817
- artifactPaths?: ArtifactPaths;
818
- transcriptPath?: string;
819
- transcriptError?: string;
820
- detachedReason?: string;
821
- updatedAt?: number;
822
- }
823
-
824
- export interface ForegroundResumeRun {
825
- runId: string;
826
- mode: SubagentRunMode;
827
- cwd: string;
828
- updatedAt: number;
829
- children: ForegroundResumeChild[];
830
- }
831
-
832
- export interface SubagentState {
833
- baseCwd: string;
834
- currentSessionId: string | null;
835
- subagentInProgress?: boolean;
836
- subagentSpawns?: { sessionId: string | null; count: number };
837
- asyncJobs: Map<string, AsyncJobState>;
838
- foregroundRuns?: Map<string, ForegroundResumeRun>;
839
- foregroundControls: Map<string, {
840
- runId: string;
841
- mode: SubagentRunMode;
842
- startedAt: number;
843
- updatedAt: number;
844
- currentAgent?: string;
845
- currentIndex?: number;
846
- currentActivityState?: ActivityState;
847
- lastActivityAt?: number;
848
- currentTool?: string;
849
- currentToolStartedAt?: number;
850
- currentPath?: string;
851
- turnCount?: number;
852
- tokens?: number;
853
- toolCount?: number;
854
- nestedRoute?: NestedRouteInfo;
855
- nestedChildren?: NestedRunSummary[];
856
- interrupt?: () => boolean;
857
- }>;
858
- lastForegroundControlId: string | null;
859
- pendingForegroundControlNotices?: Map<string, ReturnType<typeof setTimeout>>;
860
- cleanupTimers: Map<string, ReturnType<typeof setTimeout>>;
861
- lastUiContext: ExtensionContext | null;
862
- poller: NodeJS.Timeout | null;
863
- completionSeen: Map<string, number>;
864
- watcher: FSWatcher | null;
865
- watcherRestartTimer: ReturnType<typeof setTimeout> | null;
866
- resultFileCoalescer: {
867
- schedule(file: string, delayMs?: number): boolean;
868
- clear(): void;
869
- };
870
- }
871
-
872
- // ============================================================================
873
- // Display
874
- // ============================================================================
875
-
876
- export type DisplayItem =
877
- | { type: "text"; text: string }
878
- | { type: "tool"; name: string; args: Record<string, unknown> };
879
-
880
- // ============================================================================
881
- // Error Handling
882
- // ============================================================================
883
-
884
- export interface ErrorInfo {
885
- hasError: boolean;
886
- exitCode?: number;
887
- errorType?: string;
888
- details?: string;
889
- }
890
-
891
- export interface IntercomEventBus {
892
- on(channel: string, handler: (data: unknown) => void): () => void;
893
- emit(channel: string, data: unknown): void;
894
- }
895
-
896
- export const INTERCOM_DETACH_REQUEST_EVENT = "pi-intercom:detach-request";
897
- export const INTERCOM_DETACH_RESPONSE_EVENT = "pi-intercom:detach-response";
898
- export const SUBAGENT_ASYNC_STARTED_EVENT = "subagent:async-started";
899
- export const SUBAGENT_ASYNC_COMPLETE_EVENT = "subagent:async-complete";
900
- export const SUBAGENT_CONTROL_EVENT = "subagent:control-event";
901
- export const SUBAGENT_CONTROL_INTERCOM_EVENT = "subagent:control-intercom";
902
- export const SUBAGENT_RESULT_INTERCOM_EVENT = "subagent:result-intercom";
903
- export const SUBAGENT_RESULT_INTERCOM_DELIVERY_EVENT = "subagent:result-intercom-delivery";
904
-
905
- // ============================================================================
906
- // Execution Options
907
- // ============================================================================
908
-
909
- export interface RunSyncOptions {
910
- /** Session id of the direct parent session for permission-system ask forwarding. */
911
- parentSessionId?: string;
912
- cwd?: string;
913
- signal?: AbortSignal;
914
- interruptSignal?: AbortSignal;
915
- timeoutMs?: number;
916
- deadlineAt?: number;
917
- turnBudget?: ResolvedTurnBudget;
918
- toolBudget?: ResolvedToolBudget;
919
- allowIntercomDetach?: boolean;
920
- intercomEvents?: IntercomEventBus;
921
- onUpdate?: (r: import("@duckmind/dm-agent-core").AgentToolResult<Details>) => void;
922
- onControlEvent?: (event: ControlEvent) => void;
923
- onDetachedExit?: (result: SingleResult) => void;
924
- controlConfig?: ResolvedControlConfig;
925
- intercomSessionName?: string;
926
- orchestratorIntercomTarget?: string;
927
- maxOutput?: MaxOutputConfig;
928
- artifactsDir?: string;
929
- artifactConfig?: ArtifactConfig;
930
- runId: string;
931
- index?: number;
932
- sessionDir?: string;
933
- sessionFile?: string;
934
- share?: boolean;
935
- outputPath?: string;
936
- outputMode?: OutputMode;
937
- maxSubagentDepth?: number;
938
- nestedRoute?: NestedRouteInfo;
939
- /** Override the agent's default model (format: "provider/id" or just "id") */
940
- modelOverride?: string;
941
- /** Override the agent's default thinking level for this run */
942
- thinkingOverride?: AgentConfig["thinking"];
943
- /** Registry models available for heuristic bare-model resolution */
944
- availableModels?: Array<{ provider: string; id: string; fullId: string }>;
945
- /** Current parent-session provider to prefer for ambiguous bare model ids */
946
- preferredModelProvider?: string;
947
- /** Optional subagent model-scope enforcement for fallback candidates */
948
- modelScope?: ModelScopeConfig;
949
- /** Skills to make available (overrides agent default if provided) */
950
- skills?: string[];
951
- structuredOutput?: {
952
- schema: JsonSchemaObject;
953
- schemaPath: string;
954
- outputPath: string;
955
- };
956
- acceptance?: AcceptanceInput;
957
- acceptanceContext?: {
958
- mode?: SubagentRunMode;
959
- async?: boolean;
960
- dynamic?: boolean;
961
- dynamicGroup?: boolean;
962
- };
963
- }
964
-
965
- export type IntercomBridgeMode = "off" | "fork-only" | "always";
966
-
967
- export interface IntercomBridgeConfig {
968
- mode?: IntercomBridgeMode;
969
- instructionFile?: string;
970
- }
971
-
972
- interface TopLevelParallelConfig {
973
- maxTasks?: number;
974
- concurrency?: number;
975
- }
976
-
977
- interface ExtensionChainConfig {
978
- dynamicFanout?: {
979
- maxItems?: number;
980
- };
981
- }
982
-
983
- export interface ProactiveSkillSubagentsConfig {
984
- enabled?: boolean;
985
- minReferences?: number;
986
- maxRecommendations?: number;
987
- preferredAgent?: string;
988
- }
989
-
990
- export type ToolDescriptionMode = "full" | "compact" | "custom";
991
-
992
- export interface ScheduledRunsConfig {
993
- enabled?: boolean;
994
- maxLatenessMs?: number;
995
- maxPending?: number;
996
- }
997
-
998
- export interface ExtensionConfig {
999
- asyncByDefault?: boolean;
1000
- /** Tool description variant registered for the parent-facing subagent tool. Defaults to full. */
1001
- toolDescriptionMode?: ToolDescriptionMode;
1002
- forceTopLevelAsync?: boolean;
1003
- defaultSessionDir?: string;
1004
- singleRunOutputBaseDir?: string;
1005
- maxSubagentDepth?: number;
1006
- maxSubagentSpawnsPerSession?: number;
1007
- /** Global cap on simultaneously-running subagent tasks within a single run. Defaults to 20. */
1008
- globalConcurrencyLimit?: number;
1009
- control?: ControlConfig;
1010
- completionBatch?: CompletionBatchConfig;
1011
- turnBudget?: TurnBudgetConfig;
1012
- toolBudget?: ToolBudgetConfig;
1013
- parallel?: TopLevelParallelConfig;
1014
- chain?: ExtensionChainConfig;
1015
- worktreeSetupHook?: string;
1016
- worktreeSetupHookTimeoutMs?: number;
1017
- worktreeBaseDir?: string;
1018
- intercomBridge?: IntercomBridgeConfig;
1019
- proactiveSkillSubagents?: ProactiveSkillSubagentsConfig | false;
1020
- scheduledRuns?: ScheduledRunsConfig;
1021
- }
1022
-
1023
- // ============================================================================
1024
- // Constants
1025
- // ============================================================================
1026
-
1027
- export const DEFAULT_MAX_OUTPUT: Required<MaxOutputConfig> = {
1028
- bytes: 200 * 1024,
1029
- lines: 5000,
1030
- };
1031
-
1032
- export const DEFAULT_ARTIFACT_CONFIG: ArtifactConfig = {
1033
- enabled: true,
1034
- includeInput: true,
1035
- includeOutput: true,
1036
- includeJsonl: false,
1037
- includeTranscript: true,
1038
- includeMetadata: true,
1039
- cleanupDays: 7,
1040
- };
1041
-
1042
- function sanitizeTempScopeSegment(value: string): string {
1043
- const sanitized = value
1044
- .trim()
1045
- .replace(/[^A-Za-z0-9._-]+/g, "-")
1046
- .replace(/^-+|-+$/g, "");
1047
- return sanitized || "unknown";
1048
- }
1049
-
1050
- export function resolveTempScopeId(options?: {
1051
- env?: NodeJS.ProcessEnv;
1052
- getuid?: (() => number) | undefined;
1053
- userInfo?: (() => { username?: string | null }) | undefined;
1054
- homedir?: (() => string) | undefined;
1055
- }): string {
1056
- const env = options?.env ?? process.env;
1057
- const getuid = options && Object.hasOwn(options, "getuid")
1058
- ? options.getuid
1059
- : process.getuid?.bind(process);
1060
- if (typeof getuid === "function") {
1061
- return `uid-${getuid()}`;
1062
- }
1063
-
1064
- for (const key of ["USERNAME", "USER", "LOGNAME"] as const) {
1065
- const value = env[key];
1066
- if (value) return `user-${sanitizeTempScopeSegment(value)}`;
1067
- }
1068
-
1069
- const userInfo = options && Object.hasOwn(options, "userInfo")
1070
- ? options.userInfo
1071
- : os.userInfo;
1072
- try {
1073
- const username = userInfo?.().username;
1074
- if (username) return `user-${sanitizeTempScopeSegment(username)}`;
1075
- } catch {
1076
- // Fall through to home-directory-based scoping.
1077
- }
1078
-
1079
- const homedir = env.USERPROFILE ?? env.HOME;
1080
- if (homedir) return `home-${sanitizeTempScopeSegment(homedir)}`;
1081
-
1082
- const resolveHomedir = options && Object.hasOwn(options, "homedir")
1083
- ? options.homedir
1084
- : os.homedir;
1085
- try {
1086
- const fallbackHomedir = resolveHomedir?.();
1087
- if (fallbackHomedir) return `home-${sanitizeTempScopeSegment(fallbackHomedir)}`;
1088
- } catch {
1089
- // Fall through to the last-resort shared scope.
1090
- }
1091
-
1092
- return "shared";
1093
- }
1094
-
1095
- const MAX_PARALLEL = 8;
1096
- export const MAX_CONCURRENCY = 4;
1097
- export const TEMP_ROOT_DIR = path.join(os.tmpdir(), `dm-subagents-${resolveTempScopeId()}`);
1098
- export const RESULTS_DIR = path.join(TEMP_ROOT_DIR, "async-subagent-results");
1099
- export const ASYNC_DIR = path.join(TEMP_ROOT_DIR, "async-subagent-runs");
1100
- export const CHAIN_RUNS_DIR = path.join(TEMP_ROOT_DIR, "chain-runs");
1101
- export const TEMP_ARTIFACTS_DIR = path.join(TEMP_ROOT_DIR, "artifacts");
1102
- export const WIDGET_KEY = "subagent-async";
1103
- export const SLASH_RESULT_TYPE = "subagent-slash-result";
1104
- export const SLASH_TEXT_RESULT_TYPE = "subagent-slash-text-result";
1105
- export const SLASH_SUBAGENT_REQUEST_EVENT = "subagent:slash:request";
1106
- export const SLASH_SUBAGENT_STARTED_EVENT = "subagent:slash:started";
1107
- export const SLASH_SUBAGENT_RESPONSE_EVENT = "subagent:slash:response";
1108
- export const SLASH_SUBAGENT_UPDATE_EVENT = "subagent:slash:update";
1109
- export const SLASH_SUBAGENT_CANCEL_EVENT = "subagent:slash:cancel";
1110
- export const POLL_INTERVAL_MS = 250;
1111
- export const MAX_WIDGET_JOBS = 4;
1112
- export const DEFAULT_SUBAGENT_MAX_DEPTH = 2;
1113
- export const DEFAULT_MAX_SUBAGENT_SPAWNS_PER_SESSION = 40;
1114
- export const SUBAGENT_ACTIONS = ["list", "get", "models", "create", "update", "delete", "eject", "disable", "enable", "reset", "status", "interrupt", "resume", "steer", "append-step", "doctor", "schedule", "schedule-list", "schedule-status", "schedule-cancel"] as const;
1115
-
1116
- export const DEFAULT_FORK_PREAMBLE =
1117
- "You are a delegated subagent running from a fork of the parent session. " +
1118
- "Treat the inherited conversation as reference-only context, not a live thread to continue. " +
1119
- "Do not continue or answer prior messages as if they are waiting for a reply. " +
1120
- "Your sole job is to execute the task below and return a focused result for that task using your tools.";
1121
-
1122
- function normalizeTopLevelParallelValue(value: unknown): number | undefined {
1123
- const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
1124
- if (!Number.isInteger(parsed) || parsed < 1) return undefined;
1125
- return parsed;
1126
- }
1127
-
1128
- export function resolveTopLevelParallelMaxTasks(value: unknown): number {
1129
- return normalizeTopLevelParallelValue(value) ?? MAX_PARALLEL;
1130
- }
1131
-
1132
- export function resolveTopLevelParallelConcurrency(
1133
- override: unknown,
1134
- configValue: unknown,
1135
- ): number {
1136
- return normalizeTopLevelParallelValue(override)
1137
- ?? normalizeTopLevelParallelValue(configValue)
1138
- ?? MAX_CONCURRENCY;
1139
- }
1140
-
1141
- export function getAsyncConfigPath(suffix: string): string {
1142
- return path.join(TEMP_ROOT_DIR, `async-cfg-${suffix}.json`);
1143
- }
1144
-
1145
- export function wrapForkTask(task: string, preamble?: string | false): string {
1146
- if (preamble === false) return task;
1147
- const effectivePreamble = preamble ?? DEFAULT_FORK_PREAMBLE;
1148
- const wrappedPrefix = `${effectivePreamble}\n\nTask:\n`;
1149
- if (task.startsWith(wrappedPrefix)) return task;
1150
- return `${wrappedPrefix}${task}`;
1151
- }
1152
-
1153
- // ============================================================================
1154
- // Recursion Depth Guard
1155
- // ============================================================================
1156
-
1157
- function normalizeNonNegativeInteger(value: unknown): number | undefined {
1158
- const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
1159
- if (!Number.isInteger(parsed) || parsed < 0) return undefined;
1160
- return parsed;
1161
- }
1162
-
1163
- export function normalizeMaxSubagentDepth(value: unknown): number | undefined {
1164
- return normalizeNonNegativeInteger(value);
1165
- }
1166
-
1167
- export function resolveCurrentMaxSubagentDepth(configMaxDepth?: number): number {
1168
- return normalizeMaxSubagentDepth(process.env.DM_SUBAGENT_MAX_DEPTH)
1169
- ?? normalizeMaxSubagentDepth(configMaxDepth)
1170
- ?? DEFAULT_SUBAGENT_MAX_DEPTH;
1171
- }
1172
-
1173
- export function resolveChildMaxSubagentDepth(parentMaxDepth: number, agentMaxDepth?: number): number {
1174
- const normalizedParent = normalizeMaxSubagentDepth(parentMaxDepth) ?? DEFAULT_SUBAGENT_MAX_DEPTH;
1175
- const normalizedAgent = normalizeMaxSubagentDepth(agentMaxDepth);
1176
- return normalizedAgent === undefined ? normalizedParent : Math.min(normalizedParent, normalizedAgent);
1177
- }
1178
-
1179
- export function checkSubagentDepth(configMaxDepth?: number): { blocked: boolean; depth: number; maxDepth: number } {
1180
- const depth = Number(process.env.DM_SUBAGENT_DEPTH ?? "0");
1181
- const maxDepth = resolveCurrentMaxSubagentDepth(configMaxDepth);
1182
- const blocked = Number.isFinite(depth) && depth >= maxDepth;
1183
- return { blocked, depth, maxDepth };
1184
- }
1185
-
1186
- export function getSubagentDepthEnv(maxDepth?: number): Record<string, string> {
1187
- const parentDepth = Number(process.env.DM_SUBAGENT_DEPTH ?? "0");
1188
- const nextDepth = Number.isFinite(parentDepth) ? parentDepth + 1 : 1;
1189
- return {
1190
- DM_SUBAGENT_DEPTH: String(nextDepth),
1191
- DM_SUBAGENT_MAX_DEPTH: String(normalizeMaxSubagentDepth(maxDepth) ?? resolveCurrentMaxSubagentDepth()),
1192
- };
1193
- }
1194
-
1195
- export function normalizeMaxSubagentSpawnsPerSession(value: unknown): number | undefined {
1196
- return normalizeNonNegativeInteger(value);
1197
- }
1198
-
1199
- export function resolveMaxSubagentSpawnsPerSession(configMaxSpawns?: number): number {
1200
- return normalizeMaxSubagentSpawnsPerSession(process.env.DM_SUBAGENT_MAX_SPAWNS_PER_SESSION)
1201
- ?? normalizeMaxSubagentSpawnsPerSession(configMaxSpawns)
1202
- ?? DEFAULT_MAX_SUBAGENT_SPAWNS_PER_SESSION;
1203
- }
1204
-
1205
- // ============================================================================
1206
- // Utility Functions
1207
- // ============================================================================
1208
-
1209
- function formatBytes(bytes: number): string {
1210
- if (bytes < 1024) return `${bytes}B`;
1211
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
1212
- return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
1213
- }
1214
-
1215
- export function truncateOutput(
1216
- output: string,
1217
- config: Required<MaxOutputConfig>,
1218
- artifactPath?: string,
1219
- ): TruncationResult {
1220
- const lines = output.split("\n");
1221
- const bytes = Buffer.byteLength(output, "utf-8");
1222
-
1223
- if (bytes <= config.bytes && lines.length <= config.lines) {
1224
- return { text: output, truncated: false };
1225
- }
1226
-
1227
- let truncatedLines = lines;
1228
- if (lines.length > config.lines) {
1229
- truncatedLines = lines.slice(0, config.lines);
1230
- }
1231
-
1232
- let result = truncatedLines.join("\n");
1233
- if (Buffer.byteLength(result, "utf-8") > config.bytes) {
1234
- let low = 0;
1235
- let high = result.length;
1236
- while (low < high) {
1237
- const mid = Math.floor((low + high + 1) / 2);
1238
- if (Buffer.byteLength(result.slice(0, mid), "utf-8") <= config.bytes) {
1239
- low = mid;
1240
- } else {
1241
- high = mid - 1;
1242
- }
1243
- }
1244
- result = result.slice(0, low);
1245
- }
1246
-
1247
- const keptLines = result.split("\n").length;
1248
- const marker = `[TRUNCATED: showing first ${keptLines} of ${lines.length} lines, ${formatBytes(Buffer.byteLength(result))} of ${formatBytes(bytes)}${artifactPath ? ` - full output at ${artifactPath}` : ""}]\n`;
1249
-
1250
- return {
1251
- text: marker + result,
1252
- truncated: true,
1253
- originalBytes: bytes,
1254
- originalLines: lines.length,
1255
- artifactPath,
1256
- };
1257
- }