@ashx-j/lunr 0.2.18 → 0.2.20

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 (190) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/README.md +2 -2
  3. package/dist/builtin-extensions/ashxj-tui.d.ts +2 -2
  4. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-tui.js +11 -8
  6. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  7. package/dist/builtin-extensions/index.d.ts.map +1 -1
  8. package/dist/builtin-extensions/index.js +0 -2
  9. package/dist/builtin-extensions/index.js.map +1 -1
  10. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts +6 -4
  11. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts.map +1 -1
  12. package/dist/builtin-extensions/pi-intercom/broker/spawn.js +93 -49
  13. package/dist/builtin-extensions/pi-intercom/broker/spawn.js.map +1 -1
  14. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  15. package/dist/builtin-extensions/pi-intercom/index.js +351 -351
  16. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  17. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +2 -1
  18. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  19. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +80 -43
  20. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  21. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +18 -8
  22. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  23. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +36 -11
  24. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  25. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -3
  26. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  27. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +21 -12
  28. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  29. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +7 -1
  30. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +225 -15
  32. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
  33. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts +29 -0
  34. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -0
  35. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +179 -0
  36. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -0
  37. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +89 -0
  38. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -0
  39. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +541 -0
  40. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -0
  41. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +9 -1
  42. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
  43. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +34 -9
  44. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
  45. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
  46. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +1 -2
  47. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
  48. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts +2 -1
  49. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +35 -8
  51. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
  53. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  54. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +3 -3
  55. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  56. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts +1 -0
  57. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  58. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +54 -38
  59. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  60. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +3 -6
  61. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
  62. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +64 -5
  63. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  65. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +1 -0
  66. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  67. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  68. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +21 -8
  69. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  70. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  71. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +62 -16
  72. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  73. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts +2 -0
  74. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js +75 -18
  76. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js.map +1 -1
  77. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +13 -1
  78. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +67 -11
  80. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  81. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
  82. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +5 -2
  83. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
  84. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  85. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +13 -3
  86. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  87. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts +3 -0
  88. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
  89. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +68 -11
  90. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
  91. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +12 -1
  92. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
  93. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +21 -2
  94. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
  95. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +16 -4
  96. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-subagents/src/shared/types.js +1 -1
  98. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  99. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +2 -0
  100. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  101. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +24 -6
  102. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  103. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +44 -4
  104. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  105. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +227 -133
  106. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  107. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.d.ts.map +1 -1
  108. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js +1 -1
  109. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js.map +1 -1
  110. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts +2 -13
  111. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts.map +1 -1
  112. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js +5 -91
  113. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js.map +1 -1
  114. package/dist/core/permissions.d.ts +1 -0
  115. package/dist/core/permissions.d.ts.map +1 -1
  116. package/dist/core/permissions.js +8 -4
  117. package/dist/core/permissions.js.map +1 -1
  118. package/dist/core/plan-mode.d.ts.map +1 -1
  119. package/dist/core/plan-mode.js +0 -5
  120. package/dist/core/plan-mode.js.map +1 -1
  121. package/dist/core/runtime-bridges.d.ts.map +1 -1
  122. package/dist/core/runtime-bridges.js +0 -2
  123. package/dist/core/runtime-bridges.js.map +1 -1
  124. package/dist/core/subagent-cancellation.d.ts +21 -0
  125. package/dist/core/subagent-cancellation.d.ts.map +1 -0
  126. package/dist/core/subagent-cancellation.js +53 -0
  127. package/dist/core/subagent-cancellation.js.map +1 -0
  128. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  129. package/dist/modes/interactive/components/assistant-message.js +12 -18
  130. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  131. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  132. package/dist/modes/interactive/components/tool-execution.js +12 -0
  133. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  134. package/dist/modes/interactive/interactive-mode.d.ts +1 -2
  135. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  136. package/dist/modes/interactive/interactive-mode.js +29 -22
  137. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  138. package/dist/node-runtime/{agent-session-services-35WNVGMR.js → agent-session-services-75JKASCW.js} +3 -3
  139. package/dist/node-runtime/{builtin-extensions-QATGXENO.js → builtin-extensions-X4JMM4ZS.js} +3 -3
  140. package/dist/node-runtime/{chunk-XATUM2HK.js → chunk-25I2BHAA.js} +1 -1
  141. package/dist/node-runtime/{chunk-MCUNIRD5.js → chunk-46ECNOLF.js} +477 -246
  142. package/dist/node-runtime/{chunk-J26TSGDL.js → chunk-6N22HULO.js} +8 -5
  143. package/dist/node-runtime/{chunk-NI6OTSBH.js → chunk-AL2FMKKM.js} +7 -7
  144. package/dist/node-runtime/chunk-AOFXZQKA.js +24 -0
  145. package/dist/node-runtime/chunk-BBUVIEZB.js +51 -0
  146. package/dist/node-runtime/{chunk-EBF6COVM.js → chunk-ELWEXVO5.js} +7 -7
  147. package/dist/node-runtime/{chunk-R5EDISSV.js → chunk-JHYKXIMM.js} +5 -2
  148. package/dist/node-runtime/{chunk-ATGA2WLC.js → chunk-JYNNB7DU.js} +397 -34
  149. package/dist/node-runtime/{chunk-ZBV7FAHG.js → chunk-K3646JTM.js} +17 -118
  150. package/dist/node-runtime/{chunk-PNJSG3IZ.js → chunk-LTYWTR3V.js} +1 -369
  151. package/dist/node-runtime/{chunk-G4P75AIS.js → chunk-QKFMBRAL.js} +47 -54
  152. package/dist/node-runtime/cli-runtime.js +1 -1
  153. package/dist/node-runtime/{command-AAV3YRR5.js → command-RBTRL55A.js} +1 -1
  154. package/dist/node-runtime/{gateway-OAC4OBBL.js → gateway-L4ANRTVE.js} +2 -2
  155. package/dist/node-runtime/index.js +10 -9
  156. package/dist/node-runtime/{interactive-mode-2SZUO53H.js → interactive-mode-HPUNH7SV.js} +5 -4
  157. package/dist/node-runtime/{interactive-view-S6J3QHEF.js → interactive-view-ILS6TAN5.js} +1 -1
  158. package/dist/node-runtime/{lunr-cron-AUUYP4N4.js → lunr-cron-NNYTWTGF.js} +2 -2
  159. package/dist/node-runtime/main.js +8 -8
  160. package/dist/node-runtime/{pi-intercom-EEMBGQID.js → pi-intercom-DDQMRNPJ.js} +96 -76
  161. package/dist/node-runtime/{pi-subagents-7YJ3I4VE.js → pi-subagents-T5WMMLBB.js} +1040 -318
  162. package/dist/node-runtime/rpc-entry.js +8 -8
  163. package/dist/node-runtime/{runtime-bridges-3RKBDLNA.js → runtime-bridges-NJQERQ72.js} +2 -4
  164. package/dist/node-runtime/{subagent-executor-5Q5A4HJ2.js → subagent-executor-SRFC26SJ.js} +168 -249
  165. package/docs/features.md +17 -3
  166. package/docs/keybindings.md +3 -1
  167. package/docs/settings.md +1 -1
  168. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  169. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  170. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  171. package/examples/extensions/gondolin/package-lock.json +2 -2
  172. package/examples/extensions/gondolin/package.json +1 -1
  173. package/examples/extensions/sandbox/package-lock.json +2 -2
  174. package/examples/extensions/sandbox/package.json +1 -1
  175. package/examples/extensions/with-deps/package-lock.json +2 -2
  176. package/examples/extensions/with-deps/package.json +1 -1
  177. package/package.json +4 -4
  178. package/dist/builtin-extensions/lunr-settings-tools.d.ts +0 -4
  179. package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +0 -1
  180. package/dist/builtin-extensions/lunr-settings-tools.js +0 -120
  181. package/dist/builtin-extensions/lunr-settings-tools.js.map +0 -1
  182. package/dist/core/settings-tools-bridge.d.ts +0 -35
  183. package/dist/core/settings-tools-bridge.d.ts.map +0 -1
  184. package/dist/core/settings-tools-bridge.js +0 -56
  185. package/dist/core/settings-tools-bridge.js.map +0 -1
  186. package/dist/modes/interactive/injected-context.d.ts +0 -2
  187. package/dist/modes/interactive/injected-context.d.ts.map +0 -1
  188. package/dist/modes/interactive/injected-context.js +0 -7
  189. package/dist/modes/interactive/injected-context.js.map +0 -1
  190. package/dist/node-runtime/chunk-3NMWLTPV.js +0 -64
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/builtin-extensions/pi-subagents/src/shared/types.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Type definitions for the subagent extension\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { Message } from \"@ashx-j/lunr-ai\";\nimport type { FSWatcher } from \"node:fs\";\nimport type { ExtensionContext } from \"@ashx-j/lunr\";\nimport type { ModelScopeConfig } from \"../runs/shared/model-scope.ts\";\n\n// ============================================================================\n// Basic Types\n// ============================================================================\n\nexport interface MaxOutputConfig {\n\tbytes?: number;\n\tlines?: number;\n}\n\nexport type OutputMode = \"inline\" | \"file-only\";\n\nexport type ChildPermission = \"full\" | \"read-only\";\nexport type ChildTier = \"light\" | \"standard\" | \"heavy\";\n\n/** How the child model was chosen. Captured from requested params before resolution. */\nexport type ModelSelection = { kind: \"tier\"; tier: ChildTier };\n\nexport interface ChildSpec {\n\tchildId: string;\n\ttask: string;\n\tdescription: string;\n\trequestedPermissions: ChildPermission;\n\teffectivePermissions: ChildPermission;\n\tmodel?: string;\n\ttier: ChildTier;\n\tmodelSelection?: ModelSelection;\n\tskill?: string | string[] | false;\n\tcwd?: string;\n\toutput?: string | false;\n\toutputMode?: OutputMode;\n\tacceptance?: AcceptanceInput;\n\ttoolBudget?: ToolBudgetConfig;\n\tcount?: number;\n\treads?: string[] | false;\n\tprogress?: boolean;\n\tlabel?: string;\n\tphase?: string;\n\tas?: string;\n\toutputSchema?: JsonSchemaObject;\n\tfanoutAuthorized?: boolean;\n}\n\n/** Internal execution compatibility shape. It is built from ChildSpec and is never user-discovered. */\nexport interface ChildRuntimeConfig {\n\tname: string;\n\tdescription: string;\n\ttools?: string[];\n\tmcpDirectTools?: string[];\n\tmodel?: string;\n\tfallbackModels?: string[];\n\tthinking?: string | false;\n\tsystemPromptMode: \"append\" | \"replace\";\n\tinheritProjectContext: boolean;\n\tinheritSkills: boolean;\n\tacceptanceRole?: AcceptanceRole;\n\tsystemPrompt: string;\n\tskills?: string[];\n\tskillPath?: string[];\n\textensions?: string[];\n\tsubagentOnlyExtensions?: string[];\n\toutput?: string;\n\tmaxSubagentDepth?: number;\n\tcompletionGuard?: boolean;\n\ttoolBudget?: ToolBudgetConfig;\n}\n\nexport function childRowLabel(entry: {\n\tdescription?: string;\n\tlabel?: string;\n\tagent?: string;\n\tchildId?: string;\n}): string {\n\treturn entry.label?.trim() || entry.description?.trim() || entry.agent?.trim() || entry.childId || \"child\";\n}\n\nexport type AcceptanceRole = \"read-only\" | \"writer\";\n\nexport type JsonSchemaObject = Record<string, unknown>;\n\nexport interface ChainOutputMapEntry {\n\ttext: string;\n\tstructured?: unknown;\n\tagent: string;\n\tstepIndex: number;\n}\n\nexport type ChainOutputMap = Record<string, ChainOutputMapEntry>;\n\nexport type WorkflowNodeStatus = \"pending\" | \"running\" | \"completed\" | \"failed\" | \"paused\" | \"stopped\" | \"detached\";\n\nexport interface WorkflowGraphNode {\n\tid: string;\n\tkind: \"step\" | \"parallel-group\" | \"dynamic-parallel-group\" | \"agent\";\n\tagent?: string;\n\tphase?: string;\n\tlabel: string;\n\tstatus: WorkflowNodeStatus;\n\tflatIndex?: number;\n\tstepIndex?: number;\n\tchildren?: WorkflowGraphNode[];\n\tdynamic?: {\n\t\tsourceOutput: string;\n\t\tsourcePath: string;\n\t\titemName: string;\n\t\tmaxItems?: number;\n\t\tcollectAs?: string;\n\t};\n\titemKey?: string;\n\toutputName?: string;\n\tstructured?: boolean;\n\tacceptanceStatus?: AcceptanceLedgerStatus;\n\terror?: string;\n}\n\nexport interface WorkflowGraphSnapshot {\n\trunId: string;\n\tmode: \"chain\" | \"parallel\" | \"single\";\n\tphases: Array<{ title: string; nodeIds: string[] }>;\n\tnodes: WorkflowGraphNode[];\n\tcurrentNodeId?: string;\n}\n\nexport interface SavedOutputReference {\n\tpath: string;\n\tbytes: number;\n\tlines: number;\n\tmessage: string;\n}\n\ninterface TruncationResult {\n\ttext: string;\n\ttruncated: boolean;\n\toriginalBytes?: number;\n\toriginalLines?: number;\n\tartifactPath?: string;\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: number;\n\tturns: number;\n}\n\nexport interface TurnBudgetConfig {\n\tmaxTurns: number;\n\tgraceTurns?: number;\n}\n\nexport interface ResolvedTurnBudget {\n\tmaxTurns: number;\n\tgraceTurns: number;\n}\n\nexport interface ToolBudgetConfig {\n\tsoft?: number;\n\thard: number;\n\tblock?: string[] | \"*\";\n}\n\nexport interface ResolvedToolBudget {\n\tsoft?: number;\n\thard: number;\n\tblock: string[] | \"*\";\n}\n\nexport type ToolBudgetOutcome = \"within-budget\" | \"soft-reached\" | \"hard-blocked\";\n\nexport interface ToolBudgetState extends ResolvedToolBudget {\n\toutcome: ToolBudgetOutcome;\n\ttoolCount: number;\n\tsoftReachedAt?: number;\n\thardReachedAt?: number;\n\tblockedTool?: string;\n}\n\nexport type TurnBudgetOutcome = \"within-budget\" | \"wrap-up-requested\" | \"exceeded\";\n\nexport interface TurnBudgetState extends ResolvedTurnBudget {\n\toutcome: TurnBudgetOutcome;\n\tturnCount: number;\n\twrapUpRequestedAtTurn?: number;\n\texceededAtTurn?: number;\n}\n\nexport interface TokenUsage {\n\tinput: number;\n\toutput: number;\n\ttotal: number;\n}\n\nexport type ActivityState = \"active_long_running\" | \"needs_attention\";\nexport type ControlEventType = \"active_long_running\" | \"needs_attention\";\nexport type ControlNotificationChannel = \"event\" | \"async\" | \"intercom\";\n\nexport interface ControlConfig {\n\tenabled?: boolean;\n\tneedsAttentionAfterMs?: number;\n\tactiveNoticeAfterMs?: number;\n\tactiveNoticeAfterTurns?: number;\n\tactiveNoticeAfterTokens?: number;\n\tfailedToolAttemptsBeforeAttention?: number;\n\tnotifyOn?: ControlEventType[];\n\tnotifyChannels?: ControlNotificationChannel[];\n}\n\nexport interface ResolvedControlConfig {\n\tenabled: boolean;\n\tneedsAttentionAfterMs: number;\n\tactiveNoticeAfterMs: number;\n\tactiveNoticeAfterTurns?: number;\n\tactiveNoticeAfterTokens?: number;\n\tfailedToolAttemptsBeforeAttention: number;\n\tnotifyOn: ControlEventType[];\n\tnotifyChannels: ControlNotificationChannel[];\n}\n\n/**\n * Smart completion batching for async-completion notifications. Successful\n * sibling completions are held briefly so they arrive as one grouped message;\n * failure and attention signals bypass grouping and always fire immediately.\n */\nexport interface CompletionBatchConfig {\n\tenabled?: boolean;\n\t/** Idle window after each arrival; resets on every new item. */\n\tdebounceMs?: number;\n\t/** Hard cap measured from the first item in a group. */\n\tmaxWaitMs?: number;\n\t/** Shorter idle window for straggler groups. */\n\tstragglerDebounceMs?: number;\n\t/** Shorter hard cap for straggler groups. */\n\tstragglerMaxWaitMs?: number;\n\t/** Arrivals within this window after an emit join a straggler group. */\n\tstragglerWindowMs?: number;\n}\n\nexport interface WaitToolConfigObject {\n\tenabled?: boolean;\n}\n\nexport type WaitToolConfig = boolean | WaitToolConfigObject;\n\nexport interface ControlEvent {\n\ttype: ControlEventType;\n\tfrom?: ActivityState;\n\tto: ActivityState;\n\tts: number;\n\tagent: string;\n\tindex?: number;\n\trunId: string;\n\tnestedRunId?: string;\n\tnestingPath?: NestedRunAddress[\"path\"];\n\tmessage: string;\n\treason?: \"idle\" | \"completion_guard\" | \"active_long_running\" | \"tool_failures\" | \"time_threshold\" | \"turn_threshold\" | \"token_threshold\";\n\tturns?: number;\n\ttokens?: number;\n\ttoolCount?: number;\n\tcurrentTool?: string;\n\tcurrentToolDurationMs?: number;\n\tcurrentPath?: string;\n\telapsedMs?: number;\n\trecentFailureSummary?: string;\n}\n\nexport type SubagentResultStatus = \"completed\" | \"failed\" | \"paused\" | \"stopped\" | \"detached\";\nexport type SubagentRunMode = \"single\" | \"parallel\" | \"chain\";\nexport const SUBAGENT_LIFECYCLE_ARTIFACT_VERSION = 4;\nexport type SubagentLifecycleArtifactVersion = typeof SUBAGENT_LIFECYCLE_ARTIFACT_VERSION;\nexport const UNSUPPORTED_SUBAGENT_LIFECYCLE_MESSAGE =\n\t\"This subagent run uses an unsupported lifecycle format. Named agent types cannot be resumed. Launch a new prompt-driven child instead.\";\n\nexport function isSupportedSubagentLifecycleVersion(version: unknown): boolean {\n\treturn version === SUBAGENT_LIFECYCLE_ARTIFACT_VERSION;\n}\n\nexport type SteeringActionState = \"delivered\" | \"scheduled\" | \"pending\" | \"partial\" | \"recovered\" | \"failed\";\nexport type SteeringTargetState = \"scheduled\" | \"routed\" | \"delivered\" | \"late\" | \"failed\" | \"recovered\";\n\nexport interface SteeringTargetStatus {\n\tindex: number;\n\tstate: SteeringTargetState;\n\troutedAt?: number;\n\tdeliveredAt?: number;\n\tlateDeliveredAt?: number;\n\tfailedAt?: number;\n\trecoveredAt?: number;\n\treason?: string;\n\treplacementRunId?: string;\n}\n\nexport interface SteeringRequestStatus {\n\tid: string;\n\trequestedAt: number;\n\tsource?: string;\n\tmessagePreview: string;\n\ttargets: SteeringTargetStatus[];\n}\n\nexport interface SteeringStatus {\n\trequested: number;\n\tscheduled: number;\n\tpending: number;\n\tdelivered: number;\n\tfailed: number;\n\trecovered: number;\n\tlastRequestedAt?: number;\n\tlastDeliveredAt?: number;\n\trecent: SteeringRequestStatus[];\n}\n\nexport interface SteerActionTarget {\n\tindex: number;\n\tstate: SteeringTargetState;\n\tdeliveredAt?: number;\n\tlateDeliveredAt?: number;\n\treason?: string;\n\treplacementRunId?: string;\n}\n\nexport interface SteerActionResult {\n\trequestId: string;\n\tstate: SteeringActionState;\n\tsourceRunId: string;\n\treplacementRunId?: string;\n\ttargets: SteerActionTarget[];\n}\n\nexport interface SteeringNotice {\n\ttype: \"subagent.steering.notice\";\n\tts: number;\n\trunId: string;\n\trequestId: string;\n\tstate: \"failed\" | \"partial\" | \"recovered\";\n\tmessage: string;\n\tcurrentSessionId?: string;\n}\n\nexport interface SteeringRecoveryDescriptor {\n\tversion: 4;\n\tlifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;\n\tsourceRunId: string;\n\tchildId: string;\n\tdescription: string;\n\tpermissions: ChildPermission;\n\tagent: string;\n\tsessionFile?: string;\n\tcwd: string;\n\tmodel?: string;\n\ttier: ChildTier;\n\tthinking?: string;\n\tmodelSelection?: ModelSelection;\n\tskills?: string[];\n\toutputPath?: string;\n\toutputMode: \"inline\" | \"file-only\";\n\tacceptance?: AcceptanceInput;\n\tcontrolConfig?: ResolvedControlConfig;\n\tabsoluteDeadlineAt?: number;\n\tinitialTurnBudget?: ResolvedTurnBudget;\n\tinitialToolBudget?: ResolvedToolBudget;\n\tmaxSubagentDepth: number;\n\tmaxOutput?: MaxOutputConfig;\n\tshare: boolean;\n\tsessionDir?: string;\n\tartifactsDir?: string;\n\tartifactConfig?: ArtifactConfig;\n}\n\nexport type PublicNestedStepSummary = Pick<\n\tNestedStepSummary,\n\t\"agent\" | \"status\" | \"sessionFile\" | \"transcriptPath\" | \"transcriptError\" | \"activityState\" | \"lastActivityAt\" | \"currentTool\" | \"currentToolStartedAt\" | \"currentPath\" | \"turnCount\" | \"toolCount\" | \"toolBudget\" | \"toolBudgetBlocked\" | \"startedAt\" | \"endedAt\" | \"error\" | \"timedOut\" | \"stopped\"\n> & {\n\tchildren?: PublicNestedRunSummary[];\n};\n\nexport type CostSummary = {\n\tinputTokens: number;\n\toutputTokens: number;\n\tcostUsd: number;\n};\n\nexport type PublicNestedRunSummary = Pick<\n\tNestedRunSummary,\n\t\"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\" | \"stopped\" | \"turnBudget\" | \"turnBudgetExceeded\" | \"wrapUpRequested\"\n> & {\n\tsteps?: PublicNestedStepSummary[];\n\tchildren?: PublicNestedRunSummary[];\n};\n\nexport interface SubagentResultIntercomChild {\n\tagent: string;\n\tstatus: SubagentResultStatus;\n\tsummary: string;\n\tindex?: number;\n\tartifactPath?: string;\n\tsessionPath?: string;\n\tintercomTarget?: string;\n\tchildren?: PublicNestedRunSummary[];\n}\n\nexport interface SubagentResultIntercomPayload {\n\tto: string;\n\tmessage: string;\n\trequestId?: string;\n\trunId: string;\n\tmode: SubagentRunMode;\n\tstatus: SubagentResultStatus;\n\tsummary: string;\n\tsource: \"foreground\" | \"async\";\n\tchildren: SubagentResultIntercomChild[];\n\tasyncId?: string;\n\tasyncDir?: string;\n\tchainSteps?: number;\n\tagent?: string;\n\tindex?: number;\n\tartifactPath?: string;\n\tsessionPath?: string;\n}\n\n// ============================================================================\n// Progress Tracking\n// ============================================================================\n\nexport interface ChildWatchdogProgress {\n\tphase: \"idle\" | \"reviewing\" | \"autofollow\" | \"settling\" | \"stale\" | \"failed\";\n\tseq: number;\n\tlastUpdate: number;\n\tfollowUpPending: boolean;\n\treason?: string;\n\ttimedOut?: boolean;\n}\n\nexport interface AgentProgress {\n\tindex: number;\n\tchildId?: string;\n\tdescription?: string;\n\tpermissions?: ChildPermission;\n\tagent: string;\n\tstatus: \"pending\" | \"running\" | \"completed\" | \"failed\" | \"detached\";\n\tactivityState?: ActivityState;\n\ttask: string;\n\tskills?: string[];\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolArgs?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: ModelSelection;\n\tthinkingText?: string;\n\trecentTools: Array<{ tool: string; args: string; endMs: number }>;\n\trecentOutput: string[];\n\ttoolCount: number;\n\tturnCount?: number;\n\ttokens: number;\n\tdurationMs: number;\n\terror?: string;\n\tfailedTool?: string;\n\twatchdog?: ChildWatchdogProgress;\n}\n\nexport interface ToolCallSummary {\n\ttext: string;\n\texpandedText: string;\n}\n\ninterface ProgressSummary {\n\ttoolCount: number;\n\ttokens: number;\n\tdurationMs: number;\n}\n\n// ============================================================================\n// Results\n// ============================================================================\n\nexport interface ModelAttempt {\n\tmodel: string;\n\tsuccess: boolean;\n\texitCode?: number | null;\n\terror?: string;\n\tusage?: Usage;\n}\n\nexport type AcceptanceLevel = \"auto\" | \"none\" | \"attested\" | \"checked\" | \"verified\" | \"reviewed\";\n\nexport type AcceptanceEvidenceKind =\n\t| \"changed-files\"\n\t| \"tests-added\"\n\t| \"commands-run\"\n\t| \"validation-output\"\n\t| \"residual-risks\"\n\t| \"no-staged-files\"\n\t| \"diff-summary\"\n\t| \"review-findings\"\n\t| \"manual-notes\";\n\nexport interface AcceptanceGate {\n\tid: string;\n\tmust: string;\n\tevidence?: AcceptanceEvidenceKind[];\n\tseverity?: \"required\" | \"recommended\";\n}\n\nexport interface AcceptanceVerifyCommand {\n\tid: string;\n\tcommand: string;\n\ttimeoutMs?: number;\n\tcwd?: string;\n\tenv?: Record<string, string>;\n\tallowFailure?: boolean;\n}\n\nexport interface AcceptanceReviewGate {\n\tagent?: string;\n\tfocus?: string;\n\trequired?: boolean;\n}\n\nexport interface AcceptanceConfig {\n\tlevel?: AcceptanceLevel;\n\tcriteria?: Array<string | AcceptanceGate>;\n\tevidence?: AcceptanceEvidenceKind[];\n\tverify?: AcceptanceVerifyCommand[];\n\treview?: AcceptanceReviewGate | false;\n\tstopRules?: string[];\n\treason?: string;\n}\n\n/** Bare \"none\" is not accepted: use { level: \"none\", reason: \"...\" }; false remains a deprecated shorthand. */\nexport type AcceptanceInput = Exclude<AcceptanceLevel, \"none\"> | false | AcceptanceConfig;\n\nexport interface ResolvedAcceptanceGate extends AcceptanceGate {\n\tid: string;\n\tmust: string;\n\tevidence: AcceptanceEvidenceKind[];\n\tseverity: \"required\" | \"recommended\";\n}\n\nexport interface ResolvedAcceptanceConfig {\n\tlevel: Exclude<AcceptanceLevel, \"auto\">;\n\texplicit: boolean;\n\tinferredReason: string[];\n\tcriteria: ResolvedAcceptanceGate[];\n\tevidence: AcceptanceEvidenceKind[];\n\tverify: AcceptanceVerifyCommand[];\n\treview?: AcceptanceReviewGate | false;\n\tstopRules: string[];\n\treason?: string;\n}\n\nexport interface AcceptanceReport {\n\tcriteriaSatisfied?: Array<{\n\t\tid?: string;\n\t\tstatus: \"satisfied\" | \"not-satisfied\" | \"not-applicable\";\n\t\tevidence: string;\n\t}>;\n\tchangedFiles?: string[];\n\ttestsAddedOrUpdated?: string[];\n\tcommandsRun?: Array<{\n\t\tcommand: string;\n\t\tresult: \"passed\" | \"failed\" | \"not-run\";\n\t\tsummary: string;\n\t}>;\n\tvalidationOutput?: string[];\n\tresidualRisks?: string[];\n\tnoStagedFiles?: boolean;\n\tdiffSummary?: string;\n\treviewFindings?: string[];\n\tmanualNotes?: string;\n\tnotes?: string;\n}\n\nexport type AcceptanceRuntimeCheckStatus = \"passed\" | \"failed\" | \"not-applicable\";\n\nexport interface AcceptanceRuntimeCheck {\n\tid: string;\n\tstatus: AcceptanceRuntimeCheckStatus;\n\tmessage: string;\n}\n\nexport interface AcceptanceVerifyResult {\n\tid: string;\n\tcommand: string;\n\tcwd?: string;\n\texitCode: number | null;\n\tstatus: \"passed\" | \"failed\" | \"timed-out\" | \"allowed-failure\";\n\tstdout?: string;\n\tstderr?: string;\n\tdurationMs: number;\n}\n\nexport interface AcceptanceReviewResult {\n\tstatus: \"no-blockers\" | \"blockers\" | \"needs-parent-decision\";\n\tfindings: Array<{\n\t\tseverity: \"blocker\" | \"non-blocking\";\n\t\tfile?: string;\n\t\tissue: string;\n\t\trationale: string;\n\t}>;\n}\n\nexport type AcceptanceLedgerStatus =\n\t| \"pending\"\n\t| \"not-required\"\n\t| \"claimed\"\n\t| \"attested\"\n\t| \"checked\"\n\t| \"verified\"\n\t| \"reviewed\"\n\t| \"accepted\"\n\t| \"rejected\";\n\nexport interface AcceptanceLedger {\n\tstatus: AcceptanceLedgerStatus;\n\texplicit: boolean;\n\teffectiveAcceptance: ResolvedAcceptanceConfig;\n\tinferredReason: string[];\n\tcriteria: ResolvedAcceptanceGate[];\n\tchildReport?: AcceptanceReport;\n\tchildReportParseError?: string;\n\truntimeChecks: AcceptanceRuntimeCheck[];\n\tverifyRuns: AcceptanceVerifyResult[];\n\treviewResult?: AcceptanceReviewResult;\n\tparentDecision?: {\n\t\tstatus: \"accepted\" | \"rejected\";\n\t\tat: string;\n\t\treason?: string;\n\t};\n}\n\nexport interface ProtocolOutputLimit {\n\tcode: \"protocol_output_limit\";\n\tstream: \"stdout\" | \"stderr\";\n\tlimitBytes: number;\n\tobservedBytes: number;\n\tdiagnosticPrefix: string;\n\tdiagnosticTail: string;\n}\n\nexport interface SingleResult {\n\tchildId?: string;\n\tdescription?: string;\n\tpermissions?: ChildPermission;\n\tagent: string;\n\ttask: string;\n\texitCode: number;\n\tdetached?: boolean;\n\tdetachedReason?: string;\n\tinterrupted?: boolean;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\tmessages?: Message[];\n\tusage: Usage;\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: ModelSelection;\n\tattemptedModels?: string[];\n\tmodelAttempts?: ModelAttempt[];\n\tcontrolEvents?: ControlEvent[];\n\terror?: string;\n\tprotocolError?: ProtocolOutputLimit;\n\tsessionFile?: string;\n\tskills?: string[];\n\tskillsWarning?: string;\n\tprogress?: AgentProgress;\n\tprogressSummary?: ProgressSummary;\n\ttoolCalls?: ToolCallSummary[];\n\tartifactPaths?: ArtifactPaths;\n\ttruncation?: TruncationResult;\n\tfinalOutput?: string;\n\toutputMode?: OutputMode;\n\tsavedOutputPath?: string;\n\toutputReference?: SavedOutputReference;\n\toutputSaveError?: string;\n\tstructuredOutput?: unknown;\n\tstructuredOutputPath?: string;\n\tstructuredOutputSchemaPath?: string;\n\tacceptance?: AcceptanceLedger;\n\ttranscriptPath?: string;\n\ttranscriptError?: string;\n\tchildren?: NestedRunSummary[];\n\twatchdog?: ChildWatchdogProgress;\n}\n\nexport interface Details {\n\tmode: SubagentRunMode | \"management\";\n\trunId?: string;\n\tcontext?: \"fresh\" | \"fork\";\n\tresults: SingleResult[];\n\tcontrolEvents?: ControlEvent[];\n\tsteering?: SteerActionResult;\n\tasyncId?: string;\n\tasyncDir?: string;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: ResolvedTurnBudget;\n\ttoolBudget?: ResolvedToolBudget;\n\tprogress?: AgentProgress[];\n\tprogressSummary?: ProgressSummary;\n\tartifacts?: {\n\t\tdir: string;\n\t\tfiles: ArtifactPaths[];\n\t};\n\ttruncation?: {\n\t\ttruncated: boolean;\n\t\toriginalBytes?: number;\n\t\toriginalLines?: number;\n\t\tartifactPath?: string;\n\t};\n\t// Chain metadata for observability\n\tchainAgents?: string[]; // deprecated: child descriptions in order\n\tchainChildren?: Array<{ childId: string; description: string; permissions: ChildPermission }>;\n\ttotalSteps?: number; // Total steps in chain\n\tcurrentStepIndex?: number; // 0-indexed current step (for running chains)\n\tworkflowGraph?: WorkflowGraphSnapshot;\n\toutputs?: ChainOutputMap;\n\t// Aggregated child usage across all agents in the run\n\ttotalChildUsage?: Usage;\n\t// Aggregated cost across all agents in the run\n\ttotalCost?: CostSummary;\n}\n\n// ============================================================================\n// Artifacts\n// ============================================================================\n\nexport interface ArtifactPaths {\n\tinputPath: string;\n\toutputPath: string;\n\tjsonlPath: string;\n\ttranscriptPath: string;\n\tmetadataPath: string;\n}\n\nexport interface ArtifactConfig {\n\tenabled: boolean;\n\tincludeInput: boolean;\n\tincludeOutput: boolean;\n\tincludeJsonl: boolean;\n\tincludeTranscript?: boolean;\n\tincludeMetadata: boolean;\n\tcleanupDays: number;\n}\n\n// ============================================================================\n// Async Execution\n// ============================================================================\n\nexport interface AsyncParallelGroupStatus {\n\tstart: number;\n\tcount: number;\n\tstepIndex: number;\n}\n\nexport type NestedRunState = \"queued\" | \"running\" | \"complete\" | \"failed\" | \"paused\" | \"stopped\";\nexport type NestedOwnerState = \"live\" | \"gone\" | \"unknown\";\n\nexport interface NestedRunAddress {\n\tid: string;\n\tparentRunId: string;\n\tparentStepIndex?: number;\n\tparentAgent?: string;\n\tdepth: number;\n\tpath: Array<{ runId: string; stepIndex?: number; agent?: string }>;\n}\n\nexport interface NestedStepSummary {\n\tagent: string;\n\tstatus: \"pending\" | \"running\" | \"complete\" | \"completed\" | \"failed\" | \"paused\" | \"stopped\";\n\tsessionFile?: string;\n\ttranscriptPath?: string;\n\ttranscriptError?: string;\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\tstartedAt?: number;\n\tendedAt?: number;\n\terror?: string;\n\twatchdog?: ChildWatchdogProgress;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\tchildren?: NestedRunSummary[];\n}\n\nexport interface NestedRunSummary extends NestedRunAddress {\n\tasyncDir?: string;\n\tpid?: number;\n\tsessionId?: string;\n\tsessionFile?: string;\n\tintercomTarget?: string;\n\townerIntercomTarget?: string;\n\tleafIntercomTarget?: string;\n\townerState?: NestedOwnerState;\n\tcontrolInbox?: string;\n\tcapabilityToken?: string;\n\tmode?: SubagentRunMode;\n\tstate: NestedRunState;\n\tagent?: string;\n\tagents?: string[];\n\tcurrentStep?: number;\n\tchainStepCount?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tsteps?: NestedStepSummary[];\n\tchildren?: NestedRunSummary[];\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\ttotalTokens?: TokenUsage;\n\ttotalCost?: CostSummary;\n\tstartedAt?: number;\n\tendedAt?: number;\n\tlastUpdate?: number;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\terror?: string;\n}\n\nexport interface NestedRouteInfo {\n\trootRunId: string;\n\teventSink: string;\n\tcontrolInbox: string;\n\tcapabilityToken: string;\n}\n\nexport interface AsyncStartedEvent {\n\tlifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;\n\tid?: string;\n\tasyncDir?: string;\n\tpid?: number;\n\tsessionId?: string;\n\tmode?: SubagentRunMode;\n\tagent?: string;\n\tagents?: string[];\n\t/** Truncated first child task retained for backwards compatibility. */\n\ttask?: string;\n\t/** Workflow-level caller task, falling back to the first child task. */\n\tgoal?: string;\n\tchain?: string[];\n\tchainStepCount?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tworkflowGraph?: WorkflowGraphSnapshot;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\tturnBudget?: TurnBudgetState;\n\tnestedRoute?: NestedRouteInfo;\n}\n\nexport interface AsyncStatus {\n\tlifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;\n\trunId: string;\n\tsessionId?: string;\n\tmode: SubagentRunMode;\n\tisNested?: boolean;\n\tstate: \"queued\" | \"running\" | \"complete\" | \"failed\" | \"paused\" | \"stopped\";\n\terror?: string;\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\tsteering?: SteeringStatus;\n\tstartedAt: number;\n\tendedAt?: number;\n\tlastUpdate?: number;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\tpid?: number;\n\tcwd?: string;\n\tcurrentStep?: number;\n\tchainStepCount?: number;\n\tpendingAppends?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tworkflowGraph?: WorkflowGraphSnapshot;\n\tsteps?: Array<{\n\t\tchildId?: string;\n\t\tdescription?: string;\n\t\tpermissions?: ChildPermission;\n\t\tagent: string;\n\t\tphase?: string;\n\t\tlabel?: string;\n\t\toutputName?: string;\n\t\tstructured?: boolean;\n\t\tstatus: \"pending\" | \"running\" | \"complete\" | \"completed\" | \"failed\" | \"paused\" | \"stopped\";\n\t\tchildren?: NestedRunSummary[];\n\t\tsessionFile?: string;\n\t\ttranscriptPath?: string;\n\t\ttranscriptError?: string;\n\t\tactivityState?: ActivityState;\n\t\tlastActivityAt?: number;\n\t\tcurrentTool?: string;\n\t\tcurrentToolArgs?: string;\n\t\tcurrentToolStartedAt?: number;\n\t\tcurrentPath?: string;\n\t\trecentTools?: Array<{ tool: string; args: string; endMs: number }>;\n\t\trecentOutput?: string[];\n\t\tturnCount?: number;\n\t\ttoolCount?: number;\n\t\tstartedAt?: number;\n\t\tendedAt?: number;\n\t\tdurationMs?: number;\n\t\texitCode?: number | null;\n\t\ttimedOut?: boolean;\n\t\tstopped?: boolean;\n\t\tturnBudget?: TurnBudgetState;\n\t\tturnBudgetExceeded?: boolean;\n\t\twrapUpRequested?: boolean;\n\t\ttoolBudget?: ToolBudgetState;\n\t\ttoolBudgetBlocked?: boolean;\n\t\ttokens?: TokenUsage;\n\t\tskills?: string[];\n\t\tmodel?: string;\n\t\tthinking?: string;\n\t\tmodelSelection?: ModelSelection;\n\t\tattemptedModels?: string[];\n\t\tmodelAttempts?: ModelAttempt[];\n\t\ttotalCost?: CostSummary;\n\t\tsteering?: SteeringStatus;\n\t\terror?: string;\n\t\tstructuredOutput?: unknown;\n\t\tstructuredOutputPath?: string;\n\t\tstructuredOutputSchemaPath?: string;\n\t\tacceptance?: AcceptanceLedger;\n\t\twatchdog?: ChildWatchdogProgress;\n\t}>;\n\tsessionDir?: string;\n\toutputFile?: string;\n\ttotalTokens?: TokenUsage;\n\ttotalCost?: CostSummary;\n\tsessionFile?: string;\n\toutputs?: ChainOutputMap;\n}\n\nexport type AsyncJobStep = NonNullable<AsyncStatus[\"steps\"]>[number] & {\n\tindex?: number;\n};\n\nexport interface AsyncJobState {\n\tasyncId: string;\n\tasyncDir: string;\n\tstatus: \"queued\" | \"running\" | \"complete\" | \"failed\" | \"paused\" | \"stopped\";\n\tpid?: number;\n\tsessionId?: string;\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\tsteering?: SteeringStatus;\n\tmode?: SubagentRunMode;\n\tagents?: string[];\n\tcurrentStep?: number;\n\tchainStepCount?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tsteps?: AsyncJobStep[];\n\tstepsTotal?: number;\n\trunningSteps?: number;\n\tcompletedSteps?: number;\n\thasParallelGroups?: boolean;\n\tactiveParallelGroup?: boolean;\n\tstartedAt?: number;\n\tupdatedAt?: number;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\tsessionDir?: string;\n\toutputFile?: string;\n\ttotalTokens?: TokenUsage;\n\tsessionFile?: string;\n\tcontrolEventCursor?: number;\n\tnestedRoute?: NestedRouteInfo;\n\tnestedChildren?: NestedRunSummary[];\n}\n\nexport interface ForegroundResumeChild {\n\tagent: string;\n\tindex: number;\n\tsessionFile?: string;\n\tstatus: SubagentResultStatus;\n\texitCode?: number;\n\terror?: string;\n\tfinalOutput?: string;\n\toutputMode?: OutputMode;\n\tsavedOutputPath?: string;\n\toutputSaveError?: string;\n\tartifactPaths?: ArtifactPaths;\n\ttranscriptPath?: string;\n\ttranscriptError?: string;\n\tdetachedReason?: string;\n\tacceptance?: AcceptanceLedger;\n\tupdatedAt?: number;\n}\n\nexport interface ForegroundResumeRun {\n\trunId: string;\n\tmode: SubagentRunMode;\n\tcwd: string;\n\t/** Originating parent session. Detached exits can outlive the active session. */\n\tsessionId?: string;\n\tupdatedAt: number;\n\tchildren: ForegroundResumeChild[];\n}\n\nexport interface SubagentState {\n\tbaseCwd: string;\n\tcurrentSessionId: string | null;\n\t/** Live foreground `subagent` tool calls. Caps same-turn overlap. */\n\tforegroundSubagentInFlight?: number;\n\tsubagentSpawns?: { sessionId: string | null; count: number };\n\tasyncJobs: Map<string, AsyncJobState>;\n\t/** Current-session active and recent async runs for the native fleet inspector. */\n\tfleetJobs?: Map<string, AsyncJobState>;\n\tforegroundRuns?: Map<string, ForegroundResumeRun>;\n\tforegroundControls: Map<string, {\n\t\trunId: string;\n\t\tmode: SubagentRunMode;\n\t\tstartedAt: number;\n\t\tupdatedAt: number;\n\t\tcurrentAgent?: string;\n\t\tcurrentChildId?: string;\n\t\tcurrentIndex?: number;\n\t\tcurrentActivityState?: ActivityState;\n\t\tlastActivityAt?: number;\n\t\tcurrentTool?: string;\n\t\tcurrentToolStartedAt?: number;\n\t\tcurrentPath?: string;\n\t\tturnCount?: number;\n\t\ttokens?: number;\n\t\ttoolCount?: number;\n\t\tnestedRoute?: NestedRouteInfo;\n\t\tnestedChildren?: NestedRunSummary[];\n\t\tinterrupt?: () => boolean;\n\t}>;\n\tlastForegroundControlId: string | null;\n\tpendingForegroundControlNotices?: Map<string, ReturnType<typeof setTimeout>>;\n\tcleanupTimers: Map<string, ReturnType<typeof setTimeout>>;\n\tlastUiContext: ExtensionContext | null;\n\tpoller: NodeJS.Timeout | null;\n\tcompletionSeen: Map<string, number>;\n\twatcher: FSWatcher | null;\n\twatcherRestartTimer: ReturnType<typeof setTimeout> | null;\n\tresultFileCoalescer: {\n\t\tschedule(file: string, delayMs?: number): boolean;\n\t\tclear(): void;\n\t};\n}\n\n// ============================================================================\n// Display\n// ============================================================================\n\nexport type DisplayItem = \n\t| { type: \"text\"; text: string } \n\t| { type: \"tool\"; name: string; args: Record<string, unknown> };\n\n// ============================================================================\n// Error Handling\n// ============================================================================\n\nexport interface ErrorInfo {\n\thasError: boolean;\n\texitCode?: number;\n\terrorType?: string;\n\tdetails?: string;\n}\n\nexport interface IntercomEventBus {\n\ton(channel: string, handler: (data: unknown) => void): () => void;\n\temit(channel: string, data: unknown): void;\n}\n\nexport const INTERCOM_DETACH_REQUEST_EVENT = \"pi-intercom:detach-request\";\nexport const INTERCOM_DETACH_RESPONSE_EVENT = \"pi-intercom:detach-response\";\nexport const SUBAGENT_ASYNC_STARTED_EVENT = \"subagent:async-started\";\nexport const SUBAGENT_ASYNC_COMPLETE_EVENT = \"subagent:async-complete\";\nexport const SUBAGENT_FOREGROUND_COMPLETE_EVENT = \"subagent:foreground-complete\";\nexport const SUBAGENT_CONTROL_EVENT = \"subagent:control-event\";\nexport const SUBAGENT_CONTROL_INTERCOM_EVENT = \"subagent:control-intercom\";\nexport const SUBAGENT_STEERING_NOTICE_EVENT = \"subagent:steering-notice\";\nexport const SUBAGENT_RESULT_INTERCOM_EVENT = \"subagent:result-intercom\";\nexport const SUBAGENT_RESULT_INTERCOM_DELIVERY_EVENT = \"subagent:result-intercom-delivery\";\n\n// ============================================================================\n// Execution Options\n// ============================================================================\n\nexport interface RunSyncOptions {\n\t/** Session id of the direct parent session for permission-system ask forwarding. */\n\tparentSessionId?: string;\n\tcwd?: string;\n\tsignal?: AbortSignal;\n\tinterruptSignal?: AbortSignal;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\tturnBudget?: ResolvedTurnBudget;\n\ttoolBudget?: ResolvedToolBudget;\n\tallowIntercomDetach?: boolean;\n\tintercomEvents?: IntercomEventBus;\n\tonUpdate?: (r: import(\"@ashx-j/lunr-agent\").AgentToolResult<Details>) => void;\n\tonControlEvent?: (event: ControlEvent) => void;\n\tonDetachedExit?: (result: SingleResult) => void;\n\tcontrolConfig?: ResolvedControlConfig;\n\tintercomSessionName?: string;\n\torchestratorIntercomTarget?: string;\n\tmaxOutput?: MaxOutputConfig;\n\tartifactsDir?: string;\n\tartifactConfig?: ArtifactConfig;\n\trunId: string;\n\tindex?: number;\n\tsessionDir?: string;\n\tsessionFile?: string;\n\tshare?: boolean;\n\toutputPath?: string;\n\toutputMode?: OutputMode;\n\tmaxSubagentDepth?: number;\n\t/** Effective parent wait-tool setting propagated to the child runtime. */\n\twaitToolEnabled?: boolean;\n\tnestedRoute?: NestedRouteInfo;\n\t/** Override the agent's default model (format: \"provider/id\" or just \"id\") */\n\tmodelOverride?: string;\n\t/** Override the agent's default thinking level for this run */\n\tthinkingOverride?: string | false;\n\t/** Registry models available for heuristic bare-model resolution */\n\tavailableModels?: Array<{ provider: string; id: string; fullId: string }>;\n\t/** Current parent-session provider to prefer for ambiguous bare model ids */\n\tpreferredModelProvider?: string;\n\t/** Optional subagent model-scope enforcement for fallback candidates */\n\tmodelScope?: ModelScopeConfig;\n\t/** Skills to make available (overrides agent default if provided) */\n\tskills?: string[];\n\tstructuredOutput?: {\n\t\tschema: JsonSchemaObject;\n\t\tschemaPath: string;\n\t\toutputPath: string;\n\t};\n\tacceptance?: AcceptanceInput;\n\tacceptanceContext?: {\n\t\tmode?: SubagentRunMode;\n\t\tasync?: boolean;\n\t\tdynamic?: boolean;\n\t\tdynamicGroup?: boolean;\n\t};\n}\n\nexport type IntercomBridgeMode = \"off\" | \"fork-only\" | \"always\";\n\nexport interface IntercomBridgeConfig {\n\tmode?: IntercomBridgeMode;\n\tinstructionFile?: string;\n}\n\ninterface TopLevelParallelConfig {\n\tmaxTasks?: number;\n\tconcurrency?: number;\n}\n\ninterface ExtensionChainConfig {\n\tdynamicFanout?: {\n\t\tmaxItems?: number;\n\t};\n}\n\nexport interface ProactiveSkillSubagentsConfig {\n\tenabled?: boolean;\n\tminReferences?: number;\n\tmaxRecommendations?: number;\n\tpreferredAgent?: string;\n}\n\nexport type ToolDescriptionMode = \"full\" | \"compact\" | \"custom\";\n\nexport interface ScheduledRunsConfig {\n\tenabled?: boolean;\n\tmaxLatenessMs?: number;\n\tmaxPending?: number;\n}\n\nexport interface ExtensionConfig {\n\tasyncByDefault?: boolean;\n\t/** Show the above-editor async runs widget. Defaults to true. */\n\tasyncWidget?: boolean;\n\t/** Tool description variant registered for the parent-facing subagent tool. Defaults to full. */\n\ttoolDescriptionMode?: ToolDescriptionMode;\n\tforceTopLevelAsync?: boolean;\n\twaitTool?: WaitToolConfig;\n\tdefaultSessionDir?: string;\n\tsingleRunOutputBaseDir?: string;\n\tmaxSubagentDepth?: number;\n\t/** Optional cumulative session cap. Unset or 0 means unlimited. */\n\tmaxSubagentSpawnsPerSession?: number;\n\t/** Global cap on simultaneously-running subagent tasks within a single run. Unset means unlimited. */\n\tglobalConcurrencyLimit?: number;\n\tcontrol?: ControlConfig;\n\tcompletionBatch?: CompletionBatchConfig;\n\tturnBudget?: TurnBudgetConfig;\n\ttoolBudget?: ToolBudgetConfig;\n\tparallel?: TopLevelParallelConfig;\n\tchain?: ExtensionChainConfig;\n\tworktreeSetupHook?: string;\n\tworktreeSetupHookTimeoutMs?: number;\n\tworktreeBaseDir?: string;\n\tintercomBridge?: IntercomBridgeConfig;\n\tproactiveSkillSubagents?: ProactiveSkillSubagentsConfig | false;\n\tscheduledRuns?: ScheduledRunsConfig;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nexport const DEFAULT_MAX_OUTPUT: Required<MaxOutputConfig> = {\n\tbytes: 200 * 1024,\n\tlines: 5000,\n};\n\nexport const DEFAULT_ARTIFACT_CONFIG: ArtifactConfig = {\n\tenabled: true,\n\tincludeInput: true,\n\tincludeOutput: true,\n\tincludeJsonl: false,\n\tincludeTranscript: true,\n\tincludeMetadata: true,\n\tcleanupDays: 7,\n};\n\nfunction sanitizeTempScopeSegment(value: string): string {\n\tconst sanitized = value\n\t\t.trim()\n\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t.replace(/^-+|-+$/g, \"\");\n\treturn sanitized || \"unknown\";\n}\n\nexport function resolveTempScopeId(options?: {\n\tenv?: NodeJS.ProcessEnv;\n\tgetuid?: (() => number) | undefined;\n\tuserInfo?: (() => { username?: string | null }) | undefined;\n\thomedir?: (() => string) | undefined;\n}): string {\n\tconst env = options?.env ?? process.env;\n\tconst getuid = options && Object.hasOwn(options, \"getuid\")\n\t\t? options.getuid\n\t\t: process.getuid?.bind(process);\n\tif (typeof getuid === \"function\") {\n\t\treturn `uid-${getuid()}`;\n\t}\n\n\tfor (const key of [\"USERNAME\", \"USER\", \"LOGNAME\"] as const) {\n\t\tconst value = env[key];\n\t\tif (value) return `user-${sanitizeTempScopeSegment(value)}`;\n\t}\n\n\tconst userInfo = options && Object.hasOwn(options, \"userInfo\")\n\t\t? options.userInfo\n\t\t: os.userInfo;\n\ttry {\n\t\tconst username = userInfo?.().username;\n\t\tif (username) return `user-${sanitizeTempScopeSegment(username)}`;\n\t} catch {\n\t\t// Fall through to home-directory-based scoping.\n\t}\n\n\tconst homedir = env.USERPROFILE ?? env.HOME;\n\tif (homedir) return `home-${sanitizeTempScopeSegment(homedir)}`;\n\n\tconst resolveHomedir = options && Object.hasOwn(options, \"homedir\")\n\t\t? options.homedir\n\t\t: os.homedir;\n\ttry {\n\t\tconst fallbackHomedir = resolveHomedir?.();\n\t\tif (fallbackHomedir) return `home-${sanitizeTempScopeSegment(fallbackHomedir)}`;\n\t} catch {\n\t\t// Fall through to the last-resort shared scope.\n\t}\n\n\treturn \"shared\";\n}\n\nconst MAX_PARALLEL = Number.MAX_SAFE_INTEGER;\nexport const MAX_CONCURRENCY = Number.MAX_SAFE_INTEGER;\nexport const TEMP_ROOT_DIR = path.join(os.tmpdir(), `pi-subagents-${resolveTempScopeId()}`);\nexport const RESULTS_DIR = path.join(TEMP_ROOT_DIR, \"async-subagent-results\");\nexport const ASYNC_DIR = path.join(TEMP_ROOT_DIR, \"async-subagent-runs\");\nexport const CHAIN_RUNS_DIR = path.join(TEMP_ROOT_DIR, \"chain-runs\");\nexport const TEMP_ARTIFACTS_DIR = path.join(TEMP_ROOT_DIR, \"artifacts\");\nexport const WIDGET_KEY = \"subagent-async\";\nexport const SLASH_RESULT_TYPE = \"subagent-slash-result\";\nexport const SLASH_TEXT_RESULT_TYPE = \"subagent-slash-text-result\";\nexport const SLASH_SUBAGENT_REQUEST_EVENT = \"subagent:slash:request\";\nexport const SLASH_SUBAGENT_STARTED_EVENT = \"subagent:slash:started\";\nexport const SLASH_SUBAGENT_RESPONSE_EVENT = \"subagent:slash:response\";\nexport const SLASH_SUBAGENT_UPDATE_EVENT = \"subagent:slash:update\";\nexport const SLASH_SUBAGENT_CANCEL_EVENT = \"subagent:slash:cancel\";\nexport const POLL_INTERVAL_MS = 250;\nexport const MAX_WIDGET_JOBS = 4;\nexport const DEFAULT_SUBAGENT_MAX_DEPTH = 2;\nexport const SUBAGENT_ACTIONS = [\"status\", \"interrupt\", \"resume\", \"steer\", \"stop\", \"append-step\", \"doctor\", \"watchdog.status\", \"watchdog.check\", \"watchdog.configure\", \"watchdog.recommend-model\", \"schedule\", \"schedule-list\", \"schedule-status\", \"schedule-cancel\"] as const;\nexport const REMOVED_SUBAGENT_ACTIONS = [\"list\", \"get\", \"models\", \"create\", \"update\", \"delete\", \"eject\", \"disable\", \"enable\", \"reset\"] as const;\n\nexport const DEFAULT_FORK_PREAMBLE =\n\t\"You are a delegated subagent running from a fork of the parent session. \" +\n\t\"Treat the inherited conversation as reference-only context, not a live thread to continue. \" +\n\t\"Do not continue or answer prior messages as if they are waiting for a reply. \" +\n\t\"Your sole job is to execute the task below and return a focused result for that task using your tools.\";\n\nfunction normalizeTopLevelParallelValue(value: unknown): number | undefined {\n\tconst parsed = typeof value === \"number\" ? value : typeof value === \"string\" ? Number(value) : NaN;\n\tif (!Number.isInteger(parsed) || parsed < 1) return undefined;\n\treturn parsed;\n}\n\nexport function resolveTopLevelParallelMaxTasks(value: unknown): number {\n\treturn normalizeTopLevelParallelValue(value) ?? MAX_PARALLEL;\n}\n\nexport function resolveTopLevelParallelConcurrency(\n\toverride: unknown,\n\tconfigValue: unknown,\n): number {\n\treturn normalizeTopLevelParallelValue(override)\n\t\t?? normalizeTopLevelParallelValue(configValue)\n\t\t?? MAX_CONCURRENCY;\n}\n\nexport function getAsyncConfigPath(suffix: string): string {\n\treturn path.join(TEMP_ROOT_DIR, `async-cfg-${suffix}.json`);\n}\n\nexport function wrapForkTask(task: string, preamble?: string | false): string {\n\tif (preamble === false) return task;\n\tconst effectivePreamble = preamble ?? DEFAULT_FORK_PREAMBLE;\n\tconst wrappedPrefix = `${effectivePreamble}\\n\\nTask:\\n`;\n\tif (task.startsWith(wrappedPrefix)) return task;\n\treturn `${wrappedPrefix}${task}`;\n}\n\n// ============================================================================\n// Recursion Depth Guard\n// ============================================================================\n\nfunction normalizeNonNegativeInteger(value: unknown): number | undefined {\n\tconst parsed = typeof value === \"number\" ? value : typeof value === \"string\" ? Number(value) : NaN;\n\tif (!Number.isInteger(parsed) || parsed < 0) return undefined;\n\treturn parsed;\n}\n\nexport function normalizeMaxSubagentDepth(value: unknown): number | undefined {\n\treturn normalizeNonNegativeInteger(value);\n}\n\nexport function resolveCurrentMaxSubagentDepth(configMaxDepth?: number): number {\n\treturn normalizeMaxSubagentDepth(process.env.PI_SUBAGENT_MAX_DEPTH)\n\t\t?? normalizeMaxSubagentDepth(configMaxDepth)\n\t\t?? DEFAULT_SUBAGENT_MAX_DEPTH;\n}\n\nexport function resolveChildMaxSubagentDepth(parentMaxDepth: number, agentMaxDepth?: number): number {\n\tconst normalizedParent = normalizeMaxSubagentDepth(parentMaxDepth) ?? DEFAULT_SUBAGENT_MAX_DEPTH;\n\tconst normalizedAgent = normalizeMaxSubagentDepth(agentMaxDepth);\n\treturn normalizedAgent === undefined ? normalizedParent : Math.min(normalizedParent, normalizedAgent);\n}\n\nexport function checkSubagentDepth(configMaxDepth?: number): { blocked: boolean; depth: number; maxDepth: number } {\n\tconst depth = Number(process.env.PI_SUBAGENT_DEPTH ?? \"0\");\n\tconst maxDepth = resolveCurrentMaxSubagentDepth(configMaxDepth);\n\tconst blocked = Number.isFinite(depth) && depth >= maxDepth;\n\treturn { blocked, depth, maxDepth };\n}\n\nexport function getSubagentDepthEnv(maxDepth?: number): Record<string, string> {\n\tconst parentDepth = Number(process.env.PI_SUBAGENT_DEPTH ?? \"0\");\n\tconst nextDepth = Number.isFinite(parentDepth) ? parentDepth + 1 : 1;\n\treturn {\n\t\tPI_SUBAGENT_DEPTH: String(nextDepth),\n\t\tPI_SUBAGENT_MAX_DEPTH: String(normalizeMaxSubagentDepth(maxDepth) ?? resolveCurrentMaxSubagentDepth()),\n\t};\n}\n\nexport function normalizeMaxSubagentSpawnsPerSession(value: unknown): number | undefined {\n\treturn normalizeNonNegativeInteger(value);\n}\n\nexport function resolveMaxSubagentSpawnsPerSession(configMaxSpawns?: number): number | undefined {\n\tconst envMaxSpawns = normalizeMaxSubagentSpawnsPerSession(process.env.PI_SUBAGENT_MAX_SPAWNS_PER_SESSION);\n\tif (envMaxSpawns !== undefined) return envMaxSpawns === 0 ? undefined : envMaxSpawns;\n\tconst configuredMaxSpawns = normalizeMaxSubagentSpawnsPerSession(configMaxSpawns);\n\treturn configuredMaxSpawns === 0 ? undefined : configuredMaxSpawns;\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nfunction formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes}B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\nexport function truncateOutput(\n\toutput: string,\n\tconfig: Required<MaxOutputConfig>,\n\tartifactPath?: string,\n): TruncationResult {\n\tconst lines = output.split(\"\\n\");\n\tconst bytes = Buffer.byteLength(output, \"utf-8\");\n\n\tif (bytes <= config.bytes && lines.length <= config.lines) {\n\t\treturn { text: output, truncated: false };\n\t}\n\n\tlet truncatedLines = lines;\n\tif (lines.length > config.lines) {\n\t\ttruncatedLines = lines.slice(0, config.lines);\n\t}\n\n\tlet result = truncatedLines.join(\"\\n\");\n\tif (Buffer.byteLength(result, \"utf-8\") > config.bytes) {\n\t\tlet low = 0;\n\t\tlet high = result.length;\n\t\twhile (low < high) {\n\t\t\tconst mid = Math.floor((low + high + 1) / 2);\n\t\t\tif (Buffer.byteLength(result.slice(0, mid), \"utf-8\") <= config.bytes) {\n\t\t\t\tlow = mid;\n\t\t\t} else {\n\t\t\t\thigh = mid - 1;\n\t\t\t}\n\t\t}\n\t\tresult = result.slice(0, low);\n\t}\n\n\tconst keptLines = result.split(\"\\n\").length;\n\tconst marker = `[TRUNCATED: showing first ${keptLines} of ${lines.length} lines, ${formatBytes(Buffer.byteLength(result))} of ${formatBytes(bytes)}${artifactPath ? ` - full output at ${artifactPath}` : \"\"}]\\n`;\n\n\treturn {\n\t\ttext: marker + result,\n\t\ttruncated: true,\n\t\toriginalBytes: bytes,\n\t\toriginalLines: lines.length,\n\t\tartifactPath,\n\t};\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/builtin-extensions/pi-subagents/src/shared/types.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\n/**\n * Type definitions for the subagent extension\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { Message } from \"@ashx-j/lunr-ai\";\nimport type { FSWatcher } from \"node:fs\";\nimport type { ExtensionContext } from \"@ashx-j/lunr\";\nimport type { ModelScopeConfig } from \"../runs/shared/model-scope.ts\";\n\n// ============================================================================\n// Basic Types\n// ============================================================================\n\nexport interface MaxOutputConfig {\n\tbytes?: number;\n\tlines?: number;\n}\n\nexport type OutputMode = \"inline\" | \"file-only\";\n\nexport type ChildPermission = \"full\" | \"read-only\";\nexport type ChildTier = \"light\" | \"standard\" | \"heavy\";\n\n/** How the child model was chosen. Captured from requested params before resolution. */\nexport type ModelSelection =\n\t| { kind: \"tier\"; tier: ChildTier }\n\t| { kind: \"model\"; model?: string };\n\nexport interface ChildSpec {\n\tchildId: string;\n\ttask: string;\n\tdescription: string;\n\trequestedPermissions: ChildPermission;\n\teffectivePermissions: ChildPermission;\n\t/** User-requested model when modelSelection.kind is \"model\". Never a tier-resolved runtime id. */\n\tmodel?: string;\n\ttier?: ChildTier;\n\tmodelSelection?: ModelSelection;\n\t/** Explicit thinking level paired with modelSelection.kind === \"model\". */\n\tthinking?: string;\n\tskill?: string | string[] | false;\n\tcwd?: string;\n\toutput?: string | false;\n\toutputMode?: OutputMode;\n\tacceptance?: AcceptanceInput;\n\ttoolBudget?: ToolBudgetConfig;\n\tcount?: number;\n\treads?: string[] | false;\n\tprogress?: boolean;\n\tlabel?: string;\n\tphase?: string;\n\tas?: string;\n\toutputSchema?: JsonSchemaObject;\n\tfanoutAuthorized?: boolean;\n}\n\n/** Internal execution compatibility shape. It is built from ChildSpec and is never user-discovered. */\nexport interface ChildRuntimeConfig {\n\tname: string;\n\tdescription: string;\n\ttools?: string[];\n\tmcpDirectTools?: string[];\n\tmodel?: string;\n\tfallbackModels?: string[];\n\tthinking?: string | false;\n\tsystemPromptMode: \"append\" | \"replace\";\n\tinheritProjectContext: boolean;\n\tinheritSkills: boolean;\n\tacceptanceRole?: AcceptanceRole;\n\tsystemPrompt: string;\n\tskills?: string[];\n\tskillPath?: string[];\n\textensions?: string[];\n\tsubagentOnlyExtensions?: string[];\n\toutput?: string;\n\tmaxSubagentDepth?: number;\n\tcompletionGuard?: boolean;\n\ttoolBudget?: ToolBudgetConfig;\n}\n\nexport function childRowLabel(entry: {\n\tdescription?: string;\n\tlabel?: string;\n\tagent?: string;\n\tchildId?: string;\n}): string {\n\treturn entry.label?.trim() || entry.description?.trim() || entry.agent?.trim() || entry.childId || \"child\";\n}\n\nexport type AcceptanceRole = \"read-only\" | \"writer\";\n\nexport type JsonSchemaObject = Record<string, unknown>;\n\nexport interface ChainOutputMapEntry {\n\ttext: string;\n\tstructured?: unknown;\n\tagent: string;\n\tstepIndex: number;\n}\n\nexport type ChainOutputMap = Record<string, ChainOutputMapEntry>;\n\nexport type WorkflowNodeStatus = \"pending\" | \"running\" | \"completed\" | \"failed\" | \"paused\" | \"stopped\" | \"detached\";\n\nexport interface WorkflowGraphNode {\n\tid: string;\n\tkind: \"step\" | \"parallel-group\" | \"dynamic-parallel-group\" | \"agent\";\n\tagent?: string;\n\tphase?: string;\n\tlabel: string;\n\tstatus: WorkflowNodeStatus;\n\tflatIndex?: number;\n\tstepIndex?: number;\n\tchildren?: WorkflowGraphNode[];\n\tdynamic?: {\n\t\tsourceOutput: string;\n\t\tsourcePath: string;\n\t\titemName: string;\n\t\tmaxItems?: number;\n\t\tcollectAs?: string;\n\t};\n\titemKey?: string;\n\toutputName?: string;\n\tstructured?: boolean;\n\tacceptanceStatus?: AcceptanceLedgerStatus;\n\terror?: string;\n}\n\nexport interface WorkflowGraphSnapshot {\n\trunId: string;\n\tmode: \"chain\" | \"parallel\" | \"single\";\n\tphases: Array<{ title: string; nodeIds: string[] }>;\n\tnodes: WorkflowGraphNode[];\n\tcurrentNodeId?: string;\n}\n\nexport interface SavedOutputReference {\n\tpath: string;\n\tbytes: number;\n\tlines: number;\n\tmessage: string;\n}\n\ninterface TruncationResult {\n\ttext: string;\n\ttruncated: boolean;\n\toriginalBytes?: number;\n\toriginalLines?: number;\n\tartifactPath?: string;\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\tcost: number;\n\tturns: number;\n}\n\nexport interface TurnBudgetConfig {\n\tmaxTurns: number;\n\tgraceTurns?: number;\n}\n\nexport interface ResolvedTurnBudget {\n\tmaxTurns: number;\n\tgraceTurns: number;\n}\n\nexport interface ToolBudgetConfig {\n\tsoft?: number;\n\thard: number;\n\tblock?: string[] | \"*\";\n}\n\nexport interface ResolvedToolBudget {\n\tsoft?: number;\n\thard: number;\n\tblock: string[] | \"*\";\n}\n\nexport type ToolBudgetOutcome = \"within-budget\" | \"soft-reached\" | \"hard-blocked\";\n\nexport interface ToolBudgetState extends ResolvedToolBudget {\n\toutcome: ToolBudgetOutcome;\n\ttoolCount: number;\n\tsoftReachedAt?: number;\n\thardReachedAt?: number;\n\tblockedTool?: string;\n}\n\nexport type TurnBudgetOutcome = \"within-budget\" | \"wrap-up-requested\" | \"exceeded\";\n\nexport interface TurnBudgetState extends ResolvedTurnBudget {\n\toutcome: TurnBudgetOutcome;\n\tturnCount: number;\n\twrapUpRequestedAtTurn?: number;\n\texceededAtTurn?: number;\n}\n\nexport interface TokenUsage {\n\tinput: number;\n\toutput: number;\n\ttotal: number;\n}\n\nexport type ActivityState = \"active_long_running\" | \"needs_attention\";\nexport type ControlEventType = \"active_long_running\" | \"needs_attention\";\nexport type ControlNotificationChannel = \"event\" | \"async\" | \"intercom\";\n\nexport interface ControlConfig {\n\tenabled?: boolean;\n\tneedsAttentionAfterMs?: number;\n\tactiveNoticeAfterMs?: number;\n\tactiveNoticeAfterTurns?: number;\n\tactiveNoticeAfterTokens?: number;\n\tfailedToolAttemptsBeforeAttention?: number;\n\tnotifyOn?: ControlEventType[];\n\tnotifyChannels?: ControlNotificationChannel[];\n}\n\nexport interface ResolvedControlConfig {\n\tenabled: boolean;\n\tneedsAttentionAfterMs: number;\n\tactiveNoticeAfterMs: number;\n\tactiveNoticeAfterTurns?: number;\n\tactiveNoticeAfterTokens?: number;\n\tfailedToolAttemptsBeforeAttention: number;\n\tnotifyOn: ControlEventType[];\n\tnotifyChannels: ControlNotificationChannel[];\n}\n\n/**\n * Smart completion batching for async-completion notifications. Successful\n * sibling completions are held briefly so they arrive as one grouped message;\n * failure and attention signals bypass grouping and always fire immediately.\n */\nexport interface CompletionBatchConfig {\n\tenabled?: boolean;\n\t/** Idle window after each arrival; resets on every new item. */\n\tdebounceMs?: number;\n\t/** Hard cap measured from the first item in a group. */\n\tmaxWaitMs?: number;\n\t/** Shorter idle window for straggler groups. */\n\tstragglerDebounceMs?: number;\n\t/** Shorter hard cap for straggler groups. */\n\tstragglerMaxWaitMs?: number;\n\t/** Arrivals within this window after an emit join a straggler group. */\n\tstragglerWindowMs?: number;\n}\n\nexport interface WaitToolConfigObject {\n\tenabled?: boolean;\n}\n\nexport type WaitToolConfig = boolean | WaitToolConfigObject;\n\nexport interface ControlEvent {\n\ttype: ControlEventType;\n\tfrom?: ActivityState;\n\tto: ActivityState;\n\tts: number;\n\tagent: string;\n\tindex?: number;\n\trunId: string;\n\tnestedRunId?: string;\n\tnestingPath?: NestedRunAddress[\"path\"];\n\tmessage: string;\n\treason?: \"idle\" | \"completion_guard\" | \"active_long_running\" | \"tool_failures\" | \"time_threshold\" | \"turn_threshold\" | \"token_threshold\";\n\tturns?: number;\n\ttokens?: number;\n\ttoolCount?: number;\n\tcurrentTool?: string;\n\tcurrentToolDurationMs?: number;\n\tcurrentPath?: string;\n\telapsedMs?: number;\n\trecentFailureSummary?: string;\n}\n\nexport type SubagentResultStatus = \"completed\" | \"failed\" | \"paused\" | \"stopped\" | \"detached\";\nexport type SubagentRunMode = \"single\" | \"parallel\" | \"chain\";\nexport const SUBAGENT_LIFECYCLE_ARTIFACT_VERSION = 4;\nexport type SubagentLifecycleArtifactVersion = typeof SUBAGENT_LIFECYCLE_ARTIFACT_VERSION;\nexport const UNSUPPORTED_SUBAGENT_LIFECYCLE_MESSAGE =\n\t\"This subagent run uses an unsupported lifecycle format. Named agent types cannot be resumed. Launch a new prompt-driven child instead.\";\n\nexport function isSupportedSubagentLifecycleVersion(version: unknown): boolean {\n\treturn version === SUBAGENT_LIFECYCLE_ARTIFACT_VERSION;\n}\n\nexport type SteeringActionState = \"delivered\" | \"scheduled\" | \"pending\" | \"partial\" | \"recovered\" | \"failed\";\nexport type SteeringTargetState = \"scheduled\" | \"routed\" | \"delivered\" | \"late\" | \"failed\" | \"recovered\";\n\nexport interface SteeringTargetStatus {\n\tindex: number;\n\tstate: SteeringTargetState;\n\troutedAt?: number;\n\tdeliveredAt?: number;\n\tlateDeliveredAt?: number;\n\tfailedAt?: number;\n\trecoveredAt?: number;\n\treason?: string;\n\treplacementRunId?: string;\n}\n\nexport interface SteeringRequestStatus {\n\tid: string;\n\trequestedAt: number;\n\tsource?: string;\n\tmessagePreview: string;\n\ttargets: SteeringTargetStatus[];\n}\n\nexport interface SteeringStatus {\n\trequested: number;\n\tscheduled: number;\n\tpending: number;\n\tdelivered: number;\n\tfailed: number;\n\trecovered: number;\n\tlastRequestedAt?: number;\n\tlastDeliveredAt?: number;\n\trecent: SteeringRequestStatus[];\n}\n\nexport interface SteerActionTarget {\n\tindex: number;\n\tstate: SteeringTargetState;\n\tdeliveredAt?: number;\n\tlateDeliveredAt?: number;\n\treason?: string;\n\treplacementRunId?: string;\n}\n\nexport interface SteerActionResult {\n\trequestId: string;\n\tstate: SteeringActionState;\n\tsourceRunId: string;\n\treplacementRunId?: string;\n\ttargets: SteerActionTarget[];\n}\n\nexport interface SteeringNotice {\n\ttype: \"subagent.steering.notice\";\n\tts: number;\n\trunId: string;\n\trequestId: string;\n\tstate: \"failed\" | \"partial\" | \"recovered\";\n\tmessage: string;\n\tcurrentSessionId?: string;\n}\n\nexport interface SteeringRecoveryDescriptor {\n\tversion: 4;\n\tlifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;\n\tsourceRunId: string;\n\tchildId: string;\n\tdescription: string;\n\tpermissions: ChildPermission;\n\tagent: string;\n\tsessionFile?: string;\n\tcwd: string;\n\tmodel?: string;\n\ttier?: ChildTier;\n\tthinking?: string;\n\tmodelSelection?: ModelSelection;\n\tskills?: string[];\n\toutputPath?: string;\n\toutputMode: \"inline\" | \"file-only\";\n\tacceptance?: ResolvedAcceptanceConfig;\n\tcontrolConfig?: ResolvedControlConfig;\n\tabsoluteDeadlineAt?: number;\n\tinitialTurnBudget?: ResolvedTurnBudget;\n\tinitialToolBudget?: ResolvedToolBudget;\n\tmaxSubagentDepth: number;\n\tmaxOutput?: MaxOutputConfig;\n\tshare: boolean;\n\tsessionDir?: string;\n\tartifactsDir?: string;\n\tartifactConfig?: ArtifactConfig;\n}\n\nexport type PublicNestedStepSummary = Pick<\n\tNestedStepSummary,\n\t\"agent\" | \"status\" | \"sessionFile\" | \"transcriptPath\" | \"transcriptError\" | \"activityState\" | \"lastActivityAt\" | \"currentTool\" | \"currentToolStartedAt\" | \"currentPath\" | \"turnCount\" | \"toolCount\" | \"toolBudget\" | \"toolBudgetBlocked\" | \"startedAt\" | \"endedAt\" | \"error\" | \"timedOut\" | \"stopped\"\n> & {\n\tchildren?: PublicNestedRunSummary[];\n};\n\nexport type CostSummary = {\n\tinputTokens: number;\n\toutputTokens: number;\n\tcostUsd: number;\n};\n\nexport type PublicNestedRunSummary = Pick<\n\tNestedRunSummary,\n\t\"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\" | \"stopped\" | \"turnBudget\" | \"turnBudgetExceeded\" | \"wrapUpRequested\"\n> & {\n\tsteps?: PublicNestedStepSummary[];\n\tchildren?: PublicNestedRunSummary[];\n};\n\nexport interface SubagentResultIntercomChild {\n\tagent: string;\n\tstatus: SubagentResultStatus;\n\tsummary: string;\n\tindex?: number;\n\tartifactPath?: string;\n\tsessionPath?: string;\n\tintercomTarget?: string;\n\tchildren?: PublicNestedRunSummary[];\n}\n\nexport interface SubagentResultIntercomPayload {\n\tto: string;\n\tmessage: string;\n\trequestId?: string;\n\trunId: string;\n\tmode: SubagentRunMode;\n\tstatus: SubagentResultStatus;\n\tsummary: string;\n\tsource: \"foreground\" | \"async\";\n\tchildren: SubagentResultIntercomChild[];\n\tasyncId?: string;\n\tasyncDir?: string;\n\tchainSteps?: number;\n\tagent?: string;\n\tindex?: number;\n\tartifactPath?: string;\n\tsessionPath?: string;\n}\n\n// ============================================================================\n// Progress Tracking\n// ============================================================================\n\nexport interface ChildWatchdogProgress {\n\tphase: \"idle\" | \"reviewing\" | \"autofollow\" | \"settling\" | \"stale\" | \"failed\";\n\tseq: number;\n\tlastUpdate: number;\n\tfollowUpPending: boolean;\n\treason?: string;\n\ttimedOut?: boolean;\n}\n\nexport interface AgentProgress {\n\tindex: number;\n\tchildId?: string;\n\tdescription?: string;\n\tpermissions?: ChildPermission;\n\tagent: string;\n\tstatus: \"pending\" | \"running\" | \"completed\" | \"failed\" | \"detached\";\n\tactivityState?: ActivityState;\n\ttask: string;\n\tskills?: string[];\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolArgs?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: ModelSelection;\n\tthinkingText?: string;\n\trecentTools: Array<{ tool: string; args: string; endMs: number }>;\n\trecentOutput: string[];\n\ttoolCount: number;\n\tturnCount?: number;\n\ttokens: number;\n\tdurationMs: number;\n\terror?: string;\n\tfailedTool?: string;\n\twatchdog?: ChildWatchdogProgress;\n}\n\nexport interface ToolCallSummary {\n\ttext: string;\n\texpandedText: string;\n}\n\ninterface ProgressSummary {\n\ttoolCount: number;\n\ttokens: number;\n\tdurationMs: number;\n}\n\n// ============================================================================\n// Results\n// ============================================================================\n\nexport interface ModelAttempt {\n\tmodel: string;\n\tsuccess: boolean;\n\texitCode?: number | null;\n\terror?: string;\n\tusage?: Usage;\n}\n\nexport type AcceptanceLevel = \"auto\" | \"none\" | \"attested\" | \"checked\" | \"verified\" | \"reviewed\";\n\nexport type AcceptanceEvidenceKind =\n\t| \"changed-files\"\n\t| \"tests-added\"\n\t| \"commands-run\"\n\t| \"validation-output\"\n\t| \"residual-risks\"\n\t| \"no-staged-files\"\n\t| \"diff-summary\"\n\t| \"review-findings\"\n\t| \"manual-notes\";\n\nexport interface AcceptanceGate {\n\tid: string;\n\tmust: string;\n\tevidence?: AcceptanceEvidenceKind[];\n\tseverity?: \"required\" | \"recommended\";\n}\n\nexport interface AcceptanceVerifyCommand {\n\tid: string;\n\tcommand: string;\n\ttimeoutMs?: number;\n\tcwd?: string;\n\tenv?: Record<string, string>;\n\tallowFailure?: boolean;\n}\n\nexport interface AcceptanceReviewGate {\n\tagent?: string;\n\tfocus?: string;\n\trequired?: boolean;\n}\n\nexport interface AcceptanceConfig {\n\tlevel?: AcceptanceLevel;\n\tcriteria?: Array<string | AcceptanceGate>;\n\tevidence?: AcceptanceEvidenceKind[];\n\tverify?: AcceptanceVerifyCommand[];\n\treview?: AcceptanceReviewGate | false;\n\tstopRules?: string[];\n\treason?: string;\n}\n\n/** Bare \"none\" is not accepted: use { level: \"none\", reason: \"...\" }; false remains a deprecated shorthand. */\nexport type AcceptanceInput = Exclude<AcceptanceLevel, \"none\"> | false | AcceptanceConfig;\n\nexport interface ResolvedAcceptanceGate extends AcceptanceGate {\n\tid: string;\n\tmust: string;\n\tevidence: AcceptanceEvidenceKind[];\n\tseverity: \"required\" | \"recommended\";\n}\n\nexport interface ResolvedAcceptanceConfig {\n\tlevel: Exclude<AcceptanceLevel, \"auto\">;\n\texplicit: boolean;\n\tinferredReason: string[];\n\tcriteria: ResolvedAcceptanceGate[];\n\tevidence: AcceptanceEvidenceKind[];\n\tverify: AcceptanceVerifyCommand[];\n\treview?: AcceptanceReviewGate | false;\n\tstopRules: string[];\n\treason?: string;\n}\n\nexport interface AcceptanceReport {\n\tcriteriaSatisfied?: Array<{\n\t\tid?: string;\n\t\tstatus: \"satisfied\" | \"not-satisfied\" | \"not-applicable\";\n\t\tevidence: string;\n\t}>;\n\tchangedFiles?: string[];\n\ttestsAddedOrUpdated?: string[];\n\tcommandsRun?: Array<{\n\t\tcommand: string;\n\t\tresult: \"passed\" | \"failed\" | \"not-run\";\n\t\tsummary: string;\n\t}>;\n\tvalidationOutput?: string[];\n\tresidualRisks?: string[];\n\tnoStagedFiles?: boolean;\n\tdiffSummary?: string;\n\treviewFindings?: string[];\n\tmanualNotes?: string;\n\tnotes?: string;\n}\n\nexport type AcceptanceRuntimeCheckStatus = \"passed\" | \"failed\" | \"not-applicable\";\n\nexport interface AcceptanceRuntimeCheck {\n\tid: string;\n\tstatus: AcceptanceRuntimeCheckStatus;\n\tmessage: string;\n}\n\nexport interface AcceptanceVerifyResult {\n\tid: string;\n\tcommand: string;\n\tcwd?: string;\n\texitCode: number | null;\n\tstatus: \"passed\" | \"failed\" | \"timed-out\" | \"allowed-failure\";\n\tstdout?: string;\n\tstderr?: string;\n\tdurationMs: number;\n}\n\nexport interface AcceptanceReviewResult {\n\tstatus: \"no-blockers\" | \"blockers\" | \"needs-parent-decision\";\n\tfindings: Array<{\n\t\tseverity: \"blocker\" | \"non-blocking\";\n\t\tfile?: string;\n\t\tissue: string;\n\t\trationale: string;\n\t}>;\n}\n\nexport type AcceptanceLedgerStatus =\n\t| \"pending\"\n\t| \"not-required\"\n\t| \"claimed\"\n\t| \"attested\"\n\t| \"checked\"\n\t| \"verified\"\n\t| \"reviewed\"\n\t| \"accepted\"\n\t| \"rejected\";\n\nexport interface AcceptanceLedger {\n\tstatus: AcceptanceLedgerStatus;\n\texplicit: boolean;\n\teffectiveAcceptance: ResolvedAcceptanceConfig;\n\tinferredReason: string[];\n\tcriteria: ResolvedAcceptanceGate[];\n\tchildReport?: AcceptanceReport;\n\tchildReportParseError?: string;\n\truntimeChecks: AcceptanceRuntimeCheck[];\n\tverifyRuns: AcceptanceVerifyResult[];\n\treviewResult?: AcceptanceReviewResult;\n\tparentDecision?: {\n\t\tstatus: \"accepted\" | \"rejected\";\n\t\tat: string;\n\t\treason?: string;\n\t};\n}\n\nexport interface ProtocolOutputLimit {\n\tcode: \"protocol_output_limit\";\n\tstream: \"stdout\" | \"stderr\";\n\tlimitBytes: number;\n\tobservedBytes: number;\n\tdiagnosticPrefix: string;\n\tdiagnosticTail: string;\n}\n\nexport interface SingleResult {\n\tchildId?: string;\n\tdescription?: string;\n\tpermissions?: ChildPermission;\n\tagent: string;\n\ttask: string;\n\texitCode: number;\n\tdetached?: boolean;\n\tdetachedReason?: string;\n\tinterrupted?: boolean;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\tmessages?: Message[];\n\tusage: Usage;\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: ModelSelection;\n\tattemptedModels?: string[];\n\tmodelAttempts?: ModelAttempt[];\n\tcontrolEvents?: ControlEvent[];\n\terror?: string;\n\tprotocolError?: ProtocolOutputLimit;\n\tsessionFile?: string;\n\tskills?: string[];\n\tskillsWarning?: string;\n\tprogress?: AgentProgress;\n\tprogressSummary?: ProgressSummary;\n\ttoolCalls?: ToolCallSummary[];\n\tartifactPaths?: ArtifactPaths;\n\ttruncation?: TruncationResult;\n\tfinalOutput?: string;\n\toutputMode?: OutputMode;\n\tsavedOutputPath?: string;\n\toutputReference?: SavedOutputReference;\n\toutputSaveError?: string;\n\tstructuredOutput?: unknown;\n\tstructuredOutputPath?: string;\n\tstructuredOutputSchemaPath?: string;\n\tacceptance?: AcceptanceLedger;\n\ttranscriptPath?: string;\n\ttranscriptError?: string;\n\tchildren?: NestedRunSummary[];\n\twatchdog?: ChildWatchdogProgress;\n}\n\nexport interface Details {\n\tmode: SubagentRunMode | \"management\";\n\trunId?: string;\n\tcontext?: \"fresh\" | \"fork\";\n\tresults: SingleResult[];\n\tcontrolEvents?: ControlEvent[];\n\tsteering?: SteerActionResult;\n\tasyncId?: string;\n\tasyncDir?: string;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: ResolvedTurnBudget;\n\ttoolBudget?: ResolvedToolBudget;\n\tprogress?: AgentProgress[];\n\tprogressSummary?: ProgressSummary;\n\tartifacts?: {\n\t\tdir: string;\n\t\tfiles: ArtifactPaths[];\n\t};\n\ttruncation?: {\n\t\ttruncated: boolean;\n\t\toriginalBytes?: number;\n\t\toriginalLines?: number;\n\t\tartifactPath?: string;\n\t};\n\t// Chain metadata for observability\n\tchainAgents?: string[]; // deprecated: child descriptions in order\n\tchainChildren?: Array<{ childId: string; description: string; permissions: ChildPermission }>;\n\ttotalSteps?: number; // Total steps in chain\n\tcurrentStepIndex?: number; // 0-indexed current step (for running chains)\n\tworkflowGraph?: WorkflowGraphSnapshot;\n\toutputs?: ChainOutputMap;\n\t// Aggregated child usage across all agents in the run\n\ttotalChildUsage?: Usage;\n\t// Aggregated cost across all agents in the run\n\ttotalCost?: CostSummary;\n\tquestionId?: string;\n\tstate?: string;\n\tanswered?: boolean;\n\tdelivered?: boolean;\n}\n\n// ============================================================================\n// Artifacts\n// ============================================================================\n\nexport interface ArtifactPaths {\n\tinputPath: string;\n\toutputPath: string;\n\tjsonlPath: string;\n\ttranscriptPath: string;\n\tmetadataPath: string;\n}\n\nexport interface ArtifactConfig {\n\tenabled: boolean;\n\tincludeInput: boolean;\n\tincludeOutput: boolean;\n\tincludeJsonl: boolean;\n\tincludeTranscript?: boolean;\n\tincludeMetadata: boolean;\n\tcleanupDays: number;\n}\n\n// ============================================================================\n// Async Execution\n// ============================================================================\n\nexport interface AsyncParallelGroupStatus {\n\tstart: number;\n\tcount: number;\n\tstepIndex: number;\n}\n\nexport type NestedRunState = \"queued\" | \"running\" | \"complete\" | \"failed\" | \"paused\" | \"stopped\";\nexport type NestedOwnerState = \"live\" | \"gone\" | \"unknown\";\n\nexport interface NestedRunAddress {\n\tid: string;\n\tparentRunId: string;\n\tparentStepIndex?: number;\n\tparentAgent?: string;\n\tdepth: number;\n\tpath: Array<{ runId: string; stepIndex?: number; agent?: string }>;\n}\n\nexport interface NestedStepSummary {\n\tagent: string;\n\tstatus: \"pending\" | \"running\" | \"complete\" | \"completed\" | \"failed\" | \"paused\" | \"stopped\";\n\tsessionFile?: string;\n\ttranscriptPath?: string;\n\ttranscriptError?: string;\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\tstartedAt?: number;\n\tendedAt?: number;\n\terror?: string;\n\twatchdog?: ChildWatchdogProgress;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\tchildren?: NestedRunSummary[];\n}\n\nexport interface NestedRunSummary extends NestedRunAddress {\n\tasyncDir?: string;\n\tpid?: number;\n\tsessionId?: string;\n\tsessionFile?: string;\n\tintercomTarget?: string;\n\townerIntercomTarget?: string;\n\tleafIntercomTarget?: string;\n\townerState?: NestedOwnerState;\n\tcontrolInbox?: string;\n\tcapabilityToken?: string;\n\tmode?: SubagentRunMode;\n\tstate: NestedRunState;\n\tagent?: string;\n\tagents?: string[];\n\tcurrentStep?: number;\n\tchainStepCount?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tsteps?: NestedStepSummary[];\n\tchildren?: NestedRunSummary[];\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\ttotalTokens?: TokenUsage;\n\ttotalCost?: CostSummary;\n\tstartedAt?: number;\n\tendedAt?: number;\n\tlastUpdate?: number;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\terror?: string;\n}\n\nexport interface NestedRouteInfo {\n\trootRunId: string;\n\teventSink: string;\n\tcontrolInbox: string;\n\tcapabilityToken: string;\n}\n\nexport interface AsyncStartedEvent {\n\tlifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;\n\tid?: string;\n\tasyncDir?: string;\n\tpid?: number;\n\tsessionId?: string;\n\tmode?: SubagentRunMode;\n\tagent?: string;\n\tagents?: string[];\n\t/** Truncated first child task retained for backwards compatibility. */\n\ttask?: string;\n\t/** Workflow-level caller task, falling back to the first child task. */\n\tgoal?: string;\n\tchain?: string[];\n\tchainStepCount?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tworkflowGraph?: WorkflowGraphSnapshot;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\tturnBudget?: TurnBudgetState;\n\tnestedRoute?: NestedRouteInfo;\n}\n\nexport interface AsyncStatus {\n\tlifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;\n\trunId: string;\n\tsessionId?: string;\n\tmode: SubagentRunMode;\n\tisNested?: boolean;\n\tstate: \"queued\" | \"running\" | \"complete\" | \"failed\" | \"paused\" | \"stopped\";\n\terror?: string;\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\tsteering?: SteeringStatus;\n\tstartedAt: number;\n\tendedAt?: number;\n\tlastUpdate?: number;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\tpid?: number;\n\tcwd?: string;\n\tcurrentStep?: number;\n\tchainStepCount?: number;\n\tpendingAppends?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tworkflowGraph?: WorkflowGraphSnapshot;\n\tsteps?: Array<{\n\t\tchildId?: string;\n\t\tdescription?: string;\n\t\tpermissions?: ChildPermission;\n\t\tagent: string;\n\t\tphase?: string;\n\t\tlabel?: string;\n\t\toutputName?: string;\n\t\tstructured?: boolean;\n\t\tstatus: \"pending\" | \"running\" | \"complete\" | \"completed\" | \"failed\" | \"paused\" | \"stopped\";\n\t\tchildren?: NestedRunSummary[];\n\t\tsessionFile?: string;\n\t\ttranscriptPath?: string;\n\t\ttranscriptError?: string;\n\t\tactivityState?: ActivityState;\n\t\tlastActivityAt?: number;\n\t\tcurrentTool?: string;\n\t\tcurrentToolArgs?: string;\n\t\tcurrentToolStartedAt?: number;\n\t\tcurrentPath?: string;\n\t\trecentTools?: Array<{ tool: string; args: string; endMs: number }>;\n\t\trecentOutput?: string[];\n\t\tturnCount?: number;\n\t\ttoolCount?: number;\n\t\tstartedAt?: number;\n\t\tendedAt?: number;\n\t\tdurationMs?: number;\n\t\texitCode?: number | null;\n\t\ttimedOut?: boolean;\n\t\tstopped?: boolean;\n\t\tturnBudget?: TurnBudgetState;\n\t\tturnBudgetExceeded?: boolean;\n\t\twrapUpRequested?: boolean;\n\t\ttoolBudget?: ToolBudgetState;\n\t\ttoolBudgetBlocked?: boolean;\n\t\ttokens?: TokenUsage;\n\t\tskills?: string[];\n\t\tmodel?: string;\n\t\tthinking?: string;\n\t\tmodelSelection?: ModelSelection;\n\t\tattemptedModels?: string[];\n\t\tmodelAttempts?: ModelAttempt[];\n\t\ttotalCost?: CostSummary;\n\t\tsteering?: SteeringStatus;\n\t\terror?: string;\n\t\tstructuredOutput?: unknown;\n\t\tstructuredOutputPath?: string;\n\t\tstructuredOutputSchemaPath?: string;\n\t\tacceptance?: AcceptanceLedger;\n\t\twatchdog?: ChildWatchdogProgress;\n\t}>;\n\tsessionDir?: string;\n\toutputFile?: string;\n\ttotalTokens?: TokenUsage;\n\ttotalCost?: CostSummary;\n\tsessionFile?: string;\n\toutputs?: ChainOutputMap;\n}\n\nexport type AsyncJobStep = NonNullable<AsyncStatus[\"steps\"]>[number] & {\n\tindex?: number;\n};\n\nexport interface AsyncJobState {\n\tasyncId: string;\n\tasyncDir: string;\n\tstatus: \"queued\" | \"running\" | \"complete\" | \"failed\" | \"paused\" | \"stopped\";\n\tpid?: number;\n\tsessionId?: string;\n\tactivityState?: ActivityState;\n\tlastActivityAt?: number;\n\tcurrentTool?: string;\n\tcurrentToolStartedAt?: number;\n\tcurrentPath?: string;\n\tturnCount?: number;\n\ttoolCount?: number;\n\tsteering?: SteeringStatus;\n\tmode?: SubagentRunMode;\n\tagents?: string[];\n\tcurrentStep?: number;\n\tchainStepCount?: number;\n\tparallelGroups?: AsyncParallelGroupStatus[];\n\tsteps?: AsyncJobStep[];\n\tstepsTotal?: number;\n\trunningSteps?: number;\n\tcompletedSteps?: number;\n\thasParallelGroups?: boolean;\n\tactiveParallelGroup?: boolean;\n\tstartedAt?: number;\n\tupdatedAt?: number;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\ttimedOut?: boolean;\n\tstopped?: boolean;\n\tturnBudget?: TurnBudgetState;\n\tturnBudgetExceeded?: boolean;\n\twrapUpRequested?: boolean;\n\ttoolBudget?: ToolBudgetState;\n\ttoolBudgetBlocked?: boolean;\n\tsessionDir?: string;\n\toutputFile?: string;\n\ttotalTokens?: TokenUsage;\n\tsessionFile?: string;\n\tcontrolEventCursor?: number;\n\tnestedRoute?: NestedRouteInfo;\n\tnestedChildren?: NestedRunSummary[];\n}\n\nexport interface ForegroundResumeChild {\n\tagent: string;\n\tindex: number;\n\tsessionFile?: string;\n\tstatus: SubagentResultStatus;\n\texitCode?: number;\n\terror?: string;\n\tfinalOutput?: string;\n\toutputMode?: OutputMode;\n\tsavedOutputPath?: string;\n\toutputSaveError?: string;\n\tartifactPaths?: ArtifactPaths;\n\ttranscriptPath?: string;\n\ttranscriptError?: string;\n\tdetachedReason?: string;\n\tacceptance?: AcceptanceLedger;\n\tupdatedAt?: number;\n}\n\nexport interface ForegroundResumeRun {\n\trunId: string;\n\tmode: SubagentRunMode;\n\tcwd: string;\n\t/** Originating parent session. Detached exits can outlive the active session. */\n\tsessionId?: string;\n\tupdatedAt: number;\n\tchildren: ForegroundResumeChild[];\n}\n\nexport interface SubagentState {\n\tbaseCwd: string;\n\tcurrentSessionId: string | null;\n\t/** Bumps on session_start / session replacement so owned supervisor questions fail closed. */\n\tsessionGeneration?: number;\n\t/** Live foreground `subagent` tool calls. Caps same-turn overlap. */\n\tforegroundSubagentInFlight?: number;\n\tsubagentSpawns?: { sessionId: string | null; count: number };\n\tasyncJobs: Map<string, AsyncJobState>;\n\t/** Current-session active and recent async runs for the native fleet inspector. */\n\tfleetJobs?: Map<string, AsyncJobState>;\n\tforegroundRuns?: Map<string, ForegroundResumeRun>;\n\tforegroundControls: Map<string, {\n\t\trunId: string;\n\t\tmode: SubagentRunMode;\n\t\tstartedAt: number;\n\t\tupdatedAt: number;\n\t\tcurrentAgent?: string;\n\t\tcurrentChildId?: string;\n\t\tcurrentIndex?: number;\n\t\tcurrentActivityState?: ActivityState;\n\t\tlastActivityAt?: number;\n\t\tcurrentTool?: string;\n\t\tcurrentToolStartedAt?: number;\n\t\tcurrentPath?: string;\n\t\tturnCount?: number;\n\t\ttokens?: number;\n\t\ttoolCount?: number;\n\t\tnestedRoute?: NestedRouteInfo;\n\t\tnestedChildren?: NestedRunSummary[];\n\t\tinterrupt?: () => boolean;\n\t}>;\n\tlastForegroundControlId: string | null;\n\tpendingForegroundControlNotices?: Map<string, ReturnType<typeof setTimeout>>;\n\tcleanupTimers: Map<string, ReturnType<typeof setTimeout>>;\n\tlastUiContext: ExtensionContext | null;\n\tpoller: NodeJS.Timeout | null;\n\tcompletionSeen: Map<string, number>;\n\twatcher: FSWatcher | null;\n\twatcherRestartTimer: ReturnType<typeof setTimeout> | null;\n\tresultFileCoalescer: {\n\t\tschedule(file: string, delayMs?: number): boolean;\n\t\tclear(): void;\n\t};\n}\n\n// ============================================================================\n// Display\n// ============================================================================\n\nexport type DisplayItem = \n\t| { type: \"text\"; text: string } \n\t| { type: \"tool\"; name: string; args: Record<string, unknown> };\n\n// ============================================================================\n// Error Handling\n// ============================================================================\n\nexport interface ErrorInfo {\n\thasError: boolean;\n\texitCode?: number;\n\terrorType?: string;\n\tdetails?: string;\n}\n\nexport interface IntercomEventBus {\n\ton(channel: string, handler: (data: unknown) => void): () => void;\n\temit(channel: string, data: unknown): void;\n}\n\nexport const INTERCOM_DETACH_REQUEST_EVENT = \"pi-intercom:detach-request\";\nexport const INTERCOM_DETACH_RESPONSE_EVENT = \"pi-intercom:detach-response\";\nexport const SUBAGENT_ASYNC_STARTED_EVENT = \"subagent:async-started\";\nexport const SUBAGENT_ASYNC_COMPLETE_EVENT = \"subagent:async-complete\";\nexport const SUBAGENT_FOREGROUND_COMPLETE_EVENT = \"subagent:foreground-complete\";\nexport const SUBAGENT_CONTROL_EVENT = \"subagent:control-event\";\nexport const SUBAGENT_CONTROL_INTERCOM_EVENT = \"subagent:control-intercom\";\nexport const SUBAGENT_STEERING_NOTICE_EVENT = \"subagent:steering-notice\";\nexport const SUBAGENT_RESULT_INTERCOM_EVENT = \"subagent:result-intercom\";\nexport const SUBAGENT_RESULT_INTERCOM_DELIVERY_EVENT = \"subagent:result-intercom-delivery\";\n\n// ============================================================================\n// Execution Options\n// ============================================================================\n\nexport interface RunSyncOptions {\n\t/** Session id of the direct parent session for permission-system ask forwarding. */\n\tparentSessionId?: string;\n\tcwd?: string;\n\tsignal?: AbortSignal;\n\tinterruptSignal?: AbortSignal;\n\ttimeoutMs?: number;\n\tdeadlineAt?: number;\n\tturnBudget?: ResolvedTurnBudget;\n\ttoolBudget?: ResolvedToolBudget;\n\tallowIntercomDetach?: boolean;\n\tintercomEvents?: IntercomEventBus;\n\tonUpdate?: (r: import(\"@ashx-j/lunr-agent\").AgentToolResult<Details>) => void;\n\tonControlEvent?: (event: ControlEvent) => void;\n\tonDetachedExit?: (result: SingleResult) => void;\n\tcontrolConfig?: ResolvedControlConfig;\n\tintercomSessionName?: string;\n\torchestratorIntercomTarget?: string;\n\tmaxOutput?: MaxOutputConfig;\n\tartifactsDir?: string;\n\tartifactConfig?: ArtifactConfig;\n\trunId: string;\n\tindex?: number;\n\tsessionDir?: string;\n\tsessionFile?: string;\n\tshare?: boolean;\n\toutputPath?: string;\n\toutputMode?: OutputMode;\n\tmaxSubagentDepth?: number;\n\t/** Effective parent wait-tool setting propagated to the child runtime. */\n\twaitToolEnabled?: boolean;\n\tnestedRoute?: NestedRouteInfo;\n\t/** Override the agent's default model (format: \"provider/id\" or just \"id\") */\n\tmodelOverride?: string;\n\t/** Override the agent's default thinking level for this run */\n\tthinkingOverride?: string | false;\n\t/** Registry models available for heuristic bare-model resolution */\n\tavailableModels?: Array<{ provider: string; id: string; fullId: string }>;\n\t/** Current parent-session provider to prefer for ambiguous bare model ids */\n\tpreferredModelProvider?: string;\n\t/** Optional subagent model-scope enforcement for fallback candidates */\n\tmodelScope?: ModelScopeConfig;\n\t/** Skills to make available (overrides agent default if provided) */\n\tskills?: string[];\n\tstructuredOutput?: {\n\t\tschema: JsonSchemaObject;\n\t\tschemaPath: string;\n\t\toutputPath: string;\n\t};\n\tacceptance?: AcceptanceInput;\n\tacceptanceContext?: {\n\t\tmode?: SubagentRunMode;\n\t\tasync?: boolean;\n\t\tdynamic?: boolean;\n\t\tdynamicGroup?: boolean;\n\t};\n}\n\nexport type IntercomBridgeMode = \"off\" | \"fork-only\" | \"always\";\n\nexport interface IntercomBridgeConfig {\n\tmode?: IntercomBridgeMode;\n\tinstructionFile?: string;\n}\n\ninterface TopLevelParallelConfig {\n\tmaxTasks?: number;\n\tconcurrency?: number;\n}\n\ninterface ExtensionChainConfig {\n\tdynamicFanout?: {\n\t\tmaxItems?: number;\n\t};\n}\n\nexport interface ProactiveSkillSubagentsConfig {\n\tenabled?: boolean;\n\tminReferences?: number;\n\tmaxRecommendations?: number;\n\tpreferredAgent?: string;\n}\n\nexport type ToolDescriptionMode = \"full\" | \"compact\" | \"custom\";\n\nexport interface ScheduledRunsConfig {\n\tenabled?: boolean;\n\tmaxLatenessMs?: number;\n\tmaxPending?: number;\n}\n\nexport interface ExtensionConfig {\n\tasyncByDefault?: boolean;\n\t/** Show the above-editor async runs widget. Defaults to true. */\n\tasyncWidget?: boolean;\n\t/** Tool description variant registered for the parent-facing subagent tool. Defaults to full. */\n\ttoolDescriptionMode?: ToolDescriptionMode;\n\tforceTopLevelAsync?: boolean;\n\twaitTool?: WaitToolConfig;\n\tdefaultSessionDir?: string;\n\tsingleRunOutputBaseDir?: string;\n\tmaxSubagentDepth?: number;\n\t/** Optional cumulative session cap. Unset or 0 means unlimited. */\n\tmaxSubagentSpawnsPerSession?: number;\n\t/** Global cap on simultaneously-running subagent tasks within a single run. Unset means unlimited. */\n\tglobalConcurrencyLimit?: number;\n\tcontrol?: ControlConfig;\n\tcompletionBatch?: CompletionBatchConfig;\n\tturnBudget?: TurnBudgetConfig;\n\ttoolBudget?: ToolBudgetConfig;\n\tparallel?: TopLevelParallelConfig;\n\tchain?: ExtensionChainConfig;\n\tworktreeSetupHook?: string;\n\tworktreeSetupHookTimeoutMs?: number;\n\tworktreeBaseDir?: string;\n\tintercomBridge?: IntercomBridgeConfig;\n\tproactiveSkillSubagents?: ProactiveSkillSubagentsConfig | false;\n\tscheduledRuns?: ScheduledRunsConfig;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nexport const DEFAULT_MAX_OUTPUT: Required<MaxOutputConfig> = {\n\tbytes: 200 * 1024,\n\tlines: 5000,\n};\n\nexport const DEFAULT_ARTIFACT_CONFIG: ArtifactConfig = {\n\tenabled: true,\n\tincludeInput: true,\n\tincludeOutput: true,\n\tincludeJsonl: false,\n\tincludeTranscript: true,\n\tincludeMetadata: true,\n\tcleanupDays: 7,\n};\n\nfunction sanitizeTempScopeSegment(value: string): string {\n\tconst sanitized = value\n\t\t.trim()\n\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t.replace(/^-+|-+$/g, \"\");\n\treturn sanitized || \"unknown\";\n}\n\nexport function resolveTempScopeId(options?: {\n\tenv?: NodeJS.ProcessEnv;\n\tgetuid?: (() => number) | undefined;\n\tuserInfo?: (() => { username?: string | null }) | undefined;\n\thomedir?: (() => string) | undefined;\n}): string {\n\tconst env = options?.env ?? process.env;\n\tconst getuid = options && Object.hasOwn(options, \"getuid\")\n\t\t? options.getuid\n\t\t: process.getuid?.bind(process);\n\tif (typeof getuid === \"function\") {\n\t\treturn `uid-${getuid()}`;\n\t}\n\n\tfor (const key of [\"USERNAME\", \"USER\", \"LOGNAME\"] as const) {\n\t\tconst value = env[key];\n\t\tif (value) return `user-${sanitizeTempScopeSegment(value)}`;\n\t}\n\n\tconst userInfo = options && Object.hasOwn(options, \"userInfo\")\n\t\t? options.userInfo\n\t\t: os.userInfo;\n\ttry {\n\t\tconst username = userInfo?.().username;\n\t\tif (username) return `user-${sanitizeTempScopeSegment(username)}`;\n\t} catch {\n\t\t// Fall through to home-directory-based scoping.\n\t}\n\n\tconst homedir = env.USERPROFILE ?? env.HOME;\n\tif (homedir) return `home-${sanitizeTempScopeSegment(homedir)}`;\n\n\tconst resolveHomedir = options && Object.hasOwn(options, \"homedir\")\n\t\t? options.homedir\n\t\t: os.homedir;\n\ttry {\n\t\tconst fallbackHomedir = resolveHomedir?.();\n\t\tif (fallbackHomedir) return `home-${sanitizeTempScopeSegment(fallbackHomedir)}`;\n\t} catch {\n\t\t// Fall through to the last-resort shared scope.\n\t}\n\n\treturn \"shared\";\n}\n\nconst MAX_PARALLEL = Number.MAX_SAFE_INTEGER;\nexport const MAX_CONCURRENCY = Number.MAX_SAFE_INTEGER;\nexport const TEMP_ROOT_DIR = path.join(os.tmpdir(), `pi-subagents-${resolveTempScopeId()}`);\nexport const RESULTS_DIR = path.join(TEMP_ROOT_DIR, \"async-subagent-results\");\nexport const ASYNC_DIR = path.join(TEMP_ROOT_DIR, \"async-subagent-runs\");\nexport const CHAIN_RUNS_DIR = path.join(TEMP_ROOT_DIR, \"chain-runs\");\nexport const TEMP_ARTIFACTS_DIR = path.join(TEMP_ROOT_DIR, \"artifacts\");\nexport const WIDGET_KEY = \"subagent-async\";\nexport const SLASH_RESULT_TYPE = \"subagent-slash-result\";\nexport const SLASH_TEXT_RESULT_TYPE = \"subagent-slash-text-result\";\nexport const SLASH_SUBAGENT_REQUEST_EVENT = \"subagent:slash:request\";\nexport const SLASH_SUBAGENT_STARTED_EVENT = \"subagent:slash:started\";\nexport const SLASH_SUBAGENT_RESPONSE_EVENT = \"subagent:slash:response\";\nexport const SLASH_SUBAGENT_UPDATE_EVENT = \"subagent:slash:update\";\nexport const SLASH_SUBAGENT_CANCEL_EVENT = \"subagent:slash:cancel\";\nexport const POLL_INTERVAL_MS = 250;\nexport const MAX_WIDGET_JOBS = 4;\nexport const DEFAULT_SUBAGENT_MAX_DEPTH = 2;\nexport const SUBAGENT_ACTIONS = [\"status\", \"interrupt\", \"resume\", \"steer\", \"stop\", \"append-step\", \"doctor\", \"watchdog.status\", \"watchdog.check\", \"watchdog.recommend-model\", \"schedule\", \"schedule-list\", \"schedule-status\", \"schedule-cancel\"] as const;\nexport const REMOVED_SUBAGENT_ACTIONS = [\"list\", \"get\", \"models\", \"create\", \"update\", \"delete\", \"eject\", \"disable\", \"enable\", \"reset\"] as const;\n\nexport const DEFAULT_FORK_PREAMBLE =\n\t\"You are a delegated subagent running from a fork of the parent session. \" +\n\t\"Treat the inherited conversation as reference-only context, not a live thread to continue. \" +\n\t\"Do not continue or answer prior messages as if they are waiting for a reply. \" +\n\t\"Your sole job is to execute the task below and return a focused result for that task using your tools.\";\n\nfunction normalizeTopLevelParallelValue(value: unknown): number | undefined {\n\tconst parsed = typeof value === \"number\" ? value : typeof value === \"string\" ? Number(value) : NaN;\n\tif (!Number.isInteger(parsed) || parsed < 1) return undefined;\n\treturn parsed;\n}\n\nexport function resolveTopLevelParallelMaxTasks(value: unknown): number {\n\treturn normalizeTopLevelParallelValue(value) ?? MAX_PARALLEL;\n}\n\nexport function resolveTopLevelParallelConcurrency(\n\toverride: unknown,\n\tconfigValue: unknown,\n): number {\n\treturn normalizeTopLevelParallelValue(override)\n\t\t?? normalizeTopLevelParallelValue(configValue)\n\t\t?? MAX_CONCURRENCY;\n}\n\nexport function getAsyncConfigPath(suffix: string): string {\n\treturn path.join(TEMP_ROOT_DIR, `async-cfg-${suffix}.json`);\n}\n\nexport function wrapForkTask(task: string, preamble?: string | false): string {\n\tif (preamble === false) return task;\n\tconst effectivePreamble = preamble ?? DEFAULT_FORK_PREAMBLE;\n\tconst wrappedPrefix = `${effectivePreamble}\\n\\nTask:\\n`;\n\tif (task.startsWith(wrappedPrefix)) return task;\n\treturn `${wrappedPrefix}${task}`;\n}\n\n// ============================================================================\n// Recursion Depth Guard\n// ============================================================================\n\nfunction normalizeNonNegativeInteger(value: unknown): number | undefined {\n\tconst parsed = typeof value === \"number\" ? value : typeof value === \"string\" ? Number(value) : NaN;\n\tif (!Number.isInteger(parsed) || parsed < 0) return undefined;\n\treturn parsed;\n}\n\nexport function normalizeMaxSubagentDepth(value: unknown): number | undefined {\n\treturn normalizeNonNegativeInteger(value);\n}\n\nexport function resolveCurrentMaxSubagentDepth(configMaxDepth?: number): number {\n\treturn normalizeMaxSubagentDepth(process.env.PI_SUBAGENT_MAX_DEPTH)\n\t\t?? normalizeMaxSubagentDepth(configMaxDepth)\n\t\t?? DEFAULT_SUBAGENT_MAX_DEPTH;\n}\n\nexport function resolveChildMaxSubagentDepth(parentMaxDepth: number, agentMaxDepth?: number): number {\n\tconst normalizedParent = normalizeMaxSubagentDepth(parentMaxDepth) ?? DEFAULT_SUBAGENT_MAX_DEPTH;\n\tconst normalizedAgent = normalizeMaxSubagentDepth(agentMaxDepth);\n\treturn normalizedAgent === undefined ? normalizedParent : Math.min(normalizedParent, normalizedAgent);\n}\n\nexport function checkSubagentDepth(configMaxDepth?: number): { blocked: boolean; depth: number; maxDepth: number } {\n\tconst depth = Number(process.env.PI_SUBAGENT_DEPTH ?? \"0\");\n\tconst maxDepth = resolveCurrentMaxSubagentDepth(configMaxDepth);\n\tconst blocked = Number.isFinite(depth) && depth >= maxDepth;\n\treturn { blocked, depth, maxDepth };\n}\n\nexport function getSubagentDepthEnv(maxDepth?: number): Record<string, string> {\n\tconst parentDepth = Number(process.env.PI_SUBAGENT_DEPTH ?? \"0\");\n\tconst nextDepth = Number.isFinite(parentDepth) ? parentDepth + 1 : 1;\n\treturn {\n\t\tPI_SUBAGENT_DEPTH: String(nextDepth),\n\t\tPI_SUBAGENT_MAX_DEPTH: String(normalizeMaxSubagentDepth(maxDepth) ?? resolveCurrentMaxSubagentDepth()),\n\t};\n}\n\nexport function normalizeMaxSubagentSpawnsPerSession(value: unknown): number | undefined {\n\treturn normalizeNonNegativeInteger(value);\n}\n\nexport function resolveMaxSubagentSpawnsPerSession(configMaxSpawns?: number): number | undefined {\n\tconst envMaxSpawns = normalizeMaxSubagentSpawnsPerSession(process.env.PI_SUBAGENT_MAX_SPAWNS_PER_SESSION);\n\tif (envMaxSpawns !== undefined) return envMaxSpawns === 0 ? undefined : envMaxSpawns;\n\tconst configuredMaxSpawns = normalizeMaxSubagentSpawnsPerSession(configMaxSpawns);\n\treturn configuredMaxSpawns === 0 ? undefined : configuredMaxSpawns;\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nfunction formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes}B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\nexport function truncateOutput(\n\toutput: string,\n\tconfig: Required<MaxOutputConfig>,\n\tartifactPath?: string,\n): TruncationResult {\n\tconst lines = output.split(\"\\n\");\n\tconst bytes = Buffer.byteLength(output, \"utf-8\");\n\n\tif (bytes <= config.bytes && lines.length <= config.lines) {\n\t\treturn { text: output, truncated: false };\n\t}\n\n\tlet truncatedLines = lines;\n\tif (lines.length > config.lines) {\n\t\ttruncatedLines = lines.slice(0, config.lines);\n\t}\n\n\tlet result = truncatedLines.join(\"\\n\");\n\tif (Buffer.byteLength(result, \"utf-8\") > config.bytes) {\n\t\tlet low = 0;\n\t\tlet high = result.length;\n\t\twhile (low < high) {\n\t\t\tconst mid = Math.floor((low + high + 1) / 2);\n\t\t\tif (Buffer.byteLength(result.slice(0, mid), \"utf-8\") <= config.bytes) {\n\t\t\t\tlow = mid;\n\t\t\t} else {\n\t\t\t\thigh = mid - 1;\n\t\t\t}\n\t\t}\n\t\tresult = result.slice(0, low);\n\t}\n\n\tconst keptLines = result.split(\"\\n\").length;\n\tconst marker = `[TRUNCATED: showing first ${keptLines} of ${lines.length} lines, ${formatBytes(Buffer.byteLength(result))} of ${formatBytes(bytes)}${artifactPath ? ` - full output at ${artifactPath}` : \"\"}]\\n`;\n\n\treturn {\n\t\ttext: marker + result,\n\t\ttruncated: true,\n\t\toriginalBytes: bytes,\n\t\toriginalLines: lines.length,\n\t\tartifactPath,\n\t};\n}\n"]}
@@ -6,6 +6,8 @@ interface InlineConfig {
6
6
  outputMode?: "inline" | "file-only";
7
7
  reads?: string[] | false;
8
8
  tier?: "light" | "standard" | "heavy";
9
+ model?: string;
10
+ thinking?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
9
11
  permissions?: "full" | "read-only";
10
12
  skill?: string[] | false;
11
13
  progress?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"slash-commands.d.ts","sourceRoot":"","sources":["../../../../../src/builtin-extensions/pi-subagents/src/slash/slash-commands.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAItF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAiBvD,OAAO,EAYN,KAAK,aAAa,EAElB,MAAM,oBAAoB,CAAC;AAE5B,UAAU,YAAY;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,UAAU,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AA4fD,MAAM,WAAW,WAAW;IAAG,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE;AAC7F,MAAM,WAAW,UAAU;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE;AAC/F,MAAM,WAAW,WAAW;IAAG,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE;AACxF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,WAAW,CAAC;AAEvD,eAAO,MAAM,oBAAoB,kFACyC,CAAC;AAE3E,qBAAa,eAAgB,SAAQ,KAAK;CAAG;AA4D7C,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAiB9D;AA0CD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAW9D;AAOD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,eAAe,EAAE,CAAA;CAAE,CAyBhF;AAqID,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,gBAAgB,GACnB;IAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoE7C;AAED,wBAAgB,qBAAqB,CACpC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,aAAa,GAClB,IAAI,CAyJN","sourcesContent":["// @ts-nocheck\nimport { randomUUID } from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { ExtensionAPI, ExtensionContext } from \"@ashx-j/lunr\";\nimport { keyText } from \"../../../../modes/interactive/components/keybinding-hints.ts\";\nimport { Key, matchesKey, type Component, type TUI } from \"@ashx-j/lunr-tui\";\nimport type { SubagentParamsLike } from \"../runs/foreground/subagent-executor.ts\";\nimport type { ChainStep } from \"../shared/settings.ts\";\nimport { formatTokens, shortenPath } from \"../shared/formatters.ts\";\nimport { listAsyncRuns, formatAsyncRunProgressLabel, type AsyncRunSummary } from \"../runs/background/async-status.ts\";\nimport { scheduledRunStorePath } from \"../runs/background/scheduled-runs.ts\";\nimport { SUBAGENT_FANOUT_CHILD_ENV } from \"../runs/shared/pi-args.ts\";\nimport { assertJsonSchemaObject } from \"../runs/shared/structured-output.ts\";\nimport { validateAcceptanceInput } from \"../runs/shared/acceptance.ts\";\nimport type { SlashSubagentResponse, SlashSubagentUpdate } from \"./slash-bridge.ts\";\nimport { registerPromptWorkflowCommands } from \"./prompt-workflows.ts\";\nimport { openSubagentFleet } from \"../tui/fleet.ts\";\nimport {\n\tapplySlashUpdate,\n\tbuildSlashInitialResult,\n\tfailSlashResult,\n\tfinalizeSlashResult,\n\tresolveSlashMessageDetails,\n} from \"./slash-live-state.ts\";\nimport {\n\tSLASH_RESULT_TYPE,\n\tSLASH_TEXT_RESULT_TYPE,\n\tSLASH_SUBAGENT_CANCEL_EVENT,\n\tSLASH_SUBAGENT_REQUEST_EVENT,\n\tSLASH_SUBAGENT_RESPONSE_EVENT,\n\tSLASH_SUBAGENT_STARTED_EVENT,\n\tSLASH_SUBAGENT_UPDATE_EVENT,\n\tASYNC_DIR,\n\ttype Details,\n\ttype JsonSchemaObject,\n\ttype SingleResult,\n\ttype SubagentState,\n\ttype Usage,\n} from \"../shared/types.ts\";\n\ninterface InlineConfig {\n\toutput?: string | false;\n\toutputMode?: \"inline\" | \"file-only\";\n\treads?: string[] | false;\n\ttier?: \"light\" | \"standard\" | \"heavy\";\n\tpermissions?: \"full\" | \"read-only\";\n\tskill?: string[] | false;\n\tprogress?: boolean;\n\tas?: string;\n\tlabel?: string;\n\tphase?: string;\n\tcwd?: string;\n\tcount?: number;\n\toutputSchema?: string;\n\tacceptance?: string;\n}\n\nconst parseInlineConfig = (raw: string): InlineConfig => {\n\tconst config: InlineConfig = {};\n\tfor (const part of raw.split(\",\")) {\n\t\tconst trimmed = part.trim();\n\t\tif (!trimmed) continue;\n\t\tconst eq = trimmed.indexOf(\"=\");\n\t\tif (eq === -1) {\n\t\t\tif (trimmed === \"progress\") config.progress = true;\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = trimmed.slice(0, eq).trim();\n\t\tconst val = trimmed.slice(eq + 1).trim();\n\t\tswitch (key) {\n\t\t\tcase \"output\": config.output = val === \"false\" ? false : val; break;\n\t\t\tcase \"outputMode\": if (val === \"inline\" || val === \"file-only\") config.outputMode = val; break;\n\t\t\tcase \"reads\": config.reads = val === \"false\" ? false : val.split(\"+\").filter(Boolean); break;\n\t\t\tcase \"tier\": if (val === \"light\" || val === \"standard\" || val === \"heavy\") config.tier = val; break;\n\t\t\tcase \"permissions\": if (val === \"full\" || val === \"read-only\") config.permissions = val; break;\n\t\t\tcase \"skill\": case \"skills\": config.skill = val === \"false\" ? false : val.split(\"+\").filter(Boolean); break;\n\t\t\tcase \"progress\": config.progress = val !== \"false\"; break;\n\t\t\tcase \"as\": config.as = val || undefined; break;\n\t\t\tcase \"label\": config.label = val || undefined; break;\n\t\t\tcase \"phase\": config.phase = val || undefined; break;\n\t\t\tcase \"cwd\": config.cwd = val || undefined; break;\n\t\t\tcase \"count\": { const n = Number(val); if (Number.isInteger(n) && n > 0) config.count = n; break; }\n\t\t\tcase \"outputSchema\": config.outputSchema = val || undefined; break;\n\t\t\tcase \"acceptance\": config.acceptance = val || undefined; break;\n\t\t}\n\t}\n\treturn config;\n};\n\nconst parseAgentToken = (token: string): { name: string; config: InlineConfig } => {\n\tconst bracket = token.indexOf(\"[\");\n\tif (bracket === -1) return { name: token, config: {} };\n\tconst end = token.lastIndexOf(\"]\");\n\treturn { name: token.slice(0, bracket), config: parseInlineConfig(token.slice(bracket + 1, end !== -1 ? end : undefined)) };\n};\n\nconst extractExecutionFlags = (rawArgs: string): { args: string; bg: boolean } => {\n\tlet args = rawArgs.trim();\n\tlet bg = false;\n\n\twhile (true) {\n\t\tif (args.endsWith(\" --bg\") || args === \"--bg\") {\n\t\t\tbg = true;\n\t\t\targs = args === \"--bg\" ? \"\" : args.slice(0, -5).trim();\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n\n\treturn { args, bg };\n};\n\nfunction sendSlashText(pi: ExtensionAPI, text: string): void {\n\tpi.sendMessage({ customType: SLASH_TEXT_RESULT_TYPE, content: text, display: true });\n}\n\ntype Theme = ExtensionContext[\"ui\"][\"theme\"];\n\ntype StopSelectorTarget = {\n\tkind: \"async\" | \"scheduled\";\n\tid: string;\n\tlabel: string;\n\tdetail: string;\n\tactionLabel: string;\n};\n\ntype StopSelectorResult = { confirmed: boolean; target?: StopSelectorTarget };\n\nfunction commandForTarget(target: StopSelectorTarget): string {\n\treturn target.kind === \"scheduled\"\n\t\t? `subagent({ action: \"schedule-cancel\", id: ${JSON.stringify(target.id)} })`\n\t\t: `subagent({ action: \"stop\", id: ${JSON.stringify(target.id)} })`;\n}\n\nfunction formatAsyncStopTarget(run: AsyncRunSummary): StopSelectorTarget {\n\tconst progress = formatAsyncRunProgressLabel(run);\n\tconst cwd = run.cwd ? shortenPath(run.cwd) : shortenPath(run.asyncDir);\n\treturn {\n\t\tkind: \"async\",\n\t\tid: run.id,\n\t\tlabel: `${run.id} · ${run.mode} · ${progress}`,\n\t\tdetail: `${run.state} · ${cwd}`,\n\t\tactionLabel: \"stop async run\",\n\t};\n}\n\nfunction scheduledStopTargets(ctx: ExtensionContext, state: SubagentState): StopSelectorTarget[] {\n\tconst sessionId = state.currentSessionId ?? ctx.sessionManager.getSessionId();\n\tif (!sessionId) return [];\n\tconst storePath = scheduledRunStorePath(ctx.cwd, sessionId);\n\tif (!fs.existsSync(storePath)) return [];\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(fs.readFileSync(storePath, \"utf-8\"));\n\t} catch {\n\t\treturn [];\n\t}\n\tconst jobs = parsed && typeof parsed === \"object\" && Array.isArray((parsed as { jobs?: unknown }).jobs)\n\t\t? (parsed as { jobs: Array<Record<string, unknown>> }).jobs\n\t\t: [];\n\treturn jobs\n\t\t.filter((job) => job.state === \"scheduled\" && typeof job.id === \"string\" && typeof job.name === \"string\" && typeof job.runAt === \"number\")\n\t\t.sort((left, right) => Number(left.runAt) - Number(right.runAt))\n\t\t.map((job) => ({\n\t\t\tkind: \"scheduled\" as const,\n\t\t\tid: String(job.id),\n\t\t\tlabel: `${String(job.id)} · ${String(job.name)}`,\n\t\t\tdetail: `scheduled · ${new Date(Number(job.runAt)).toISOString()}`,\n\t\t\tactionLabel: \"cancel scheduled run\",\n\t\t}));\n}\n\nfunction discoverStopTargets(ctx: ExtensionContext, state: SubagentState): StopSelectorTarget[] {\n\tconst sessionId = state.currentSessionId ?? ctx.sessionManager.getSessionId() ?? undefined;\n\tconst asyncTargets = listAsyncRuns(ASYNC_DIR, {\n\t\tstates: [\"queued\", \"running\"],\n\t\t...(sessionId ? { sessionId } : {}),\n\t}).map(formatAsyncStopTarget);\n\treturn [...asyncTargets, ...scheduledStopTargets(ctx, state)];\n}\n\nfunction stopFallbackText(targets: StopSelectorTarget[]): string {\n\tif (targets.length === 0) return \"No active current-session async runs or scheduled subagent runs to stop.\";\n\tconst lines = [\"Subagent stop targets:\", \"\"];\n\tfor (const target of targets) {\n\t\tlines.push(`- ${target.label}`);\n\t\tlines.push(` ${target.detail}`);\n\t\tlines.push(` ${target.actionLabel}: ${commandForTarget(target)}`);\n\t\tif (target.kind === \"async\") lines.push(` slash: /subagents-stop ${target.id}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nclass SubagentsStopSelector implements Component {\n\treadonly width = 84;\n\tprivate selected = 0;\n\tprivate confirming = false;\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly targets: StopSelectorTarget[];\n\tprivate readonly done: (result: StopSelectorResult) => void;\n\n\tconstructor(tui: TUI, theme: Theme, targets: StopSelectorTarget[], done: (result: StopSelectorResult) => void) {\n\t\tthis.tui = tui;\n\t\tthis.theme = theme;\n\t\tthis.targets = targets;\n\t\tthis.done = done;\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.done({ confirmed: false });\n\t\t\treturn;\n\t\t}\n\t\tif (this.confirming) {\n\t\t\tif (matchesKey(data, \"return\") || data.toLowerCase() === \"y\") {\n\t\t\t\tthis.done({ confirmed: true, target: this.targets[this.selected] });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (data.toLowerCase() === \"n\" || matchesKey(data, \"backspace\")) {\n\t\t\t\tthis.confirming = false;\n\t\t\t\tthis.tui.requestRender();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tthis.selected = Math.max(0, this.selected - 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tthis.selected = Math.min(this.targets.length - 1, this.selected + 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tthis.confirming = true;\n\t\t\tthis.tui.requestRender();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tconst contentWidth = Math.max(40, Math.min(this.width, width || this.width));\n\t\tconst lines = [this.theme.bold(\"Stop subagent run\"), this.theme.fg(\"dim\", \"Select a current-session async run to stop, or a scheduled run to cancel.\"), \"\"];\n\t\tconst maxRows = 10;\n\t\tconst start = Math.max(0, Math.min(this.selected - maxRows + 1, Math.max(0, this.targets.length - maxRows)));\n\t\tfor (let index = start; index < Math.min(this.targets.length, start + maxRows); index++) {\n\t\t\tconst target = this.targets[index]!;\n\t\t\tconst selected = index === this.selected;\n\t\t\tconst marker = selected ? \"›\" : \" \";\n\t\t\t\tconst actionLabel = target.actionLabel;\n\t\t\tconst action = target.kind === \"scheduled\" ? this.theme.fg(\"warning\", actionLabel) : this.theme.fg(\"accent\", actionLabel);\n\t\t\tconst labelWidth = Math.max(0, contentWidth - marker.length - actionLabel.length - 2);\n\t\t\tlines.push(`${marker} ${action} ${target.label.slice(0, labelWidth)}`);\n\t\t\tif (selected) lines.push(this.theme.fg(\"dim\", ` ${target.detail}`.slice(0, contentWidth)));\n\t\t}\n\t\tif (this.targets.length > maxRows) lines.push(this.theme.fg(\"dim\", `Showing ${start + 1}-${Math.min(this.targets.length, start + maxRows)} of ${this.targets.length}`));\n\t\tlines.push(\"\");\n\t\tif (this.confirming) {\n\t\t\tconst target = this.targets[this.selected]!;\n\t\t\tlines.push(this.theme.fg(\"warning\", `Confirm: ${target.actionLabel} ${target.id}?`));\n\t\t\tif (target.kind === \"async\") lines.push(this.theme.fg(\"dim\", \"Stop ends this run; use interrupt for a resumable pause.\"));\n\t\t\tlines.push(this.theme.fg(\"dim\", \"Enter/Y confirms · N returns · Esc cancels\"));\n\t\t} else {\n\t\t\tlines.push(this.theme.fg(\"dim\", \"↑/↓ select · Enter confirm · Esc cancel\"));\n\t\t}\n\t\treturn lines;\n\t}\n}\n\nfunction emptyUsage(): Usage {\n\treturn { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };\n}\n\nfunction addUsage(target: Usage, source: Usage): void {\n\ttarget.input += source.input;\n\ttarget.output += source.output;\n\ttarget.cacheRead += source.cacheRead;\n\ttarget.cacheWrite += source.cacheWrite;\n\ttarget.cost += source.cost;\n\ttarget.turns += source.turns;\n}\n\nfunction usageHasValue(usage: Usage): boolean {\n\treturn usage.input !== 0 || usage.output !== 0 || usage.cacheRead !== 0 || usage.cacheWrite !== 0 || usage.cost !== 0 || usage.turns !== 0;\n}\n\nfunction assistantUsageFromMessage(message: unknown): Usage | undefined {\n\tif (!message || typeof message !== \"object\") return undefined;\n\tconst msg = message as { role?: unknown; usage?: unknown };\n\tif (msg.role !== \"assistant\" || !msg.usage || typeof msg.usage !== \"object\") return undefined;\n\tconst usage = msg.usage as {\n\t\tinput?: unknown;\n\t\toutput?: unknown;\n\t\tcacheRead?: unknown;\n\t\tcacheWrite?: unknown;\n\t\tcost?: { total?: unknown };\n\t};\n\treturn {\n\t\tinput: typeof usage.input === \"number\" ? usage.input : 0,\n\t\toutput: typeof usage.output === \"number\" ? usage.output : 0,\n\t\tcacheRead: typeof usage.cacheRead === \"number\" ? usage.cacheRead : 0,\n\t\tcacheWrite: typeof usage.cacheWrite === \"number\" ? usage.cacheWrite : 0,\n\t\tcost: typeof usage.cost?.total === \"number\" ? usage.cost.total : 0,\n\t\tturns: 1,\n\t};\n}\n\nfunction isSubagentDetails(value: unknown): value is Details {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst details = value as { mode?: unknown; results?: unknown };\n\treturn typeof details.mode === \"string\" && Array.isArray(details.results);\n}\n\nfunction detailsFromSessionEntry(entry: unknown): Details | undefined {\n\tif (!entry || typeof entry !== \"object\") return undefined;\n\tconst record = entry as { type?: unknown; customType?: unknown; details?: unknown; message?: unknown };\n\tif (record.type === \"custom_message\" && record.customType === SLASH_RESULT_TYPE) {\n\t\tconst details = resolveSlashMessageDetails(record.details)?.result.details;\n\t\treturn isSubagentDetails(details) ? details : undefined;\n\t}\n\tif (record.type !== \"message\" || !record.message || typeof record.message !== \"object\") return undefined;\n\tconst message = record.message as { role?: unknown; toolName?: unknown; details?: unknown };\n\tif (message.role !== \"toolResult\" || message.toolName !== \"subagent\") return undefined;\n\treturn isSubagentDetails(message.details) ? message.details : undefined;\n}\n\nfunction formatCostUsage(label: string, usage: Usage): string {\n\tconst extras = [\n\t\tusage.cacheRead ? `cache read ${formatTokens(usage.cacheRead)}` : \"\",\n\t\tusage.cacheWrite ? `cache write ${formatTokens(usage.cacheWrite)}` : \"\",\n\t\tusage.turns ? `${usage.turns} turn${usage.turns === 1 ? \"\" : \"s\"}` : \"\",\n\t].filter(Boolean);\n\treturn `${label}: ↑${formatTokens(usage.input)} ↓${formatTokens(usage.output)} $${usage.cost.toFixed(4)}${extras.length ? ` (${extras.join(\", \")})` : \"\"}`;\n}\n\nfunction buildSubagentCostReport(ctx: ExtensionContext): string {\n\tconst parent = emptyUsage();\n\tconst childTotal = emptyUsage();\n\tconst total = emptyUsage();\n\tconst children: Array<{ label: string; usage: Usage; sessionFile?: string }> = [];\n\tfor (const entry of ctx.sessionManager.getBranch()) {\n\t\tconst message = entry.type === \"message\" ? (entry as { message?: unknown }).message : undefined;\n\t\tconst parentUsage = assistantUsageFromMessage(message);\n\t\tif (parentUsage) addUsage(parent, parentUsage);\n\t\tconst details = detailsFromSessionEntry(entry);\n\t\tif (!details) continue;\n\t\tfor (const result of details.results) {\n\t\t\tif (!usageHasValue(result.usage)) continue;\n\t\t\tconst usage = { ...result.usage };\n\t\t\tchildren.push({\n\t\t\t\tlabel: `Child ${children.length + 1} (${result.agent})`,\n\t\t\t\tusage,\n\t\t\t\t...(result.sessionFile ? { sessionFile: result.sessionFile } : {}),\n\t\t\t});\n\t\t\taddUsage(childTotal, usage);\n\t\t}\n\t}\n\taddUsage(total, parent);\n\taddUsage(total, childTotal);\n\tconst lines = [\n\t\t\"Subagent cost\",\n\t\t\"\",\n\t\tformatCostUsage(\"Parent\", parent),\n\t];\n\tif (children.length === 0) {\n\t\tlines.push(\"No subagent child usage found in this session.\");\n\t} else {\n\t\tfor (const child of children) {\n\t\t\tlines.push(formatCostUsage(child.label, child.usage));\n\t\t\tif (child.sessionFile) lines.push(` Session: ${child.sessionFile}`);\n\t\t}\n\t}\n\tlines.push(\"────────────────────────────\", formatCostUsage(\"Children\", childTotal), formatCostUsage(\"Total\", total));\n\treturn lines.join(\"\\n\");\n}\n\nasync function requestSlashRun(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\trequestId: string,\n\tparams: SubagentParamsLike,\n): Promise<SlashSubagentResponse> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet done = false;\n\t\tlet started = false;\n\n\t\tconst startTimeoutMs = 15_000;\n\t\tconst startTimeout = setTimeout(() => {\n\t\t\tfinish(() => reject(new Error(\n\t\t\t\t\"Slash subagent bridge did not start within 15s. Ensure the extension is loaded correctly.\",\n\t\t\t)));\n\t\t}, startTimeoutMs);\n\n\t\tconst onStarted = (data: unknown) => {\n\t\t\tif (done || !data || typeof data !== \"object\") return;\n\t\t\tif ((data as { requestId?: unknown }).requestId !== requestId) return;\n\t\t\tstarted = true;\n\t\t\tclearTimeout(startTimeout);\n\t\t\tif (ctx.hasUI) ctx.ui.setStatus(\"subagent-slash\", \"running...\");\n\t\t};\n\n\t\tconst onResponse = (data: unknown) => {\n\t\t\tif (done || !data || typeof data !== \"object\") return;\n\t\t\tconst response = data as Partial<SlashSubagentResponse>;\n\t\t\tif (response.requestId !== requestId) return;\n\t\t\tclearTimeout(startTimeout);\n\t\t\tfinish(() => resolve(response as SlashSubagentResponse));\n\t\t};\n\n\t\tconst onUpdate = (data: unknown) => {\n\t\t\tif (done || !data || typeof data !== \"object\") return;\n\t\t\tconst update = data as SlashSubagentUpdate;\n\t\t\tif (update.requestId !== requestId) return;\n\t\t\tapplySlashUpdate(requestId, update);\n\t\t\tif (!ctx.hasUI) return;\n\t\t\tconst tool = update.currentTool ? ` ${update.currentTool}` : \"\";\n\t\t\tconst count = update.toolCount ?? 0;\n\t\t\tconst liveDetailKey = keyText(\"app.tools.expand\");\n\t\t\tctx.ui.setStatus(\"subagent-slash\", `${count} tools${tool} | ${liveDetailKey} live detail`);\n\t\t};\n\n\t\tconst onTerminalInput = ctx.hasUI\n\t\t\t? ctx.ui.onTerminalInput((input) => {\n\t\t\t\tif (!matchesKey(input, Key.escape)) return undefined;\n\t\t\t\tpi.events.emit(SLASH_SUBAGENT_CANCEL_EVENT, { requestId });\n\t\t\t\tfinish(() => reject(new Error(\"Cancelled\")));\n\t\t\t\treturn { consume: true };\n\t\t\t})\n\t\t\t: undefined;\n\n\t\tconst unsubStarted = pi.events.on(SLASH_SUBAGENT_STARTED_EVENT, onStarted);\n\t\tconst unsubResponse = pi.events.on(SLASH_SUBAGENT_RESPONSE_EVENT, onResponse);\n\t\tconst unsubUpdate = pi.events.on(SLASH_SUBAGENT_UPDATE_EVENT, onUpdate);\n\n\t\tconst finish = (next: () => void) => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclearTimeout(startTimeout);\n\t\t\tunsubStarted();\n\t\t\tunsubResponse();\n\t\t\tunsubUpdate();\n\t\t\tonTerminalInput?.();\n\t\t\tnext();\n\t\t};\n\n\t\tpi.events.emit(SLASH_SUBAGENT_REQUEST_EVENT, { requestId, params, ctx });\n\n\t\t// Bridge emits STARTED synchronously during REQUEST emit.\n\t\t// If not started, no bridge received the request.\n\t\tif (!started && done) return;\n\t\tif (!started) {\n\t\t\tfinish(() => reject(new Error(\n\t\t\t\t\"No slash subagent bridge responded. Ensure the subagent extension is loaded correctly.\",\n\t\t\t)));\n\t\t}\n\t});\n}\n\nfunction extractSlashMessageText(content: string | Array<{ type?: string; text?: string }>): string {\n\tif (typeof content === \"string\") return content;\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.filter((part): part is { type: \"text\"; text: string } => part?.type === \"text\" && typeof part.text === \"string\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction formatExportPathList(paths: string[]): string {\n\treturn paths.map((file) => `- \\`${file}\\``).join(\"\\n\");\n}\n\nfunction collectResultPaths(results: SingleResult[], getPath: (result: SingleResult) => string | undefined): string[] {\n\treturn results\n\t\t.map(getPath)\n\t\t.filter((file): file is string => typeof file === \"string\" && file.length > 0);\n}\n\nfunction buildSlashExportText(response: SlashSubagentResponse): string {\n\tconst output = extractSlashMessageText(response.result.content) || response.errorText || \"(no output)\";\n\tconst results = response.result.details?.results ?? [];\n\tconst sessionFiles = collectResultPaths(results, (result) => result.sessionFile);\n\tconst savedOutputs = collectResultPaths(results, (result) => result.savedOutputPath);\n\tconst artifactOutputs = collectResultPaths(results, (result) => result.artifactPaths?.outputPath);\n\tconst sections = [\"## Subagent result\", output];\n\tif (sessionFiles.length > 0) sections.push(\"## Child session exports\", formatExportPathList(sessionFiles));\n\tif (savedOutputs.length > 0) sections.push(\"## Saved outputs\", formatExportPathList(savedOutputs));\n\tif (artifactOutputs.length > 0) sections.push(\"## Artifact outputs\", formatExportPathList(artifactOutputs));\n\treturn sections.join(\"\\n\\n\");\n}\n\nfunction persistSlashSessionSnapshot(ctx: ExtensionContext): void {\n\ttry {\n\t\tif (!ctx.sessionManager) return;\n\t\tconst sessionManager = ctx.sessionManager as typeof ctx.sessionManager & {\n\t\t\t_rewriteFile?: () => void;\n\t\t\tflushed?: boolean;\n\t\t};\n\t\tconst sessionFile = sessionManager.getSessionFile();\n\t\tif (!sessionFile || typeof sessionManager._rewriteFile !== \"function\") return;\n\t\tfs.mkdirSync(path.dirname(sessionFile), { recursive: true });\n\t\tsessionManager._rewriteFile();\n\t\tsessionManager.flushed = true;\n\t} catch (error) {\n\t\tconsole.error(\"Failed to persist slash session snapshot for export:\", error);\n\t}\n}\n\nasync function runSlashSubagent(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tparams: SubagentParamsLike,\n): Promise<void> {\n\tif (ctx.hasUI) ctx.ui.setToolsExpanded(false);\n\tconst requestId = randomUUID();\n\tconst initialDetails = buildSlashInitialResult(requestId, params);\n\tconst initialText = extractSlashMessageText(initialDetails.result.content) || \"Running subagent...\";\n\tpi.sendMessage({\n\t\tcustomType: SLASH_RESULT_TYPE,\n\t\tcontent: initialText,\n\t\tdisplay: true,\n\t\tdetails: initialDetails,\n\t});\n\tpersistSlashSessionSnapshot(ctx);\n\n\ttry {\n\t\tconst response = await requestSlashRun(pi, ctx, requestId, params);\n\t\tconst finalDetails = finalizeSlashResult(response);\n\t\tpi.sendMessage({\n\t\t\tcustomType: SLASH_RESULT_TYPE,\n\t\t\tcontent: buildSlashExportText(response),\n\t\t\tdisplay: !ctx.hasUI,\n\t\t\tdetails: finalDetails,\n\t\t});\n\t\tpersistSlashSessionSnapshot(ctx);\n\t\tif (ctx.hasUI) {\n\t\t\tctx.ui.setStatus(\"subagent-slash\", undefined);\n\t\t}\n\t\tif (response.isError && ctx.hasUI) {\n\t\t\tctx.ui.notify(response.errorText || \"Subagent failed\", \"error\");\n\t\t}\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst failedDetails = failSlashResult(requestId, params, message);\n\t\tpi.sendMessage({\n\t\t\tcustomType: SLASH_RESULT_TYPE,\n\t\t\tcontent: `## Subagent result\\n\\n${message}`,\n\t\t\tdisplay: !ctx.hasUI,\n\t\t\tdetails: failedDetails,\n\t\t});\n\t\tpersistSlashSessionSnapshot(ctx);\n\t\tif (ctx.hasUI) {\n\t\t\tctx.ui.setStatus(\"subagent-slash\", undefined);\n\t\t}\n\t\tif (message === \"Cancelled\") {\n\t\t\tif (ctx.hasUI) ctx.ui.notify(\"Cancelled\", \"warning\");\n\t\t\treturn;\n\t\t}\n\t\tif (ctx.hasUI) ctx.ui.notify(message, \"error\");\n\t}\n}\n\n\nexport interface GroupConfig { concurrency?: number; failFast?: boolean; worktree?: boolean }\nexport interface ParsedStep { kind: \"step\"; name: string; config: InlineConfig; task?: string }\nexport interface ParsedGroup { kind: \"group\"; tasks: ParsedStep[]; config: GroupConfig }\nexport type ParsedGroupStep = ParsedStep | ParsedGroup;\n\nexport const PARALLEL_GROUP_USAGE =\n\t'Usage: /chain agent \"task\" -> (agent2 \"task\" | agent3 \"task\") -> agent4';\n\nexport class SlashParseError extends Error {}\n\n// Walk `input` tracking quote/paren state; returns true if parens are unbalanced.\nfunction findUnmatchedCloseParen(input: string): boolean {\n\tlet depth = 0, inSingle = false, inDouble = false;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst ch = input[i]!;\n\t\tif (inSingle) { if (ch === \"'\") inSingle = false; continue; }\n\t\tif (inDouble) { if (ch === '\"') inDouble = false; continue; }\n\t\tif (ch === \"'\") { inSingle = true; continue; }\n\t\tif (ch === '\"') { inDouble = true; continue; }\n\t\tif (ch === \"(\") depth++;\n\t\telse if (ch === \")\") { depth--; if (depth < 0) return true; }\n\t}\n\treturn depth !== 0;\n}\n\n// Split on top-level \" -> \", ignoring arrows inside quotes or parentheses.\nfunction splitOnArrow(input: string): string[] {\n\tconst segments: string[] = [];\n\tlet depth = 0, inSingle = false, inDouble = false, start = 0;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst ch = input[i]!;\n\t\tif (inSingle) { if (ch === \"'\") inSingle = false; continue; }\n\t\tif (inDouble) { if (ch === '\"') inDouble = false; continue; }\n\t\tif (ch === \"'\") { inSingle = true; continue; }\n\t\tif (ch === '\"') { inDouble = true; continue; }\n\t\tif (ch === \"(\") depth++;\n\t\telse if (ch === \")\") depth--;\n\t\telse if (depth === 0 && ch === \"-\" && input[i + 1] === \">\" && input[i + 2] === \" \") {\n\t\t\tsegments.push(input.slice(start, i));\n\t\t\ti += 2;\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n\tsegments.push(input.slice(start));\n\treturn segments;\n}\n\n// Split a group's inner text on top-level \" | \", ignoring pipes inside quotes/parens.\nfunction splitGroupTasks(inner: string): string[] {\n\tconst parts: string[] = [];\n\tlet depth = 0, inSingle = false, inDouble = false, start = 0;\n\tfor (let i = 0; i < inner.length; i++) {\n\t\tconst ch = inner[i]!;\n\t\tif (inSingle) { if (ch === \"'\") inSingle = false; continue; }\n\t\tif (inDouble) { if (ch === '\"') inDouble = false; continue; }\n\t\tif (ch === \"'\") { inSingle = true; continue; }\n\t\tif (ch === '\"') { inDouble = true; continue; }\n\t\tif (ch === \"(\") depth++;\n\t\telse if (ch === \")\") depth--;\n\t\telse if (ch === \"|\" && depth === 0) {\n\t\t\tparts.push(inner.slice(start, i));\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n\tparts.push(inner.slice(start));\n\treturn parts;\n}\n\nexport function parseSingleTaskToken(token: string): ParsedStep {\n\tlet agentPart: string;\n\tlet task: string | undefined;\n\tconst qMatch = token.match(/^(\\S+(?:\\[[^\\]]*\\])?)\\s+(?:\"([^\"]*)\"|'([^']*)')$/);\n\tif (qMatch) {\n\t\tagentPart = qMatch[1]!;\n\t\ttask = (qMatch[2] ?? qMatch[3]) || undefined;\n\t} else {\n\t\tconst dashIdx = token.indexOf(\" -- \");\n\t\tif (dashIdx !== -1) {\n\t\t\tagentPart = token.slice(0, dashIdx).trim();\n\t\t\ttask = token.slice(dashIdx + 4).trim() || undefined;\n\t\t} else {\n\t\t\tagentPart = token;\n\t\t}\n\t}\n\treturn { kind: \"step\", ...parseAgentToken(agentPart), task };\n}\n\nconst parseGroupConfig = (raw: string): GroupConfig => {\n\tconst config: GroupConfig = {};\n\tfor (const part of raw.split(\",\")) {\n\t\tconst trimmed = part.trim();\n\t\tif (!trimmed) continue;\n\t\tconst eq = trimmed.indexOf(\"=\");\n\t\tconst key = eq === -1 ? trimmed : trimmed.slice(0, eq).trim();\n\t\tconst val = eq === -1 ? \"\" : trimmed.slice(eq + 1).trim();\n\t\tswitch (key) {\n\t\t\tcase \"concurrency\": { const n = Number(val); if (Number.isInteger(n) && n > 0) config.concurrency = n; break; }\n\t\t\tcase \"failFast\": config.failFast = eq === -1 ? true : val !== \"false\"; break;\n\t\t\tcase \"worktree\": config.worktree = eq === -1 ? true : val !== \"false\"; break;\n\t\t}\n\t}\n\treturn config;\n};\n\n// Split `(...)` from an optional trailing `[...]` group-config suffix, respecting\n// quotes and nested parens. Returns the inner group text and the parsed config.\nconst splitGroupBody = (trimmed: string): { inner: string; config: GroupConfig } => {\n\tlet depth = 0, inSingle = false, inDouble = false, closeIdx = -1;\n\tfor (let i = 0; i < trimmed.length; i++) {\n\t\tconst ch = trimmed[i]!;\n\t\tif (inSingle) { if (ch === \"'\") inSingle = false; continue; }\n\t\tif (inDouble) { if (ch === '\"') inDouble = false; continue; }\n\t\tif (ch === \"'\") { inSingle = true; continue; }\n\t\tif (ch === '\"') { inDouble = true; continue; }\n\t\tif (ch === \"(\") depth++;\n\t\telse if (ch === \")\") { depth--; if (depth === 0) { closeIdx = i; break; } }\n\t}\n\tif (closeIdx === -1) throw new SlashParseError(`Unmatched parentheses in group: '${trimmed}'`);\n\tconst inner = trimmed.slice(1, closeIdx);\n\tconst suffix = trimmed.slice(closeIdx + 1).trim();\n\tif (!suffix) return { inner, config: {} };\n\tif (!suffix.startsWith(\"[\") || !suffix.endsWith(\"]\")) {\n\t\tthrow new SlashParseError(`Group options must be wrapped in [...]: '${suffix}'`);\n\t}\n\treturn { inner, config: parseGroupConfig(suffix.slice(1, -1)) };\n};\n\nexport function parseGroupSegment(segment: string): ParsedGroup {\n\tconst trimmed = segment.trim();\n\tif (!trimmed.startsWith(\"(\")) {\n\t\tthrow new SlashParseError(`Parallel group must be wrapped in parentheses: '${trimmed}'`);\n\t}\n\tconst { inner, config } = splitGroupBody(trimmed);\n\tconst rawParts = splitGroupTasks(inner).map((p) => p.trim()).filter((p) => p.length > 0);\n\tif (rawParts.length < 2) {\n\t\tthrow new SlashParseError(\"Parallel group must contain at least two tasks separated by ' | '\");\n\t}\n\treturn { kind: \"group\", tasks: rawParts.map((part) => parseSingleTaskToken(part)), config };\n}\n\n// True if `input` uses inline parallel-group syntax. A group is a *step* that begins\n// with `(` at the top level, so we split on top-level ` -> ` arrows and look for a\n// segment that opens with `(`. Parentheses appearing inside a task (e.g.\n// `scout -- inspect auth (backend)`) do not count, which keeps legacy shared-task\n// `-- task` parsing — including a bare `|` inside the task — on the single-agent path.\nexport function hasGroupSyntax(input: string): boolean {\n\treturn splitOnArrow(input).some((seg) => seg.trim().startsWith(\"(\"));\n}\n\nexport function parseChainExpression(input: string): { steps: ParsedGroupStep[] } {\n\tconst trimmed = input.trim();\n\tif (!trimmed.includes(\" -> \")) {\n\t\tthrow new SlashParseError('Parallel groups in /chain require \" -> \" between steps');\n\t}\n\tif (findUnmatchedCloseParen(trimmed)) {\n\t\tthrow new SlashParseError(\"Unmatched parentheses in /chain expression\");\n\t}\n\tconst steps: ParsedGroupStep[] = [];\n\tfor (const seg of splitOnArrow(trimmed)) {\n\t\tconst t = seg.trim();\n\t\tif (!t) continue;\n\t\tif (t.startsWith(\"(\")) {\n\t\t\tsteps.push(parseGroupSegment(t));\n\t\t\tcontinue;\n\t\t}\n\t\tif (findUnmatchedCloseParen(t)) {\n\t\t\tthrow new SlashParseError(`Unmatched parentheses in chain segment: '${t}'`);\n\t\t}\n\t\tsteps.push(parseSingleTaskToken(t));\n\t}\n\tif (steps.length === 0) {\n\t\tthrow new SlashParseError(\"/chain expression must include at least one step\");\n\t}\n\treturn { steps };\n}\n\nconst parseAgentArgs = (\n\tstate: SubagentState,\n\targs: string,\n\tcommand: string,\n\tctx: ExtensionContext,\n): { steps: ParsedStep[]; task: string } | null => {\n\tconst input = args.trim();\n\tconst usage = `Usage: /${command} description1 \"task1\" -> description2 \"task2\"`;\n\tlet steps: ParsedStep[];\n\tlet sharedTask: string;\n\tlet perStep = false;\n\n\tif (input.includes(\" -> \")) {\n\t\tperStep = true;\n\t\tconst segments = input.split(\" -> \");\n\t\tsteps = [];\n\t\tfor (const seg of segments) {\n\t\t\tconst trimmed = seg.trim();\n\t\t\tif (!trimmed) continue;\n\t\t\tsteps.push(parseSingleTaskToken(trimmed));\n\t\t}\n\t\tsharedTask = steps.find((s) => s.task)?.task ?? \"\";\n\t} else {\n\t\tconst delimiterIndex = input.indexOf(\" -- \");\n\t\tif (delimiterIndex === -1) {\n\t\t\tctx.ui.notify(usage, \"error\");\n\t\t\treturn null;\n\t\t}\n\t\tconst agentsPart = input.slice(0, delimiterIndex).trim();\n\t\tsharedTask = input.slice(delimiterIndex + 4).trim();\n\t\tif (!agentsPart || !sharedTask) {\n\t\t\tctx.ui.notify(usage, \"error\");\n\t\t\treturn null;\n\t\t}\n\t\tsteps = agentsPart.split(/\\s+/).filter(Boolean).map((t) => parseSingleTaskToken(t));\n\t}\n\n\tif (steps.length === 0) {\n\t\tctx.ui.notify(usage, \"error\");\n\t\treturn null;\n\t}\n\tif (!state.baseCwd) {\n\t\tctx.ui.notify(\"Subagent session cwd is not initialized yet\", \"error\");\n\t\treturn null;\n\t}\n\tif (command === \"chain\" && !steps[0]?.task && (perStep || !sharedTask)) {\n\t\tctx.ui.notify(`First step must have a task: /chain description \"task\" -> description2`, \"error\");\n\t\treturn null;\n\t}\n\tif (command === \"parallel\" && !steps.some((s) => s.task) && !sharedTask) {\n\t\tctx.ui.notify(\"At least one step must have a task\", \"error\");\n\t\treturn null;\n\t}\n\treturn { steps, task: sharedTask };\n};\n\ntype ChainStepObject = {\n\tdescription: string;\n\tpermissions: \"full\" | \"read-only\";\n\ttier: \"light\" | \"standard\" | \"heavy\";\n\ttask?: string;\n\toutput?: string | false;\n\toutputMode?: \"inline\" | \"file-only\";\n\treads?: string[] | false;\n\tskill?: string[] | false;\n\tprogress?: boolean;\n\tas?: string;\n\tlabel?: string;\n\tphase?: string;\n\tcwd?: string;\n\tcount?: number;\n\toutputSchema?: JsonSchemaObject;\n\tacceptance?: string;\n};\n\nconst INLINE_ACCEPTANCE_LEVELS = new Set([\"auto\", \"attested\", \"checked\"]);\n\nfunction validateInlineAcceptanceInput(value: string, agent: string): void {\n\tconst errors = validateAcceptanceInput(value, `acceptance for step '${agent}'`);\n\tif (errors.length > 0) throw new SlashParseError(errors[0]!);\n\tif (!INLINE_ACCEPTANCE_LEVELS.has(value)) {\n\t\tthrow new SlashParseError(`Inline acceptance for step '${agent}' supports auto, attested, or checked. Use the subagent tool API or a saved .chain.json file for none or verified acceptance contracts; reviewed is inferred-only.`);\n\t}\n}\n\n// Load an inline `outputSchema=<path>` JSON file, resolved against the session cwd.\n// Throws (SlashParseError / fs / JSON) on a missing or malformed schema.\nfunction loadInlineOutputSchema(baseCwd: string, agent: string, value: string): JsonSchemaObject {\n\tconst schemaPath = path.isAbsolute(value) ? value : path.join(baseCwd, value);\n\tconst label = `outputSchema for step '${agent}' (${schemaPath})`;\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(fs.readFileSync(schemaPath, \"utf-8\"));\n\t} catch (error) {\n\t\tthrow new SlashParseError(`Cannot read ${label}: ${error instanceof Error ? error.message : String(error)}`);\n\t}\n\tassertJsonSchemaObject(parsed, label);\n\treturn parsed;\n}\n\n// Build a ChainStep object from a parsed token. `inGroup` enables `count` (parallel-only).\n// May throw SlashParseError for an invalid acceptance level or outputSchema path.\nconst mapParsedTaskToStepObject = (\n\tstep: ParsedStep,\n\tfallbackTask: string | undefined,\n\tisFirst: boolean,\n\topts: { baseCwd: string; inGroup: boolean },\n): ChainStepObject => {\n\tconst { name, config, task: stepTask } = step;\n\tif (!config.tier) throw new SlashParseError(`Step '${name}' requires tier=light, tier=standard, or tier=heavy.`);\n\tif (config.acceptance !== undefined) validateInlineAcceptanceInput(config.acceptance, name);\n\treturn {\n\t\tdescription: name,\n\t\tpermissions: config.permissions ?? \"full\",\n\t\ttier: config.tier,\n\t\t...(stepTask ? { task: stepTask } : isFirst && fallbackTask ? { task: fallbackTask } : {}),\n\t\t...(config.output !== undefined ? { output: config.output } : {}),\n\t\t...(config.outputMode !== undefined ? { outputMode: config.outputMode } : {}),\n\t\t...(config.reads !== undefined ? { reads: config.reads } : {}),\n\t\t...(config.skill !== undefined ? { skill: config.skill } : {}),\n\t\t...(config.progress !== undefined ? { progress: config.progress } : {}),\n\t\t...(config.as ? { as: config.as } : {}),\n\t\t...(config.label ? { label: config.label } : {}),\n\t\t...(config.phase ? { phase: config.phase } : {}),\n\t\t...(config.cwd ? { cwd: config.cwd } : {}),\n\t\t...(opts.inGroup && config.count !== undefined ? { count: config.count } : {}),\n\t\t...(config.outputSchema ? { outputSchema: loadInlineOutputSchema(opts.baseCwd, name, config.outputSchema) } : {}),\n\t\t...(config.acceptance ? { acceptance: config.acceptance } : {}),\n\t};\n};\n\nexport function buildChainExpressionSteps(\n\tstate: SubagentState,\n\tinput: string,\n\tctx: ExtensionContext,\n): { chain: ChainStep[]; task: string } | null {\n\tconst notify = (message: string) => ctx.ui.notify(message, \"error\");\n\tif (!hasGroupSyntax(input)) {\n\t\tconst parsed = parseAgentArgs(state, input, \"chain\", ctx);\n\t\tif (!parsed) return null;\n\t\tconst baseCwd = state.baseCwd!; // parseAgentArgs already verified baseCwd is set\n\t\ttry {\n\t\t\tconst chain: ChainStep[] = parsed.steps.map((step, i) =>\n\t\t\t\tmapParsedTaskToStepObject(step, parsed.task || undefined, i === 0, { baseCwd, inGroup: false }),\n\t\t\t);\n\t\t\treturn { chain, task: parsed.task };\n\t\t} catch (error) {\n\t\t\tnotify(error instanceof Error ? error.message : String(error));\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tlet expression: { steps: ParsedGroupStep[] };\n\ttry {\n\t\texpression = parseChainExpression(input);\n\t} catch (error) {\n\t\tnotify(error instanceof Error ? error.message : String(error));\n\t\treturn null;\n\t}\n\tif (!state.baseCwd) {\n\t\tnotify(\"Subagent session cwd is not initialized yet\");\n\t\treturn null;\n\t}\n\t// Every task inside a parallel group needs its own task; there is no shared-task fallback.\n\tfor (const step of expression.steps) {\n\t\tif (step.kind === \"group\" && step.tasks.some((t) => !t.task)) {\n\t\t\tnotify('Each child in a parallel group needs a task: (description \"a\" | description2 \"b\")');\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst firstStep = expression.steps[0]!;\n\tconst firstHasTask =\n\t\tfirstStep.kind === \"group\"\n\t\t\t? firstStep.tasks.some((t) => Boolean(t.task))\n\t\t\t: Boolean(firstStep.task);\n\tif (!firstHasTask) {\n\t\tnotify('First step must have a task: /chain description \"task\" -> description2');\n\t\treturn null;\n\t}\n\tconst sharedTask =\n\t\tfirstStep.kind === \"group\"\n\t\t\t? (firstStep.tasks.find((t) => t.task)?.task ?? \"\")\n\t\t\t: (firstStep.task ?? \"\");\n\tconst baseCwd = state.baseCwd;\n\tlet chain: ChainStep[];\n\ttry {\n\t\tchain = expression.steps.map((step) => {\n\t\t\tif (step.kind === \"group\") {\n\t\t\t\tconst parallel = step.tasks.map((t) => mapParsedTaskToStepObject(t, undefined, false, { baseCwd, inGroup: true }));\n\t\t\t\treturn {\n\t\t\t\t\tparallel,\n\t\t\t\t\t...(step.config.concurrency !== undefined ? { concurrency: step.config.concurrency } : {}),\n\t\t\t\t\t...(step.config.failFast !== undefined ? { failFast: step.config.failFast } : {}),\n\t\t\t\t\t...(step.config.worktree !== undefined ? { worktree: step.config.worktree } : {}),\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn mapParsedTaskToStepObject(step, sharedTask || undefined, false, { baseCwd, inGroup: false });\n\t\t});\n\t} catch (error) {\n\t\tnotify(error instanceof Error ? error.message : String(error));\n\t\treturn null;\n\t}\n\treturn { chain, task: sharedTask };\n}\n\nexport function registerSlashCommands(\n\tpi: ExtensionAPI,\n\tstate: SubagentState,\n): void {\n\tlet fleetOpen = false;\n\tconst showFleet = async (ctx: ExtensionContext) => {\n\t\tstate.lastUiContext = ctx;\n\t\tif (!ctx.hasUI) {\n\t\t\tawait runSlashSubagent(pi, ctx, { action: \"status\", view: \"fleet\" });\n\t\t\treturn;\n\t\t}\n\t\tif (fleetOpen) {\n\t\t\tctx.ui.notify(\"Subagent fleet inspector is already open.\", \"info\");\n\t\t\treturn;\n\t\t}\n\t\tfleetOpen = true;\n\t\ttry {\n\t\t\tawait openSubagentFleet(ctx, state);\n\t\t} finally {\n\t\t\tfleetOpen = false;\n\t\t}\n\t};\n\n\tpi.registerCommand(\"run\", {\n\t\tdescription: \"Run a prompt-defined child: /run description[tier=standard] task [--bg]\",\n\t\thandler: async (args, ctx) => {\n\t\t\tconst { args: cleanedArgs, bg } = extractExecutionFlags(args);\n\t\t\tconst input = cleanedArgs.trim();\n\t\t\tconst firstSpace = input.indexOf(\" \");\n\t\t\tif (!input) { ctx.ui.notify(\"Usage: /run <description> <task> [--bg]\", \"error\"); return; }\n\t\t\tconst { name: description, config: inline } = parseAgentToken(firstSpace === -1 ? input : input.slice(0, firstSpace));\n\t\t\tconst task = firstSpace === -1 ? \"\" : input.slice(firstSpace + 1).trim();\n\t\t\tif (!description || !task || !inline.tier) { ctx.ui.notify(\"Usage: /run <description>[tier=light|standard|heavy] <task> [--bg]\", \"error\"); return; }\n\n\t\t\tlet finalTask = task;\n\t\t\tif (inline.reads && Array.isArray(inline.reads) && inline.reads.length > 0) {\n\t\t\t\tfinalTask = `[Read from: ${inline.reads.join(\", \")}]\\n\\n${finalTask}`;\n\t\t\t}\n\t\t\tconst params: SubagentParamsLike = { description, permissions: inline.permissions ?? \"full\", tier: inline.tier, task: finalTask, clarify: false };\n\t\t\tif (inline.output !== undefined) params.output = inline.output;\n\t\t\tif (inline.outputMode !== undefined) params.outputMode = inline.outputMode;\n\t\t\tif (inline.skill !== undefined) params.skill = inline.skill;\n\t\t\tif (bg) params.async = true;\n\t\t\tawait runSlashSubagent(pi, ctx, params);\n\t\t},\n\t});\n\n\tpi.registerCommand(\"chain\", {\n\t\tdescription: \"Run prompt-defined children in sequence: /chain inspect \\\"task\\\" -> implement [--bg]\",\n\t\thandler: async (args, ctx) => {\n\t\t\tconst { args: cleanedArgs, bg } = extractExecutionFlags(args);\n\t\t\tconst built = buildChainExpressionSteps(state, cleanedArgs, ctx);\n\t\t\tif (!built) return;\n\t\t\tconst params: SubagentParamsLike = { chain: built.chain, task: built.task, clarify: false };\n\t\t\tif (bg) params.async = true;\n\t\t\tawait runSlashSubagent(pi, ctx, params);\n\t\t},\n\t});\n\n\tpi.registerCommand(\"parallel\", {\n\t\tdescription: \"Run prompt-defined children in parallel: /parallel inspect \\\"task1\\\" -> review \\\"task2\\\" [--bg]\",\n\t\thandler: async (args, ctx) => {\n\t\t\tconst { args: cleanedArgs, bg } = extractExecutionFlags(args);\n\t\t\tconst parsed = parseAgentArgs(state, cleanedArgs, \"parallel\", ctx);\n\t\t\tif (!parsed) return;\n\t\t\tconst tasks = parsed.steps.map(({ name, config, task: stepTask }) => ({\n\t\t\t\tdescription: name,\n\t\t\t\tpermissions: config.permissions ?? \"full\" as const,\n\t\t\t\ttier: config.tier,\n\t\t\t\ttask: stepTask ?? parsed.task,\n\t\t\t\t...(config.output !== undefined ? { output: config.output } : {}),\n\t\t\t\t...(config.outputMode !== undefined ? { outputMode: config.outputMode } : {}),\n\t\t\t\t...(config.reads !== undefined ? { reads: config.reads } : {}),\n\t\t\t\t...(config.skill !== undefined ? { skill: config.skill } : {}),\n\t\t\t\t...(config.progress !== undefined ? { progress: config.progress } : {}),\n\t\t\t}));\n\t\t\tif (tasks.some((task) => !task.tier)) { ctx.ui.notify(\"Every parallel child requires [tier=light|standard|heavy].\", \"error\"); return; }\n\t\t\tconst params: SubagentParamsLike = { tasks, clarify: false };\n\t\t\tif (bg) params.async = true;\n\t\t\tawait runSlashSubagent(pi, ctx, params);\n\t\t},\n\t});\n\n\tpi.registerCommand(\"subagent-cost\", {\n\t\tdescription: \"Show parent and subagent child usage cost for this session\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tsendSlashText(pi, buildSubagentCostReport(ctx));\n\t\t},\n\t});\n\n\tpi.registerCommand(\"subagents-doctor\", {\n\t\tdescription: \"Show subagent diagnostics\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tawait runSlashSubagent(pi, ctx, { action: \"doctor\" });\n\t\t},\n\t});\n\n\tpi.registerCommand(\"subagents-fleet\", {\n\t\tdescription: \"Open the live, inspection-only subagent fleet\",\n\t\thandler: async (_args, ctx) => showFleet(ctx),\n\t});\n\n\tpi.registerShortcut(Key.ctrlAlt(\"f\"), {\n\t\tdescription: \"Open subagent fleet inspector\",\n\t\thandler: async (ctx) => showFleet(ctx),\n\t});\n\n\tpi.registerCommand(\"subagents-stop\", {\n\t\tdescription: \"Stop a current-session async subagent run\",\n\t\thandler: async (args, ctx) => {\n\t\t\tconst id = args.trim();\n\t\t\tif (id) {\n\t\t\t\tawait runSlashSubagent(pi, ctx, { action: \"stop\", id });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (process.env[SUBAGENT_FANOUT_CHILD_ENV] === \"1\") {\n\t\t\t\tsendSlashText(pi, \"Selector unavailable in child-safe fanout mode. Pass an explicit current-session top-level async run id, for example `/subagents-stop <run-id>` or `subagent({ action: \\\"stop\\\", id: \\\"<run-id>\\\" })`.\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet targets: StopSelectorTarget[];\n\t\t\ttry {\n\t\t\t\ttargets = discoverStopTargets(ctx, state);\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(message, \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!ctx.hasUI) {\n\t\t\t\tsendSlashText(pi, stopFallbackText(targets));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (targets.length === 0) {\n\t\t\t\tctx.ui.notify(\"No active current-session async runs or scheduled subagent runs to stop.\", \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst result = await ctx.ui.custom<StopSelectorResult>(\n\t\t\t\t(tui, theme, _kb, done) => new SubagentsStopSelector(tui, theme, targets, done),\n\t\t\t\t{ overlay: true, overlayOptions: { anchor: \"center\", width: 88, maxHeight: \"80%\" } },\n\t\t\t);\n\t\t\tif (!result?.confirmed || !result.target) return;\n\t\t\tif (result.target.kind === \"scheduled\") {\n\t\t\t\tawait runSlashSubagent(pi, ctx, { action: \"schedule-cancel\", id: result.target.id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runSlashSubagent(pi, ctx, { action: \"stop\", id: result.target.id });\n\t\t},\n\t});\n\n\tregisterPromptWorkflowCommands({\n\t\tpi,\n\t\trun: (params, ctx) => runSlashSubagent(pi, ctx, params),\n\t});\n\n}\n"]}
1
+ {"version":3,"file":"slash-commands.d.ts","sourceRoot":"","sources":["../../../../../src/builtin-extensions/pi-subagents/src/slash/slash-commands.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAItF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAiBvD,OAAO,EAYN,KAAK,aAAa,EAElB,MAAM,oBAAoB,CAAC;AAE5B,UAAU,YAAY;IACrB,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,UAAU,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;IAC3E,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AA8fD,MAAM,WAAW,WAAW;IAAG,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE;AAC7F,MAAM,WAAW,UAAU;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE;AAC/F,MAAM,WAAW,WAAW;IAAG,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE;AACxF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,WAAW,CAAC;AAEvD,eAAO,MAAM,oBAAoB,kFACyC,CAAC;AAE3E,qBAAa,eAAgB,SAAQ,KAAK;CAAG;AA4D7C,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAiB9D;AA0CD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAW9D;AAOD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,eAAe,EAAE,CAAA;CAAE,CAyBhF;AAwID,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,gBAAgB,GACnB;IAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoE7C;AAED,wBAAgB,qBAAqB,CACpC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,aAAa,GAClB,IAAI,CA4JN","sourcesContent":["// @ts-nocheck\nimport { randomUUID } from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { ExtensionAPI, ExtensionContext } from \"@ashx-j/lunr\";\nimport { keyText } from \"../../../../modes/interactive/components/keybinding-hints.ts\";\nimport { Key, matchesKey, type Component, type TUI } from \"@ashx-j/lunr-tui\";\nimport type { SubagentParamsLike } from \"../runs/foreground/subagent-executor.ts\";\nimport type { ChainStep } from \"../shared/settings.ts\";\nimport { formatTokens, shortenPath } from \"../shared/formatters.ts\";\nimport { listAsyncRuns, formatAsyncRunProgressLabel, type AsyncRunSummary } from \"../runs/background/async-status.ts\";\nimport { scheduledRunStorePath } from \"../runs/background/scheduled-runs.ts\";\nimport { SUBAGENT_FANOUT_CHILD_ENV } from \"../runs/shared/pi-args.ts\";\nimport { assertJsonSchemaObject } from \"../runs/shared/structured-output.ts\";\nimport { validateAcceptanceInput } from \"../runs/shared/acceptance.ts\";\nimport type { SlashSubagentResponse, SlashSubagentUpdate } from \"./slash-bridge.ts\";\nimport { registerPromptWorkflowCommands } from \"./prompt-workflows.ts\";\nimport { openSubagentFleet } from \"../tui/fleet.ts\";\nimport {\n\tapplySlashUpdate,\n\tbuildSlashInitialResult,\n\tfailSlashResult,\n\tfinalizeSlashResult,\n\tresolveSlashMessageDetails,\n} from \"./slash-live-state.ts\";\nimport {\n\tSLASH_RESULT_TYPE,\n\tSLASH_TEXT_RESULT_TYPE,\n\tSLASH_SUBAGENT_CANCEL_EVENT,\n\tSLASH_SUBAGENT_REQUEST_EVENT,\n\tSLASH_SUBAGENT_RESPONSE_EVENT,\n\tSLASH_SUBAGENT_STARTED_EVENT,\n\tSLASH_SUBAGENT_UPDATE_EVENT,\n\tASYNC_DIR,\n\ttype Details,\n\ttype JsonSchemaObject,\n\ttype SingleResult,\n\ttype SubagentState,\n\ttype Usage,\n} from \"../shared/types.ts\";\n\ninterface InlineConfig {\n\toutput?: string | false;\n\toutputMode?: \"inline\" | \"file-only\";\n\treads?: string[] | false;\n\ttier?: \"light\" | \"standard\" | \"heavy\";\n\tmodel?: string;\n\tthinking?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\tpermissions?: \"full\" | \"read-only\";\n\tskill?: string[] | false;\n\tprogress?: boolean;\n\tas?: string;\n\tlabel?: string;\n\tphase?: string;\n\tcwd?: string;\n\tcount?: number;\n\toutputSchema?: string;\n\tacceptance?: string;\n}\n\nconst parseInlineConfig = (raw: string): InlineConfig => {\n\tconst config: InlineConfig = {};\n\tfor (const part of raw.split(\",\")) {\n\t\tconst trimmed = part.trim();\n\t\tif (!trimmed) continue;\n\t\tconst eq = trimmed.indexOf(\"=\");\n\t\tif (eq === -1) {\n\t\t\tif (trimmed === \"progress\") config.progress = true;\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = trimmed.slice(0, eq).trim();\n\t\tconst val = trimmed.slice(eq + 1).trim();\n\t\tswitch (key) {\n\t\t\tcase \"output\": config.output = val === \"false\" ? false : val; break;\n\t\t\tcase \"outputMode\": if (val === \"inline\" || val === \"file-only\") config.outputMode = val; break;\n\t\t\tcase \"reads\": config.reads = val === \"false\" ? false : val.split(\"+\").filter(Boolean); break;\n\t\t\tcase \"tier\": if (val === \"light\" || val === \"standard\" || val === \"heavy\") config.tier = val; break;\n\t\t\tcase \"model\": if (val) config.model = val; break;\n\t\t\tcase \"thinking\": if ([\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"].includes(val)) config.thinking = val as InlineConfig[\"thinking\"]; break;\n\t\t\tcase \"permissions\": if (val === \"full\" || val === \"read-only\") config.permissions = val; break;\n\t\t\tcase \"skill\": case \"skills\": config.skill = val === \"false\" ? false : val.split(\"+\").filter(Boolean); break;\n\t\t\tcase \"progress\": config.progress = val !== \"false\"; break;\n\t\t\tcase \"as\": config.as = val || undefined; break;\n\t\t\tcase \"label\": config.label = val || undefined; break;\n\t\t\tcase \"phase\": config.phase = val || undefined; break;\n\t\t\tcase \"cwd\": config.cwd = val || undefined; break;\n\t\t\tcase \"count\": { const n = Number(val); if (Number.isInteger(n) && n > 0) config.count = n; break; }\n\t\t\tcase \"outputSchema\": config.outputSchema = val || undefined; break;\n\t\t\tcase \"acceptance\": config.acceptance = val || undefined; break;\n\t\t}\n\t}\n\treturn config;\n};\n\nconst parseAgentToken = (token: string): { name: string; config: InlineConfig } => {\n\tconst bracket = token.indexOf(\"[\");\n\tif (bracket === -1) return { name: token, config: {} };\n\tconst end = token.lastIndexOf(\"]\");\n\treturn { name: token.slice(0, bracket), config: parseInlineConfig(token.slice(bracket + 1, end !== -1 ? end : undefined)) };\n};\n\nconst extractExecutionFlags = (rawArgs: string): { args: string; bg: boolean } => {\n\tlet args = rawArgs.trim();\n\tlet bg = false;\n\n\twhile (true) {\n\t\tif (args.endsWith(\" --bg\") || args === \"--bg\") {\n\t\t\tbg = true;\n\t\t\targs = args === \"--bg\" ? \"\" : args.slice(0, -5).trim();\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n\n\treturn { args, bg };\n};\n\nfunction sendSlashText(pi: ExtensionAPI, text: string): void {\n\tpi.sendMessage({ customType: SLASH_TEXT_RESULT_TYPE, content: text, display: true });\n}\n\ntype Theme = ExtensionContext[\"ui\"][\"theme\"];\n\ntype StopSelectorTarget = {\n\tkind: \"async\" | \"scheduled\";\n\tid: string;\n\tlabel: string;\n\tdetail: string;\n\tactionLabel: string;\n};\n\ntype StopSelectorResult = { confirmed: boolean; target?: StopSelectorTarget };\n\nfunction commandForTarget(target: StopSelectorTarget): string {\n\treturn target.kind === \"scheduled\"\n\t\t? `subagent({ action: \"schedule-cancel\", id: ${JSON.stringify(target.id)} })`\n\t\t: `subagent({ action: \"stop\", id: ${JSON.stringify(target.id)} })`;\n}\n\nfunction formatAsyncStopTarget(run: AsyncRunSummary): StopSelectorTarget {\n\tconst progress = formatAsyncRunProgressLabel(run);\n\tconst cwd = run.cwd ? shortenPath(run.cwd) : shortenPath(run.asyncDir);\n\treturn {\n\t\tkind: \"async\",\n\t\tid: run.id,\n\t\tlabel: `${run.id} · ${run.mode} · ${progress}`,\n\t\tdetail: `${run.state} · ${cwd}`,\n\t\tactionLabel: \"stop async run\",\n\t};\n}\n\nfunction scheduledStopTargets(ctx: ExtensionContext, state: SubagentState): StopSelectorTarget[] {\n\tconst sessionId = state.currentSessionId ?? ctx.sessionManager.getSessionId();\n\tif (!sessionId) return [];\n\tconst storePath = scheduledRunStorePath(ctx.cwd, sessionId);\n\tif (!fs.existsSync(storePath)) return [];\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(fs.readFileSync(storePath, \"utf-8\"));\n\t} catch {\n\t\treturn [];\n\t}\n\tconst jobs = parsed && typeof parsed === \"object\" && Array.isArray((parsed as { jobs?: unknown }).jobs)\n\t\t? (parsed as { jobs: Array<Record<string, unknown>> }).jobs\n\t\t: [];\n\treturn jobs\n\t\t.filter((job) => job.state === \"scheduled\" && typeof job.id === \"string\" && typeof job.name === \"string\" && typeof job.runAt === \"number\")\n\t\t.sort((left, right) => Number(left.runAt) - Number(right.runAt))\n\t\t.map((job) => ({\n\t\t\tkind: \"scheduled\" as const,\n\t\t\tid: String(job.id),\n\t\t\tlabel: `${String(job.id)} · ${String(job.name)}`,\n\t\t\tdetail: `scheduled · ${new Date(Number(job.runAt)).toISOString()}`,\n\t\t\tactionLabel: \"cancel scheduled run\",\n\t\t}));\n}\n\nfunction discoverStopTargets(ctx: ExtensionContext, state: SubagentState): StopSelectorTarget[] {\n\tconst sessionId = state.currentSessionId ?? ctx.sessionManager.getSessionId() ?? undefined;\n\tconst asyncTargets = listAsyncRuns(ASYNC_DIR, {\n\t\tstates: [\"queued\", \"running\"],\n\t\t...(sessionId ? { sessionId } : {}),\n\t}).map(formatAsyncStopTarget);\n\treturn [...asyncTargets, ...scheduledStopTargets(ctx, state)];\n}\n\nfunction stopFallbackText(targets: StopSelectorTarget[]): string {\n\tif (targets.length === 0) return \"No active current-session async runs or scheduled subagent runs to stop.\";\n\tconst lines = [\"Subagent stop targets:\", \"\"];\n\tfor (const target of targets) {\n\t\tlines.push(`- ${target.label}`);\n\t\tlines.push(` ${target.detail}`);\n\t\tlines.push(` ${target.actionLabel}: ${commandForTarget(target)}`);\n\t\tif (target.kind === \"async\") lines.push(` slash: /subagents-stop ${target.id}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nclass SubagentsStopSelector implements Component {\n\treadonly width = 84;\n\tprivate selected = 0;\n\tprivate confirming = false;\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly targets: StopSelectorTarget[];\n\tprivate readonly done: (result: StopSelectorResult) => void;\n\n\tconstructor(tui: TUI, theme: Theme, targets: StopSelectorTarget[], done: (result: StopSelectorResult) => void) {\n\t\tthis.tui = tui;\n\t\tthis.theme = theme;\n\t\tthis.targets = targets;\n\t\tthis.done = done;\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (matchesKey(data, \"escape\") || matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.done({ confirmed: false });\n\t\t\treturn;\n\t\t}\n\t\tif (this.confirming) {\n\t\t\tif (matchesKey(data, \"return\") || data.toLowerCase() === \"y\") {\n\t\t\t\tthis.done({ confirmed: true, target: this.targets[this.selected] });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (data.toLowerCase() === \"n\" || matchesKey(data, \"backspace\")) {\n\t\t\t\tthis.confirming = false;\n\t\t\t\tthis.tui.requestRender();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"up\")) {\n\t\t\tthis.selected = Math.max(0, this.selected - 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"down\")) {\n\t\t\tthis.selected = Math.min(this.targets.length - 1, this.selected + 1);\n\t\t\tthis.tui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"return\")) {\n\t\t\tthis.confirming = true;\n\t\t\tthis.tui.requestRender();\n\t\t}\n\t}\n\n\trender(width: number): string[] {\n\t\tconst contentWidth = Math.max(40, Math.min(this.width, width || this.width));\n\t\tconst lines = [this.theme.bold(\"Stop subagent run\"), this.theme.fg(\"dim\", \"Select a current-session async run to stop, or a scheduled run to cancel.\"), \"\"];\n\t\tconst maxRows = 10;\n\t\tconst start = Math.max(0, Math.min(this.selected - maxRows + 1, Math.max(0, this.targets.length - maxRows)));\n\t\tfor (let index = start; index < Math.min(this.targets.length, start + maxRows); index++) {\n\t\t\tconst target = this.targets[index]!;\n\t\t\tconst selected = index === this.selected;\n\t\t\tconst marker = selected ? \"›\" : \" \";\n\t\t\t\tconst actionLabel = target.actionLabel;\n\t\t\tconst action = target.kind === \"scheduled\" ? this.theme.fg(\"warning\", actionLabel) : this.theme.fg(\"accent\", actionLabel);\n\t\t\tconst labelWidth = Math.max(0, contentWidth - marker.length - actionLabel.length - 2);\n\t\t\tlines.push(`${marker} ${action} ${target.label.slice(0, labelWidth)}`);\n\t\t\tif (selected) lines.push(this.theme.fg(\"dim\", ` ${target.detail}`.slice(0, contentWidth)));\n\t\t}\n\t\tif (this.targets.length > maxRows) lines.push(this.theme.fg(\"dim\", `Showing ${start + 1}-${Math.min(this.targets.length, start + maxRows)} of ${this.targets.length}`));\n\t\tlines.push(\"\");\n\t\tif (this.confirming) {\n\t\t\tconst target = this.targets[this.selected]!;\n\t\t\tlines.push(this.theme.fg(\"warning\", `Confirm: ${target.actionLabel} ${target.id}?`));\n\t\t\tif (target.kind === \"async\") lines.push(this.theme.fg(\"dim\", \"Stop ends this run; use interrupt for a resumable pause.\"));\n\t\t\tlines.push(this.theme.fg(\"dim\", \"Enter/Y confirms · N returns · Esc cancels\"));\n\t\t} else {\n\t\t\tlines.push(this.theme.fg(\"dim\", \"↑/↓ select · Enter confirm · Esc cancel\"));\n\t\t}\n\t\treturn lines;\n\t}\n}\n\nfunction emptyUsage(): Usage {\n\treturn { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };\n}\n\nfunction addUsage(target: Usage, source: Usage): void {\n\ttarget.input += source.input;\n\ttarget.output += source.output;\n\ttarget.cacheRead += source.cacheRead;\n\ttarget.cacheWrite += source.cacheWrite;\n\ttarget.cost += source.cost;\n\ttarget.turns += source.turns;\n}\n\nfunction usageHasValue(usage: Usage): boolean {\n\treturn usage.input !== 0 || usage.output !== 0 || usage.cacheRead !== 0 || usage.cacheWrite !== 0 || usage.cost !== 0 || usage.turns !== 0;\n}\n\nfunction assistantUsageFromMessage(message: unknown): Usage | undefined {\n\tif (!message || typeof message !== \"object\") return undefined;\n\tconst msg = message as { role?: unknown; usage?: unknown };\n\tif (msg.role !== \"assistant\" || !msg.usage || typeof msg.usage !== \"object\") return undefined;\n\tconst usage = msg.usage as {\n\t\tinput?: unknown;\n\t\toutput?: unknown;\n\t\tcacheRead?: unknown;\n\t\tcacheWrite?: unknown;\n\t\tcost?: { total?: unknown };\n\t};\n\treturn {\n\t\tinput: typeof usage.input === \"number\" ? usage.input : 0,\n\t\toutput: typeof usage.output === \"number\" ? usage.output : 0,\n\t\tcacheRead: typeof usage.cacheRead === \"number\" ? usage.cacheRead : 0,\n\t\tcacheWrite: typeof usage.cacheWrite === \"number\" ? usage.cacheWrite : 0,\n\t\tcost: typeof usage.cost?.total === \"number\" ? usage.cost.total : 0,\n\t\tturns: 1,\n\t};\n}\n\nfunction isSubagentDetails(value: unknown): value is Details {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst details = value as { mode?: unknown; results?: unknown };\n\treturn typeof details.mode === \"string\" && Array.isArray(details.results);\n}\n\nfunction detailsFromSessionEntry(entry: unknown): Details | undefined {\n\tif (!entry || typeof entry !== \"object\") return undefined;\n\tconst record = entry as { type?: unknown; customType?: unknown; details?: unknown; message?: unknown };\n\tif (record.type === \"custom_message\" && record.customType === SLASH_RESULT_TYPE) {\n\t\tconst details = resolveSlashMessageDetails(record.details)?.result.details;\n\t\treturn isSubagentDetails(details) ? details : undefined;\n\t}\n\tif (record.type !== \"message\" || !record.message || typeof record.message !== \"object\") return undefined;\n\tconst message = record.message as { role?: unknown; toolName?: unknown; details?: unknown };\n\tif (message.role !== \"toolResult\" || message.toolName !== \"subagent\") return undefined;\n\treturn isSubagentDetails(message.details) ? message.details : undefined;\n}\n\nfunction formatCostUsage(label: string, usage: Usage): string {\n\tconst extras = [\n\t\tusage.cacheRead ? `cache read ${formatTokens(usage.cacheRead)}` : \"\",\n\t\tusage.cacheWrite ? `cache write ${formatTokens(usage.cacheWrite)}` : \"\",\n\t\tusage.turns ? `${usage.turns} turn${usage.turns === 1 ? \"\" : \"s\"}` : \"\",\n\t].filter(Boolean);\n\treturn `${label}: ↑${formatTokens(usage.input)} ↓${formatTokens(usage.output)} $${usage.cost.toFixed(4)}${extras.length ? ` (${extras.join(\", \")})` : \"\"}`;\n}\n\nfunction buildSubagentCostReport(ctx: ExtensionContext): string {\n\tconst parent = emptyUsage();\n\tconst childTotal = emptyUsage();\n\tconst total = emptyUsage();\n\tconst children: Array<{ label: string; usage: Usage; sessionFile?: string }> = [];\n\tfor (const entry of ctx.sessionManager.getBranch()) {\n\t\tconst message = entry.type === \"message\" ? (entry as { message?: unknown }).message : undefined;\n\t\tconst parentUsage = assistantUsageFromMessage(message);\n\t\tif (parentUsage) addUsage(parent, parentUsage);\n\t\tconst details = detailsFromSessionEntry(entry);\n\t\tif (!details) continue;\n\t\tfor (const result of details.results) {\n\t\t\tif (!usageHasValue(result.usage)) continue;\n\t\t\tconst usage = { ...result.usage };\n\t\t\tchildren.push({\n\t\t\t\tlabel: `Child ${children.length + 1} (${result.agent})`,\n\t\t\t\tusage,\n\t\t\t\t...(result.sessionFile ? { sessionFile: result.sessionFile } : {}),\n\t\t\t});\n\t\t\taddUsage(childTotal, usage);\n\t\t}\n\t}\n\taddUsage(total, parent);\n\taddUsage(total, childTotal);\n\tconst lines = [\n\t\t\"Subagent cost\",\n\t\t\"\",\n\t\tformatCostUsage(\"Parent\", parent),\n\t];\n\tif (children.length === 0) {\n\t\tlines.push(\"No subagent child usage found in this session.\");\n\t} else {\n\t\tfor (const child of children) {\n\t\t\tlines.push(formatCostUsage(child.label, child.usage));\n\t\t\tif (child.sessionFile) lines.push(` Session: ${child.sessionFile}`);\n\t\t}\n\t}\n\tlines.push(\"────────────────────────────\", formatCostUsage(\"Children\", childTotal), formatCostUsage(\"Total\", total));\n\treturn lines.join(\"\\n\");\n}\n\nasync function requestSlashRun(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\trequestId: string,\n\tparams: SubagentParamsLike,\n): Promise<SlashSubagentResponse> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet done = false;\n\t\tlet started = false;\n\n\t\tconst startTimeoutMs = 15_000;\n\t\tconst startTimeout = setTimeout(() => {\n\t\t\tfinish(() => reject(new Error(\n\t\t\t\t\"Slash subagent bridge did not start within 15s. Ensure the extension is loaded correctly.\",\n\t\t\t)));\n\t\t}, startTimeoutMs);\n\n\t\tconst onStarted = (data: unknown) => {\n\t\t\tif (done || !data || typeof data !== \"object\") return;\n\t\t\tif ((data as { requestId?: unknown }).requestId !== requestId) return;\n\t\t\tstarted = true;\n\t\t\tclearTimeout(startTimeout);\n\t\t\tif (ctx.hasUI) ctx.ui.setStatus(\"subagent-slash\", \"running...\");\n\t\t};\n\n\t\tconst onResponse = (data: unknown) => {\n\t\t\tif (done || !data || typeof data !== \"object\") return;\n\t\t\tconst response = data as Partial<SlashSubagentResponse>;\n\t\t\tif (response.requestId !== requestId) return;\n\t\t\tclearTimeout(startTimeout);\n\t\t\tfinish(() => resolve(response as SlashSubagentResponse));\n\t\t};\n\n\t\tconst onUpdate = (data: unknown) => {\n\t\t\tif (done || !data || typeof data !== \"object\") return;\n\t\t\tconst update = data as SlashSubagentUpdate;\n\t\t\tif (update.requestId !== requestId) return;\n\t\t\tapplySlashUpdate(requestId, update);\n\t\t\tif (!ctx.hasUI) return;\n\t\t\tconst tool = update.currentTool ? ` ${update.currentTool}` : \"\";\n\t\t\tconst count = update.toolCount ?? 0;\n\t\t\tconst liveDetailKey = keyText(\"app.tools.expand\");\n\t\t\tctx.ui.setStatus(\"subagent-slash\", `${count} tools${tool} | ${liveDetailKey} live detail`);\n\t\t};\n\n\t\tconst onTerminalInput = ctx.hasUI\n\t\t\t? ctx.ui.onTerminalInput((input) => {\n\t\t\t\tif (!matchesKey(input, Key.escape)) return undefined;\n\t\t\t\tpi.events.emit(SLASH_SUBAGENT_CANCEL_EVENT, { requestId });\n\t\t\t\tfinish(() => reject(new Error(\"Cancelled\")));\n\t\t\t\treturn { consume: true };\n\t\t\t})\n\t\t\t: undefined;\n\n\t\tconst unsubStarted = pi.events.on(SLASH_SUBAGENT_STARTED_EVENT, onStarted);\n\t\tconst unsubResponse = pi.events.on(SLASH_SUBAGENT_RESPONSE_EVENT, onResponse);\n\t\tconst unsubUpdate = pi.events.on(SLASH_SUBAGENT_UPDATE_EVENT, onUpdate);\n\n\t\tconst finish = (next: () => void) => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclearTimeout(startTimeout);\n\t\t\tunsubStarted();\n\t\t\tunsubResponse();\n\t\t\tunsubUpdate();\n\t\t\tonTerminalInput?.();\n\t\t\tnext();\n\t\t};\n\n\t\tpi.events.emit(SLASH_SUBAGENT_REQUEST_EVENT, { requestId, params, ctx });\n\n\t\t// Bridge emits STARTED synchronously during REQUEST emit.\n\t\t// If not started, no bridge received the request.\n\t\tif (!started && done) return;\n\t\tif (!started) {\n\t\t\tfinish(() => reject(new Error(\n\t\t\t\t\"No slash subagent bridge responded. Ensure the subagent extension is loaded correctly.\",\n\t\t\t)));\n\t\t}\n\t});\n}\n\nfunction extractSlashMessageText(content: string | Array<{ type?: string; text?: string }>): string {\n\tif (typeof content === \"string\") return content;\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.filter((part): part is { type: \"text\"; text: string } => part?.type === \"text\" && typeof part.text === \"string\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction formatExportPathList(paths: string[]): string {\n\treturn paths.map((file) => `- \\`${file}\\``).join(\"\\n\");\n}\n\nfunction collectResultPaths(results: SingleResult[], getPath: (result: SingleResult) => string | undefined): string[] {\n\treturn results\n\t\t.map(getPath)\n\t\t.filter((file): file is string => typeof file === \"string\" && file.length > 0);\n}\n\nfunction buildSlashExportText(response: SlashSubagentResponse): string {\n\tconst output = extractSlashMessageText(response.result.content) || response.errorText || \"(no output)\";\n\tconst results = response.result.details?.results ?? [];\n\tconst sessionFiles = collectResultPaths(results, (result) => result.sessionFile);\n\tconst savedOutputs = collectResultPaths(results, (result) => result.savedOutputPath);\n\tconst artifactOutputs = collectResultPaths(results, (result) => result.artifactPaths?.outputPath);\n\tconst sections = [\"## Subagent result\", output];\n\tif (sessionFiles.length > 0) sections.push(\"## Child session exports\", formatExportPathList(sessionFiles));\n\tif (savedOutputs.length > 0) sections.push(\"## Saved outputs\", formatExportPathList(savedOutputs));\n\tif (artifactOutputs.length > 0) sections.push(\"## Artifact outputs\", formatExportPathList(artifactOutputs));\n\treturn sections.join(\"\\n\\n\");\n}\n\nfunction persistSlashSessionSnapshot(ctx: ExtensionContext): void {\n\ttry {\n\t\tif (!ctx.sessionManager) return;\n\t\tconst sessionManager = ctx.sessionManager as typeof ctx.sessionManager & {\n\t\t\t_rewriteFile?: () => void;\n\t\t\tflushed?: boolean;\n\t\t};\n\t\tconst sessionFile = sessionManager.getSessionFile();\n\t\tif (!sessionFile || typeof sessionManager._rewriteFile !== \"function\") return;\n\t\tfs.mkdirSync(path.dirname(sessionFile), { recursive: true });\n\t\tsessionManager._rewriteFile();\n\t\tsessionManager.flushed = true;\n\t} catch (error) {\n\t\tconsole.error(\"Failed to persist slash session snapshot for export:\", error);\n\t}\n}\n\nasync function runSlashSubagent(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tparams: SubagentParamsLike,\n): Promise<void> {\n\tif (ctx.hasUI) ctx.ui.setToolsExpanded(false);\n\tconst requestId = randomUUID();\n\tconst initialDetails = buildSlashInitialResult(requestId, params);\n\tconst initialText = extractSlashMessageText(initialDetails.result.content) || \"Running subagent...\";\n\tpi.sendMessage({\n\t\tcustomType: SLASH_RESULT_TYPE,\n\t\tcontent: initialText,\n\t\tdisplay: true,\n\t\tdetails: initialDetails,\n\t});\n\tpersistSlashSessionSnapshot(ctx);\n\n\ttry {\n\t\tconst response = await requestSlashRun(pi, ctx, requestId, params);\n\t\tconst finalDetails = finalizeSlashResult(response);\n\t\tpi.sendMessage({\n\t\t\tcustomType: SLASH_RESULT_TYPE,\n\t\t\tcontent: buildSlashExportText(response),\n\t\t\tdisplay: !ctx.hasUI,\n\t\t\tdetails: finalDetails,\n\t\t});\n\t\tpersistSlashSessionSnapshot(ctx);\n\t\tif (ctx.hasUI) {\n\t\t\tctx.ui.setStatus(\"subagent-slash\", undefined);\n\t\t}\n\t\tif (response.isError && ctx.hasUI) {\n\t\t\tctx.ui.notify(response.errorText || \"Subagent failed\", \"error\");\n\t\t}\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst failedDetails = failSlashResult(requestId, params, message);\n\t\tpi.sendMessage({\n\t\t\tcustomType: SLASH_RESULT_TYPE,\n\t\t\tcontent: `## Subagent result\\n\\n${message}`,\n\t\t\tdisplay: !ctx.hasUI,\n\t\t\tdetails: failedDetails,\n\t\t});\n\t\tpersistSlashSessionSnapshot(ctx);\n\t\tif (ctx.hasUI) {\n\t\t\tctx.ui.setStatus(\"subagent-slash\", undefined);\n\t\t}\n\t\tif (message === \"Cancelled\") {\n\t\t\tif (ctx.hasUI) ctx.ui.notify(\"Cancelled\", \"warning\");\n\t\t\treturn;\n\t\t}\n\t\tif (ctx.hasUI) ctx.ui.notify(message, \"error\");\n\t}\n}\n\n\nexport interface GroupConfig { concurrency?: number; failFast?: boolean; worktree?: boolean }\nexport interface ParsedStep { kind: \"step\"; name: string; config: InlineConfig; task?: string }\nexport interface ParsedGroup { kind: \"group\"; tasks: ParsedStep[]; config: GroupConfig }\nexport type ParsedGroupStep = ParsedStep | ParsedGroup;\n\nexport const PARALLEL_GROUP_USAGE =\n\t'Usage: /chain agent \"task\" -> (agent2 \"task\" | agent3 \"task\") -> agent4';\n\nexport class SlashParseError extends Error {}\n\n// Walk `input` tracking quote/paren state; returns true if parens are unbalanced.\nfunction findUnmatchedCloseParen(input: string): boolean {\n\tlet depth = 0, inSingle = false, inDouble = false;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst ch = input[i]!;\n\t\tif (inSingle) { if (ch === \"'\") inSingle = false; continue; }\n\t\tif (inDouble) { if (ch === '\"') inDouble = false; continue; }\n\t\tif (ch === \"'\") { inSingle = true; continue; }\n\t\tif (ch === '\"') { inDouble = true; continue; }\n\t\tif (ch === \"(\") depth++;\n\t\telse if (ch === \")\") { depth--; if (depth < 0) return true; }\n\t}\n\treturn depth !== 0;\n}\n\n// Split on top-level \" -> \", ignoring arrows inside quotes or parentheses.\nfunction splitOnArrow(input: string): string[] {\n\tconst segments: string[] = [];\n\tlet depth = 0, inSingle = false, inDouble = false, start = 0;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst ch = input[i]!;\n\t\tif (inSingle) { if (ch === \"'\") inSingle = false; continue; }\n\t\tif (inDouble) { if (ch === '\"') inDouble = false; continue; }\n\t\tif (ch === \"'\") { inSingle = true; continue; }\n\t\tif (ch === '\"') { inDouble = true; continue; }\n\t\tif (ch === \"(\") depth++;\n\t\telse if (ch === \")\") depth--;\n\t\telse if (depth === 0 && ch === \"-\" && input[i + 1] === \">\" && input[i + 2] === \" \") {\n\t\t\tsegments.push(input.slice(start, i));\n\t\t\ti += 2;\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n\tsegments.push(input.slice(start));\n\treturn segments;\n}\n\n// Split a group's inner text on top-level \" | \", ignoring pipes inside quotes/parens.\nfunction splitGroupTasks(inner: string): string[] {\n\tconst parts: string[] = [];\n\tlet depth = 0, inSingle = false, inDouble = false, start = 0;\n\tfor (let i = 0; i < inner.length; i++) {\n\t\tconst ch = inner[i]!;\n\t\tif (inSingle) { if (ch === \"'\") inSingle = false; continue; }\n\t\tif (inDouble) { if (ch === '\"') inDouble = false; continue; }\n\t\tif (ch === \"'\") { inSingle = true; continue; }\n\t\tif (ch === '\"') { inDouble = true; continue; }\n\t\tif (ch === \"(\") depth++;\n\t\telse if (ch === \")\") depth--;\n\t\telse if (ch === \"|\" && depth === 0) {\n\t\t\tparts.push(inner.slice(start, i));\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n\tparts.push(inner.slice(start));\n\treturn parts;\n}\n\nexport function parseSingleTaskToken(token: string): ParsedStep {\n\tlet agentPart: string;\n\tlet task: string | undefined;\n\tconst qMatch = token.match(/^(\\S+(?:\\[[^\\]]*\\])?)\\s+(?:\"([^\"]*)\"|'([^']*)')$/);\n\tif (qMatch) {\n\t\tagentPart = qMatch[1]!;\n\t\ttask = (qMatch[2] ?? qMatch[3]) || undefined;\n\t} else {\n\t\tconst dashIdx = token.indexOf(\" -- \");\n\t\tif (dashIdx !== -1) {\n\t\t\tagentPart = token.slice(0, dashIdx).trim();\n\t\t\ttask = token.slice(dashIdx + 4).trim() || undefined;\n\t\t} else {\n\t\t\tagentPart = token;\n\t\t}\n\t}\n\treturn { kind: \"step\", ...parseAgentToken(agentPart), task };\n}\n\nconst parseGroupConfig = (raw: string): GroupConfig => {\n\tconst config: GroupConfig = {};\n\tfor (const part of raw.split(\",\")) {\n\t\tconst trimmed = part.trim();\n\t\tif (!trimmed) continue;\n\t\tconst eq = trimmed.indexOf(\"=\");\n\t\tconst key = eq === -1 ? trimmed : trimmed.slice(0, eq).trim();\n\t\tconst val = eq === -1 ? \"\" : trimmed.slice(eq + 1).trim();\n\t\tswitch (key) {\n\t\t\tcase \"concurrency\": { const n = Number(val); if (Number.isInteger(n) && n > 0) config.concurrency = n; break; }\n\t\t\tcase \"failFast\": config.failFast = eq === -1 ? true : val !== \"false\"; break;\n\t\t\tcase \"worktree\": config.worktree = eq === -1 ? true : val !== \"false\"; break;\n\t\t}\n\t}\n\treturn config;\n};\n\n// Split `(...)` from an optional trailing `[...]` group-config suffix, respecting\n// quotes and nested parens. Returns the inner group text and the parsed config.\nconst splitGroupBody = (trimmed: string): { inner: string; config: GroupConfig } => {\n\tlet depth = 0, inSingle = false, inDouble = false, closeIdx = -1;\n\tfor (let i = 0; i < trimmed.length; i++) {\n\t\tconst ch = trimmed[i]!;\n\t\tif (inSingle) { if (ch === \"'\") inSingle = false; continue; }\n\t\tif (inDouble) { if (ch === '\"') inDouble = false; continue; }\n\t\tif (ch === \"'\") { inSingle = true; continue; }\n\t\tif (ch === '\"') { inDouble = true; continue; }\n\t\tif (ch === \"(\") depth++;\n\t\telse if (ch === \")\") { depth--; if (depth === 0) { closeIdx = i; break; } }\n\t}\n\tif (closeIdx === -1) throw new SlashParseError(`Unmatched parentheses in group: '${trimmed}'`);\n\tconst inner = trimmed.slice(1, closeIdx);\n\tconst suffix = trimmed.slice(closeIdx + 1).trim();\n\tif (!suffix) return { inner, config: {} };\n\tif (!suffix.startsWith(\"[\") || !suffix.endsWith(\"]\")) {\n\t\tthrow new SlashParseError(`Group options must be wrapped in [...]: '${suffix}'`);\n\t}\n\treturn { inner, config: parseGroupConfig(suffix.slice(1, -1)) };\n};\n\nexport function parseGroupSegment(segment: string): ParsedGroup {\n\tconst trimmed = segment.trim();\n\tif (!trimmed.startsWith(\"(\")) {\n\t\tthrow new SlashParseError(`Parallel group must be wrapped in parentheses: '${trimmed}'`);\n\t}\n\tconst { inner, config } = splitGroupBody(trimmed);\n\tconst rawParts = splitGroupTasks(inner).map((p) => p.trim()).filter((p) => p.length > 0);\n\tif (rawParts.length < 2) {\n\t\tthrow new SlashParseError(\"Parallel group must contain at least two tasks separated by ' | '\");\n\t}\n\treturn { kind: \"group\", tasks: rawParts.map((part) => parseSingleTaskToken(part)), config };\n}\n\n// True if `input` uses inline parallel-group syntax. A group is a *step* that begins\n// with `(` at the top level, so we split on top-level ` -> ` arrows and look for a\n// segment that opens with `(`. Parentheses appearing inside a task (e.g.\n// `scout -- inspect auth (backend)`) do not count, which keeps legacy shared-task\n// `-- task` parsing — including a bare `|` inside the task — on the single-agent path.\nexport function hasGroupSyntax(input: string): boolean {\n\treturn splitOnArrow(input).some((seg) => seg.trim().startsWith(\"(\"));\n}\n\nexport function parseChainExpression(input: string): { steps: ParsedGroupStep[] } {\n\tconst trimmed = input.trim();\n\tif (!trimmed.includes(\" -> \")) {\n\t\tthrow new SlashParseError('Parallel groups in /chain require \" -> \" between steps');\n\t}\n\tif (findUnmatchedCloseParen(trimmed)) {\n\t\tthrow new SlashParseError(\"Unmatched parentheses in /chain expression\");\n\t}\n\tconst steps: ParsedGroupStep[] = [];\n\tfor (const seg of splitOnArrow(trimmed)) {\n\t\tconst t = seg.trim();\n\t\tif (!t) continue;\n\t\tif (t.startsWith(\"(\")) {\n\t\t\tsteps.push(parseGroupSegment(t));\n\t\t\tcontinue;\n\t\t}\n\t\tif (findUnmatchedCloseParen(t)) {\n\t\t\tthrow new SlashParseError(`Unmatched parentheses in chain segment: '${t}'`);\n\t\t}\n\t\tsteps.push(parseSingleTaskToken(t));\n\t}\n\tif (steps.length === 0) {\n\t\tthrow new SlashParseError(\"/chain expression must include at least one step\");\n\t}\n\treturn { steps };\n}\n\nconst parseAgentArgs = (\n\tstate: SubagentState,\n\targs: string,\n\tcommand: string,\n\tctx: ExtensionContext,\n): { steps: ParsedStep[]; task: string } | null => {\n\tconst input = args.trim();\n\tconst usage = `Usage: /${command} description1 \"task1\" -> description2 \"task2\"`;\n\tlet steps: ParsedStep[];\n\tlet sharedTask: string;\n\tlet perStep = false;\n\n\tif (input.includes(\" -> \")) {\n\t\tperStep = true;\n\t\tconst segments = input.split(\" -> \");\n\t\tsteps = [];\n\t\tfor (const seg of segments) {\n\t\t\tconst trimmed = seg.trim();\n\t\t\tif (!trimmed) continue;\n\t\t\tsteps.push(parseSingleTaskToken(trimmed));\n\t\t}\n\t\tsharedTask = steps.find((s) => s.task)?.task ?? \"\";\n\t} else {\n\t\tconst delimiterIndex = input.indexOf(\" -- \");\n\t\tif (delimiterIndex === -1) {\n\t\t\tctx.ui.notify(usage, \"error\");\n\t\t\treturn null;\n\t\t}\n\t\tconst agentsPart = input.slice(0, delimiterIndex).trim();\n\t\tsharedTask = input.slice(delimiterIndex + 4).trim();\n\t\tif (!agentsPart || !sharedTask) {\n\t\t\tctx.ui.notify(usage, \"error\");\n\t\t\treturn null;\n\t\t}\n\t\tsteps = agentsPart.split(/\\s+/).filter(Boolean).map((t) => parseSingleTaskToken(t));\n\t}\n\n\tif (steps.length === 0) {\n\t\tctx.ui.notify(usage, \"error\");\n\t\treturn null;\n\t}\n\tif (!state.baseCwd) {\n\t\tctx.ui.notify(\"Subagent session cwd is not initialized yet\", \"error\");\n\t\treturn null;\n\t}\n\tif (command === \"chain\" && !steps[0]?.task && (perStep || !sharedTask)) {\n\t\tctx.ui.notify(`First step must have a task: /chain description \"task\" -> description2`, \"error\");\n\t\treturn null;\n\t}\n\tif (command === \"parallel\" && !steps.some((s) => s.task) && !sharedTask) {\n\t\tctx.ui.notify(\"At least one step must have a task\", \"error\");\n\t\treturn null;\n\t}\n\treturn { steps, task: sharedTask };\n};\n\ntype ChainStepObject = {\n\tdescription: string;\n\tpermissions: \"full\" | \"read-only\";\n\ttier: \"light\" | \"standard\" | \"heavy\";\n\ttask?: string;\n\toutput?: string | false;\n\toutputMode?: \"inline\" | \"file-only\";\n\treads?: string[] | false;\n\tskill?: string[] | false;\n\tprogress?: boolean;\n\tas?: string;\n\tlabel?: string;\n\tphase?: string;\n\tcwd?: string;\n\tcount?: number;\n\toutputSchema?: JsonSchemaObject;\n\tacceptance?: string;\n};\n\nconst INLINE_ACCEPTANCE_LEVELS = new Set([\"auto\", \"attested\", \"checked\"]);\n\nfunction validateInlineAcceptanceInput(value: string, agent: string): void {\n\tconst errors = validateAcceptanceInput(value, `acceptance for step '${agent}'`);\n\tif (errors.length > 0) throw new SlashParseError(errors[0]!);\n\tif (!INLINE_ACCEPTANCE_LEVELS.has(value)) {\n\t\tthrow new SlashParseError(`Inline acceptance for step '${agent}' supports auto, attested, or checked. Use the subagent tool API or a saved .chain.json file for none or verified acceptance contracts; reviewed is inferred-only.`);\n\t}\n}\n\n// Load an inline `outputSchema=<path>` JSON file, resolved against the session cwd.\n// Throws (SlashParseError / fs / JSON) on a missing or malformed schema.\nfunction loadInlineOutputSchema(baseCwd: string, agent: string, value: string): JsonSchemaObject {\n\tconst schemaPath = path.isAbsolute(value) ? value : path.join(baseCwd, value);\n\tconst label = `outputSchema for step '${agent}' (${schemaPath})`;\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(fs.readFileSync(schemaPath, \"utf-8\"));\n\t} catch (error) {\n\t\tthrow new SlashParseError(`Cannot read ${label}: ${error instanceof Error ? error.message : String(error)}`);\n\t}\n\tassertJsonSchemaObject(parsed, label);\n\treturn parsed;\n}\n\n// Build a ChainStep object from a parsed token. `inGroup` enables `count` (parallel-only).\n// May throw SlashParseError for an invalid acceptance level or outputSchema path.\nconst mapParsedTaskToStepObject = (\n\tstep: ParsedStep,\n\tfallbackTask: string | undefined,\n\tisFirst: boolean,\n\topts: { baseCwd: string; inGroup: boolean },\n): ChainStepObject => {\n\tconst { name, config, task: stepTask } = step;\n\tif (!config.tier && !config.model) throw new SlashParseError(`Step '${name}' requires tier=light|standard|heavy or model=provider/id.`);\n\tif (config.tier && config.model) throw new SlashParseError(`Step '${name}' must choose exactly one of tier or model.`);\n\tif (config.acceptance !== undefined) validateInlineAcceptanceInput(config.acceptance, name);\n\treturn {\n\t\tdescription: name,\n\t\tpermissions: config.permissions ?? \"full\",\n\t\t...(config.tier ? { tier: config.tier } : {}),\n\t\t...(config.model ? { model: config.model } : {}),\n\t\t...(config.thinking ? { thinking: config.thinking } : {}),\n\t\t...(stepTask ? { task: stepTask } : isFirst && fallbackTask ? { task: fallbackTask } : {}),\n\t\t...(config.output !== undefined ? { output: config.output } : {}),\n\t\t...(config.outputMode !== undefined ? { outputMode: config.outputMode } : {}),\n\t\t...(config.reads !== undefined ? { reads: config.reads } : {}),\n\t\t...(config.skill !== undefined ? { skill: config.skill } : {}),\n\t\t...(config.progress !== undefined ? { progress: config.progress } : {}),\n\t\t...(config.as ? { as: config.as } : {}),\n\t\t...(config.label ? { label: config.label } : {}),\n\t\t...(config.phase ? { phase: config.phase } : {}),\n\t\t...(config.cwd ? { cwd: config.cwd } : {}),\n\t\t...(opts.inGroup && config.count !== undefined ? { count: config.count } : {}),\n\t\t...(config.outputSchema ? { outputSchema: loadInlineOutputSchema(opts.baseCwd, name, config.outputSchema) } : {}),\n\t\t...(config.acceptance ? { acceptance: config.acceptance } : {}),\n\t};\n};\n\nexport function buildChainExpressionSteps(\n\tstate: SubagentState,\n\tinput: string,\n\tctx: ExtensionContext,\n): { chain: ChainStep[]; task: string } | null {\n\tconst notify = (message: string) => ctx.ui.notify(message, \"error\");\n\tif (!hasGroupSyntax(input)) {\n\t\tconst parsed = parseAgentArgs(state, input, \"chain\", ctx);\n\t\tif (!parsed) return null;\n\t\tconst baseCwd = state.baseCwd!; // parseAgentArgs already verified baseCwd is set\n\t\ttry {\n\t\t\tconst chain: ChainStep[] = parsed.steps.map((step, i) =>\n\t\t\t\tmapParsedTaskToStepObject(step, parsed.task || undefined, i === 0, { baseCwd, inGroup: false }),\n\t\t\t);\n\t\t\treturn { chain, task: parsed.task };\n\t\t} catch (error) {\n\t\t\tnotify(error instanceof Error ? error.message : String(error));\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tlet expression: { steps: ParsedGroupStep[] };\n\ttry {\n\t\texpression = parseChainExpression(input);\n\t} catch (error) {\n\t\tnotify(error instanceof Error ? error.message : String(error));\n\t\treturn null;\n\t}\n\tif (!state.baseCwd) {\n\t\tnotify(\"Subagent session cwd is not initialized yet\");\n\t\treturn null;\n\t}\n\t// Every task inside a parallel group needs its own task; there is no shared-task fallback.\n\tfor (const step of expression.steps) {\n\t\tif (step.kind === \"group\" && step.tasks.some((t) => !t.task)) {\n\t\t\tnotify('Each child in a parallel group needs a task: (description \"a\" | description2 \"b\")');\n\t\t\treturn null;\n\t\t}\n\t}\n\tconst firstStep = expression.steps[0]!;\n\tconst firstHasTask =\n\t\tfirstStep.kind === \"group\"\n\t\t\t? firstStep.tasks.some((t) => Boolean(t.task))\n\t\t\t: Boolean(firstStep.task);\n\tif (!firstHasTask) {\n\t\tnotify('First step must have a task: /chain description \"task\" -> description2');\n\t\treturn null;\n\t}\n\tconst sharedTask =\n\t\tfirstStep.kind === \"group\"\n\t\t\t? (firstStep.tasks.find((t) => t.task)?.task ?? \"\")\n\t\t\t: (firstStep.task ?? \"\");\n\tconst baseCwd = state.baseCwd;\n\tlet chain: ChainStep[];\n\ttry {\n\t\tchain = expression.steps.map((step) => {\n\t\t\tif (step.kind === \"group\") {\n\t\t\t\tconst parallel = step.tasks.map((t) => mapParsedTaskToStepObject(t, undefined, false, { baseCwd, inGroup: true }));\n\t\t\t\treturn {\n\t\t\t\t\tparallel,\n\t\t\t\t\t...(step.config.concurrency !== undefined ? { concurrency: step.config.concurrency } : {}),\n\t\t\t\t\t...(step.config.failFast !== undefined ? { failFast: step.config.failFast } : {}),\n\t\t\t\t\t...(step.config.worktree !== undefined ? { worktree: step.config.worktree } : {}),\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn mapParsedTaskToStepObject(step, sharedTask || undefined, false, { baseCwd, inGroup: false });\n\t\t});\n\t} catch (error) {\n\t\tnotify(error instanceof Error ? error.message : String(error));\n\t\treturn null;\n\t}\n\treturn { chain, task: sharedTask };\n}\n\nexport function registerSlashCommands(\n\tpi: ExtensionAPI,\n\tstate: SubagentState,\n): void {\n\tlet fleetOpen = false;\n\tconst showFleet = async (ctx: ExtensionContext) => {\n\t\tstate.lastUiContext = ctx;\n\t\tif (!ctx.hasUI) {\n\t\t\tawait runSlashSubagent(pi, ctx, { action: \"status\", view: \"fleet\" });\n\t\t\treturn;\n\t\t}\n\t\tif (fleetOpen) {\n\t\t\tctx.ui.notify(\"Subagent fleet inspector is already open.\", \"info\");\n\t\t\treturn;\n\t\t}\n\t\tfleetOpen = true;\n\t\ttry {\n\t\t\tawait openSubagentFleet(ctx, state);\n\t\t} finally {\n\t\t\tfleetOpen = false;\n\t\t}\n\t};\n\n\tpi.registerCommand(\"run\", {\n\t\tdescription: \"Run a prompt-defined child: /run description[tier=standard] task [--bg]\",\n\t\thandler: async (args, ctx) => {\n\t\t\tconst { args: cleanedArgs, bg } = extractExecutionFlags(args);\n\t\t\tconst input = cleanedArgs.trim();\n\t\t\tconst firstSpace = input.indexOf(\" \");\n\t\t\tif (!input) { ctx.ui.notify(\"Usage: /run <description> <task> [--bg]\", \"error\"); return; }\n\t\t\tconst { name: description, config: inline } = parseAgentToken(firstSpace === -1 ? input : input.slice(0, firstSpace));\n\t\t\tconst task = firstSpace === -1 ? \"\" : input.slice(firstSpace + 1).trim();\n\t\t\tif (!description || !task || !inline.tier) { ctx.ui.notify(\"Usage: /run <description>[tier=light|standard|heavy] <task> [--bg]\", \"error\"); return; }\n\n\t\t\tlet finalTask = task;\n\t\t\tif (inline.reads && Array.isArray(inline.reads) && inline.reads.length > 0) {\n\t\t\t\tfinalTask = `[Read from: ${inline.reads.join(\", \")}]\\n\\n${finalTask}`;\n\t\t\t}\n\t\t\tconst params: SubagentParamsLike = { description, permissions: inline.permissions ?? \"full\", tier: inline.tier, task: finalTask, clarify: false };\n\t\t\tif (inline.output !== undefined) params.output = inline.output;\n\t\t\tif (inline.outputMode !== undefined) params.outputMode = inline.outputMode;\n\t\t\tif (inline.skill !== undefined) params.skill = inline.skill;\n\t\t\tif (bg) params.async = true;\n\t\t\tawait runSlashSubagent(pi, ctx, params);\n\t\t},\n\t});\n\n\tpi.registerCommand(\"chain\", {\n\t\tdescription: \"Run prompt-defined children in sequence: /chain inspect \\\"task\\\" -> implement [--bg]\",\n\t\thandler: async (args, ctx) => {\n\t\t\tconst { args: cleanedArgs, bg } = extractExecutionFlags(args);\n\t\t\tconst built = buildChainExpressionSteps(state, cleanedArgs, ctx);\n\t\t\tif (!built) return;\n\t\t\tconst params: SubagentParamsLike = { chain: built.chain, task: built.task, clarify: false };\n\t\t\tif (bg) params.async = true;\n\t\t\tawait runSlashSubagent(pi, ctx, params);\n\t\t},\n\t});\n\n\tpi.registerCommand(\"parallel\", {\n\t\tdescription: \"Run prompt-defined children in parallel: /parallel inspect \\\"task1\\\" -> review \\\"task2\\\" [--bg]\",\n\t\thandler: async (args, ctx) => {\n\t\t\tconst { args: cleanedArgs, bg } = extractExecutionFlags(args);\n\t\t\tconst parsed = parseAgentArgs(state, cleanedArgs, \"parallel\", ctx);\n\t\t\tif (!parsed) return;\n\t\t\tconst tasks = parsed.steps.map(({ name, config, task: stepTask }) => ({\n\t\t\t\tdescription: name,\n\t\t\t\tpermissions: config.permissions ?? \"full\" as const,\n\t\t\t\t...(config.tier ? { tier: config.tier } : {}),\n\t\t\t\t...(config.model ? { model: config.model } : {}),\n\t\t\t\t...(config.thinking ? { thinking: config.thinking } : {}),\n\t\t\t\ttask: stepTask ?? parsed.task,\n\t\t\t\t...(config.output !== undefined ? { output: config.output } : {}),\n\t\t\t\t...(config.outputMode !== undefined ? { outputMode: config.outputMode } : {}),\n\t\t\t\t...(config.reads !== undefined ? { reads: config.reads } : {}),\n\t\t\t\t...(config.skill !== undefined ? { skill: config.skill } : {}),\n\t\t\t\t...(config.progress !== undefined ? { progress: config.progress } : {}),\n\t\t\t}));\n\t\t\tif (tasks.some((task) => !task.tier && !task.model)) { ctx.ui.notify(\"Every parallel child requires [tier=light|standard|heavy] or [model=provider/id].\", \"error\"); return; }\n\t\t\tif (tasks.some((task) => task.tier && task.model)) { ctx.ui.notify(\"Each parallel child must choose exactly one of tier or model.\", \"error\"); return; }\n\t\t\tconst params: SubagentParamsLike = { tasks, clarify: false };\n\t\t\tif (bg) params.async = true;\n\t\t\tawait runSlashSubagent(pi, ctx, params);\n\t\t},\n\t});\n\n\tpi.registerCommand(\"subagent-cost\", {\n\t\tdescription: \"Show parent and subagent child usage cost for this session\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tsendSlashText(pi, buildSubagentCostReport(ctx));\n\t\t},\n\t});\n\n\tpi.registerCommand(\"subagents-doctor\", {\n\t\tdescription: \"Show subagent diagnostics\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tawait runSlashSubagent(pi, ctx, { action: \"doctor\" });\n\t\t},\n\t});\n\n\tpi.registerCommand(\"subagents-fleet\", {\n\t\tdescription: \"Open the live, inspection-only subagent fleet\",\n\t\thandler: async (_args, ctx) => showFleet(ctx),\n\t});\n\n\tpi.registerShortcut(Key.ctrlAlt(\"f\"), {\n\t\tdescription: \"Open subagent fleet inspector\",\n\t\thandler: async (ctx) => showFleet(ctx),\n\t});\n\n\tpi.registerCommand(\"subagents-stop\", {\n\t\tdescription: \"Stop a current-session async subagent run\",\n\t\thandler: async (args, ctx) => {\n\t\t\tconst id = args.trim();\n\t\t\tif (id) {\n\t\t\t\tawait runSlashSubagent(pi, ctx, { action: \"stop\", id });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (process.env[SUBAGENT_FANOUT_CHILD_ENV] === \"1\") {\n\t\t\t\tsendSlashText(pi, \"Selector unavailable in child-safe fanout mode. Pass an explicit current-session top-level async run id, for example `/subagents-stop <run-id>` or `subagent({ action: \\\"stop\\\", id: \\\"<run-id>\\\" })`.\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet targets: StopSelectorTarget[];\n\t\t\ttry {\n\t\t\t\ttargets = discoverStopTargets(ctx, state);\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tctx.ui.notify(message, \"error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!ctx.hasUI) {\n\t\t\t\tsendSlashText(pi, stopFallbackText(targets));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (targets.length === 0) {\n\t\t\t\tctx.ui.notify(\"No active current-session async runs or scheduled subagent runs to stop.\", \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst result = await ctx.ui.custom<StopSelectorResult>(\n\t\t\t\t(tui, theme, _kb, done) => new SubagentsStopSelector(tui, theme, targets, done),\n\t\t\t\t{ overlay: true, overlayOptions: { anchor: \"center\", width: 88, maxHeight: \"80%\" } },\n\t\t\t);\n\t\t\tif (!result?.confirmed || !result.target) return;\n\t\t\tif (result.target.kind === \"scheduled\") {\n\t\t\t\tawait runSlashSubagent(pi, ctx, { action: \"schedule-cancel\", id: result.target.id });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runSlashSubagent(pi, ctx, { action: \"stop\", id: result.target.id });\n\t\t},\n\t});\n\n\tregisterPromptWorkflowCommands({\n\t\tpi,\n\t\trun: (params, ctx) => runSlashSubagent(pi, ctx, params),\n\t});\n\n}\n"]}