@ashx-j/lunr 0.2.25 → 0.2.27

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 (729) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/LICENSE +22 -0
  3. package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -1
  4. package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-thinking.js +1 -1
  6. package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
  7. package/dist/builtin-extensions/ashxj-tui.d.ts +11 -1
  8. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  9. package/dist/builtin-extensions/ashxj-tui.js +6 -10
  10. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  11. package/dist/builtin-extensions/index.d.ts.map +1 -1
  12. package/dist/builtin-extensions/index.js +1 -0
  13. package/dist/builtin-extensions/index.js.map +1 -1
  14. package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
  15. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
  16. package/dist/builtin-extensions/lunr-computer-use.js +179 -0
  17. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
  18. package/dist/builtin-extensions/lunr-cron.d.ts +4 -5
  19. package/dist/builtin-extensions/lunr-cron.d.ts.map +1 -1
  20. package/dist/builtin-extensions/lunr-cron.js +94 -108
  21. package/dist/builtin-extensions/lunr-cron.js.map +1 -1
  22. package/dist/builtin-extensions/lunr-local-providers/local-servers.d.ts.map +1 -1
  23. package/dist/builtin-extensions/lunr-local-providers/local-servers.js +3 -1
  24. package/dist/builtin-extensions/lunr-local-providers/local-servers.js.map +1 -1
  25. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.d.ts.map +1 -1
  26. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js +2 -2
  27. package/dist/builtin-extensions/narumiruna-pi-goal/src/commands.js.map +1 -1
  28. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  29. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +1 -1
  30. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  31. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.d.ts.map +1 -1
  32. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js +1 -1
  33. package/dist/builtin-extensions/narumiruna-pi-goal/src/runtime.js.map +1 -1
  34. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-intercom/index.js +2 -2
  36. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  37. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts +1 -1
  38. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.d.ts.map +1 -1
  39. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js +1 -1
  40. package/dist/builtin-extensions/pi-lsp-extension/bemol-extension/index.js.map +1 -1
  41. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  42. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +1 -15
  43. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  44. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts +6 -0
  45. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.d.ts.map +1 -1
  46. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js +187 -132
  47. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-client.js.map +1 -1
  48. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts +8 -0
  49. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js +142 -112
  51. package/dist/builtin-extensions/pi-lsp-extension/src/lsp-manager.js.map +1 -1
  52. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts +12 -1
  53. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.d.ts.map +1 -1
  54. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js +14 -7
  55. package/dist/builtin-extensions/pi-lsp-extension/src/tools/code-rewrite.js.map +1 -1
  56. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts +11 -3
  57. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.d.ts.map +1 -1
  58. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js +67 -41
  59. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/rewrite-engine.js.map +1 -1
  60. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts +4 -2
  61. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.d.ts.map +1 -1
  62. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js +3 -0
  63. package/dist/builtin-extensions/pi-lsp-extension/src/tree-sitter/search-engine.js.map +1 -1
  64. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts +2 -1
  65. package/dist/builtin-extensions/pi-mcp-adapter/commands.d.ts.map +1 -1
  66. package/dist/builtin-extensions/pi-mcp-adapter/commands.js +6 -6
  67. package/dist/builtin-extensions/pi-mcp-adapter/commands.js.map +1 -1
  68. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts +1 -1
  69. package/dist/builtin-extensions/pi-mcp-adapter/config.d.ts.map +1 -1
  70. package/dist/builtin-extensions/pi-mcp-adapter/config.js +11 -5
  71. package/dist/builtin-extensions/pi-mcp-adapter/config.js.map +1 -1
  72. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -1
  73. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +2 -2
  74. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -1
  75. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.d.ts.map +1 -1
  76. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js +1 -1
  77. package/dist/builtin-extensions/pi-mcp-adapter/host-html-template.js.map +1 -1
  78. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-mcp-adapter/index.js +48 -40
  80. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  81. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  82. package/dist/builtin-extensions/pi-mcp-adapter/init.js +3 -1
  83. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  84. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts +12 -40
  85. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.d.ts.map +1 -1
  86. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js +166 -235
  87. package/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js.map +1 -1
  88. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts +5 -0
  89. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js +43 -13
  91. package/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js.map +1 -1
  92. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts +14 -3
  93. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.d.ts.map +1 -1
  94. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js +73 -21
  95. package/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js.map +1 -1
  96. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js +4 -4
  98. package/dist/builtin-extensions/pi-mcp-adapter/proxy-modes.js.map +1 -1
  99. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  100. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +2 -2
  101. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  102. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts +2 -0
  103. package/dist/builtin-extensions/pi-mcp-adapter/state.d.ts.map +1 -1
  104. package/dist/builtin-extensions/pi-mcp-adapter/state.js.map +1 -1
  105. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts +1 -1
  106. package/dist/builtin-extensions/pi-ollama-cloud/index.d.ts.map +1 -1
  107. package/dist/builtin-extensions/pi-ollama-cloud/index.js +1 -1
  108. package/dist/builtin-extensions/pi-ollama-cloud/index.js.map +1 -1
  109. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts +11 -5
  110. package/dist/builtin-extensions/pi-ollama-cloud/models.d.ts.map +1 -1
  111. package/dist/builtin-extensions/pi-ollama-cloud/models.js +12 -32
  112. package/dist/builtin-extensions/pi-ollama-cloud/models.js.map +1 -1
  113. package/dist/builtin-extensions/pi-prompt-template-model/index.d.ts.map +1 -1
  114. package/dist/builtin-extensions/pi-prompt-template-model/index.js +5 -3
  115. package/dist/builtin-extensions/pi-prompt-template-model/index.js.map +1 -1
  116. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts +2 -1
  117. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  118. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +21 -12
  119. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  120. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  121. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +7 -24
  122. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  123. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  124. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +39 -77
  125. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  126. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  127. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +1 -1
  128. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  129. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -4
  130. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  131. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +8 -5
  132. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  133. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +1 -1
  134. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  135. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +15 -31
  136. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  137. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  138. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +7 -2
  139. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  140. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +1 -0
  141. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  142. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +21 -4
  143. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  144. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  145. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +11 -4
  146. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  147. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  148. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +121 -25
  149. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  150. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  151. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +25 -5
  152. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  153. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts +1 -0
  154. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts.map +1 -1
  155. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js +5 -0
  156. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js.map +1 -1
  157. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  158. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  159. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
  160. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  161. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +1 -1
  162. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  163. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +1 -1
  164. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  165. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +7 -8
  166. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  167. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js +60 -32
  168. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  169. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts +1 -1
  170. package/dist/builtin-extensions/pi-subagents/src/shared/utils.d.ts.map +1 -1
  171. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js +15 -5
  172. package/dist/builtin-extensions/pi-subagents/src/shared/utils.js.map +1 -1
  173. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  174. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +4 -3
  175. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  176. package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
  177. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +1 -1
  178. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
  179. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -1
  180. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  181. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +22 -11
  182. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  183. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  184. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +3 -3
  185. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  186. package/dist/builtin-extensions/pi-tps.d.ts.map +1 -1
  187. package/dist/builtin-extensions/pi-tps.js +20 -17
  188. package/dist/builtin-extensions/pi-tps.js.map +1 -1
  189. package/dist/builtin-extensions/pi-web-access/activity.d.ts +1 -0
  190. package/dist/builtin-extensions/pi-web-access/activity.d.ts.map +1 -1
  191. package/dist/builtin-extensions/pi-web-access/activity.js +27 -5
  192. package/dist/builtin-extensions/pi-web-access/activity.js.map +1 -1
  193. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts +3 -0
  194. package/dist/builtin-extensions/pi-web-access/bounded-body.d.ts.map +1 -0
  195. package/dist/builtin-extensions/pi-web-access/bounded-body.js +43 -0
  196. package/dist/builtin-extensions/pi-web-access/bounded-body.js.map +1 -0
  197. package/dist/builtin-extensions/pi-web-access/content-page.d.ts +24 -0
  198. package/dist/builtin-extensions/pi-web-access/content-page.d.ts.map +1 -0
  199. package/dist/builtin-extensions/pi-web-access/content-page.js +57 -0
  200. package/dist/builtin-extensions/pi-web-access/content-page.js.map +1 -0
  201. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  202. package/dist/builtin-extensions/pi-web-access/extract.js +7 -2
  203. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  204. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts +0 -1
  205. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  206. package/dist/builtin-extensions/pi-web-access/github-extract.js +147 -36
  207. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  208. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  209. package/dist/builtin-extensions/pi-web-access/index.js +48 -73
  210. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  211. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +12 -4
  212. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -1
  213. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +35 -12
  214. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -1
  215. package/dist/builtin-extensions/pi-web-access/storage.d.ts +9 -6
  216. package/dist/builtin-extensions/pi-web-access/storage.d.ts.map +1 -1
  217. package/dist/builtin-extensions/pi-web-access/storage.js +36 -24
  218. package/dist/builtin-extensions/pi-web-access/storage.js.map +1 -1
  219. package/dist/builtin-extensions/simple-pi-memory.d.ts +1 -1
  220. package/dist/builtin-extensions/simple-pi-memory.d.ts.map +1 -1
  221. package/dist/builtin-extensions/simple-pi-memory.js +1 -1
  222. package/dist/builtin-extensions/simple-pi-memory.js.map +1 -1
  223. package/dist/cli/install-cli.d.ts.map +1 -1
  224. package/dist/cli/install-cli.js +38 -30
  225. package/dist/cli/install-cli.js.map +1 -1
  226. package/dist/core/agent-session-runtime.d.ts +13 -0
  227. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  228. package/dist/core/agent-session-runtime.js +75 -11
  229. package/dist/core/agent-session-runtime.js.map +1 -1
  230. package/dist/core/agent-session-services.d.ts +1 -0
  231. package/dist/core/agent-session-services.d.ts.map +1 -1
  232. package/dist/core/agent-session-services.js +1 -0
  233. package/dist/core/agent-session-services.js.map +1 -1
  234. package/dist/core/agent-session.d.ts +40 -6
  235. package/dist/core/agent-session.d.ts.map +1 -1
  236. package/dist/core/agent-session.js +309 -76
  237. package/dist/core/agent-session.js.map +1 -1
  238. package/dist/core/browser/runtime.d.ts +2 -0
  239. package/dist/core/browser/runtime.d.ts.map +1 -1
  240. package/dist/core/browser/runtime.js +80 -45
  241. package/dist/core/browser/runtime.js.map +1 -1
  242. package/dist/core/browser/setup.d.ts.map +1 -1
  243. package/dist/core/browser/setup.js +12 -1
  244. package/dist/core/browser/setup.js.map +1 -1
  245. package/dist/core/computer-use/adapter.d.ts +28 -0
  246. package/dist/core/computer-use/adapter.d.ts.map +1 -0
  247. package/dist/core/computer-use/adapter.js +138 -0
  248. package/dist/core/computer-use/adapter.js.map +1 -0
  249. package/dist/core/computer-use/image.d.ts +27 -0
  250. package/dist/core/computer-use/image.d.ts.map +1 -0
  251. package/dist/core/computer-use/image.js +84 -0
  252. package/dist/core/computer-use/image.js.map +1 -0
  253. package/dist/core/computer-use/lease.d.ts +18 -0
  254. package/dist/core/computer-use/lease.d.ts.map +1 -0
  255. package/dist/core/computer-use/lease.js +129 -0
  256. package/dist/core/computer-use/lease.js.map +1 -0
  257. package/dist/core/computer-use/macos-runtime.d.ts +14 -0
  258. package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
  259. package/dist/core/computer-use/macos-runtime.js +148 -0
  260. package/dist/core/computer-use/macos-runtime.js.map +1 -0
  261. package/dist/core/computer-use/policy.d.ts +19 -0
  262. package/dist/core/computer-use/policy.d.ts.map +1 -0
  263. package/dist/core/computer-use/policy.js +67 -0
  264. package/dist/core/computer-use/policy.js.map +1 -0
  265. package/dist/core/computer-use/release.generated.d.ts +31 -0
  266. package/dist/core/computer-use/release.generated.d.ts.map +1 -0
  267. package/dist/core/computer-use/release.generated.js +36 -0
  268. package/dist/core/computer-use/release.generated.js.map +1 -0
  269. package/dist/core/computer-use/runtime.d.ts +13 -0
  270. package/dist/core/computer-use/runtime.d.ts.map +1 -0
  271. package/dist/core/computer-use/runtime.js +158 -0
  272. package/dist/core/computer-use/runtime.js.map +1 -0
  273. package/dist/core/computer-use/schemas.d.ts +100 -0
  274. package/dist/core/computer-use/schemas.d.ts.map +1 -0
  275. package/dist/core/computer-use/schemas.js +96 -0
  276. package/dist/core/computer-use/schemas.js.map +1 -0
  277. package/dist/core/computer-use/windows-desktop.d.ts +3 -0
  278. package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
  279. package/dist/core/computer-use/windows-desktop.js +48 -0
  280. package/dist/core/computer-use/windows-desktop.js.map +1 -0
  281. package/dist/core/computer-use/workflow.d.ts +38 -0
  282. package/dist/core/computer-use/workflow.d.ts.map +1 -0
  283. package/dist/core/computer-use/workflow.js +900 -0
  284. package/dist/core/computer-use/workflow.js.map +1 -0
  285. package/dist/core/cron/jobs.d.ts +26 -8
  286. package/dist/core/cron/jobs.d.ts.map +1 -1
  287. package/dist/core/cron/jobs.js +357 -232
  288. package/dist/core/cron/jobs.js.map +1 -1
  289. package/dist/core/cron/origin-context.d.ts +1 -0
  290. package/dist/core/cron/origin-context.d.ts.map +1 -1
  291. package/dist/core/cron/origin-context.js.map +1 -1
  292. package/dist/core/cron/scheduler.d.ts +22 -17
  293. package/dist/core/cron/scheduler.d.ts.map +1 -1
  294. package/dist/core/cron/scheduler.js +153 -73
  295. package/dist/core/cron/scheduler.js.map +1 -1
  296. package/dist/core/extensions/index.d.ts +1 -1
  297. package/dist/core/extensions/index.d.ts.map +1 -1
  298. package/dist/core/extensions/index.js.map +1 -1
  299. package/dist/core/extensions/loader.d.ts.map +1 -1
  300. package/dist/core/extensions/loader.js +4 -0
  301. package/dist/core/extensions/loader.js.map +1 -1
  302. package/dist/core/extensions/runner.d.ts +1 -0
  303. package/dist/core/extensions/runner.d.ts.map +1 -1
  304. package/dist/core/extensions/runner.js +8 -0
  305. package/dist/core/extensions/runner.js.map +1 -1
  306. package/dist/core/extensions/types.d.ts +8 -0
  307. package/dist/core/extensions/types.d.ts.map +1 -1
  308. package/dist/core/extensions/types.js.map +1 -1
  309. package/dist/core/footer-data-provider.d.ts +4 -0
  310. package/dist/core/footer-data-provider.d.ts.map +1 -1
  311. package/dist/core/footer-data-provider.js +22 -1
  312. package/dist/core/footer-data-provider.js.map +1 -1
  313. package/dist/core/large-subagent-launch.d.ts +1 -1
  314. package/dist/core/large-subagent-launch.d.ts.map +1 -1
  315. package/dist/core/large-subagent-launch.js +7 -7
  316. package/dist/core/large-subagent-launch.js.map +1 -1
  317. package/dist/core/model-registry.d.ts +2 -0
  318. package/dist/core/model-registry.d.ts.map +1 -1
  319. package/dist/core/model-registry.js +5 -0
  320. package/dist/core/model-registry.js.map +1 -1
  321. package/dist/core/model-runtime.d.ts +4 -1
  322. package/dist/core/model-runtime.d.ts.map +1 -1
  323. package/dist/core/model-runtime.js +40 -4
  324. package/dist/core/model-runtime.js.map +1 -1
  325. package/dist/core/package-manager.d.ts.map +1 -1
  326. package/dist/core/package-manager.js.map +1 -1
  327. package/dist/core/permissions.d.ts +4 -4
  328. package/dist/core/permissions.d.ts.map +1 -1
  329. package/dist/core/permissions.js +25 -38
  330. package/dist/core/permissions.js.map +1 -1
  331. package/dist/core/plan-mode.d.ts +5 -13
  332. package/dist/core/plan-mode.d.ts.map +1 -1
  333. package/dist/core/plan-mode.js +135 -116
  334. package/dist/core/plan-mode.js.map +1 -1
  335. package/dist/core/project-trust.d.ts.map +1 -1
  336. package/dist/core/project-trust.js +1 -1
  337. package/dist/core/project-trust.js.map +1 -1
  338. package/dist/core/prompt-resource-bridge.d.ts +12 -0
  339. package/dist/core/prompt-resource-bridge.d.ts.map +1 -0
  340. package/dist/core/prompt-resource-bridge.js +9 -0
  341. package/dist/core/prompt-resource-bridge.js.map +1 -0
  342. package/dist/core/protected-targets.d.ts +6 -0
  343. package/dist/core/protected-targets.d.ts.map +1 -0
  344. package/dist/core/protected-targets.js +45 -0
  345. package/dist/core/protected-targets.js.map +1 -0
  346. package/dist/core/resource-loader.d.ts.map +1 -1
  347. package/dist/core/resource-loader.js +7 -0
  348. package/dist/core/resource-loader.js.map +1 -1
  349. package/dist/core/rollback.d.ts +19 -3
  350. package/dist/core/rollback.d.ts.map +1 -1
  351. package/dist/core/rollback.js +172 -56
  352. package/dist/core/rollback.js.map +1 -1
  353. package/dist/core/runtime-credentials.d.ts +3 -0
  354. package/dist/core/runtime-credentials.d.ts.map +1 -1
  355. package/dist/core/runtime-credentials.js +14 -1
  356. package/dist/core/runtime-credentials.js.map +1 -1
  357. package/dist/core/sdk.d.ts +3 -0
  358. package/dist/core/sdk.d.ts.map +1 -1
  359. package/dist/core/sdk.js +1 -0
  360. package/dist/core/sdk.js.map +1 -1
  361. package/dist/core/session-manager.d.ts +6 -0
  362. package/dist/core/session-manager.d.ts.map +1 -1
  363. package/dist/core/session-manager.js +95 -32
  364. package/dist/core/session-manager.js.map +1 -1
  365. package/dist/core/session-ownership.d.ts.map +1 -1
  366. package/dist/core/session-ownership.js +8 -3
  367. package/dist/core/session-ownership.js.map +1 -1
  368. package/dist/core/session-retention.d.ts.map +1 -1
  369. package/dist/core/session-retention.js +18 -7
  370. package/dist/core/session-retention.js.map +1 -1
  371. package/dist/core/session-startup-settings.d.ts +10 -0
  372. package/dist/core/session-startup-settings.d.ts.map +1 -0
  373. package/dist/core/session-startup-settings.js +70 -0
  374. package/dist/core/session-startup-settings.js.map +1 -0
  375. package/dist/core/settings-manager.d.ts +6 -0
  376. package/dist/core/settings-manager.d.ts.map +1 -1
  377. package/dist/core/settings-manager.js +19 -0
  378. package/dist/core/settings-manager.js.map +1 -1
  379. package/dist/core/subagent-event-transport.d.ts +3 -0
  380. package/dist/core/subagent-event-transport.d.ts.map +1 -0
  381. package/dist/core/subagent-event-transport.js +61 -0
  382. package/dist/core/subagent-event-transport.js.map +1 -0
  383. package/dist/core/subscriptions.d.ts +16 -7
  384. package/dist/core/subscriptions.d.ts.map +1 -1
  385. package/dist/core/subscriptions.js +96 -55
  386. package/dist/core/subscriptions.js.map +1 -1
  387. package/dist/core/trust-manager.d.ts +2 -1
  388. package/dist/core/trust-manager.d.ts.map +1 -1
  389. package/dist/core/trust-manager.js +6 -1
  390. package/dist/core/trust-manager.js.map +1 -1
  391. package/dist/core/update-check.d.ts.map +1 -1
  392. package/dist/core/update-check.js.map +1 -1
  393. package/dist/core/usage-adapters/kimi-coding.d.ts +2 -2
  394. package/dist/core/usage-adapters/kimi-coding.d.ts.map +1 -1
  395. package/dist/core/usage-adapters/kimi-coding.js +2 -2
  396. package/dist/core/usage-adapters/kimi-coding.js.map +1 -1
  397. package/dist/core/usage-adapters/openai-codex.d.ts +3 -2
  398. package/dist/core/usage-adapters/openai-codex.d.ts.map +1 -1
  399. package/dist/core/usage-adapters/openai-codex.js +3 -3
  400. package/dist/core/usage-adapters/openai-codex.js.map +1 -1
  401. package/dist/core/usage-adapters/xai.d.ts +2 -2
  402. package/dist/core/usage-adapters/xai.d.ts.map +1 -1
  403. package/dist/core/usage-adapters/xai.js +3 -3
  404. package/dist/core/usage-adapters/xai.js.map +1 -1
  405. package/dist/core/usage-adapters/zai.d.ts +2 -2
  406. package/dist/core/usage-adapters/zai.d.ts.map +1 -1
  407. package/dist/core/usage-adapters/zai.js +2 -2
  408. package/dist/core/usage-adapters/zai.js.map +1 -1
  409. package/dist/core/usage-service.d.ts +9 -2
  410. package/dist/core/usage-service.d.ts.map +1 -1
  411. package/dist/core/usage-service.js +95 -50
  412. package/dist/core/usage-service.js.map +1 -1
  413. package/dist/gateway/adapters/discord.d.ts.map +1 -1
  414. package/dist/gateway/adapters/discord.js +2 -2
  415. package/dist/gateway/adapters/discord.js.map +1 -1
  416. package/dist/gateway/agent-bridge.d.ts +9 -1
  417. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  418. package/dist/gateway/agent-bridge.js +91 -37
  419. package/dist/gateway/agent-bridge.js.map +1 -1
  420. package/dist/gateway/approval.d.ts.map +1 -1
  421. package/dist/gateway/approval.js +3 -3
  422. package/dist/gateway/approval.js.map +1 -1
  423. package/dist/gateway/authz.d.ts +4 -4
  424. package/dist/gateway/authz.d.ts.map +1 -1
  425. package/dist/gateway/authz.js +8 -12
  426. package/dist/gateway/authz.js.map +1 -1
  427. package/dist/gateway/buttons.d.ts +8 -1
  428. package/dist/gateway/buttons.d.ts.map +1 -1
  429. package/dist/gateway/buttons.js +76 -18
  430. package/dist/gateway/buttons.js.map +1 -1
  431. package/dist/gateway/commands.d.ts +1 -0
  432. package/dist/gateway/commands.d.ts.map +1 -1
  433. package/dist/gateway/commands.js +12 -10
  434. package/dist/gateway/commands.js.map +1 -1
  435. package/dist/gateway/cron.d.ts +12 -11
  436. package/dist/gateway/cron.d.ts.map +1 -1
  437. package/dist/gateway/cron.js +85 -62
  438. package/dist/gateway/cron.js.map +1 -1
  439. package/dist/gateway/index.d.ts.map +1 -1
  440. package/dist/gateway/index.js +5 -4
  441. package/dist/gateway/index.js.map +1 -1
  442. package/dist/gateway/mobile-commands.d.ts +1 -0
  443. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  444. package/dist/gateway/mobile-commands.js +64 -22
  445. package/dist/gateway/mobile-commands.js.map +1 -1
  446. package/dist/gateway/presenter.d.ts +12 -2
  447. package/dist/gateway/presenter.d.ts.map +1 -1
  448. package/dist/gateway/presenter.js +74 -39
  449. package/dist/gateway/presenter.js.map +1 -1
  450. package/dist/gateway/router.d.ts +2 -2
  451. package/dist/gateway/router.d.ts.map +1 -1
  452. package/dist/gateway/router.js +22 -9
  453. package/dist/gateway/router.js.map +1 -1
  454. package/dist/gateway/service.d.ts +2 -0
  455. package/dist/gateway/service.d.ts.map +1 -1
  456. package/dist/gateway/service.js +153 -0
  457. package/dist/gateway/service.js.map +1 -1
  458. package/dist/gateway/setup.d.ts.map +1 -1
  459. package/dist/gateway/setup.js +6 -4
  460. package/dist/gateway/setup.js.map +1 -1
  461. package/dist/main.d.ts.map +1 -1
  462. package/dist/main.js +86 -33
  463. package/dist/main.js.map +1 -1
  464. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  465. package/dist/modes/interactive/components/assistant-message.js +6 -4
  466. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  467. package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
  468. package/dist/modes/interactive/components/copyable-text.js +3 -2
  469. package/dist/modes/interactive/components/copyable-text.js.map +1 -1
  470. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  471. package/dist/modes/interactive/components/extension-editor.js +1 -1
  472. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  473. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  474. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  475. package/dist/modes/interactive/components/settings-selector.js +20 -0
  476. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  477. package/dist/modes/interactive/interactive-mode.d.ts +2 -2
  478. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  479. package/dist/modes/interactive/interactive-mode.js +104 -109
  480. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  481. package/dist/modes/interactive/smooth-streaming.d.ts.map +1 -1
  482. package/dist/modes/interactive/smooth-streaming.js.map +1 -1
  483. package/dist/modes/print-mode.d.ts.map +1 -1
  484. package/dist/modes/print-mode.js +9 -1
  485. package/dist/modes/print-mode.js.map +1 -1
  486. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  487. package/dist/modes/rpc/rpc-mode.js +2 -1
  488. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  489. package/dist/node-runtime/adapter-247RTYLS.js +16 -0
  490. package/dist/node-runtime/agent-session-services-KDMSPQDY.js +53 -0
  491. package/dist/node-runtime/{brave-UWDA3I22.js → brave-2AFFAXNN.js} +1 -1
  492. package/dist/node-runtime/{builtin-extensions-ZLAX7TUH.js → builtin-extensions-OX6KELNX.js} +9 -7
  493. package/dist/node-runtime/{chunk-QH6YL7VK.js → chunk-252ZVPPF.js} +3 -3
  494. package/dist/node-runtime/{chunk-PCEW76PM.js → chunk-2OIPYKLZ.js} +6 -6
  495. package/dist/node-runtime/{chunk-XBWPBZBN.js → chunk-2SWW7KMW.js} +1 -1
  496. package/dist/node-runtime/{chunk-UQUCFAJ3.js → chunk-2VIW3IMF.js} +40 -7
  497. package/dist/node-runtime/{chunk-UOEDI7RP.js → chunk-4KNKQGHM.js} +2 -2
  498. package/dist/node-runtime/{chunk-FQMM2EZ2.js → chunk-64XTQNLA.js} +29 -7
  499. package/dist/node-runtime/{chunk-NRKGMJYU.js → chunk-6O3IW3IA.js} +2 -2
  500. package/dist/node-runtime/{chunk-5ZQXRPMC.js → chunk-6ZZHGUSA.js} +2 -2
  501. package/dist/node-runtime/chunk-A2WO6WIN.js +1197 -0
  502. package/dist/node-runtime/{chunk-ZXSGTGJ6.js → chunk-APVM5NEU.js} +169 -148
  503. package/dist/node-runtime/{chunk-RC7DMV45.js → chunk-AYHH7YSD.js} +205 -144
  504. package/dist/node-runtime/{chunk-LWYIVUGV.js → chunk-B2IBAXNX.js} +48 -31
  505. package/dist/node-runtime/{chunk-M3LZLQW2.js → chunk-BDRGN3L2.js} +1 -0
  506. package/dist/node-runtime/{chunk-GJ2RDBRL.js → chunk-BYC6RKCN.js} +4 -2
  507. package/dist/node-runtime/{chunk-KWIYUUZK.js → chunk-C3P6Q3B2.js} +469 -283
  508. package/dist/node-runtime/{chunk-YCUZEGJG.js → chunk-DQSCFU7R.js} +17 -8
  509. package/dist/node-runtime/chunk-EBLAZVSA.js +4170 -0
  510. package/dist/node-runtime/{chunk-2KIPT4HJ.js → chunk-EPR2F3GU.js} +68 -20
  511. package/dist/node-runtime/{chunk-CSFI6YXL.js → chunk-ES6PBSIE.js} +1 -1
  512. package/dist/node-runtime/{chunk-IF24A3FH.js → chunk-EVM653DD.js} +4 -4
  513. package/dist/node-runtime/{chunk-HTFRRDSF.js → chunk-F2SMQ6ES.js} +3 -2
  514. package/dist/node-runtime/chunk-F2V2F4ZG.js +114 -0
  515. package/dist/node-runtime/chunk-FE3WZI7F.js +290 -0
  516. package/dist/node-runtime/{chunk-GYIXXQAO.js → chunk-FIRA54AC.js} +2 -5
  517. package/dist/node-runtime/{chunk-6VYZ5UFP.js → chunk-FLGEEH27.js} +1 -1
  518. package/dist/node-runtime/{chunk-5EFIU3OM.js → chunk-FTKEZL27.js} +1 -1
  519. package/dist/node-runtime/chunk-FY4A63RK.js +73 -0
  520. package/dist/node-runtime/chunk-FYIFPFXE.js +98 -0
  521. package/dist/node-runtime/{chunk-HMBGROQK.js → chunk-GLDXBBL6.js} +3 -3
  522. package/dist/node-runtime/{chunk-KWA4OC2J.js → chunk-H6YBCWKG.js} +1 -1
  523. package/dist/node-runtime/{chunk-2MI5OPMN.js → chunk-HNNHHJAB.js} +68 -50
  524. package/dist/node-runtime/{chunk-6XL67VVY.js → chunk-HUD2RFJW.js} +17 -2
  525. package/dist/node-runtime/{chunk-I54LGHWM.js → chunk-I2H5QMWW.js} +3 -3
  526. package/dist/node-runtime/chunk-IAZSK7KK.js +108 -0
  527. package/dist/node-runtime/{chunk-2HHLJWGD.js → chunk-IHHTWSXN.js} +9 -9
  528. package/dist/node-runtime/{chunk-DAPBPCBP.js → chunk-IPP5BIV5.js} +25 -3
  529. package/dist/node-runtime/{chunk-QFWG2RVL.js → chunk-IXG6F4NT.js} +11 -0
  530. package/dist/node-runtime/{chunk-RDDAZOMU.js → chunk-JL4HYQXK.js} +1 -1
  531. package/dist/node-runtime/{chunk-CDVHZOOK.js → chunk-JQYNHAKX.js} +1 -1
  532. package/dist/node-runtime/{chunk-WF7PGWRZ.js → chunk-JWEVT363.js} +37 -28
  533. package/dist/node-runtime/{chunk-2HMIRK7W.js → chunk-LHV3V67B.js} +5 -5
  534. package/dist/node-runtime/{chunk-UAEOTO52.js → chunk-MNQXDFPV.js} +6 -2
  535. package/dist/node-runtime/{chunk-IJIFHRTB.js → chunk-MQPKUHRN.js} +165 -85
  536. package/dist/node-runtime/{chunk-MPKSOJBT.js → chunk-NHATCSOI.js} +4 -7
  537. package/dist/node-runtime/{chunk-RMQZU2YU.js → chunk-NNNR3QIY.js} +1 -1
  538. package/dist/node-runtime/{chunk-RWTKOC3B.js → chunk-QBTJG3UM.js} +1 -1
  539. package/dist/node-runtime/{chunk-E4D3IGP2.js → chunk-QNVMKNNN.js} +20 -17
  540. package/dist/node-runtime/{chunk-GS42T6MX.js → chunk-QW3AAHWN.js} +1 -1
  541. package/dist/node-runtime/{chunk-7S3T6YEA.js → chunk-R4WSB2MQ.js} +5 -5
  542. package/dist/node-runtime/{chunk-B4HP6ZWM.js → chunk-RHCGYWO7.js} +1 -1
  543. package/dist/node-runtime/{chunk-3XPLBUEM.js → chunk-RLGY2QIL.js} +49 -59
  544. package/dist/node-runtime/{chunk-KKUTQQV7.js → chunk-RYRGL7P4.js} +1 -1
  545. package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-TCT6PCUR.js} +47 -115
  546. package/dist/node-runtime/chunk-U5F4IC7R.js +53 -0
  547. package/dist/node-runtime/{chunk-OCVIXVTZ.js → chunk-UBWW2PID.js} +13 -2
  548. package/dist/node-runtime/{chunk-HFVZUPFJ.js → chunk-UNUZICC4.js} +3 -3
  549. package/dist/node-runtime/{chunk-LQP3RB67.js → chunk-UYRKUKFE.js} +1 -1
  550. package/dist/node-runtime/{chunk-DSIKTUPW.js → chunk-VSUEAI7O.js} +2993 -3820
  551. package/dist/node-runtime/{chunk-NAY6UUQZ.js → chunk-WDIVLMOH.js} +1 -1
  552. package/dist/node-runtime/{chunk-E24EO34J.js → chunk-WPXUR3HE.js} +1 -1
  553. package/dist/node-runtime/{chunk-SLVOAQOY.js → chunk-WXYNALHD.js} +113 -1
  554. package/dist/node-runtime/{chunk-KJ6DWS3K.js → chunk-XEOCUEUJ.js} +121 -60
  555. package/dist/node-runtime/chunk-YD3IZAZ7.js +47 -0
  556. package/dist/node-runtime/chunk-YSB6URMT.js +41 -0
  557. package/dist/node-runtime/{chunk-VQFSUJJG.js → chunk-ZDJUR45D.js} +430 -129
  558. package/dist/node-runtime/{chunk-YDO2F2IA.js → chunk-ZEVFBFNF.js} +95 -142
  559. package/dist/node-runtime/chunk-ZIQUS5QO.js +180 -0
  560. package/dist/node-runtime/cli-runtime.js +4 -4
  561. package/dist/node-runtime/{command-6WDOYKS6.js → command-3HMSY6W2.js} +5 -5
  562. package/dist/node-runtime/{commands-NZLSOHPE.js → commands-D6A6H4TS.js} +11 -16
  563. package/dist/node-runtime/commands-OCSSEEWJ.js +37 -0
  564. package/dist/node-runtime/{config-QDD5PUE2.js → config-CU7M7BTK.js} +1 -1
  565. package/dist/node-runtime/{config-D4QUPAHX.js → config-DS7XLMEM.js} +2 -2
  566. package/dist/node-runtime/{direct-tool-executor-77GW4F5P.js → direct-tool-executor-2QJXVQD2.js} +8 -10
  567. package/dist/node-runtime/{exa-LL64QZR2.js → exa-6VBZNPGE.js} +1 -1
  568. package/dist/node-runtime/{export-html-VM4J2MNR.js → export-html-BRWF5AHI.js} +4 -4
  569. package/dist/node-runtime/{extension-input-E7BJZ35H.js → extension-input-VBBMX7YV.js} +5 -5
  570. package/dist/node-runtime/{extension-selector-WU42XDTU.js → extension-selector-T5AOG5XB.js} +5 -5
  571. package/dist/node-runtime/{extract-EQJE7FZZ.js → extract-BFX2N35A.js} +3 -3
  572. package/dist/node-runtime/{gateway-INAYBF4Q.js → gateway-6623C2U3.js} +61 -53
  573. package/dist/node-runtime/{gemini-search-35OCRFLN.js → gemini-search-C66QHDT6.js} +2 -2
  574. package/dist/node-runtime/{gemini-url-context-UQY3PHHW.js → gemini-url-context-T7DEK73R.js} +3 -3
  575. package/dist/node-runtime/{github-extract-F64RZOEA.js → github-extract-HOGE3D6F.js} +107 -38
  576. package/dist/node-runtime/{goal-NJEE5CTU.js → goal-AIHEDUYA.js} +5 -5
  577. package/dist/node-runtime/index.js +54 -48
  578. package/dist/node-runtime/{init-HS6NQXSK.js → init-JBQJIPYI.js} +3 -4
  579. package/dist/node-runtime/{install-cli-KL4UDDAD.js → install-cli-INGHIVBY.js} +30 -25
  580. package/dist/node-runtime/interactive-mode-FM5DNUSW.js +74 -0
  581. package/dist/node-runtime/{interactive-view-NGFAMHPW.js → interactive-view-K33PM4OS.js} +8 -8
  582. package/dist/node-runtime/{lsp-manager-3ASUSO4T.js → lsp-manager-S554V5HR.js} +240 -155
  583. package/dist/node-runtime/{lunr-browser-IR7TL3J7.js → lunr-browser-H4FDOR3C.js} +7 -7
  584. package/dist/node-runtime/lunr-computer-use-VDP2QNRQ.js +158 -0
  585. package/dist/node-runtime/{lunr-cron-LWIZJM2N.js → lunr-cron-LKVA5CZZ.js} +94 -79
  586. package/dist/node-runtime/main.js +42 -39
  587. package/dist/node-runtime/{mobile-commands-J7OJEKFO.js → mobile-commands-XT3NQXLD.js} +13 -12
  588. package/dist/node-runtime/{model-runtime-OO5HFLWE.js → model-runtime-MZ2JMDV4.js} +4 -4
  589. package/dist/node-runtime/{openai-search-B3MSNCQA.js → openai-search-K72LJDYN.js} +1 -1
  590. package/dist/node-runtime/{package-manager-cli-VYZM5WHN.js → package-manager-cli-CYM262SI.js} +20 -19
  591. package/dist/node-runtime/{parallel-AI2MNSCU.js → parallel-X724NCNU.js} +1 -1
  592. package/dist/node-runtime/{perplexity-QVJW3I35.js → perplexity-RDHQHVMK.js} +2 -2
  593. package/dist/node-runtime/{pi-intercom-QM53RLTS.js → pi-intercom-NHHEPBMI.js} +2 -2
  594. package/dist/node-runtime/{pi-mcp-adapter-5UKBZP44.js → pi-mcp-adapter-PP3GQJQ2.js} +98 -94
  595. package/dist/node-runtime/{pi-ollama-cloud-2F3Y2QNM.js → pi-ollama-cloud-4MNWIMFN.js} +11 -24
  596. package/dist/node-runtime/{pi-prompt-template-model-QWTCGLJU.js → pi-prompt-template-model-FTGELLS5.js} +32 -36
  597. package/dist/node-runtime/{pi-subagents-DNY7EAIG.js → pi-subagents-LT3CTO4E.js} +114 -116
  598. package/dist/node-runtime/{pi-web-access-WTGMNZ32.js → pi-web-access-Z3LP246C.js} +144 -108
  599. package/dist/node-runtime/{print-mode-XSFM26EL.js → print-mode-2XHN5SUA.js} +4 -3
  600. package/dist/node-runtime/{process-registry-4FAKZQOL.js → process-registry-Q4QWIU33.js} +3 -3
  601. package/dist/node-runtime/{proxy-modes-LGEUYD7R.js → proxy-modes-VEGC6QG5.js} +9 -13
  602. package/dist/node-runtime/rpc-entry.js +42 -39
  603. package/dist/node-runtime/{rpc-mode-O3XV4SID.js → rpc-mode-32DHJPEJ.js} +4 -4
  604. package/dist/node-runtime/{runtime-4VA6JKNF.js → runtime-EDUUGAQD.js} +56 -46
  605. package/dist/node-runtime/runtime-UGXM4NPQ.js +21 -0
  606. package/dist/node-runtime/{runtime-bridges-VRDDR73P.js → runtime-bridges-DNKMNJCF.js} +8 -7
  607. package/dist/node-runtime/{service-MDQIPQ26.js → service-IHLGFLBT.js} +6 -4
  608. package/dist/node-runtime/{session-handoff-GWARVEWT.js → session-handoff-LNSPDTKY.js} +4 -4
  609. package/dist/node-runtime/{session-manager-JB5J6XBN.js → session-manager-YIFIAVGC.js} +3 -3
  610. package/dist/node-runtime/{session-selector-GIM4DHQ2.js → session-selector-I73U3EIO.js} +7 -7
  611. package/dist/node-runtime/{settings-manager-J4SPQPDJ.js → settings-manager-P2TKGYTR.js} +6 -5
  612. package/dist/node-runtime/{setup-JBKOLJ6F.js → setup-H7CCELIL.js} +15 -1
  613. package/dist/node-runtime/{setup-CQ2NLVK5.js → setup-OLQ4GXWS.js} +22 -21
  614. package/dist/node-runtime/{src-IVPNZ2BX.js → src-6RV4PXKJ.js} +64 -36
  615. package/dist/node-runtime/{subagent-executor-KZZQGAKV.js → subagent-executor-Q5F7DBVM.js} +141 -62
  616. package/dist/node-runtime/{tavily-WEZFVFP7.js → tavily-KZBFYQB6.js} +1 -1
  617. package/dist/node-runtime/{theme-UOO5RVFN.js → theme-YLVZKKZD.js} +2 -2
  618. package/dist/node-runtime/{trust-manager-MMISNCYO.js → trust-manager-ZCU76D23.js} +2 -2
  619. package/dist/node-runtime/{update-cli-GTFJC7XK.js → update-cli-F3XXJANQ.js} +7 -6
  620. package/dist/node-runtime/{usage-service-LFB2SWYV.js → usage-service-CPAGBED5.js} +1 -1
  621. package/dist/node-runtime/{video-extract-OOZHR7SU.js → video-extract-UPKYIBW3.js} +3 -3
  622. package/dist/node-runtime/workflow-ICDI4N3J.js +767 -0
  623. package/dist/node-runtime/{youtube-extract-FNPAUNHU.js → youtube-extract-77NT7FWH.js} +4 -4
  624. package/dist/utils/clipboard-image.d.ts.map +1 -1
  625. package/dist/utils/clipboard-image.js.map +1 -1
  626. package/dist/utils/exif-orientation.d.ts.map +1 -1
  627. package/dist/utils/exif-orientation.js +25 -10
  628. package/dist/utils/exif-orientation.js.map +1 -1
  629. package/dist/utils/image-resize-core.d.ts +2 -0
  630. package/dist/utils/image-resize-core.d.ts.map +1 -1
  631. package/dist/utils/image-resize-core.js +12 -0
  632. package/dist/utils/image-resize-core.js.map +1 -1
  633. package/dist/utils/paths.d.ts +4 -0
  634. package/dist/utils/paths.d.ts.map +1 -1
  635. package/dist/utils/paths.js +33 -2
  636. package/dist/utils/paths.js.map +1 -1
  637. package/dist/utils/sanitize-terminal-text.d.ts +7 -0
  638. package/dist/utils/sanitize-terminal-text.d.ts.map +1 -0
  639. package/dist/utils/sanitize-terminal-text.js +67 -0
  640. package/dist/utils/sanitize-terminal-text.js.map +1 -0
  641. package/docs/browser.md +1 -1
  642. package/docs/computer-use.md +362 -0
  643. package/docs/custom-provider.md +3 -3
  644. package/docs/extensions.md +8 -4
  645. package/docs/features.md +22 -12
  646. package/docs/keybindings.md +1 -1
  647. package/docs/models.md +5 -5
  648. package/docs/packages.md +1 -1
  649. package/docs/providers.md +2 -2
  650. package/docs/rpc.md +7 -7
  651. package/docs/security.md +10 -5
  652. package/docs/sessions.md +2 -2
  653. package/docs/skills.md +1 -1
  654. package/docs/terminal-setup.md +7 -7
  655. package/docs/themes.md +1 -1
  656. package/docs/usage.md +1 -1
  657. package/examples/extensions/auto-commit-on-exit.ts +1 -1
  658. package/examples/extensions/bash-spawn-hook.ts +1 -1
  659. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  660. package/examples/extensions/claude-rules.ts +1 -1
  661. package/examples/extensions/commands.ts +1 -1
  662. package/examples/extensions/custom-compaction.ts +1 -1
  663. package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
  664. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  665. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  666. package/examples/extensions/custom-provider-gitlab-duo/index.ts +1 -1
  667. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  668. package/examples/extensions/doom-overlay/index.ts +1 -1
  669. package/examples/extensions/git-merge-and-resolve.ts +2 -2
  670. package/examples/extensions/gondolin/index.ts +1 -1
  671. package/examples/extensions/gondolin/package-lock.json +2 -2
  672. package/examples/extensions/gondolin/package.json +1 -1
  673. package/examples/extensions/hidden-thinking-label.ts +1 -1
  674. package/examples/extensions/inline-bash.ts +2 -2
  675. package/examples/extensions/input-transform-streaming.ts +2 -2
  676. package/examples/extensions/input-transform.ts +2 -2
  677. package/examples/extensions/interactive-shell.ts +1 -1
  678. package/examples/extensions/kimi-deferred-tools.ts +1 -1
  679. package/examples/extensions/mac-system-theme.ts +1 -1
  680. package/examples/extensions/minimal-mode.ts +1 -1
  681. package/examples/extensions/modal-editor.ts +1 -1
  682. package/examples/extensions/model-status.ts +1 -1
  683. package/examples/extensions/notify.ts +3 -3
  684. package/examples/extensions/overlay-qa-tests.ts +1 -1
  685. package/examples/extensions/overlay-test.ts +1 -1
  686. package/examples/extensions/pirate.ts +1 -1
  687. package/examples/extensions/preset.ts +3 -3
  688. package/examples/extensions/project-trust.ts +4 -4
  689. package/examples/extensions/prompt-customizer.ts +1 -1
  690. package/examples/extensions/rainbow-editor.ts +1 -1
  691. package/examples/extensions/rpc-demo.ts +1 -1
  692. package/examples/extensions/sandbox/index.ts +7 -7
  693. package/examples/extensions/sandbox/package-lock.json +2 -2
  694. package/examples/extensions/sandbox/package.json +1 -1
  695. package/examples/extensions/shutdown-command.ts +5 -5
  696. package/examples/extensions/ssh.ts +2 -2
  697. package/examples/extensions/subagent/README.md +3 -3
  698. package/examples/extensions/subagent/index.ts +2 -2
  699. package/examples/extensions/titlebar-spinner.ts +1 -1
  700. package/examples/extensions/tool-override.ts +1 -1
  701. package/examples/extensions/tools.ts +1 -1
  702. package/examples/extensions/with-deps/package-lock.json +2 -2
  703. package/examples/extensions/with-deps/package.json +1 -1
  704. package/examples/extensions/working-indicator.ts +1 -1
  705. package/examples/extensions/working-message-test.ts +1 -1
  706. package/examples/sdk/01-minimal.ts +1 -1
  707. package/examples/sdk/03-custom-prompt.ts +1 -1
  708. package/examples/sdk/04-skills.ts +1 -1
  709. package/examples/sdk/06-extensions.ts +2 -2
  710. package/examples/sdk/08-prompt-templates.ts +1 -1
  711. package/install-lock/package-lock.json +3841 -0
  712. package/install-lock/package.json +18 -0
  713. package/native/computer-use/LICENSE.md +21 -0
  714. package/npm-shrinkwrap.json +3858 -0
  715. package/package.json +15 -9
  716. package/dist/modes/interactive/components/exit-card.d.ts +0 -22
  717. package/dist/modes/interactive/components/exit-card.d.ts.map +0 -1
  718. package/dist/modes/interactive/components/exit-card.js +0 -69
  719. package/dist/modes/interactive/components/exit-card.js.map +0 -1
  720. package/dist/node-runtime/agent-session-services-YXXFCP5J.js +0 -49
  721. package/dist/node-runtime/chunk-4HXHDDCF.js +0 -16
  722. package/dist/node-runtime/chunk-4TLO4PO2.js +0 -3427
  723. package/dist/node-runtime/chunk-AUXVGBO4.js +0 -19
  724. package/dist/node-runtime/chunk-OVX6X377.js +0 -50
  725. package/dist/node-runtime/chunk-QTU6AKNJ.js +0 -773
  726. package/dist/node-runtime/chunk-TORR5XBV.js +0 -356
  727. package/dist/node-runtime/commands-QC6VUZJQ.js +0 -36
  728. package/dist/node-runtime/interactive-mode-Z5M7WYYZ.js +0 -72
  729. package/dist/node-runtime/mcp-auth-flow-QIXHW6QN.js +0 -32
@@ -1 +1 @@
1
- {"version":3,"file":"tool-manager.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-prompt-template-model/tool-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAK/G,MAAM,WAAW,eAAe;IAC/B,QAAQ,IAAI,OAAO,CAAC;IACpB,YAAY,IAAI,uBAAuB,GAAG,IAAI,CAAC;IAC/C,YAAY,CAAC,GAAG,EAAE,uBAAuB,GAAG,IAAI,GAAG,IAAI,CAAC;IACxD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7E;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe;;;;;;;;EA+MxE","sourcesContent":["// @ts-nocheck\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from \"@ashx-j/lunr\";\nimport { getAgentDir } from \"../../config.ts\";\nimport { Type } from \"typebox\";\nimport { notify } from \"./notifications.ts\";\n\nexport interface ToolManagerDeps {\n\tisActive(): boolean;\n\tgetStoredCtx(): ExtensionCommandContext | null;\n\tsetStoredCtx(ctx: ExtensionCommandContext | null): void;\n\texecuteCommand(command: string, ctx: ExtensionCommandContext): Promise<void>;\n}\n\nexport function createToolManager(pi: ExtensionAPI, deps: ToolManagerDeps) {\n\tlet toolEnabled = false;\n\tlet toolGuidance: string | null = null;\n\tlet toolRegistered = false;\n\tlet toolQueuedCommand: string | null = null;\n\tconst configPath = join(getAgentDir(), \"prompt-template-model.json\");\n\n\ttry {\n\t\tconst rawConfig = JSON.parse(readFileSync(configPath, \"utf-8\"));\n\t\tif (rawConfig && typeof rawConfig === \"object\") {\n\t\t\tconst config = rawConfig as { toolEnabled?: unknown; toolGuidance?: unknown };\n\t\t\tif (typeof config.toolEnabled === \"boolean\") {\n\t\t\t\ttoolEnabled = config.toolEnabled;\n\t\t\t}\n\t\t\tif (typeof config.toolGuidance === \"string\") {\n\t\t\t\ttoolGuidance = config.toolGuidance;\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tconst err = error as NodeJS.ErrnoException;\n\t\tif (err.code !== \"ENOENT\") {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi-prompt-template-model] Failed to read ${configPath}: ${error instanceof Error ? error.message : String(error)}\\n`,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction saveToolConfig() {\n\t\ttry {\n\t\t\tmkdirSync(getAgentDir(), { recursive: true });\n\t\t\twriteFileSync(configPath, JSON.stringify({ toolEnabled, toolGuidance }, null, 2));\n\t\t} catch (error) {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi-prompt-template-model] Failed to write ${configPath}: ${error instanceof Error ? error.message : String(error)}\\n`,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction ensureRegistered() {\n\t\tif (toolRegistered) return;\n\t\ttoolRegistered = true;\n\t\tpi.registerTool({\n\t\t\tname: \"run-prompt\",\n\t\t\tlabel: \"Run Prompt\",\n\t\t\tdescription:\n\t\t\t\t\"Run a prompt template command. Pass the template name and any arguments. \" +\n\t\t\t\t\"Supports --loop for loops (e.g. 'deslop --loop 5', 'deslop --loop=5', 'deslop --loop' for unlimited until convergence with a 999-iteration cap), \" +\n\t\t\t\t\"--fresh for context collapse between iterations, and --no-converge to disable early stopping for bounded loops. \" +\n\t\t\t\t\"Supports runtime delegation override via --subagent, --subagent=<name>, or --subagent:<name>. \" +\n\t\t\t\t\"Use 'chain-prompts template1 -> template2' for chaining and add --chain-context to pass previous step summaries into delegated steps.\",\n\t\t\tpromptSnippet:\n\t\t\t\t\"Use this to run slash/prompt templates by name with args (including --loop/--fresh and chain-prompts flows) when the user asks to execute a prompt template.\",\n\t\t\tparameters: Type.Object({\n\t\t\t\tcommand: Type.String({\n\t\t\t\t\tdescription: \"Template name and arguments (e.g. 'deslop --loop 5 --fresh', 'deslop --subagent:worker', 'deslop --subagent', 'chain-prompts analyze -> fix --chain-context', 'chain-prompts analyze -> fix --loop=3')\",\n\t\t\t\t}),\n\t\t\t}),\n\t\t\texecute: async (_id, params) => {\n\t\t\t\tif (!toolEnabled) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"run-prompt tool is disabled. User must run `/prompt-tool on` to enable.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (deps.isActive()) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"A prompt command is already running. Wait for it to complete.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (!deps.getStoredCtx()) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No command context. Run any prompt command first to initialize.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst commandParam = (params as { command?: unknown }).command;\n\t\t\t\tconst command = typeof commandParam === \"string\" ? commandParam.trim() : \"\";\n\t\t\t\tif (!command) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No command specified.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (toolQueuedCommand) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"A prompt command is already queued. Wait for it to execute.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\ttoolQueuedCommand = command;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Prompt command queued: \"${command}\". Will execute when this turn ends.` }],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t},\n\t\t});\n\t}\n\n\tfunction registerCommand() {\n\t\tpi.registerCommand(\"prompt-tool\", {\n\t\t\tdescription: \"Manage the run-prompt tool (agent-accessible prompt execution)\",\n\t\t\thandler: async (args, ctx) => {\n\t\t\t\tdeps.setStoredCtx(ctx);\n\t\t\t\tconst trimmed = args.trim();\n\n\t\t\t\tif (trimmed === \"on\" || trimmed.startsWith(\"on \")) {\n\t\t\t\t\ttoolEnabled = true;\n\t\t\t\t\tensureRegistered();\n\t\t\t\t\tconst guidanceRaw = trimmed.slice(\"on\".length).trim();\n\t\t\t\t\tif (guidanceRaw) {\n\t\t\t\t\t\ttoolGuidance = guidanceRaw.replace(/^[\"']|[\"']$/g, \"\");\n\t\t\t\t\t\tnotify(ctx, `run-prompt tool enabled with guidance: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(ctx, \"run-prompt tool enabled.\", \"info\");\n\t\t\t\t\t}\n\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (trimmed === \"off\") {\n\t\t\t\t\ttoolEnabled = false;\n\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\tnotify(ctx, \"run-prompt tool disabled.\", \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (trimmed === \"guidance\" || trimmed.startsWith(\"guidance \")) {\n\t\t\t\t\tif (trimmed === \"guidance\" || trimmed === \"guidance show\") {\n\t\t\t\t\t\tif (toolGuidance) {\n\t\t\t\t\t\t\tnotify(ctx, `Current guidance: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnotify(ctx, \"No guidance set. Use `/prompt-tool guidance <text>` to set.\", \"info\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (trimmed === \"guidance clear\") {\n\t\t\t\t\t\ttoolGuidance = null;\n\t\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\t\tnotify(ctx, \"Guidance cleared.\", \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst guidanceRaw = trimmed.slice(\"guidance\".length).trim();\n\t\t\t\t\t\ttoolGuidance = guidanceRaw.replace(/^[\"']|[\"']$/g, \"\");\n\t\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\t\tnotify(ctx, `Guidance set: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!trimmed) {\n\t\t\t\t\tif (toolEnabled) {\n\t\t\t\t\t\tconst guidanceInfo = toolGuidance ? ` | Guidance: \"${toolGuidance}\"` : \"\";\n\t\t\t\t\t\tnotify(ctx, `run-prompt tool is enabled${guidanceInfo}`, \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(ctx, \"run-prompt tool is disabled\", \"info\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tnotify(ctx, \"Usage: /prompt-tool [on [guidance] | off | guidance [text|clear]]\", \"error\");\n\t\t\t},\n\t\t});\n\t}\n\n\tasync function processQueue(ctx: ExtensionContext, restoreFn: () => Promise<void>) {\n\t\tif (!toolQueuedCommand) return false;\n\t\tconst storedCtx = deps.getStoredCtx();\n\t\tif (!storedCtx) {\n\t\t\ttoolQueuedCommand = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tconst command = toolQueuedCommand;\n\t\ttoolQueuedCommand = null;\n\t\tawait restoreFn();\n\t\ttry {\n\t\t\tawait deps.executeCommand(command, storedCtx);\n\t\t} catch (error) {\n\t\t\tnotify(\n\t\t\t\tctx,\n\t\t\t\t`Failed to execute queued prompt command \"${command}\": ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\"error\",\n\t\t\t);\n\t\t}\n\t\treturn true;\n\t}\n\n\treturn {\n\t\tisEnabled() {\n\t\t\treturn toolEnabled;\n\t\t},\n\t\tgetGuidance() {\n\t\t\treturn toolGuidance;\n\t\t},\n\t\thasQueuedCommand() {\n\t\t\treturn toolQueuedCommand !== null;\n\t\t},\n\t\tclearQueue() {\n\t\t\ttoolQueuedCommand = null;\n\t\t},\n\t\tensureRegistered,\n\t\tregisterCommand,\n\t\tprocessQueue,\n\t};\n}\n"]}
1
+ {"version":3,"file":"tool-manager.d.ts","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-prompt-template-model/tool-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAK/G,MAAM,WAAW,eAAe;IAC/B,QAAQ,IAAI,OAAO,CAAC;IACpB,YAAY,IAAI,uBAAuB,GAAG,IAAI,CAAC;IAC/C,YAAY,CAAC,GAAG,EAAE,uBAAuB,GAAG,IAAI,GAAG,IAAI,CAAC;IACxD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7E;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe;;;;;;;;EA8LxE","sourcesContent":["// @ts-nocheck\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from \"@ashx-j/lunr\";\nimport { getAgentDir } from \"../../config.ts\";\nimport { Type } from \"typebox\";\nimport { notify } from \"./notifications.ts\";\n\nexport interface ToolManagerDeps {\n\tisActive(): boolean;\n\tgetStoredCtx(): ExtensionCommandContext | null;\n\tsetStoredCtx(ctx: ExtensionCommandContext | null): void;\n\texecuteCommand(command: string, ctx: ExtensionCommandContext): Promise<void>;\n}\n\nexport function createToolManager(pi: ExtensionAPI, deps: ToolManagerDeps) {\n\tlet toolEnabled = false;\n\tlet toolGuidance: string | null = null;\n\tlet toolRegistered = false;\n\tlet toolQueuedCommand: string | null = null;\n\tconst configPath = join(getAgentDir(), \"prompt-template-model.json\");\n\n\ttry {\n\t\tconst rawConfig = JSON.parse(readFileSync(configPath, \"utf-8\"));\n\t\tif (rawConfig && typeof rawConfig === \"object\") {\n\t\t\tconst config = rawConfig as { toolEnabled?: unknown; toolGuidance?: unknown };\n\t\t\tif (typeof config.toolEnabled === \"boolean\") {\n\t\t\t\ttoolEnabled = config.toolEnabled;\n\t\t\t}\n\t\t\tif (typeof config.toolGuidance === \"string\") {\n\t\t\t\ttoolGuidance = config.toolGuidance;\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tconst err = error as NodeJS.ErrnoException;\n\t\tif (err.code !== \"ENOENT\") {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi-prompt-template-model] Failed to read ${configPath}: ${error instanceof Error ? error.message : String(error)}\\n`,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction saveToolConfig() {\n\t\ttry {\n\t\t\tmkdirSync(getAgentDir(), { recursive: true });\n\t\t\twriteFileSync(configPath, JSON.stringify({ toolEnabled, toolGuidance }, null, 2));\n\t\t} catch (error) {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi-prompt-template-model] Failed to write ${configPath}: ${error instanceof Error ? error.message : String(error)}\\n`,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction ensureRegistered() {\n\t\tif (toolRegistered) return;\n\t\ttoolRegistered = true;\n\t\tpi.registerTool({\n\t\t\tname: \"run-prompt\",\n\t\t\tlabel: \"Run Prompt\",\n\t\t\tdescription:\n\t\t\t\t\"Queue a prompt template command to execute when the current turn ends. Pass the template name and any arguments. \" +\n\t\t\t\t\"A queued result confirms acceptance, not completion. Rejected requests fail without changing the queue; wait for queued or running work to finish before retrying. \" +\n\t\t\t\t\"Supports --loop for loops (e.g. 'deslop --loop 5', 'deslop --loop=5', 'deslop --loop' for unlimited until convergence with a 999-iteration cap), \" +\n\t\t\t\t\"--fresh for context collapse between iterations, and --no-converge to disable early stopping for bounded loops. \" +\n\t\t\t\t\"Supports runtime delegation override via --subagent, --subagent=<name>, or --subagent:<name>. \" +\n\t\t\t\t\"Use 'chain-prompts template1 -> template2' for chaining and add --chain-context to pass previous step summaries into delegated steps.\",\n\t\t\tpromptSnippet:\n\t\t\t\t\"Use this to run slash/prompt templates by name with args (including --loop/--fresh and chain-prompts flows) when the user asks to execute a prompt template.\",\n\t\t\tparameters: Type.Object({\n\t\t\t\tcommand: Type.String({\n\t\t\t\t\tdescription: \"Template name and arguments (e.g. 'deslop --loop 5 --fresh', 'deslop --subagent:worker', 'deslop --subagent', 'chain-prompts analyze -> fix --chain-context', 'chain-prompts analyze -> fix --loop=3')\",\n\t\t\t\t}),\n\t\t\t}),\n\t\t\texecute: async (_id, params) => {\n\t\t\t\tif (!toolEnabled) {\n\t\t\t\t\tthrow new Error(\"run-prompt tool is disabled. User must run `/prompt-tool on` to enable.\");\n\t\t\t\t}\n\t\t\t\tif (deps.isActive()) {\n\t\t\t\t\tthrow new Error(\"A prompt command is already running. Wait for it to complete.\");\n\t\t\t\t}\n\t\t\t\tif (!deps.getStoredCtx()) {\n\t\t\t\t\tthrow new Error(\"No command context. Run any prompt command first to initialize.\");\n\t\t\t\t}\n\n\t\t\t\tconst commandParam = (params as { command?: unknown }).command;\n\t\t\t\tconst command = typeof commandParam === \"string\" ? commandParam.trim() : \"\";\n\t\t\t\tif (!command) {\n\t\t\t\t\tthrow new Error(\"No command specified.\");\n\t\t\t\t}\n\t\t\t\tif (toolQueuedCommand) {\n\t\t\t\t\tthrow new Error(\"A prompt command is already queued. Wait for it to execute.\");\n\t\t\t\t}\n\n\t\t\t\ttoolQueuedCommand = command;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Prompt command queued: \"${command}\". Will execute when this turn ends.` }],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t},\n\t\t});\n\t}\n\n\tfunction registerCommand() {\n\t\tpi.registerCommand(\"prompt-tool\", {\n\t\t\tdescription: \"Manage the run-prompt tool (agent-accessible prompt execution)\",\n\t\t\thandler: async (args, ctx) => {\n\t\t\t\tdeps.setStoredCtx(ctx);\n\t\t\t\tconst trimmed = args.trim();\n\n\t\t\t\tif (trimmed === \"on\" || trimmed.startsWith(\"on \")) {\n\t\t\t\t\ttoolEnabled = true;\n\t\t\t\t\tensureRegistered();\n\t\t\t\t\tconst guidanceRaw = trimmed.slice(\"on\".length).trim();\n\t\t\t\t\tif (guidanceRaw) {\n\t\t\t\t\t\ttoolGuidance = guidanceRaw.replace(/^[\"']|[\"']$/g, \"\");\n\t\t\t\t\t\tnotify(ctx, `run-prompt tool enabled with guidance: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(ctx, \"run-prompt tool enabled.\", \"info\");\n\t\t\t\t\t}\n\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (trimmed === \"off\") {\n\t\t\t\t\ttoolEnabled = false;\n\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\tnotify(ctx, \"run-prompt tool disabled.\", \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (trimmed === \"guidance\" || trimmed.startsWith(\"guidance \")) {\n\t\t\t\t\tif (trimmed === \"guidance\" || trimmed === \"guidance show\") {\n\t\t\t\t\t\tif (toolGuidance) {\n\t\t\t\t\t\t\tnotify(ctx, `Current guidance: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnotify(ctx, \"No guidance set. Use `/prompt-tool guidance <text>` to set.\", \"info\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (trimmed === \"guidance clear\") {\n\t\t\t\t\t\ttoolGuidance = null;\n\t\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\t\tnotify(ctx, \"Guidance cleared.\", \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst guidanceRaw = trimmed.slice(\"guidance\".length).trim();\n\t\t\t\t\t\ttoolGuidance = guidanceRaw.replace(/^[\"']|[\"']$/g, \"\");\n\t\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\t\tnotify(ctx, `Guidance set: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!trimmed) {\n\t\t\t\t\tif (toolEnabled) {\n\t\t\t\t\t\tconst guidanceInfo = toolGuidance ? ` | Guidance: \"${toolGuidance}\"` : \"\";\n\t\t\t\t\t\tnotify(ctx, `run-prompt tool is enabled${guidanceInfo}`, \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(ctx, \"run-prompt tool is disabled\", \"info\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tnotify(ctx, \"Usage: /prompt-tool [on [guidance] | off | guidance [text|clear]]\", \"error\");\n\t\t\t},\n\t\t});\n\t}\n\n\tasync function processQueue(ctx: ExtensionContext, restoreFn: () => Promise<void>) {\n\t\tif (!toolQueuedCommand) return false;\n\t\tconst storedCtx = deps.getStoredCtx();\n\t\tif (!storedCtx) {\n\t\t\ttoolQueuedCommand = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tconst command = toolQueuedCommand;\n\t\ttoolQueuedCommand = null;\n\t\tawait restoreFn();\n\t\ttry {\n\t\t\tawait deps.executeCommand(command, storedCtx);\n\t\t} catch (error) {\n\t\t\tnotify(\n\t\t\t\tctx,\n\t\t\t\t`Failed to execute queued prompt command \"${command}\": ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\"error\",\n\t\t\t);\n\t\t}\n\t\treturn true;\n\t}\n\n\treturn {\n\t\tisEnabled() {\n\t\t\treturn toolEnabled;\n\t\t},\n\t\tgetGuidance() {\n\t\t\treturn toolGuidance;\n\t\t},\n\t\thasQueuedCommand() {\n\t\t\treturn toolQueuedCommand !== null;\n\t\t},\n\t\tclearQueue() {\n\t\t\ttoolQueuedCommand = null;\n\t\t},\n\t\tensureRegistered,\n\t\tregisterCommand,\n\t\tprocessQueue,\n\t};\n}\n"]}
@@ -44,7 +44,8 @@ export function createToolManager(pi, deps) {
44
44
  pi.registerTool({
45
45
  name: "run-prompt",
46
46
  label: "Run Prompt",
47
- description: "Run a prompt template command. Pass the template name and any arguments. " +
47
+ description: "Queue a prompt template command to execute when the current turn ends. Pass the template name and any arguments. " +
48
+ "A queued result confirms acceptance, not completion. Rejected requests fail without changing the queue; wait for queued or running work to finish before retrying. " +
48
49
  "Supports --loop for loops (e.g. 'deslop --loop 5', 'deslop --loop=5', 'deslop --loop' for unlimited until convergence with a 999-iteration cap), " +
49
50
  "--fresh for context collapse between iterations, and --no-converge to disable early stopping for bounded loops. " +
50
51
  "Supports runtime delegation override via --subagent, --subagent=<name>, or --subagent:<name>. " +
@@ -57,39 +58,21 @@ export function createToolManager(pi, deps) {
57
58
  }),
58
59
  execute: async (_id, params) => {
59
60
  if (!toolEnabled) {
60
- return {
61
- content: [{ type: "text", text: "run-prompt tool is disabled. User must run `/prompt-tool on` to enable." }],
62
- details: {},
63
- };
61
+ throw new Error("run-prompt tool is disabled. User must run `/prompt-tool on` to enable.");
64
62
  }
65
63
  if (deps.isActive()) {
66
- return {
67
- content: [{ type: "text", text: "A prompt command is already running. Wait for it to complete." }],
68
- details: {},
69
- };
64
+ throw new Error("A prompt command is already running. Wait for it to complete.");
70
65
  }
71
66
  if (!deps.getStoredCtx()) {
72
- return {
73
- content: [{ type: "text", text: "No command context. Run any prompt command first to initialize." }],
74
- details: {},
75
- isError: true,
76
- };
67
+ throw new Error("No command context. Run any prompt command first to initialize.");
77
68
  }
78
69
  const commandParam = params.command;
79
70
  const command = typeof commandParam === "string" ? commandParam.trim() : "";
80
71
  if (!command) {
81
- return {
82
- content: [{ type: "text", text: "No command specified." }],
83
- details: {},
84
- isError: true,
85
- };
72
+ throw new Error("No command specified.");
86
73
  }
87
74
  if (toolQueuedCommand) {
88
- return {
89
- content: [{ type: "text", text: "A prompt command is already queued. Wait for it to execute." }],
90
- details: {},
91
- isError: true,
92
- };
75
+ throw new Error("A prompt command is already queued. Wait for it to execute.");
93
76
  }
94
77
  toolQueuedCommand = command;
95
78
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"tool-manager.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-prompt-template-model/tool-manager.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from \"@ashx-j/lunr\";\nimport { getAgentDir } from \"../../config.ts\";\nimport { Type } from \"typebox\";\nimport { notify } from \"./notifications.ts\";\n\nexport interface ToolManagerDeps {\n\tisActive(): boolean;\n\tgetStoredCtx(): ExtensionCommandContext | null;\n\tsetStoredCtx(ctx: ExtensionCommandContext | null): void;\n\texecuteCommand(command: string, ctx: ExtensionCommandContext): Promise<void>;\n}\n\nexport function createToolManager(pi: ExtensionAPI, deps: ToolManagerDeps) {\n\tlet toolEnabled = false;\n\tlet toolGuidance: string | null = null;\n\tlet toolRegistered = false;\n\tlet toolQueuedCommand: string | null = null;\n\tconst configPath = join(getAgentDir(), \"prompt-template-model.json\");\n\n\ttry {\n\t\tconst rawConfig = JSON.parse(readFileSync(configPath, \"utf-8\"));\n\t\tif (rawConfig && typeof rawConfig === \"object\") {\n\t\t\tconst config = rawConfig as { toolEnabled?: unknown; toolGuidance?: unknown };\n\t\t\tif (typeof config.toolEnabled === \"boolean\") {\n\t\t\t\ttoolEnabled = config.toolEnabled;\n\t\t\t}\n\t\t\tif (typeof config.toolGuidance === \"string\") {\n\t\t\t\ttoolGuidance = config.toolGuidance;\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tconst err = error as NodeJS.ErrnoException;\n\t\tif (err.code !== \"ENOENT\") {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi-prompt-template-model] Failed to read ${configPath}: ${error instanceof Error ? error.message : String(error)}\\n`,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction saveToolConfig() {\n\t\ttry {\n\t\t\tmkdirSync(getAgentDir(), { recursive: true });\n\t\t\twriteFileSync(configPath, JSON.stringify({ toolEnabled, toolGuidance }, null, 2));\n\t\t} catch (error) {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi-prompt-template-model] Failed to write ${configPath}: ${error instanceof Error ? error.message : String(error)}\\n`,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction ensureRegistered() {\n\t\tif (toolRegistered) return;\n\t\ttoolRegistered = true;\n\t\tpi.registerTool({\n\t\t\tname: \"run-prompt\",\n\t\t\tlabel: \"Run Prompt\",\n\t\t\tdescription:\n\t\t\t\t\"Run a prompt template command. Pass the template name and any arguments. \" +\n\t\t\t\t\"Supports --loop for loops (e.g. 'deslop --loop 5', 'deslop --loop=5', 'deslop --loop' for unlimited until convergence with a 999-iteration cap), \" +\n\t\t\t\t\"--fresh for context collapse between iterations, and --no-converge to disable early stopping for bounded loops. \" +\n\t\t\t\t\"Supports runtime delegation override via --subagent, --subagent=<name>, or --subagent:<name>. \" +\n\t\t\t\t\"Use 'chain-prompts template1 -> template2' for chaining and add --chain-context to pass previous step summaries into delegated steps.\",\n\t\t\tpromptSnippet:\n\t\t\t\t\"Use this to run slash/prompt templates by name with args (including --loop/--fresh and chain-prompts flows) when the user asks to execute a prompt template.\",\n\t\t\tparameters: Type.Object({\n\t\t\t\tcommand: Type.String({\n\t\t\t\t\tdescription: \"Template name and arguments (e.g. 'deslop --loop 5 --fresh', 'deslop --subagent:worker', 'deslop --subagent', 'chain-prompts analyze -> fix --chain-context', 'chain-prompts analyze -> fix --loop=3')\",\n\t\t\t\t}),\n\t\t\t}),\n\t\t\texecute: async (_id, params) => {\n\t\t\t\tif (!toolEnabled) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"run-prompt tool is disabled. User must run `/prompt-tool on` to enable.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (deps.isActive()) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"A prompt command is already running. Wait for it to complete.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (!deps.getStoredCtx()) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No command context. Run any prompt command first to initialize.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst commandParam = (params as { command?: unknown }).command;\n\t\t\t\tconst command = typeof commandParam === \"string\" ? commandParam.trim() : \"\";\n\t\t\t\tif (!command) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No command specified.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (toolQueuedCommand) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"A prompt command is already queued. Wait for it to execute.\" }],\n\t\t\t\t\t\tdetails: {},\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\ttoolQueuedCommand = command;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Prompt command queued: \"${command}\". Will execute when this turn ends.` }],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t},\n\t\t});\n\t}\n\n\tfunction registerCommand() {\n\t\tpi.registerCommand(\"prompt-tool\", {\n\t\t\tdescription: \"Manage the run-prompt tool (agent-accessible prompt execution)\",\n\t\t\thandler: async (args, ctx) => {\n\t\t\t\tdeps.setStoredCtx(ctx);\n\t\t\t\tconst trimmed = args.trim();\n\n\t\t\t\tif (trimmed === \"on\" || trimmed.startsWith(\"on \")) {\n\t\t\t\t\ttoolEnabled = true;\n\t\t\t\t\tensureRegistered();\n\t\t\t\t\tconst guidanceRaw = trimmed.slice(\"on\".length).trim();\n\t\t\t\t\tif (guidanceRaw) {\n\t\t\t\t\t\ttoolGuidance = guidanceRaw.replace(/^[\"']|[\"']$/g, \"\");\n\t\t\t\t\t\tnotify(ctx, `run-prompt tool enabled with guidance: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(ctx, \"run-prompt tool enabled.\", \"info\");\n\t\t\t\t\t}\n\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (trimmed === \"off\") {\n\t\t\t\t\ttoolEnabled = false;\n\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\tnotify(ctx, \"run-prompt tool disabled.\", \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (trimmed === \"guidance\" || trimmed.startsWith(\"guidance \")) {\n\t\t\t\t\tif (trimmed === \"guidance\" || trimmed === \"guidance show\") {\n\t\t\t\t\t\tif (toolGuidance) {\n\t\t\t\t\t\t\tnotify(ctx, `Current guidance: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnotify(ctx, \"No guidance set. Use `/prompt-tool guidance <text>` to set.\", \"info\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (trimmed === \"guidance clear\") {\n\t\t\t\t\t\ttoolGuidance = null;\n\t\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\t\tnotify(ctx, \"Guidance cleared.\", \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst guidanceRaw = trimmed.slice(\"guidance\".length).trim();\n\t\t\t\t\t\ttoolGuidance = guidanceRaw.replace(/^[\"']|[\"']$/g, \"\");\n\t\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\t\tnotify(ctx, `Guidance set: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!trimmed) {\n\t\t\t\t\tif (toolEnabled) {\n\t\t\t\t\t\tconst guidanceInfo = toolGuidance ? ` | Guidance: \"${toolGuidance}\"` : \"\";\n\t\t\t\t\t\tnotify(ctx, `run-prompt tool is enabled${guidanceInfo}`, \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(ctx, \"run-prompt tool is disabled\", \"info\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tnotify(ctx, \"Usage: /prompt-tool [on [guidance] | off | guidance [text|clear]]\", \"error\");\n\t\t\t},\n\t\t});\n\t}\n\n\tasync function processQueue(ctx: ExtensionContext, restoreFn: () => Promise<void>) {\n\t\tif (!toolQueuedCommand) return false;\n\t\tconst storedCtx = deps.getStoredCtx();\n\t\tif (!storedCtx) {\n\t\t\ttoolQueuedCommand = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tconst command = toolQueuedCommand;\n\t\ttoolQueuedCommand = null;\n\t\tawait restoreFn();\n\t\ttry {\n\t\t\tawait deps.executeCommand(command, storedCtx);\n\t\t} catch (error) {\n\t\t\tnotify(\n\t\t\t\tctx,\n\t\t\t\t`Failed to execute queued prompt command \"${command}\": ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\"error\",\n\t\t\t);\n\t\t}\n\t\treturn true;\n\t}\n\n\treturn {\n\t\tisEnabled() {\n\t\t\treturn toolEnabled;\n\t\t},\n\t\tgetGuidance() {\n\t\t\treturn toolGuidance;\n\t\t},\n\t\thasQueuedCommand() {\n\t\t\treturn toolQueuedCommand !== null;\n\t\t},\n\t\tclearQueue() {\n\t\t\ttoolQueuedCommand = null;\n\t\t},\n\t\tensureRegistered,\n\t\tregisterCommand,\n\t\tprocessQueue,\n\t};\n}\n"]}
1
+ {"version":3,"file":"tool-manager.js","sourceRoot":"","sources":["../../../src/builtin-extensions/pi-prompt-template-model/tool-manager.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from \"@ashx-j/lunr\";\nimport { getAgentDir } from \"../../config.ts\";\nimport { Type } from \"typebox\";\nimport { notify } from \"./notifications.ts\";\n\nexport interface ToolManagerDeps {\n\tisActive(): boolean;\n\tgetStoredCtx(): ExtensionCommandContext | null;\n\tsetStoredCtx(ctx: ExtensionCommandContext | null): void;\n\texecuteCommand(command: string, ctx: ExtensionCommandContext): Promise<void>;\n}\n\nexport function createToolManager(pi: ExtensionAPI, deps: ToolManagerDeps) {\n\tlet toolEnabled = false;\n\tlet toolGuidance: string | null = null;\n\tlet toolRegistered = false;\n\tlet toolQueuedCommand: string | null = null;\n\tconst configPath = join(getAgentDir(), \"prompt-template-model.json\");\n\n\ttry {\n\t\tconst rawConfig = JSON.parse(readFileSync(configPath, \"utf-8\"));\n\t\tif (rawConfig && typeof rawConfig === \"object\") {\n\t\t\tconst config = rawConfig as { toolEnabled?: unknown; toolGuidance?: unknown };\n\t\t\tif (typeof config.toolEnabled === \"boolean\") {\n\t\t\t\ttoolEnabled = config.toolEnabled;\n\t\t\t}\n\t\t\tif (typeof config.toolGuidance === \"string\") {\n\t\t\t\ttoolGuidance = config.toolGuidance;\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tconst err = error as NodeJS.ErrnoException;\n\t\tif (err.code !== \"ENOENT\") {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi-prompt-template-model] Failed to read ${configPath}: ${error instanceof Error ? error.message : String(error)}\\n`,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction saveToolConfig() {\n\t\ttry {\n\t\t\tmkdirSync(getAgentDir(), { recursive: true });\n\t\t\twriteFileSync(configPath, JSON.stringify({ toolEnabled, toolGuidance }, null, 2));\n\t\t} catch (error) {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[pi-prompt-template-model] Failed to write ${configPath}: ${error instanceof Error ? error.message : String(error)}\\n`,\n\t\t\t);\n\t\t}\n\t}\n\n\tfunction ensureRegistered() {\n\t\tif (toolRegistered) return;\n\t\ttoolRegistered = true;\n\t\tpi.registerTool({\n\t\t\tname: \"run-prompt\",\n\t\t\tlabel: \"Run Prompt\",\n\t\t\tdescription:\n\t\t\t\t\"Queue a prompt template command to execute when the current turn ends. Pass the template name and any arguments. \" +\n\t\t\t\t\"A queued result confirms acceptance, not completion. Rejected requests fail without changing the queue; wait for queued or running work to finish before retrying. \" +\n\t\t\t\t\"Supports --loop for loops (e.g. 'deslop --loop 5', 'deslop --loop=5', 'deslop --loop' for unlimited until convergence with a 999-iteration cap), \" +\n\t\t\t\t\"--fresh for context collapse between iterations, and --no-converge to disable early stopping for bounded loops. \" +\n\t\t\t\t\"Supports runtime delegation override via --subagent, --subagent=<name>, or --subagent:<name>. \" +\n\t\t\t\t\"Use 'chain-prompts template1 -> template2' for chaining and add --chain-context to pass previous step summaries into delegated steps.\",\n\t\t\tpromptSnippet:\n\t\t\t\t\"Use this to run slash/prompt templates by name with args (including --loop/--fresh and chain-prompts flows) when the user asks to execute a prompt template.\",\n\t\t\tparameters: Type.Object({\n\t\t\t\tcommand: Type.String({\n\t\t\t\t\tdescription: \"Template name and arguments (e.g. 'deslop --loop 5 --fresh', 'deslop --subagent:worker', 'deslop --subagent', 'chain-prompts analyze -> fix --chain-context', 'chain-prompts analyze -> fix --loop=3')\",\n\t\t\t\t}),\n\t\t\t}),\n\t\t\texecute: async (_id, params) => {\n\t\t\t\tif (!toolEnabled) {\n\t\t\t\t\tthrow new Error(\"run-prompt tool is disabled. User must run `/prompt-tool on` to enable.\");\n\t\t\t\t}\n\t\t\t\tif (deps.isActive()) {\n\t\t\t\t\tthrow new Error(\"A prompt command is already running. Wait for it to complete.\");\n\t\t\t\t}\n\t\t\t\tif (!deps.getStoredCtx()) {\n\t\t\t\t\tthrow new Error(\"No command context. Run any prompt command first to initialize.\");\n\t\t\t\t}\n\n\t\t\t\tconst commandParam = (params as { command?: unknown }).command;\n\t\t\t\tconst command = typeof commandParam === \"string\" ? commandParam.trim() : \"\";\n\t\t\t\tif (!command) {\n\t\t\t\t\tthrow new Error(\"No command specified.\");\n\t\t\t\t}\n\t\t\t\tif (toolQueuedCommand) {\n\t\t\t\t\tthrow new Error(\"A prompt command is already queued. Wait for it to execute.\");\n\t\t\t\t}\n\n\t\t\t\ttoolQueuedCommand = command;\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Prompt command queued: \"${command}\". Will execute when this turn ends.` }],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t},\n\t\t});\n\t}\n\n\tfunction registerCommand() {\n\t\tpi.registerCommand(\"prompt-tool\", {\n\t\t\tdescription: \"Manage the run-prompt tool (agent-accessible prompt execution)\",\n\t\t\thandler: async (args, ctx) => {\n\t\t\t\tdeps.setStoredCtx(ctx);\n\t\t\t\tconst trimmed = args.trim();\n\n\t\t\t\tif (trimmed === \"on\" || trimmed.startsWith(\"on \")) {\n\t\t\t\t\ttoolEnabled = true;\n\t\t\t\t\tensureRegistered();\n\t\t\t\t\tconst guidanceRaw = trimmed.slice(\"on\".length).trim();\n\t\t\t\t\tif (guidanceRaw) {\n\t\t\t\t\t\ttoolGuidance = guidanceRaw.replace(/^[\"']|[\"']$/g, \"\");\n\t\t\t\t\t\tnotify(ctx, `run-prompt tool enabled with guidance: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(ctx, \"run-prompt tool enabled.\", \"info\");\n\t\t\t\t\t}\n\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (trimmed === \"off\") {\n\t\t\t\t\ttoolEnabled = false;\n\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\tnotify(ctx, \"run-prompt tool disabled.\", \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (trimmed === \"guidance\" || trimmed.startsWith(\"guidance \")) {\n\t\t\t\t\tif (trimmed === \"guidance\" || trimmed === \"guidance show\") {\n\t\t\t\t\t\tif (toolGuidance) {\n\t\t\t\t\t\t\tnotify(ctx, `Current guidance: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnotify(ctx, \"No guidance set. Use `/prompt-tool guidance <text>` to set.\", \"info\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (trimmed === \"guidance clear\") {\n\t\t\t\t\t\ttoolGuidance = null;\n\t\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\t\tnotify(ctx, \"Guidance cleared.\", \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst guidanceRaw = trimmed.slice(\"guidance\".length).trim();\n\t\t\t\t\t\ttoolGuidance = guidanceRaw.replace(/^[\"']|[\"']$/g, \"\");\n\t\t\t\t\t\tsaveToolConfig();\n\t\t\t\t\t\tnotify(ctx, `Guidance set: \"${toolGuidance}\"`, \"info\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!trimmed) {\n\t\t\t\t\tif (toolEnabled) {\n\t\t\t\t\t\tconst guidanceInfo = toolGuidance ? ` | Guidance: \"${toolGuidance}\"` : \"\";\n\t\t\t\t\t\tnotify(ctx, `run-prompt tool is enabled${guidanceInfo}`, \"info\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnotify(ctx, \"run-prompt tool is disabled\", \"info\");\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tnotify(ctx, \"Usage: /prompt-tool [on [guidance] | off | guidance [text|clear]]\", \"error\");\n\t\t\t},\n\t\t});\n\t}\n\n\tasync function processQueue(ctx: ExtensionContext, restoreFn: () => Promise<void>) {\n\t\tif (!toolQueuedCommand) return false;\n\t\tconst storedCtx = deps.getStoredCtx();\n\t\tif (!storedCtx) {\n\t\t\ttoolQueuedCommand = null;\n\t\t\treturn false;\n\t\t}\n\n\t\tconst command = toolQueuedCommand;\n\t\ttoolQueuedCommand = null;\n\t\tawait restoreFn();\n\t\ttry {\n\t\t\tawait deps.executeCommand(command, storedCtx);\n\t\t} catch (error) {\n\t\t\tnotify(\n\t\t\t\tctx,\n\t\t\t\t`Failed to execute queued prompt command \"${command}\": ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\"error\",\n\t\t\t);\n\t\t}\n\t\treturn true;\n\t}\n\n\treturn {\n\t\tisEnabled() {\n\t\t\treturn toolEnabled;\n\t\t},\n\t\tgetGuidance() {\n\t\t\treturn toolGuidance;\n\t\t},\n\t\thasQueuedCommand() {\n\t\t\treturn toolQueuedCommand !== null;\n\t\t},\n\t\tclearQueue() {\n\t\t\ttoolQueuedCommand = null;\n\t\t},\n\t\tensureRegistered,\n\t\tregisterCommand,\n\t\tprocessQueue,\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/builtin-extensions/pi-subagents/src/extension/index.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAoC,MAAM,iCAAiC,CAAC;AAEtG,OAAO,EAAO,SAAS,EAAU,IAAI,EAAmE,MAAM,wBAAwB,CAAC;AAsCvI,OAAO,EAGN,KAAK,aAAa,EAYlB,MAAM,oBAAoB,CAAC;AAS5B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiFzC,wBAAgB,iCAAiC,CAAC,IAAI,KAAA,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAgBhG;AAED,wBAAgB,kBAAkB,CAAC,OAAO,KAAA,EAAE,KAAK,KAAA,EAAE,OAAO,KAAA,EAAE,OAAO,KAAA,oBA4ClE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,KAAA,EAAE,KAAK,KAAA,QASlD;AA8FD,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAucxE","sourcesContent":["// @ts-nocheck\n/**\n * Subagent Tool\n *\n * Full-featured subagent with foreground and async modes.\n * - Async (default): Background execution, emits events when done\n * - Foreground (async:false or clarify:true): Streams output, renders markdown, tracks usage\n *\n * Modes: single (agent + task), parallel (tasks[]), chain (chain[] with {previous})\n *\n * Config file: ~/.lunr/agent/extensions/subagent/config.json\n * { \"maxSubagentDepth\": 1, \"intercomBridge\": { \"mode\": \"always\", \"instructionFile\": \"./intercom-bridge.md\" }, \"worktreeSetupHook\": \"./scripts/setup-worktree.mjs\" }\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { createSubagentCancellation, registerSubagentCancellation } from \"../../../../core/subagent-cancellation.ts\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { AgentToolResult } from \"@ashx-j/lunr-agent\";\nimport type { ExtensionAPI, ExtensionContext, ToolDefinition } from \"@ashx-j/lunr\";\nimport { awaitWithAbort } from \"../../../../utils/await-with-abort.ts\";\nimport { Box, Container, Spacer, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi, type Component } from \"@ashx-j/lunr-tui\";\n\nimport { cleanupAllArtifactDirs, cleanupOldArtifacts, getArtifactsDir } from \"../shared/artifacts.ts\";\nimport { resolveCurrentSessionId } from \"../shared/session-identity.ts\";\nimport { cleanupOldChainDirs } from \"../shared/settings.ts\";\nimport {\n\tclearLegacyResultAnimationTimer,\n\tdisposeSubagentWidget,\n\trenderSubagentResult,\n\tSUBAGENT_PAINT_INTERVAL_MS,\n\tsubagentAnimSink,\n} from \"../tui/render.ts\";\nimport { SubagentParams } from \"./schemas.ts\";\nimport { validateChainInput } from \"./chain-validation.ts\";\nimport type { createSubagentExecutor, SubagentParamsLike } from \"../runs/foreground/subagent-executor.ts\";\nimport { resolveSubagentRequestParams } from \"../runs/foreground/request-params.ts\";\nimport { createAsyncJobTracker } from \"../runs/background/async-job-tracker.ts\";\nimport { createResultWatcher } from \"../runs/background/result-watcher.ts\";\nimport { createScheduledRunManager } from \"../runs/background/scheduled-runs.ts\";\nimport { isAsyncSubagentExecution, normalizeAsyncLaunchConfig, subagentLaunchRunsAsync } from \"../runs/background/top-level-async.ts\";\nimport { registerSlashCommands } from \"../slash/slash-commands.ts\";\nimport { registerPromptTemplateDelegationBridge } from \"../slash/prompt-template-bridge.ts\";\nimport { registerMainWatchdog } from \"../watchdog/register-main.ts\";\nimport { registerSlashSubagentBridge } from \"../slash/slash-bridge.ts\";\nimport { createNativeSupervisorChannel, registerSupervisorRenderers } from \"../intercom/native-supervisor-channel.ts\";\nimport { renderCommunicationCall, renderCommunicationResult } from \"../tui/communication.ts\";\nimport { registerSubagentRpcBridge } from \"./rpc.ts\";\nimport { clearSlashSnapshots, getSlashRenderableSnapshot, resolveSlashMessageDetails, restoreSlashFinalSnapshots, type SlashMessageDetails } from \"../slash/slash-live-state.ts\";\nimport { inspectSubagentStatus } from \"../runs/background/run-status.ts\";\nimport { resolveWaitToolConfig } from \"../runs/background/subagent-wait.ts\";\nimport { registerWaitTool } from \"../runs/background/wait-tool.ts\";\nimport { drainOutstandingWork } from \"../runs/background/auto-drain.ts\";\nimport registerSubagentNotify, { parseSubagentNotifyContent, type SubagentNotifyDetails } from \"../runs/background/notify.ts\";\nimport { formatSteeringNotice, handleSubagentSteeringNotice, SUBAGENT_STEERING_MESSAGE_TYPE, type SubagentSteeringMessageDetails } from \"./steering-notices.ts\";\nimport { SUBAGENT_CHILD_ENV, SUBAGENT_PARENT_SESSION_ENV } from \"../runs/shared/pi-args.ts\";\n\nimport { loadConfig } from \"./config.ts\";\nimport { buildSubagentToolDescription } from \"./tool-description.ts\";\nimport {\n\ttype AsyncJobState,\n\ttype Details,\n\ttype SubagentState,\n\tASYNC_DIR,\n\tchildRowLabel,\n\tDEFAULT_ARTIFACT_CONFIG,\n\tRESULTS_DIR,\n\tSLASH_RESULT_TYPE,\n\tSLASH_TEXT_RESULT_TYPE,\n\tSUBAGENT_ASYNC_COMPLETE_EVENT,\n\tSUBAGENT_ASYNC_STARTED_EVENT,\n\tSUBAGENT_CONTROL_EVENT,\n\tSUBAGENT_STEERING_NOTICE_EVENT,\n\tWIDGET_KEY,\n} from \"../shared/types.ts\";\nimport {\n\tclearPendingForegroundControlNotices,\n\tformatSubagentControlNotice,\n\thandleSubagentControlNotice,\n\tSUBAGENT_CONTROL_MESSAGE_TYPE,\n\ttype SubagentControlMessageDetails,\n} from \"./control-notices.ts\";\n\nexport { loadConfig } from \"./config.ts\";\n\n/**\n * Derive subagent session base directory from parent session file.\n * If parent session is ~/.lunr/agent/sessions/abc123.jsonl,\n * returns ~/.lunr/agent/sessions/abc123/ as the base.\n * Callers add runId to create the actual session root: abc123/{runId}/\n * Falls back to a unique temp directory if no parent session.\n */\nfunction getSubagentSessionRoot(parentSessionFile: string | null): string {\n\tif (parentSessionFile) {\n\t\tconst baseName = path.basename(parentSessionFile, \".jsonl\");\n\t\tconst sessionsDir = path.dirname(parentSessionFile);\n\t\treturn path.join(sessionsDir, baseName);\n\t}\n\treturn fs.mkdtempSync(path.join(os.tmpdir(), \"pi-subagent-session-\"));\n}\n\nfunction expandTilde(p: string): string {\n\treturn p.startsWith(\"~/\") ? path.join(os.homedir(), p.slice(2)) : p;\n}\n\n/**\n * Create a directory and verify it is actually accessible.\n * On Windows with Azure AD/Entra ID, directories created shortly after\n * wake-from-sleep can end up with broken NTFS ACLs (null DACL) when the\n * cloud SID cannot be resolved without network connectivity. This leaves\n * the directory completely inaccessible to the creating user.\n */\nfunction ensureAccessibleDir(dirPath: string): void {\n\tfs.mkdirSync(dirPath, { recursive: true });\n\ttry {\n\t\tfs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n\t} catch {\n\t\ttry {\n\t\t\tfs.rmSync(dirPath, { recursive: true, force: true });\n\t\t} catch {\n\t\t\t// Best effort: retry mkdir/access even if cleanup fails.\n\t\t}\n\t\tfs.mkdirSync(dirPath, { recursive: true });\n\t\tfs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n\t}\n}\n\nfunction isSlashResultRunning(result: { details?: Details }): boolean {\n\treturn result.details?.progress?.some((entry) => entry.status === \"running\")\n\t\t|| result.details?.results.some((entry) => entry.progress?.status === \"running\")\n\t\t|| false;\n}\n\n// Drives the inline running-indicator braille animation for foreground subagent\n// results. Foreground runs receive progress only on child events, so the glyph\n// (derived from progress fields) would freeze between events. While a result is\n// running we tick a frame counter every 80ms; renderResult registers the\n// running-glyph lines in state.animEntries (via subagentAnimSink) and the timer\n// rewrites just those Text nodes + requests a repaint, instead of invalidate()-ing\n// the whole tool component (a full renderSubagentResult rebuild 12.5x/s made the\n// spinner laggy).\nfunction subagentResultIsRunning(result: { details?: Details }): boolean {\n\treturn result.details?.progress?.some((entry) => entry.status === \"running\")\n\t\t|| result.details?.results.some((entry) => entry.progress?.status === \"running\")\n\t\t|| false;\n}\n\nfunction effectiveParallelTaskCount(tasks: Array<{ count?: unknown }> | undefined): number {\n\tif (!tasks || tasks.length === 0) return 0;\n\treturn tasks.reduce((total, task) => {\n\t\tconst count = typeof task.count === \"number\" && Number.isInteger(task.count) && task.count >= 1 ? task.count : 1;\n\t\treturn total + count;\n\t}, 0);\n}\n\nfunction matchingActionJobs(state: SubagentState, requestedId: string): AsyncJobState[] {\n\tconst jobs = new Map<string, AsyncJobState>();\n\tfor (const job of state.asyncJobs.values()) jobs.set(job.asyncId, job);\n\tfor (const job of state.fleetJobs?.values() ?? []) jobs.set(job.asyncId, job);\n\tconst exact = jobs.get(requestedId);\n\tif (exact) return [exact];\n\treturn [...jobs.values()].filter((job) => job.asyncId.startsWith(requestedId));\n}\n\nexport function resolveSubagentActionDisplayTitle(args, state: SubagentState): string | undefined {\n\tconst requestedId = (args.id || args.runId || \"\").trim();\n\tif (!requestedId) return undefined;\n\tconst matches = matchingActionJobs(state, requestedId);\n\tif (matches.length !== 1) return undefined;\n\tconst job = matches[0]!;\n\tconst steps = job.steps ?? [];\n\tif (Number.isInteger(args.index)) {\n\t\tconst step = steps.find((candidate) => candidate.index === args.index) ?? steps[args.index];\n\t\treturn step ? childRowLabel(step) : undefined;\n\t}\n\tif (steps.length === 1) return childRowLabel(steps[0]!);\n\tif (steps.length > 1) return `${job.mode ?? \"subagent\"} run`;\n\tif (job.agents?.length === 1) return job.agents[0];\n\tif (job.agents?.length) return `${job.mode ?? \"subagent\"} run`;\n\treturn undefined;\n}\n\nexport function renderSubagentCall(rawArgs, theme, context, options) {\n\tconst args = resolveSubagentRequestParams(rawArgs);\n\tif (args.action) {\n\t\tconst resultTitle = context?.result?.details?.displayTitle;\n\t\tconst resolvedTitle = resultTitle || options?.resolveActionTitle?.(args);\n\t\tconst target = resolvedTitle || args.id || args.runId || \"\";\n\t\tif ((args.action === \"steer\" || args.action === \"resume\") && args.message) {\n\t\t\treturn renderCommunicationCall(\n\t\t\t\t\"subagent\",\n\t\t\t\targs,\n\t\t\t\ttheme,\n\t\t\t\tcontext,\n\t\t\t\t{ direction: \"to\", peer: resolvedTitle || \"Subagent\", kind: \"steer\", message: args.message },\n\t\t\t\tresolvedTitle,\n\t\t\t);\n\t\t}\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"subagent \"))}${args.action}${target ? ` ${theme.fg(\"accent\", target)}` : \"\"}`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tconst isParallel = (args.tasks?.length ?? 0) > 0;\n\tconst parallelCount = effectiveParallelTaskCount(args.tasks as Array<{ count?: unknown }> | undefined);\n\tconst asyncMark = subagentLaunchRunsAsync(args) ? `${theme.fg(\"warning\", \"async\")} ` : \"\";\n\tif (args.chain?.length) {\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"subagent \"))}${asyncMark}chain (${args.chain.length})`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tif (isParallel) {\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"subagent \"))}${asyncMark}parallel (${parallelCount})`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tconst showDescription = !context?.result && !context?.isPartial && !context?.expanded && !context?.isError;\n\tconst description = showDescription ? theme.fg(\"accent\", args.description || args.task || \"?\") : \"\";\n\tconst title = theme.fg(\"toolTitle\", theme.bold(\"subagent\"));\n\tconst rest = [asyncMark.trim() ? theme.fg(\"warning\", \"async\") : \"\", description].filter(Boolean).join(\" \");\n\treturn new Text(rest ? `${title} ${rest}` : title, 0, 0);\n}\n\nexport function renderSubagentNotify(details, theme) {\n\tconst status = typeof details?.status === \"string\" ? details.status : \"\";\n\tconst icon = status === \"completed\"\n\t\t? theme.fg(\"success\", \"✓\")\n\t\t: status === \"failed\"\n\t\t\t? theme.fg(\"error\", \"✗\")\n\t\t\t: theme.fg(\"warning\", \"■\");\n\tconst title = details?.agent || \"child\";\n\treturn new Text(`${icon} ${theme.bold(title)} ${theme.fg(\"dim\", status)}`, 0, 0);\n}\n\nfunction ensureSubagentResultAnimation(context: { state: Record<string, unknown>; invalidate?: () => void; requestRender?: () => void }): void {\n\tconst state = context.state as {\n\t\tsubagentResultAnimationTimer?: ReturnType<typeof setInterval>;\n\t\tframe?: number;\n\t\tanimEntries?: Array<{ text: Text; line: (frame: number, now: number) => string }>;\n\t};\n\tif (state.subagentResultAnimationTimer) return;\n\tif (typeof context.invalidate !== \"function\") return;\n\tif (state.frame === undefined) state.frame = 0;\n\tstate.subagentResultAnimationTimer = setInterval(() => {\n\t\tstate.frame = (state.frame ?? 0) + 1;\n\t\ttry {\n\t\t\tconst entries = state.animEntries;\n\t\t\tif (entries?.length && typeof context.requestRender === \"function\") {\n\t\t\t\tconst now = Date.now();\n\t\t\t\tfor (const entry of entries) entry.text.setText(entry.line(state.frame ?? 0, now));\n\t\t\t\tcontext.requestRender();\n\t\t\t} else {\n\t\t\t\tcontext.invalidate();\n\t\t\t}\n\t\t} catch {}\n\t}, SUBAGENT_PAINT_INTERVAL_MS);\n}\n\nfunction isSlashResultError(result: { details?: Details }): boolean {\n\treturn result.details?.results.some((entry) => entry.exitCode !== 0 && entry.progress?.status !== \"running\") || false;\n}\n\nfunction isStaleExtensionContextError(error: unknown): boolean {\n\treturn error instanceof Error && error.message.includes(\"Extension context no longer active\");\n}\n\nfunction rebuildSlashResultContainer(\n\tcontainer: Container,\n\tresult: AgentToolResult<Details>,\n\toptions: { expanded: boolean },\n\ttheme: ExtensionContext[\"ui\"][\"theme\"],\n): void {\n\tcontainer.clear();\n\tcontainer.addChild(new Spacer(1));\n\tconst boxTheme = isSlashResultRunning(result) ? \"toolPendingBg\" : isSlashResultError(result) ? \"toolErrorBg\" : \"toolSuccessBg\";\n\tconst box = new Box(1, 1, (text: string) => theme.bg(boxTheme, text));\n\tbox.addChild(renderSubagentResult(result, options, theme));\n\tcontainer.addChild(box);\n}\n\nfunction createSlashResultComponent(\n\tdetails: SlashMessageDetails,\n\toptions: { expanded: boolean },\n\ttheme: ExtensionContext[\"ui\"][\"theme\"],\n): Container {\n\tconst container = new Container();\n\tlet lastVersion = -1;\n\tcontainer.render = (width: number): string[] => {\n\t\tconst snapshot = getSlashRenderableSnapshot(details);\n\t\tif (snapshot.version !== lastVersion || isSlashResultRunning(snapshot.result)) {\n\t\t\tlastVersion = snapshot.version;\n\t\t\trebuildSlashResultContainer(container, snapshot.result, options, theme);\n\t\t}\n\t\treturn Container.prototype.render.call(container, width);\n\t};\n\treturn container;\n}\n\nclass SubagentControlNoticeComponent implements Component {\n\tconstructor(\n\t\tprivate readonly details: SubagentControlMessageDetails,\n\t\tprivate readonly theme: ExtensionContext[\"ui\"][\"theme\"],\n\t) {}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst eventLabel = this.details.event.type.replaceAll(\"_\", \" \");\n\t\tif (width < 3) return [truncateToWidth(`Subagent ${eventLabel}`, width)];\n\t\tconst bodyWidth = Math.max(1, width - 2);\n\t\tconst borderChar = \"─\";\n\t\tconst header = ` ⚠ Subagent ${eventLabel}: ${this.details.event.agent} `;\n\t\tconst headerText = truncateToWidth(header, bodyWidth, \"\");\n\t\tconst headerPadding = Math.max(0, bodyWidth - visibleWidth(headerText));\n\t\tconst lines = [this.theme.fg(\"accent\", `╭${headerText}${borderChar.repeat(headerPadding)}╮`)];\n\n\t\tfor (const line of wrapTextWithAnsi(formatSubagentControlNotice(this.details), bodyWidth)) {\n\t\t\tconst text = truncateToWidth(line, bodyWidth, \"\");\n\t\t\tconst padding = Math.max(0, bodyWidth - visibleWidth(text));\n\t\t\tlines.push(this.theme.fg(\"accent\", `│${text}${\" \".repeat(padding)}│`));\n\t\t}\n\t\tlines.push(this.theme.fg(\"accent\", `╰${borderChar.repeat(bodyWidth)}╯`));\n\t\treturn lines;\n\t}\n}\n\nexport default function registerSubagentExtension(pi: ExtensionAPI): void {\n\tif (process.env[SUBAGENT_CHILD_ENV] === \"1\") {\n\t\treturn;\n\t}\n\tconst globalStore = globalThis as Record<string, unknown>;\n\tconst runtimeCleanupStoreKey = \"__piSubagentRuntimeCleanup\";\n\tconst previousRuntimeCleanup = globalStore[runtimeCleanupStoreKey];\n\tif (typeof previousRuntimeCleanup === \"function\") {\n\t\ttry {\n\t\t\tpreviousRuntimeCleanup();\n\t\t} catch {\n\t\t\t// Best effort cleanup for stale timers from an older reload.\n\t\t}\n\t}\n\n\tensureAccessibleDir(RESULTS_DIR);\n\tensureAccessibleDir(ASYNC_DIR);\n\tcleanupOldChainDirs();\n\n\tconst config = normalizeAsyncLaunchConfig(loadConfig());\n\tconst waitToolConfig = resolveWaitToolConfig(config.waitTool);\n\tconst tempArtifactsDir = getArtifactsDir(null);\n\tcleanupAllArtifactDirs(DEFAULT_ARTIFACT_CONFIG.cleanupDays);\n\n\tconst state: SubagentState = {\n\t\tbaseCwd: \"\",\n\t\tcurrentSessionId: null,\n\t\tsessionGeneration: 0,\n\t\tforegroundSubagentInFlight: 0,\n\t\tsubagentSpawns: { sessionId: null, count: 0 },\n\t\tasyncJobs: new Map(),\n\t\tfleetJobs: new Map(),\n\t\tforegroundRuns: new Map(),\n\t\tforegroundControls: new Map(),\n\t\tlastForegroundControlId: null,\n\t\tpendingForegroundControlNotices: new Map(),\n\t\tcleanupTimers: new Map(),\n\t\tlastUiContext: null,\n\t\tpoller: null,\n\t\tcompletionSeen: new Map(),\n\t\twatcher: null,\n\t\twatcherRestartTimer: null,\n\t\tresultFileCoalescer: {\n\t\t\tschedule: () => false,\n\t\t\tclear: () => {},\n\t\t},\n\t};\n\n\tconst supervisorChannel = createNativeSupervisorChannel(pi, state);\n\tconst mainWatchdog = registerMainWatchdog(pi);\n\tconst { startResultWatcher, primeExistingResults, stopResultWatcher } = createResultWatcher(\n\t\tpi,\n\t\tstate,\n\t\tRESULTS_DIR,\n\t\t10 * 60 * 1000,\n\t);\n\tstartResultWatcher();\n\tprimeExistingResults();\n\n\tlet generation = 0;\n\tlet executorPromise: Promise<ReturnType<typeof createSubagentExecutor>> | undefined;\n\tconst pendingLaunches = new Set<Promise<void>>();\n\tconst pendingAsyncLaunches = new Set<Promise<void>>();\n\tlet unregisterCancellation: (() => void) | undefined;\n\tconst runtimeCleanup = () => {\n\t\tgeneration++;\n\t\tsupervisorChannel.cancelOwnedQuestions(\"parent runtime replaced\");\n\t\tstate.sessionGeneration = (state.sessionGeneration ?? 0) + 1;\n\t\texecutorPromise = undefined;\n\t\tpendingLaunches.clear();\n\t\tpendingAsyncLaunches.clear();\n\t\tunregisterCancellation?.();\n\t\tmainWatchdog.dispose();\n\t\tstopResultWatcher();\n\t\tscheduledRunManager.stop();\n\t\tsupervisorChannel.dispose();\n\t\tclearPendingForegroundControlNotices(state);\n\t\tdisposeSubagentWidget();\n\t\tif (state.poller) {\n\t\t\tclearInterval(state.poller);\n\t\t\tstate.poller = null;\n\t\t}\n\t};\n\tglobalStore[runtimeCleanupStoreKey] = runtimeCleanup;\n\n\tconst { ensurePoller, refreshWidget, handleStarted, handleComplete: trackComplete, resetJobs, restoreActiveJobs } = createAsyncJobTracker(pi, state, ASYNC_DIR, {\n\t\twidgetEnabled: config.asyncWidget !== false,\n\t});\n\tconst handleComplete = (data: unknown) => {\n\t\ttrackComplete(data);\n\t\tconst result = data as { id?: string; sessionId?: string };\n\t\tif (typeof state.currentSessionId === \"string\" && result.sessionId !== state.currentSessionId) return;\n\t\tif (typeof result.id === \"string\" && result.id.trim()) {\n\t\t\tsupervisorChannel.settleRunQuestions(result.id, \"async run settled\");\n\t\t}\n\t};\n\tlet executorExecute: ((id: string, params: SubagentParamsLike, signal: AbortSignal, onUpdate: ((r: AgentToolResult<Details>) => void) | undefined, ctx: ExtensionContext) => Promise<AgentToolResult<Details>>) | undefined;\n\tconst scheduledRunManager = createScheduledRunManager({\n\t\tconfig,\n\t\tlaunch: (params, ctx, signal) => {\n\t\t\tif (!executorExecute) {\n\t\t\t\treturn Promise.resolve({\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Scheduled subagent launch is unavailable (executor not ready).\" }],\n\t\t\t\t\tisError: true,\n\t\t\t\t\tdetails: { mode: \"management\" as const, results: [] },\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn executorExecute(randomUUID(), params, signal, undefined, ctx);\n\t\t},\n\t});\n\tconst executor: ReturnType<typeof createSubagentExecutor> = {\n\t\tasync execute(id, params, signal, onUpdate, ctx) {\n\t\t\tlet resolveLaunchReady!: () => void;\n\t\t\tlet launchReady = false;\n\t\t\tconst launchReadyPromise = new Promise<void>((resolve) => {\n\t\t\t\tresolveLaunchReady = resolve;\n\t\t\t});\n\t\t\tconst markLaunchReady = () => {\n\t\t\t\tif (launchReady) return;\n\t\t\t\tlaunchReady = true;\n\t\t\t\tpendingLaunches.delete(launchReadyPromise);\n\t\t\t\tpendingAsyncLaunches.delete(launchReadyPromise);\n\t\t\t\tresolveLaunchReady();\n\t\t\t};\n\t\t\tpendingLaunches.add(launchReadyPromise);\n\t\t\tif (isAsyncSubagentExecution(resolveSubagentRequestParams(params))) pendingAsyncLaunches.add(launchReadyPromise);\n\t\t\ttry {\n\t\t\t\tconst currentGeneration = generation;\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\tif (!executorPromise) {\n\t\t\t\t\tconst pending = import(\"../runs/foreground/subagent-executor.ts\").then(({ createSubagentExecutor }) => {\n\t\t\t\t\t\tif (generation !== currentGeneration) throw new Error(\"Subagent session changed before initialization\");\n\t\t\t\t\t\treturn createSubagentExecutor({\n\t\t\t\t\t\t\tpi, state, config,\n\t\t\t\t\t\t\twaitToolEnabled: waitToolConfig.enabled,\n\t\t\t\t\t\t\thandleScheduledRunAction: (params, ctx) => scheduledRunManager.handleToolCall(params, ctx),\n\t\t\t\t\t\t\twatchdog: mainWatchdog, tempArtifactsDir, getSubagentSessionRoot, expandTilde,\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\texecutorPromise = pending;\n\t\t\t\t\tvoid pending.catch(() => {\n\t\t\t\t\t\tif (executorPromise === pending) executorPromise = undefined;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst ready = await awaitWithAbort(executorPromise, signal);\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\tif (generation !== currentGeneration) throw new Error(\"Subagent session changed before execution\");\n\t\t\t\tconst execution = ready.execute(id, params, signal, onUpdate, ctx);\n\t\t\t\tmarkLaunchReady();\n\t\t\t\treturn await execution;\n\t\t\t} finally {\n\t\t\t\tmarkLaunchReady();\n\t\t\t}\n\t\t},\n\t};\n\texecutorExecute = executor.execute;\n\n\tregisterSupervisorRenderers(pi, state);\n\n\tpi.registerMessageRenderer<SlashMessageDetails>(SLASH_RESULT_TYPE, (message, options, theme) => {\n\t\tconst details = resolveSlashMessageDetails(message.details);\n\t\tif (!details) return undefined;\n\t\treturn createSlashResultComponent(details, options, theme);\n\t});\n\n\tpi.registerMessageRenderer<undefined>(SLASH_TEXT_RESULT_TYPE, (message, _options, _theme) => {\n\t\tconst content = typeof message.content === \"string\"\n\t\t\t? message.content\n\t\t\t: message.content\n\t\t\t\t.filter((entry) => entry.type === \"text\")\n\t\t\t\t.map((entry) => entry.text)\n\t\t\t\t.join(\"\\n\");\n\t\treturn new Text(content, 0, 0);\n\t});\n\n\tpi.registerMessageRenderer<SubagentNotifyDetails>(\"subagent-notify\", (message, _options, theme) => {\n\t\tconst content = typeof message.content === \"string\" ? message.content : \"\";\n\t\tconst details = (message.details as SubagentNotifyDetails | undefined) ?? parseSubagentNotifyContent(content);\n\t\tif (!details) return new Text(content, 0, 0);\n\t\treturn renderSubagentNotify(details, theme);\n\t});\n\n\tpi.registerMessageRenderer<SubagentSteeringMessageDetails>(SUBAGENT_STEERING_MESSAGE_TYPE, (message, _options, theme) => {\n\t\tconst details = message.details as SubagentSteeringMessageDetails | undefined;\n\t\tif (!details) return undefined;\n\t\treturn new Text(theme.fg(details.state === \"recovered\" ? \"warning\" : \"error\", formatSteeringNotice(details)), 0, 0);\n\t});\n\n\tpi.registerMessageRenderer<SubagentControlMessageDetails>(SUBAGENT_CONTROL_MESSAGE_TYPE, () => undefined);\n\n\tconst executeSubagentCollapsed = async (id: string, params: SubagentParamsLike, signal: AbortSignal, onUpdate: ((result: AgentToolResult<Details>) => void) | undefined, ctx: ExtensionContext) => {\n\t\tif (ctx.hasUI) ctx.ui.setToolsExpanded(false);\n\t\tconst isCommunication = (params.action === \"steer\" || params.action === \"resume\") && typeof params.message === \"string\";\n\t\tconst displayTitle = isCommunication ? resolveSubagentActionDisplayTitle(params, state) : undefined;\n\t\tconst jobs = isCommunication ? matchingActionJobs(state, (params.id || params.runId || \"\").trim()) : [];\n\t\tconst targetNames = new Map(jobs.length === 1 ? jobs[0]!.steps?.map((step, index) => [step.index ?? index, childRowLabel(step)]) : []);\n\t\tconst result = await executor.execute(id, params, signal, onUpdate, ctx);\n\t\tif (displayTitle && result.details) result.details.displayTitle = displayTitle;\n\t\tif (isCommunication && result.details) {\n\t\t\tconst targets = result.details.steering?.targets.map((target) => targetNames.get(target.index) ?? `Subagent ${target.index + 1}`);\n\t\t\tconst peer = targets?.length ? targets.join(\", \") : displayTitle || \"Subagent\";\n\t\t\tresult.details.communication = { direction: \"to\", peer, kind: \"steer\", message: params.message };\n\t\t}\n\t\treturn result;\n\t};\n\n\tconst slashBridge = registerSlashSubagentBridge({\n\t\tevents: pi.events,\n\t\tgetContext: () => state.lastUiContext,\n\t\texecute: (id, params, signal, onUpdate, ctx) =>\n\t\t\texecuteSubagentCollapsed(id, params, signal, onUpdate, ctx),\n\t});\n\n\tconst promptTemplateBridge = registerPromptTemplateDelegationBridge({\n\t\tevents: pi.events,\n\t\tgetContext: () => state.lastUiContext,\n\t\texecute: (requestId, params, signal, ctx, onUpdate) =>\n\t\t\texecuteSubagentCollapsed(requestId, params, signal, onUpdate, ctx),\n\t});\n\n\tconst rpcBridge = registerSubagentRpcBridge({\n\t\tevents: pi.events,\n\t\tgetContext: () => state.lastUiContext,\n\t\texecute: (id, params, signal, onUpdate, ctx) => executor.execute(id, params, signal, onUpdate, ctx),\n\t});\n\n\tconst tool: ToolDefinition<typeof SubagentParams, Details> = {\n\t\tname: \"subagent\",\n\t\tlabel: \"Subagent\",\n\t\tdescription: buildSubagentToolDescription(config),\n\t\tparameters: SubagentParams,\n\t\t// lunr: same-turn SINGLE calls overlap; sequential work uses chain.\n\t\texecutionMode: \"parallel\",\n\n\t\tprepareArguments(args) {\n\t\t\t// Run friendly chain validation before pi-ai's raw TypeBox schema check\n\t\t\t// so the model sees which property is disallowed, what is allowed, and a\n\t\t\t// valid example instead of `chain.N: must not have additional properties`.\n\t\t\tvalidateChainInput(args);\n\t\t\treturn args as never;\n\t\t},\n\n\t\texecute(id, params, signal, onUpdate, ctx) {\n\t\t\treturn executeSubagentCollapsed(id, params, signal, onUpdate, ctx);\n\t\t},\n\n\t\trenderCall: (args, theme, context) => renderSubagentCall(args, theme, context, {\n\t\t\tresolveActionTitle: (params) => resolveSubagentActionDisplayTitle(params, state),\n\t\t}),\n\n\t\trenderResult(result, options, theme, context) {\n\t\t\tif (result.details?.communication) return renderCommunicationResult(result.content, result.details, options.expanded, context.isError, theme);\n\t\t\tif (subagentResultIsRunning(result)) {\n\t\t\t\tensureSubagentResultAnimation(context);\n\t\t\t} else {\n\t\t\t\tclearLegacyResultAnimationTimer(context);\n\t\t\t}\n\t\t\tconst state = context.state as { frame?: number; animEntries?: Array<{ text: Text; line: (frame: number) => string }> };\n\t\t\t// lunr: collect running-glyph line templates while rendering so the\n\t\t\t// animation timer can rewrite them in place (see ensureSubagentResultAnimation).\n\t\t\tconst entries: Array<{ text: Text; line: (frame: number) => string }> = [];\n\t\t\tstate.animEntries = entries;\n\t\t\tsubagentAnimSink.current = entries;\n\t\t\ttry {\n\t\t\t\treturn renderSubagentResult(result, options, theme, state.frame ?? 0);\n\t\t\t} finally {\n\t\t\t\tsubagentAnimSink.current = null;\n\t\t\t}\n\t\t},\n\n\t};\n\n\tpi.registerTool(tool);\n\n\t// lunr: register a callback so model-tier settings changes rebuild the subagent\n\t// tool description and refresh the live registry.\n\tconst modelTierBridge = (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/model-tiers\")] as\n\t\t| { registerToolDescriptionRefresher?: (refresher: () => void) => void }\n\t\t| undefined;\n\tmodelTierBridge?.registerToolDescriptionRefresher?.(() => {\n\t\ttool.description = buildSubagentToolDescription(config);\n\t\t// pi.runtime is not on ExtensionAPI; registerTool refreshes the live registry.\n\t\tpi.registerTool(tool);\n\t});\n\n\tregisterWaitTool(pi, state, waitToolConfig.enabled, async (signal) => {\n\t\tconst launches = [...pendingLaunches];\n\t\tif (launches.length === 0) return;\n\t\tawait awaitWithAbort(Promise.all(launches).then(() => {}), signal);\n\t});\n\n\tpi.on(\"agent_end\", async (_event, ctx) => {\n\t\tif (ctx.hasUI) return;\n\t\tawait drainOutstandingWork({ state, events: pi.events, hasPendingMessages: () => ctx.hasPendingMessages() });\n\t});\n\n\tregisterSlashCommands(pi, state);\n\n\tconst eventUnsubscribeStoreKey = \"__piSubagentEventUnsubscribes\";\n\tconst controlNoticeSeenStoreKey = \"__piSubagentVisibleControlNotices\";\n\tconst previousEventUnsubscribes = globalStore[eventUnsubscribeStoreKey];\n\tif (Array.isArray(previousEventUnsubscribes)) {\n\t\tfor (const unsubscribe of previousEventUnsubscribes) {\n\t\t\tif (typeof unsubscribe !== \"function\") continue;\n\t\t\ttry {\n\t\t\t\tunsubscribe();\n\t\t\t} catch {\n\t\t\t\t// Best effort cleanup for stale handlers from an older reload.\n\t\t\t}\n\t\t}\n\t}\n\tregisterSubagentNotify(pi, state, { batchConfig: config.completionBatch });\n\n\tconst existingVisibleControlNotices = globalStore[controlNoticeSeenStoreKey];\n\tconst visibleControlNotices = existingVisibleControlNotices instanceof Set ? existingVisibleControlNotices as Set<string> : new Set<string>();\n\tglobalStore[controlNoticeSeenStoreKey] = visibleControlNotices;\n\tconst controlEventHandler = (payload: unknown) => {\n\t\thandleSubagentControlNotice({\n\t\t\tpi,\n\t\t\tstate,\n\t\t\tvisibleControlNotices,\n\t\t\tdetails: payload as SubagentControlMessageDetails,\n\t\t});\n\t};\n\tconst steeringNoticeHandler = (payload: unknown) => {\n\t\thandleSubagentSteeringNotice({ pi, state, details: payload as SubagentSteeringMessageDetails });\n\t};\n\tconst eventUnsubscribes = [\n\t\tpi.events.on(SUBAGENT_ASYNC_STARTED_EVENT, handleStarted),\n\t\tpi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete),\n\t\tpi.events.on(SUBAGENT_CONTROL_EVENT, controlEventHandler),\n\t\tpi.events.on(SUBAGENT_STEERING_NOTICE_EVENT, steeringNoticeHandler),\n\t\trpcBridge.dispose,\n\t];\n\tglobalStore[eventUnsubscribeStoreKey] = eventUnsubscribes;\n\n\tpi.on(\"tool_result\", (event, ctx) => {\n\t\tif (event.toolName !== \"subagent\") return;\n\t\tif (!ctx.hasUI) return;\n\t\tstate.lastUiContext = ctx;\n\t\tif (state.asyncJobs.size > 0) {\n\t\t\trefreshWidget(ctx);\n\t\t\tensurePoller();\n\t\t}\n\t});\n\n\tconst cleanupSessionArtifacts = (ctx: ExtensionContext) => {\n\t\ttry {\n\t\t\tconst sessionFile = ctx.sessionManager.getSessionFile();\n\t\t\tif (sessionFile) {\n\t\t\t\tcleanupOldArtifacts(getArtifactsDir(sessionFile), DEFAULT_ARTIFACT_CONFIG.cleanupDays);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Cleanup failures should not block session lifecycle events.\n\t\t}\n\t};\n\n\tconst resetSessionState = (ctx: ExtensionContext) => {\n\t\tgeneration++;\n\t\tsupervisorChannel.cancelOwnedQuestions(\"parent session replaced\");\n\t\tstate.sessionGeneration = (state.sessionGeneration ?? 0) + 1;\n\t\texecutorPromise = undefined;\n\t\tpendingLaunches.clear();\n\t\tpendingAsyncLaunches.clear();\n\t\tunregisterCancellation?.();\n\t\tstate.baseCwd = ctx.cwd;\n\t\tstate.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);\n\t\tstate.subagentSpawns = { sessionId: state.currentSessionId, count: 0 };\n\t\t// Set PI_SUBAGENT_PARENT_SESSION for permission-system forwarding.\n\t\t// Only set in the root session (the interactive UI session), not in\n\t\t// child subagent processes — children inherit the parent's value\n\t\t// through the process environment at spawn time and must not overwrite\n\t\t// it with their own session identity.\n\t\tif (!process.env[SUBAGENT_CHILD_ENV]) {\n\t\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\t\tif (sessionId) {\n\t\t\t\tprocess.env[SUBAGENT_PARENT_SESSION_ENV] = sessionId;\n\t\t\t}\n\t\t}\n\t\tstate.lastUiContext = ctx;\n\t\tcleanupSessionArtifacts(ctx);\n\t\tclearPendingForegroundControlNotices(state);\n\t\tresetJobs(ctx);\n\t\trestoreActiveJobs(ctx);\n\t\tconst sessionId = state.currentSessionId;\n\t\tconst sessionGeneration = generation;\n\t\tif (sessionId) unregisterCancellation = registerSubagentCancellation(sessionId, createSubagentCancellation({\n\t\t\tpendingLaunches: pendingAsyncLaunches,\n\t\t\tisCurrent: () => generation === sessionGeneration && state.currentSessionId === sessionId,\n\t\t\tgetActiveRunIds: () => [...state.asyncJobs.values()]\n\t\t\t\t.filter((job) => job.sessionId === sessionId && (job.status === \"queued\" || job.status === \"running\"))\n\t\t\t\t.map((job) => job.asyncId),\n\t\t\tasync stopRun(id) {\n\t\t\t\tconst result = await executor.execute(randomUUID(), { action: \"stop\", id }, new AbortController().signal, undefined, ctx);\n\t\t\t\treturn !result.isError;\n\t\t\t},\n\t\t}));\n\t\tscheduledRunManager.bindSession(ctx);\n\t\trestoreSlashFinalSnapshots(ctx.sessionManager.getEntries());\n\t\tprimeExistingResults();\n\t};\n\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tresetSessionState(ctx);\n\t\trpcBridge.emitReady(ctx);\n\t\tsupervisorChannel.start();\n\t});\n\n\tpi.on(\"session_shutdown\", () => {\n\t\tgeneration++;\n\t\tsupervisorChannel.cancelOwnedQuestions(\"parent session shutdown\");\n\t\tstate.sessionGeneration = (state.sessionGeneration ?? 0) + 1;\n\t\texecutorPromise = undefined;\n\t\tpendingLaunches.clear();\n\t\tpendingAsyncLaunches.clear();\n\t\tunregisterCancellation?.();\n\t\tdelete process.env[SUBAGENT_PARENT_SESSION_ENV];\n\t\tfor (const unsubscribe of eventUnsubscribes) {\n\t\t\ttry {\n\t\t\t\tunsubscribe();\n\t\t\t} catch {\n\t\t\t\t// Best effort cleanup during shutdown.\n\t\t\t}\n\t\t}\n\t\tif (globalStore[eventUnsubscribeStoreKey] === eventUnsubscribes) {\n\t\t\tdelete globalStore[eventUnsubscribeStoreKey];\n\t\t}\n\t\tstopResultWatcher();\n\t\tscheduledRunManager.stop();\n\t\tif (state.poller) clearInterval(state.poller);\n\t\tstate.poller = null;\n\t\tclearPendingForegroundControlNotices(state);\n\t\tfor (const timer of state.cleanupTimers.values()) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tstate.cleanupTimers.clear();\n\t\tstate.asyncJobs.clear();\n\t\tclearSlashSnapshots();\n\t\tslashBridge.cancelAll();\n\t\tslashBridge.dispose();\n\t\tpromptTemplateBridge.cancelAll();\n\t\tpromptTemplateBridge.dispose();\n\t\tsupervisorChannel.dispose();\n\t\tif (globalStore[runtimeCleanupStoreKey] === runtimeCleanup) {\n\t\t\tdelete globalStore[runtimeCleanupStoreKey];\n\t\t}\n\t\tdisposeSubagentWidget();\n\t\ttry {\n\t\t\tif (state.lastUiContext?.hasUI) {\n\t\t\t\tstate.lastUiContext.ui.setWidget(WIDGET_KEY, undefined);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (!isStaleExtensionContextError(error)) throw error;\n\t\t}\n\t});\n}\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/builtin-extensions/pi-subagents/src/extension/index.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAoC,MAAM,iCAAiC,CAAC;AAEtG,OAAO,EAAO,SAAS,EAAU,IAAI,EAAmE,MAAM,wBAAwB,CAAC;AAuCvI,OAAO,EAGN,KAAK,aAAa,EAYlB,MAAM,oBAAoB,CAAC;AAS5B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiFzC,wBAAgB,iCAAiC,CAAC,IAAI,KAAA,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAgBhG;AAED,wBAAgB,kBAAkB,CAAC,OAAO,KAAA,EAAE,KAAK,KAAA,EAAE,OAAO,KAAA,EAAE,OAAO,KAAA,oBA4ClE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,KAAA,EAAE,KAAK,KAAA,QASlD;AA8FD,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA8ZxE","sourcesContent":["// @ts-nocheck\n/**\n * Subagent Tool\n *\n * Full-featured subagent with foreground and async modes.\n * - Async (default): Background execution, emits events when done\n * - Foreground (async:false or clarify:true): Streams output, renders markdown, tracks usage\n *\n * Modes: single (agent + task), parallel (tasks[]), chain (chain[] with {previous})\n *\n * Config file: ~/.lunr/agent/extensions/subagent/config.json\n * { \"maxSubagentDepth\": 1, \"intercomBridge\": { \"mode\": \"always\", \"instructionFile\": \"./intercom-bridge.md\" }, \"worktreeSetupHook\": \"./scripts/setup-worktree.mjs\" }\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { createSubagentCancellation, registerSubagentCancellation } from \"../../../../core/subagent-cancellation.ts\";\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { AgentToolResult } from \"@ashx-j/lunr-agent\";\nimport type { ExtensionAPI, ExtensionContext, ToolDefinition } from \"@ashx-j/lunr\";\nimport { awaitWithAbort } from \"../../../../utils/await-with-abort.ts\";\nimport { Box, Container, Spacer, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi, type Component } from \"@ashx-j/lunr-tui\";\n\nimport { cleanupAllArtifactDirs, cleanupOldArtifacts, getArtifactsDir } from \"../shared/artifacts.ts\";\nimport { resolveCurrentSessionId } from \"../shared/session-identity.ts\";\nimport { cleanupOldChainDirs } from \"../shared/settings.ts\";\nimport {\n\tclearLegacyResultAnimationTimer,\n\tdisposeSubagentWidget,\n\trenderSubagentResult,\n\tSUBAGENT_PAINT_INTERVAL_MS,\n\tsubagentAnimSink,\n} from \"../tui/render.ts\";\nimport { SubagentParams } from \"./schemas.ts\";\nimport { validateChainInput } from \"./chain-validation.ts\";\nimport type { createSubagentExecutor, SubagentParamsLike } from \"../runs/foreground/subagent-executor.ts\";\nimport { resolveSubagentRequestParams } from \"../runs/foreground/request-params.ts\";\nimport { createAsyncJobTracker } from \"../runs/background/async-job-tracker.ts\";\nimport { createResultWatcher } from \"../runs/background/result-watcher.ts\";\nimport { createScheduledRunManager } from \"../runs/background/scheduled-runs.ts\";\nimport { isAsyncSubagentExecution, normalizeAsyncLaunchConfig, subagentLaunchRunsAsync } from \"../runs/background/top-level-async.ts\";\nimport { registerSlashCommands } from \"../slash/slash-commands.ts\";\nimport { registerPromptTemplateDelegationBridge } from \"../slash/prompt-template-bridge.ts\";\nimport { registerMainWatchdog } from \"../watchdog/register-main.ts\";\nimport { registerSlashSubagentBridge } from \"../slash/slash-bridge.ts\";\nimport { createNativeSupervisorChannel, registerSupervisorRenderers } from \"../intercom/native-supervisor-channel.ts\";\nimport { renderCommunicationCall, renderCommunicationResult } from \"../tui/communication.ts\";\nimport { registerSubagentRpcBridge } from \"./rpc.ts\";\nimport { clearSlashSnapshots, getSlashRenderableSnapshot, resolveSlashMessageDetails, restoreSlashFinalSnapshots, type SlashMessageDetails } from \"../slash/slash-live-state.ts\";\nimport { inspectSubagentStatus } from \"../runs/background/run-status.ts\";\nimport { resolveWaitToolConfig } from \"../runs/background/subagent-wait.ts\";\nimport { registerWaitTool } from \"../runs/background/wait-tool.ts\";\nimport { drainOutstandingWork } from \"../runs/background/auto-drain.ts\";\nimport registerSubagentNotify, { parseSubagentNotifyContent, type SubagentNotifyDetails } from \"../runs/background/notify.ts\";\nimport { formatSteeringNotice, handleSubagentSteeringNotice, SUBAGENT_STEERING_MESSAGE_TYPE, type SubagentSteeringMessageDetails } from \"./steering-notices.ts\";\nimport { controlNotificationKey } from \"../runs/shared/subagent-control.ts\";\nimport { SUBAGENT_CHILD_ENV } from \"../runs/shared/pi-args.ts\";\n\nimport { loadConfig } from \"./config.ts\";\nimport { buildSubagentToolDescription } from \"./tool-description.ts\";\nimport {\n\ttype AsyncJobState,\n\ttype Details,\n\ttype SubagentState,\n\tASYNC_DIR,\n\tchildRowLabel,\n\tDEFAULT_ARTIFACT_CONFIG,\n\tRESULTS_DIR,\n\tSLASH_RESULT_TYPE,\n\tSLASH_TEXT_RESULT_TYPE,\n\tSUBAGENT_ASYNC_COMPLETE_EVENT,\n\tSUBAGENT_ASYNC_STARTED_EVENT,\n\tSUBAGENT_CONTROL_EVENT,\n\tSUBAGENT_STEERING_NOTICE_EVENT,\n\tWIDGET_KEY,\n} from \"../shared/types.ts\";\nimport {\n\tclearPendingForegroundControlNotices,\n\tformatSubagentControlNotice,\n\thandleSubagentControlNotice,\n\tSUBAGENT_CONTROL_MESSAGE_TYPE,\n\ttype SubagentControlMessageDetails,\n} from \"./control-notices.ts\";\n\nexport { loadConfig } from \"./config.ts\";\n\n/**\n * Derive subagent session base directory from parent session file.\n * If parent session is ~/.lunr/agent/sessions/abc123.jsonl,\n * returns ~/.lunr/agent/sessions/abc123/ as the base.\n * Callers add runId to create the actual session root: abc123/{runId}/\n * Falls back to a unique temp directory if no parent session.\n */\nfunction getSubagentSessionRoot(parentSessionFile: string | null): string {\n\tif (parentSessionFile) {\n\t\tconst baseName = path.basename(parentSessionFile, \".jsonl\");\n\t\tconst sessionsDir = path.dirname(parentSessionFile);\n\t\treturn path.join(sessionsDir, baseName);\n\t}\n\treturn fs.mkdtempSync(path.join(os.tmpdir(), \"pi-subagent-session-\"));\n}\n\nfunction expandTilde(p: string): string {\n\treturn p.startsWith(\"~/\") ? path.join(os.homedir(), p.slice(2)) : p;\n}\n\n/**\n * Create a directory and verify it is actually accessible.\n * On Windows with Azure AD/Entra ID, directories created shortly after\n * wake-from-sleep can end up with broken NTFS ACLs (null DACL) when the\n * cloud SID cannot be resolved without network connectivity. This leaves\n * the directory completely inaccessible to the creating user.\n */\nfunction ensureAccessibleDir(dirPath: string): void {\n\tfs.mkdirSync(dirPath, { recursive: true });\n\ttry {\n\t\tfs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n\t} catch {\n\t\ttry {\n\t\t\tfs.rmSync(dirPath, { recursive: true, force: true });\n\t\t} catch {\n\t\t\t// Best effort: retry mkdir/access even if cleanup fails.\n\t\t}\n\t\tfs.mkdirSync(dirPath, { recursive: true });\n\t\tfs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n\t}\n}\n\nfunction isSlashResultRunning(result: { details?: Details }): boolean {\n\treturn result.details?.progress?.some((entry) => entry.status === \"running\")\n\t\t|| result.details?.results.some((entry) => entry.progress?.status === \"running\")\n\t\t|| false;\n}\n\n// Drives the inline running-indicator braille animation for foreground subagent\n// results. Foreground runs receive progress only on child events, so the glyph\n// (derived from progress fields) would freeze between events. While a result is\n// running we tick a frame counter every 80ms; renderResult registers the\n// running-glyph lines in state.animEntries (via subagentAnimSink) and the timer\n// rewrites just those Text nodes + requests a repaint, instead of invalidate()-ing\n// the whole tool component (a full renderSubagentResult rebuild 12.5x/s made the\n// spinner laggy).\nfunction subagentResultIsRunning(result: { details?: Details }): boolean {\n\treturn result.details?.progress?.some((entry) => entry.status === \"running\")\n\t\t|| result.details?.results.some((entry) => entry.progress?.status === \"running\")\n\t\t|| false;\n}\n\nfunction effectiveParallelTaskCount(tasks: Array<{ count?: unknown }> | undefined): number {\n\tif (!tasks || tasks.length === 0) return 0;\n\treturn tasks.reduce((total, task) => {\n\t\tconst count = typeof task.count === \"number\" && Number.isInteger(task.count) && task.count >= 1 ? task.count : 1;\n\t\treturn total + count;\n\t}, 0);\n}\n\nfunction matchingActionJobs(state: SubagentState, requestedId: string): AsyncJobState[] {\n\tconst jobs = new Map<string, AsyncJobState>();\n\tfor (const job of state.asyncJobs.values()) jobs.set(job.asyncId, job);\n\tfor (const job of state.fleetJobs?.values() ?? []) jobs.set(job.asyncId, job);\n\tconst exact = jobs.get(requestedId);\n\tif (exact) return [exact];\n\treturn [...jobs.values()].filter((job) => job.asyncId.startsWith(requestedId));\n}\n\nexport function resolveSubagentActionDisplayTitle(args, state: SubagentState): string | undefined {\n\tconst requestedId = (args.id || args.runId || \"\").trim();\n\tif (!requestedId) return undefined;\n\tconst matches = matchingActionJobs(state, requestedId);\n\tif (matches.length !== 1) return undefined;\n\tconst job = matches[0]!;\n\tconst steps = job.steps ?? [];\n\tif (Number.isInteger(args.index)) {\n\t\tconst step = steps.find((candidate) => candidate.index === args.index) ?? steps[args.index];\n\t\treturn step ? childRowLabel(step) : undefined;\n\t}\n\tif (steps.length === 1) return childRowLabel(steps[0]!);\n\tif (steps.length > 1) return `${job.mode ?? \"subagent\"} run`;\n\tif (job.agents?.length === 1) return job.agents[0];\n\tif (job.agents?.length) return `${job.mode ?? \"subagent\"} run`;\n\treturn undefined;\n}\n\nexport function renderSubagentCall(rawArgs, theme, context, options) {\n\tconst args = resolveSubagentRequestParams(rawArgs);\n\tif (args.action) {\n\t\tconst resultTitle = context?.result?.details?.displayTitle;\n\t\tconst resolvedTitle = resultTitle || options?.resolveActionTitle?.(args);\n\t\tconst target = resolvedTitle || args.id || args.runId || \"\";\n\t\tif ((args.action === \"steer\" || args.action === \"resume\") && args.message) {\n\t\t\treturn renderCommunicationCall(\n\t\t\t\t\"subagent\",\n\t\t\t\targs,\n\t\t\t\ttheme,\n\t\t\t\tcontext,\n\t\t\t\t{ direction: \"to\", peer: resolvedTitle || \"Subagent\", kind: \"steer\", message: args.message },\n\t\t\t\tresolvedTitle,\n\t\t\t);\n\t\t}\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"subagent \"))}${args.action}${target ? ` ${theme.fg(\"accent\", target)}` : \"\"}`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tconst isParallel = (args.tasks?.length ?? 0) > 0;\n\tconst parallelCount = effectiveParallelTaskCount(args.tasks as Array<{ count?: unknown }> | undefined);\n\tconst asyncMark = subagentLaunchRunsAsync(args) ? `${theme.fg(\"warning\", \"async\")} ` : \"\";\n\tif (args.chain?.length) {\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"subagent \"))}${asyncMark}chain (${args.chain.length})`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tif (isParallel) {\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"subagent \"))}${asyncMark}parallel (${parallelCount})`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tconst showDescription = !context?.result && !context?.isPartial && !context?.expanded && !context?.isError;\n\tconst description = showDescription ? theme.fg(\"accent\", args.description || args.task || \"?\") : \"\";\n\tconst title = theme.fg(\"toolTitle\", theme.bold(\"subagent\"));\n\tconst rest = [asyncMark.trim() ? theme.fg(\"warning\", \"async\") : \"\", description].filter(Boolean).join(\" \");\n\treturn new Text(rest ? `${title} ${rest}` : title, 0, 0);\n}\n\nexport function renderSubagentNotify(details, theme) {\n\tconst status = typeof details?.status === \"string\" ? details.status : \"\";\n\tconst icon = status === \"completed\"\n\t\t? theme.fg(\"success\", \"✓\")\n\t\t: status === \"failed\"\n\t\t\t? theme.fg(\"error\", \"✗\")\n\t\t\t: theme.fg(\"warning\", \"■\");\n\tconst title = details?.agent || \"child\";\n\treturn new Text(`${icon} ${theme.bold(title)} ${theme.fg(\"dim\", status)}`, 0, 0);\n}\n\nfunction ensureSubagentResultAnimation(context: { state: Record<string, unknown>; invalidate?: () => void; requestRender?: () => void }): void {\n\tconst state = context.state as {\n\t\tsubagentResultAnimationTimer?: ReturnType<typeof setInterval>;\n\t\tframe?: number;\n\t\tanimEntries?: Array<{ text: Text; line: (frame: number, now: number) => string }>;\n\t};\n\tif (state.subagentResultAnimationTimer) return;\n\tif (typeof context.invalidate !== \"function\") return;\n\tif (state.frame === undefined) state.frame = 0;\n\tstate.subagentResultAnimationTimer = setInterval(() => {\n\t\tstate.frame = (state.frame ?? 0) + 1;\n\t\ttry {\n\t\t\tconst entries = state.animEntries;\n\t\t\tif (entries?.length && typeof context.requestRender === \"function\") {\n\t\t\t\tconst now = Date.now();\n\t\t\t\tfor (const entry of entries) entry.text.setText(entry.line(state.frame ?? 0, now));\n\t\t\t\tcontext.requestRender();\n\t\t\t} else {\n\t\t\t\tcontext.invalidate();\n\t\t\t}\n\t\t} catch {}\n\t}, SUBAGENT_PAINT_INTERVAL_MS);\n}\n\nfunction isSlashResultError(result: { details?: Details }): boolean {\n\treturn result.details?.results.some((entry) => entry.exitCode !== 0 && entry.progress?.status !== \"running\") || false;\n}\n\nfunction isStaleExtensionContextError(error: unknown): boolean {\n\treturn error instanceof Error && error.message.includes(\"Extension context no longer active\");\n}\n\nfunction rebuildSlashResultContainer(\n\tcontainer: Container,\n\tresult: AgentToolResult<Details>,\n\toptions: { expanded: boolean },\n\ttheme: ExtensionContext[\"ui\"][\"theme\"],\n): void {\n\tcontainer.clear();\n\tcontainer.addChild(new Spacer(1));\n\tconst boxTheme = isSlashResultRunning(result) ? \"toolPendingBg\" : isSlashResultError(result) ? \"toolErrorBg\" : \"toolSuccessBg\";\n\tconst box = new Box(1, 1, (text: string) => theme.bg(boxTheme, text));\n\tbox.addChild(renderSubagentResult(result, options, theme));\n\tcontainer.addChild(box);\n}\n\nfunction createSlashResultComponent(\n\tdetails: SlashMessageDetails,\n\toptions: { expanded: boolean },\n\ttheme: ExtensionContext[\"ui\"][\"theme\"],\n): Container {\n\tconst container = new Container();\n\tlet lastVersion = -1;\n\tcontainer.render = (width: number): string[] => {\n\t\tconst snapshot = getSlashRenderableSnapshot(details);\n\t\tif (snapshot.version !== lastVersion || isSlashResultRunning(snapshot.result)) {\n\t\t\tlastVersion = snapshot.version;\n\t\t\trebuildSlashResultContainer(container, snapshot.result, options, theme);\n\t\t}\n\t\treturn Container.prototype.render.call(container, width);\n\t};\n\treturn container;\n}\n\nclass SubagentControlNoticeComponent implements Component {\n\tconstructor(\n\t\tprivate readonly details: SubagentControlMessageDetails,\n\t\tprivate readonly theme: ExtensionContext[\"ui\"][\"theme\"],\n\t) {}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst eventLabel = this.details.event.type.replaceAll(\"_\", \" \");\n\t\tif (width < 3) return [truncateToWidth(`Subagent ${eventLabel}`, width)];\n\t\tconst bodyWidth = Math.max(1, width - 2);\n\t\tconst borderChar = \"─\";\n\t\tconst header = ` ⚠ Subagent ${eventLabel}: ${this.details.event.agent} `;\n\t\tconst headerText = truncateToWidth(header, bodyWidth, \"\");\n\t\tconst headerPadding = Math.max(0, bodyWidth - visibleWidth(headerText));\n\t\tconst lines = [this.theme.fg(\"accent\", `╭${headerText}${borderChar.repeat(headerPadding)}╮`)];\n\n\t\tfor (const line of wrapTextWithAnsi(formatSubagentControlNotice(this.details), bodyWidth)) {\n\t\t\tconst text = truncateToWidth(line, bodyWidth, \"\");\n\t\t\tconst padding = Math.max(0, bodyWidth - visibleWidth(text));\n\t\t\tlines.push(this.theme.fg(\"accent\", `│${text}${\" \".repeat(padding)}│`));\n\t\t}\n\t\tlines.push(this.theme.fg(\"accent\", `╰${borderChar.repeat(bodyWidth)}╯`));\n\t\treturn lines;\n\t}\n}\n\nexport default function registerSubagentExtension(pi: ExtensionAPI): void {\n\tif (process.env[SUBAGENT_CHILD_ENV] === \"1\") {\n\t\treturn;\n\t}\n\n\tensureAccessibleDir(RESULTS_DIR);\n\tensureAccessibleDir(ASYNC_DIR);\n\tcleanupOldChainDirs();\n\n\tconst config = normalizeAsyncLaunchConfig(loadConfig());\n\tconst waitToolConfig = resolveWaitToolConfig(config.waitTool);\n\tconst tempArtifactsDir = getArtifactsDir(null);\n\tcleanupAllArtifactDirs(DEFAULT_ARTIFACT_CONFIG.cleanupDays);\n\n\tconst state: SubagentState = {\n\t\tbaseCwd: \"\",\n\t\tcurrentSessionId: null,\n\t\tsessionGeneration: 0,\n\t\tforegroundSubagentInFlight: 0,\n\t\tsubagentSpawns: { sessionId: null, count: 0 },\n\t\tasyncJobs: new Map(),\n\t\tfleetJobs: new Map(),\n\t\tforegroundRuns: new Map(),\n\t\tforegroundControls: new Map(),\n\t\tlastForegroundControlId: null,\n\t\tpendingForegroundControlNotices: new Map(),\n\t\tcleanupTimers: new Map(),\n\t\tlastUiContext: null,\n\t\tpoller: null,\n\t\tcompletionSeen: new Map(),\n\t\twatcher: null,\n\t\twatcherRestartTimer: null,\n\t\tresultFileCoalescer: {\n\t\t\tschedule: () => false,\n\t\t\tclear: () => {},\n\t\t},\n\t};\n\n\tconst supervisorChannel = createNativeSupervisorChannel(pi, state);\n\tconst mainWatchdog = registerMainWatchdog(pi);\n\tconst { startResultWatcher, primeExistingResults, stopResultWatcher } = createResultWatcher(\n\t\tpi,\n\t\tstate,\n\t\tRESULTS_DIR,\n\t\t10 * 60 * 1000,\n\t);\n\n\tlet generation = 0;\n\tlet executorPromise: Promise<ReturnType<typeof createSubagentExecutor>> | undefined;\n\tconst pendingLaunches = new Set<Promise<void>>();\n\tconst pendingAsyncLaunches = new Set<Promise<void>>();\n\tlet unregisterCancellation: (() => void) | undefined;\n\n\tconst { ensurePoller, refreshWidget, handleStarted, handleComplete: trackComplete, resetJobs, restoreActiveJobs } = createAsyncJobTracker(pi, state, ASYNC_DIR, {\n\t\twidgetEnabled: config.asyncWidget !== false,\n\t});\n\tconst handleComplete = (data: unknown) => {\n\t\ttrackComplete(data);\n\t\tconst result = data as { id?: string; sessionId?: string };\n\t\tif (typeof state.currentSessionId === \"string\" && result.sessionId !== state.currentSessionId) return;\n\t\tif (typeof result.id === \"string\" && result.id.trim()) {\n\t\t\tsupervisorChannel.settleRunQuestions(result.id, \"async run settled\");\n\t\t}\n\t};\n\tlet executorExecute: ((id: string, params: SubagentParamsLike, signal: AbortSignal, onUpdate: ((r: AgentToolResult<Details>) => void) | undefined, ctx: ExtensionContext) => Promise<AgentToolResult<Details>>) | undefined;\n\tconst scheduledRunManager = createScheduledRunManager({\n\t\tconfig,\n\t\tlaunch: (params, ctx, signal) => {\n\t\t\tif (!executorExecute) {\n\t\t\t\treturn Promise.resolve({\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Scheduled subagent launch is unavailable (executor not ready).\" }],\n\t\t\t\t\tisError: true,\n\t\t\t\t\tdetails: { mode: \"management\" as const, results: [] },\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn executorExecute(randomUUID(), params, signal, undefined, ctx);\n\t\t},\n\t});\n\tconst executor: ReturnType<typeof createSubagentExecutor> = {\n\t\tasync execute(id, params, signal, onUpdate, ctx) {\n\t\t\tlet resolveLaunchReady!: () => void;\n\t\t\tlet launchReady = false;\n\t\t\tconst launchReadyPromise = new Promise<void>((resolve) => {\n\t\t\t\tresolveLaunchReady = resolve;\n\t\t\t});\n\t\t\tconst markLaunchReady = () => {\n\t\t\t\tif (launchReady) return;\n\t\t\t\tlaunchReady = true;\n\t\t\t\tpendingLaunches.delete(launchReadyPromise);\n\t\t\t\tpendingAsyncLaunches.delete(launchReadyPromise);\n\t\t\t\tresolveLaunchReady();\n\t\t\t};\n\t\t\tpendingLaunches.add(launchReadyPromise);\n\t\t\tif (isAsyncSubagentExecution(resolveSubagentRequestParams(params))) pendingAsyncLaunches.add(launchReadyPromise);\n\t\t\ttry {\n\t\t\t\tconst currentGeneration = generation;\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\tif (!executorPromise) {\n\t\t\t\t\tconst pending = import(\"../runs/foreground/subagent-executor.ts\").then(({ createSubagentExecutor }) => {\n\t\t\t\t\t\tif (generation !== currentGeneration) throw new Error(\"Subagent session changed before initialization\");\n\t\t\t\t\t\treturn createSubagentExecutor({\n\t\t\t\t\t\t\tpi, state, config,\n\t\t\t\t\t\t\twaitToolEnabled: waitToolConfig.enabled,\n\t\t\t\t\t\t\thandleScheduledRunAction: (params, ctx) => scheduledRunManager.handleToolCall(params, ctx),\n\t\t\t\t\t\t\twatchdog: mainWatchdog, tempArtifactsDir, getSubagentSessionRoot, expandTilde,\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\texecutorPromise = pending;\n\t\t\t\t\tvoid pending.catch(() => {\n\t\t\t\t\t\tif (executorPromise === pending) executorPromise = undefined;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst ready = await awaitWithAbort(executorPromise, signal);\n\t\t\t\tsignal?.throwIfAborted();\n\t\t\t\tif (generation !== currentGeneration) throw new Error(\"Subagent session changed before execution\");\n\t\t\t\tconst execution = ready.execute(id, params, signal, onUpdate, ctx);\n\t\t\t\tmarkLaunchReady();\n\t\t\t\treturn await execution;\n\t\t\t} finally {\n\t\t\t\tmarkLaunchReady();\n\t\t\t}\n\t\t},\n\t};\n\texecutorExecute = executor.execute;\n\n\tregisterSupervisorRenderers(pi, state);\n\n\tpi.registerMessageRenderer<SlashMessageDetails>(SLASH_RESULT_TYPE, (message, options, theme) => {\n\t\tconst details = resolveSlashMessageDetails(message.details);\n\t\tif (!details) return undefined;\n\t\treturn createSlashResultComponent(details, options, theme);\n\t});\n\n\tpi.registerMessageRenderer<undefined>(SLASH_TEXT_RESULT_TYPE, (message, _options, _theme) => {\n\t\tconst content = typeof message.content === \"string\"\n\t\t\t? message.content\n\t\t\t: message.content\n\t\t\t\t.filter((entry) => entry.type === \"text\")\n\t\t\t\t.map((entry) => entry.text)\n\t\t\t\t.join(\"\\n\");\n\t\treturn new Text(content, 0, 0);\n\t});\n\n\tpi.registerMessageRenderer<SubagentNotifyDetails>(\"subagent-notify\", (message, _options, theme) => {\n\t\tconst content = typeof message.content === \"string\" ? message.content : \"\";\n\t\tconst details = (message.details as SubagentNotifyDetails | undefined) ?? parseSubagentNotifyContent(content);\n\t\tif (!details) return new Text(content, 0, 0);\n\t\treturn renderSubagentNotify(details, theme);\n\t});\n\n\tpi.registerMessageRenderer<SubagentSteeringMessageDetails>(SUBAGENT_STEERING_MESSAGE_TYPE, (message, _options, theme) => {\n\t\tconst details = message.details as SubagentSteeringMessageDetails | undefined;\n\t\tif (!details) return undefined;\n\t\treturn new Text(theme.fg(details.state === \"recovered\" ? \"warning\" : \"error\", formatSteeringNotice(details)), 0, 0);\n\t});\n\n\tpi.registerMessageRenderer<SubagentControlMessageDetails>(SUBAGENT_CONTROL_MESSAGE_TYPE, () => undefined);\n\n\tconst executeSubagentCollapsed = async (id: string, params: SubagentParamsLike, signal: AbortSignal, onUpdate: ((result: AgentToolResult<Details>) => void) | undefined, ctx: ExtensionContext) => {\n\t\tif (ctx.hasUI) ctx.ui.setToolsExpanded(false);\n\t\tconst isCommunication = (params.action === \"steer\" || params.action === \"resume\") && typeof params.message === \"string\";\n\t\tconst displayTitle = isCommunication ? resolveSubagentActionDisplayTitle(params, state) : undefined;\n\t\tconst jobs = isCommunication ? matchingActionJobs(state, (params.id || params.runId || \"\").trim()) : [];\n\t\tconst targetNames = new Map(jobs.length === 1 ? jobs[0]!.steps?.map((step, index) => [step.index ?? index, childRowLabel(step)]) : []);\n\t\tconst result = await executor.execute(id, params, signal, onUpdate, ctx);\n\t\tif (displayTitle && result.details) result.details.displayTitle = displayTitle;\n\t\tif (isCommunication && result.details) {\n\t\t\tconst targets = result.details.steering?.targets.map((target) => targetNames.get(target.index) ?? `Subagent ${target.index + 1}`);\n\t\t\tconst peer = targets?.length ? targets.join(\", \") : displayTitle || \"Subagent\";\n\t\t\tresult.details.communication = { direction: \"to\", peer, kind: \"steer\", message: params.message };\n\t\t}\n\t\treturn result;\n\t};\n\n\tconst slashBridge = registerSlashSubagentBridge({\n\t\tevents: pi.events,\n\t\tgetContext: () => state.lastUiContext,\n\t\texecute: (id, params, signal, onUpdate, ctx) =>\n\t\t\texecuteSubagentCollapsed(id, params, signal, onUpdate, ctx),\n\t});\n\n\tconst promptTemplateBridge = registerPromptTemplateDelegationBridge({\n\t\tevents: pi.events,\n\t\tgetContext: () => state.lastUiContext,\n\t\texecute: (requestId, params, signal, ctx, onUpdate) =>\n\t\t\texecuteSubagentCollapsed(requestId, params, signal, onUpdate, ctx),\n\t});\n\n\tconst rpcBridge = registerSubagentRpcBridge({\n\t\tevents: pi.events,\n\t\tgetContext: () => state.lastUiContext,\n\t\texecute: (id, params, signal, onUpdate, ctx) => executor.execute(id, params, signal, onUpdate, ctx),\n\t});\n\n\tconst tool: ToolDefinition<typeof SubagentParams, Details> = {\n\t\tname: \"subagent\",\n\t\tlabel: \"Subagent\",\n\t\tdescription: buildSubagentToolDescription(config),\n\t\tparameters: SubagentParams,\n\t\t// lunr: same-turn SINGLE calls overlap; sequential work uses chain.\n\t\texecutionMode: \"parallel\",\n\n\t\tprepareArguments(args) {\n\t\t\t// Run friendly chain validation before pi-ai's raw TypeBox schema check\n\t\t\t// so the model sees which property is disallowed, what is allowed, and a\n\t\t\t// valid example instead of `chain.N: must not have additional properties`.\n\t\t\tvalidateChainInput(args);\n\t\t\treturn args as never;\n\t\t},\n\n\t\texecute(id, params, signal, onUpdate, ctx) {\n\t\t\treturn executeSubagentCollapsed(id, params, signal, onUpdate, ctx);\n\t\t},\n\n\t\trenderCall: (args, theme, context) => renderSubagentCall(args, theme, context, {\n\t\t\tresolveActionTitle: (params) => resolveSubagentActionDisplayTitle(params, state),\n\t\t}),\n\n\t\trenderResult(result, options, theme, context) {\n\t\t\tif (result.details?.communication) return renderCommunicationResult(result.content, result.details, options.expanded, context.isError, theme);\n\t\t\tif (subagentResultIsRunning(result)) {\n\t\t\t\tensureSubagentResultAnimation(context);\n\t\t\t} else {\n\t\t\t\tclearLegacyResultAnimationTimer(context);\n\t\t\t}\n\t\t\tconst state = context.state as { frame?: number; animEntries?: Array<{ text: Text; line: (frame: number) => string }> };\n\t\t\t// lunr: collect running-glyph line templates while rendering so the\n\t\t\t// animation timer can rewrite them in place (see ensureSubagentResultAnimation).\n\t\t\tconst entries: Array<{ text: Text; line: (frame: number) => string }> = [];\n\t\t\tstate.animEntries = entries;\n\t\t\tsubagentAnimSink.current = entries;\n\t\t\ttry {\n\t\t\t\treturn renderSubagentResult(result, options, theme, state.frame ?? 0);\n\t\t\t} finally {\n\t\t\t\tsubagentAnimSink.current = null;\n\t\t\t}\n\t\t},\n\n\t};\n\n\tpi.registerTool(tool);\n\n\t// lunr: register a callback so model-tier settings changes rebuild the subagent\n\t// tool description and refresh the live registry.\n\tconst modelTierBridge = (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/model-tiers\")] as\n\t\t| { registerToolDescriptionRefresher?: (refresher: () => void) => void }\n\t\t| undefined;\n\tmodelTierBridge?.registerToolDescriptionRefresher?.(() => {\n\t\ttool.description = buildSubagentToolDescription(config);\n\t\t// pi.runtime is not on ExtensionAPI; registerTool refreshes the live registry.\n\t\tpi.registerTool(tool);\n\t});\n\n\tregisterWaitTool(pi, state, waitToolConfig.enabled, async (signal) => {\n\t\tconst launches = [...pendingLaunches];\n\t\tif (launches.length === 0) return;\n\t\tawait awaitWithAbort(Promise.all(launches).then(() => {}), signal);\n\t});\n\n\tpi.on(\"agent_end\", async (_event, ctx) => {\n\t\tif (ctx.hasUI) return;\n\t\tawait drainOutstandingWork({ state, events: pi.events, hasPendingMessages: () => ctx.hasPendingMessages() });\n\t});\n\n\tregisterSlashCommands(pi, state);\n\n\tlet disposeNotify = registerSubagentNotify(pi, state, { batchConfig: config.completionBatch });\n\tconst visibleControlNotices = new Set<string>();\n\tconst controlEventHandler = (payload: unknown) => {\n\t\thandleSubagentControlNotice({\n\t\t\tpi,\n\t\t\tstate,\n\t\t\tvisibleControlNotices,\n\t\t\tdetails: payload as SubagentControlMessageDetails,\n\t\t});\n\t};\n\tconst steeringNoticeHandler = (payload: unknown) => {\n\t\thandleSubagentSteeringNotice({ pi, state, details: payload as SubagentSteeringMessageDetails });\n\t};\n\tconst eventUnsubscribes = [\n\t\tpi.events.on(SUBAGENT_ASYNC_STARTED_EVENT, handleStarted),\n\t\tpi.events.on(SUBAGENT_ASYNC_COMPLETE_EVENT, handleComplete),\n\t\tpi.events.on(SUBAGENT_CONTROL_EVENT, controlEventHandler),\n\t\tpi.events.on(SUBAGENT_STEERING_NOTICE_EVENT, steeringNoticeHandler),\n\t\trpcBridge.dispose,\n\t];\n\n\tpi.on(\"tool_result\", (event, ctx) => {\n\t\tif (event.toolName !== \"subagent\") return;\n\t\tif (!ctx.hasUI) return;\n\t\tstate.lastUiContext = ctx;\n\t\tif (state.asyncJobs.size > 0) {\n\t\t\trefreshWidget(ctx);\n\t\t\tensurePoller();\n\t\t}\n\t});\n\n\tconst cleanupSessionArtifacts = (ctx: ExtensionContext) => {\n\t\ttry {\n\t\t\tconst sessionFile = ctx.sessionManager.getSessionFile();\n\t\t\tif (sessionFile) {\n\t\t\t\tcleanupOldArtifacts(getArtifactsDir(sessionFile), DEFAULT_ARTIFACT_CONFIG.cleanupDays);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Cleanup failures should not block session lifecycle events.\n\t\t}\n\t};\n\n\tconst resetSessionState = (ctx: ExtensionContext) => {\n\t\tgeneration++;\n\t\tdisposeNotify();\n\t\tdisposeNotify = registerSubagentNotify(pi, state, { batchConfig: config.completionBatch });\n\t\tstopResultWatcher();\n\t\tsupervisorChannel.dispose();\n\t\tstate.sessionGeneration = (state.sessionGeneration ?? 0) + 1;\n\t\texecutorPromise = undefined;\n\t\tpendingLaunches.clear();\n\t\tpendingAsyncLaunches.clear();\n\t\tunregisterCancellation?.();\n\t\tstate.baseCwd = ctx.cwd;\n\t\tstate.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);\n\t\tstate.subagentSpawns = { sessionId: state.currentSessionId, count: 0 };\n\t\t// Child spawn paths pass the owning session explicitly. Shared process\n\t\t// environment cannot represent several simultaneous gateway parents.\n\t\tstate.lastUiContext = ctx;\n\t\tcleanupSessionArtifacts(ctx);\n\t\tclearPendingForegroundControlNotices(state);\n\t\tvisibleControlNotices.clear();\n\t\tfor (const entry of ctx.sessionManager.getEntries()) {\n\t\t\tif ((entry.type !== \"custom_message\" && entry.type !== \"custom\") || entry.customType !== SUBAGENT_CONTROL_MESSAGE_TYPE) continue;\n\t\t\tconst data = entry.type === \"custom_message\" ? entry.details : entry.data;\n\t\t\tif (!data || typeof data !== \"object\" || !(\"event\" in data)) continue;\n\t\t\tconst details = data as SubagentControlMessageDetails;\n\t\t\tif (typeof details.event?.runId !== \"string\" || typeof details.event.type !== \"string\") continue;\n\t\t\tvisibleControlNotices.add(controlNotificationKey(details.event, details.childIntercomTarget));\n\t\t}\n\t\tresetJobs(ctx);\n\t\trestoreActiveJobs(ctx);\n\t\tconst sessionId = state.currentSessionId;\n\t\tconst sessionGeneration = generation;\n\t\tif (sessionId) {\n\t\t\tconst cancellation = createSubagentCancellation({\n\t\t\t\tpendingLaunches: pendingAsyncLaunches,\n\t\t\t\tisCurrent: () => generation === sessionGeneration && state.currentSessionId === sessionId,\n\t\t\t\tgetActiveRunIds: () => [...state.asyncJobs.values()]\n\t\t\t\t\t.filter((job) => job.sessionId === sessionId && (job.status === \"queued\" || job.status === \"running\"))\n\t\t\t\t\t.map((job) => job.asyncId),\n\t\t\t\tasync stopRun(id) {\n\t\t\t\t\tconst result = await executor.execute(randomUUID(), { action: \"stop\", id }, new AbortController().signal, undefined, ctx);\n\t\t\t\t\treturn !result.isError;\n\t\t\t\t},\n\t\t\t});\n\t\t\t// Results use the session file identity; gateway controls use its UUID.\n\t\t\tconst identities = new Set([sessionId, ctx.sessionManager.getSessionId()]);\n\t\t\tconst unregisters = [...identities].filter((id): id is string => Boolean(id))\n\t\t\t\t.map((id) => registerSubagentCancellation(id, cancellation));\n\t\t\tunregisterCancellation = () => {\n\t\t\t\tfor (const unregister of unregisters) unregister();\n\t\t\t};\n\t\t}\n\t\tscheduledRunManager.bindSession(ctx);\n\t\trestoreSlashFinalSnapshots(ctx.sessionManager.getEntries());\n\t\tstartResultWatcher();\n\t\tprimeExistingResults();\n\t};\n\n\tpi.on(\"session_start\", (_event, ctx) => {\n\t\tresetSessionState(ctx);\n\t\trpcBridge.emitReady(ctx);\n\t\tsupervisorChannel.start();\n\t});\n\n\tpi.on(\"session_shutdown\", () => {\n\t\tgeneration++;\n\t\tsupervisorChannel.cancelOwnedQuestions(\"parent session shutdown\");\n\t\tstate.sessionGeneration = (state.sessionGeneration ?? 0) + 1;\n\t\texecutorPromise = undefined;\n\t\tpendingLaunches.clear();\n\t\tpendingAsyncLaunches.clear();\n\t\tunregisterCancellation?.();\n\t\tdisposeNotify();\n\t\tmainWatchdog.dispose();\n\t\tfor (const unsubscribe of eventUnsubscribes) {\n\t\t\ttry {\n\t\t\t\tunsubscribe();\n\t\t\t} catch {\n\t\t\t\t// Best effort cleanup during shutdown.\n\t\t\t}\n\t\t}\n\t\tstopResultWatcher();\n\t\tscheduledRunManager.stop();\n\t\tif (state.poller) clearInterval(state.poller);\n\t\tstate.poller = null;\n\t\tclearPendingForegroundControlNotices(state);\n\t\tfor (const timer of state.cleanupTimers.values()) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tstate.cleanupTimers.clear();\n\t\tstate.asyncJobs.clear();\n\t\tclearSlashSnapshots();\n\t\tslashBridge.cancelAll();\n\t\tslashBridge.dispose();\n\t\tpromptTemplateBridge.cancelAll();\n\t\tpromptTemplateBridge.dispose();\n\t\tsupervisorChannel.dispose();\n\t\tif (state.lastUiContext) disposeSubagentWidget(state.lastUiContext);\n\t\ttry {\n\t\t\tif (state.lastUiContext?.hasUI) {\n\t\t\t\tstate.lastUiContext.ui.setWidget(WIDGET_KEY, undefined);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (!isStaleExtensionContextError(error)) throw error;\n\t\t}\n\t});\n}\n"]}
@@ -42,7 +42,8 @@ import { registerWaitTool } from "../runs/background/wait-tool.js";
42
42
  import { drainOutstandingWork } from "../runs/background/auto-drain.js";
43
43
  import registerSubagentNotify, { parseSubagentNotifyContent } from "../runs/background/notify.js";
44
44
  import { formatSteeringNotice, handleSubagentSteeringNotice, SUBAGENT_STEERING_MESSAGE_TYPE } from "./steering-notices.js";
45
- import { SUBAGENT_CHILD_ENV, SUBAGENT_PARENT_SESSION_ENV } from "../runs/shared/pi-args.js";
45
+ import { controlNotificationKey } from "../runs/shared/subagent-control.js";
46
+ import { SUBAGENT_CHILD_ENV } from "../runs/shared/pi-args.js";
46
47
  import { loadConfig } from "./config.js";
47
48
  import { buildSubagentToolDescription } from "./tool-description.js";
48
49
  import { ASYNC_DIR, childRowLabel, DEFAULT_ARTIFACT_CONFIG, RESULTS_DIR, SLASH_RESULT_TYPE, SLASH_TEXT_RESULT_TYPE, SUBAGENT_ASYNC_COMPLETE_EVENT, SUBAGENT_ASYNC_STARTED_EVENT, SUBAGENT_CONTROL_EVENT, SUBAGENT_STEERING_NOTICE_EVENT, WIDGET_KEY, } from "../shared/types.js";
@@ -268,17 +269,6 @@ export default function registerSubagentExtension(pi) {
268
269
  if (process.env[SUBAGENT_CHILD_ENV] === "1") {
269
270
  return;
270
271
  }
271
- const globalStore = globalThis;
272
- const runtimeCleanupStoreKey = "__piSubagentRuntimeCleanup";
273
- const previousRuntimeCleanup = globalStore[runtimeCleanupStoreKey];
274
- if (typeof previousRuntimeCleanup === "function") {
275
- try {
276
- previousRuntimeCleanup();
277
- }
278
- catch {
279
- // Best effort cleanup for stale timers from an older reload.
280
- }
281
- }
282
272
  ensureAccessibleDir(RESULTS_DIR);
283
273
  ensureAccessibleDir(ASYNC_DIR);
284
274
  cleanupOldChainDirs();
@@ -312,33 +302,11 @@ export default function registerSubagentExtension(pi) {
312
302
  const supervisorChannel = createNativeSupervisorChannel(pi, state);
313
303
  const mainWatchdog = registerMainWatchdog(pi);
314
304
  const { startResultWatcher, primeExistingResults, stopResultWatcher } = createResultWatcher(pi, state, RESULTS_DIR, 10 * 60 * 1000);
315
- startResultWatcher();
316
- primeExistingResults();
317
305
  let generation = 0;
318
306
  let executorPromise;
319
307
  const pendingLaunches = new Set();
320
308
  const pendingAsyncLaunches = new Set();
321
309
  let unregisterCancellation;
322
- const runtimeCleanup = () => {
323
- generation++;
324
- supervisorChannel.cancelOwnedQuestions("parent runtime replaced");
325
- state.sessionGeneration = (state.sessionGeneration ?? 0) + 1;
326
- executorPromise = undefined;
327
- pendingLaunches.clear();
328
- pendingAsyncLaunches.clear();
329
- unregisterCancellation?.();
330
- mainWatchdog.dispose();
331
- stopResultWatcher();
332
- scheduledRunManager.stop();
333
- supervisorChannel.dispose();
334
- clearPendingForegroundControlNotices(state);
335
- disposeSubagentWidget();
336
- if (state.poller) {
337
- clearInterval(state.poller);
338
- state.poller = null;
339
- }
340
- };
341
- globalStore[runtimeCleanupStoreKey] = runtimeCleanup;
342
310
  const { ensurePoller, refreshWidget, handleStarted, handleComplete: trackComplete, resetJobs, restoreActiveJobs } = createAsyncJobTracker(pi, state, ASYNC_DIR, {
343
311
  widgetEnabled: config.asyncWidget !== false,
344
312
  });
@@ -543,25 +511,8 @@ export default function registerSubagentExtension(pi) {
543
511
  await drainOutstandingWork({ state, events: pi.events, hasPendingMessages: () => ctx.hasPendingMessages() });
544
512
  });
545
513
  registerSlashCommands(pi, state);
546
- const eventUnsubscribeStoreKey = "__piSubagentEventUnsubscribes";
547
- const controlNoticeSeenStoreKey = "__piSubagentVisibleControlNotices";
548
- const previousEventUnsubscribes = globalStore[eventUnsubscribeStoreKey];
549
- if (Array.isArray(previousEventUnsubscribes)) {
550
- for (const unsubscribe of previousEventUnsubscribes) {
551
- if (typeof unsubscribe !== "function")
552
- continue;
553
- try {
554
- unsubscribe();
555
- }
556
- catch {
557
- // Best effort cleanup for stale handlers from an older reload.
558
- }
559
- }
560
- }
561
- registerSubagentNotify(pi, state, { batchConfig: config.completionBatch });
562
- const existingVisibleControlNotices = globalStore[controlNoticeSeenStoreKey];
563
- const visibleControlNotices = existingVisibleControlNotices instanceof Set ? existingVisibleControlNotices : new Set();
564
- globalStore[controlNoticeSeenStoreKey] = visibleControlNotices;
514
+ let disposeNotify = registerSubagentNotify(pi, state, { batchConfig: config.completionBatch });
515
+ const visibleControlNotices = new Set();
565
516
  const controlEventHandler = (payload) => {
566
517
  handleSubagentControlNotice({
567
518
  pi,
@@ -580,7 +531,6 @@ export default function registerSubagentExtension(pi) {
580
531
  pi.events.on(SUBAGENT_STEERING_NOTICE_EVENT, steeringNoticeHandler),
581
532
  rpcBridge.dispose,
582
533
  ];
583
- globalStore[eventUnsubscribeStoreKey] = eventUnsubscribes;
584
534
  pi.on("tool_result", (event, ctx) => {
585
535
  if (event.toolName !== "subagent")
586
536
  return;
@@ -605,7 +555,10 @@ export default function registerSubagentExtension(pi) {
605
555
  };
606
556
  const resetSessionState = (ctx) => {
607
557
  generation++;
608
- supervisorChannel.cancelOwnedQuestions("parent session replaced");
558
+ disposeNotify();
559
+ disposeNotify = registerSubagentNotify(pi, state, { batchConfig: config.completionBatch });
560
+ stopResultWatcher();
561
+ supervisorChannel.dispose();
609
562
  state.sessionGeneration = (state.sessionGeneration ?? 0) + 1;
610
563
  executorPromise = undefined;
611
564
  pendingLaunches.clear();
@@ -614,26 +567,29 @@ export default function registerSubagentExtension(pi) {
614
567
  state.baseCwd = ctx.cwd;
615
568
  state.currentSessionId = resolveCurrentSessionId(ctx.sessionManager);
616
569
  state.subagentSpawns = { sessionId: state.currentSessionId, count: 0 };
617
- // Set PI_SUBAGENT_PARENT_SESSION for permission-system forwarding.
618
- // Only set in the root session (the interactive UI session), not in
619
- // child subagent processes — children inherit the parent's value
620
- // through the process environment at spawn time and must not overwrite
621
- // it with their own session identity.
622
- if (!process.env[SUBAGENT_CHILD_ENV]) {
623
- const sessionId = ctx.sessionManager.getSessionId();
624
- if (sessionId) {
625
- process.env[SUBAGENT_PARENT_SESSION_ENV] = sessionId;
626
- }
627
- }
570
+ // Child spawn paths pass the owning session explicitly. Shared process
571
+ // environment cannot represent several simultaneous gateway parents.
628
572
  state.lastUiContext = ctx;
629
573
  cleanupSessionArtifacts(ctx);
630
574
  clearPendingForegroundControlNotices(state);
575
+ visibleControlNotices.clear();
576
+ for (const entry of ctx.sessionManager.getEntries()) {
577
+ if ((entry.type !== "custom_message" && entry.type !== "custom") || entry.customType !== SUBAGENT_CONTROL_MESSAGE_TYPE)
578
+ continue;
579
+ const data = entry.type === "custom_message" ? entry.details : entry.data;
580
+ if (!data || typeof data !== "object" || !("event" in data))
581
+ continue;
582
+ const details = data;
583
+ if (typeof details.event?.runId !== "string" || typeof details.event.type !== "string")
584
+ continue;
585
+ visibleControlNotices.add(controlNotificationKey(details.event, details.childIntercomTarget));
586
+ }
631
587
  resetJobs(ctx);
632
588
  restoreActiveJobs(ctx);
633
589
  const sessionId = state.currentSessionId;
634
590
  const sessionGeneration = generation;
635
- if (sessionId)
636
- unregisterCancellation = registerSubagentCancellation(sessionId, createSubagentCancellation({
591
+ if (sessionId) {
592
+ const cancellation = createSubagentCancellation({
637
593
  pendingLaunches: pendingAsyncLaunches,
638
594
  isCurrent: () => generation === sessionGeneration && state.currentSessionId === sessionId,
639
595
  getActiveRunIds: () => [...state.asyncJobs.values()]
@@ -643,9 +599,19 @@ export default function registerSubagentExtension(pi) {
643
599
  const result = await executor.execute(randomUUID(), { action: "stop", id }, new AbortController().signal, undefined, ctx);
644
600
  return !result.isError;
645
601
  },
646
- }));
602
+ });
603
+ // Results use the session file identity; gateway controls use its UUID.
604
+ const identities = new Set([sessionId, ctx.sessionManager.getSessionId()]);
605
+ const unregisters = [...identities].filter((id) => Boolean(id))
606
+ .map((id) => registerSubagentCancellation(id, cancellation));
607
+ unregisterCancellation = () => {
608
+ for (const unregister of unregisters)
609
+ unregister();
610
+ };
611
+ }
647
612
  scheduledRunManager.bindSession(ctx);
648
613
  restoreSlashFinalSnapshots(ctx.sessionManager.getEntries());
614
+ startResultWatcher();
649
615
  primeExistingResults();
650
616
  };
651
617
  pi.on("session_start", (_event, ctx) => {
@@ -661,7 +627,8 @@ export default function registerSubagentExtension(pi) {
661
627
  pendingLaunches.clear();
662
628
  pendingAsyncLaunches.clear();
663
629
  unregisterCancellation?.();
664
- delete process.env[SUBAGENT_PARENT_SESSION_ENV];
630
+ disposeNotify();
631
+ mainWatchdog.dispose();
665
632
  for (const unsubscribe of eventUnsubscribes) {
666
633
  try {
667
634
  unsubscribe();
@@ -670,9 +637,6 @@ export default function registerSubagentExtension(pi) {
670
637
  // Best effort cleanup during shutdown.
671
638
  }
672
639
  }
673
- if (globalStore[eventUnsubscribeStoreKey] === eventUnsubscribes) {
674
- delete globalStore[eventUnsubscribeStoreKey];
675
- }
676
640
  stopResultWatcher();
677
641
  scheduledRunManager.stop();
678
642
  if (state.poller)
@@ -690,10 +654,8 @@ export default function registerSubagentExtension(pi) {
690
654
  promptTemplateBridge.cancelAll();
691
655
  promptTemplateBridge.dispose();
692
656
  supervisorChannel.dispose();
693
- if (globalStore[runtimeCleanupStoreKey] === runtimeCleanup) {
694
- delete globalStore[runtimeCleanupStoreKey];
695
- }
696
- disposeSubagentWidget();
657
+ if (state.lastUiContext)
658
+ disposeSubagentWidget(state.lastUiContext);
697
659
  try {
698
660
  if (state.lastUiContext?.hasUI) {
699
661
  state.lastUiContext.ui.setWidget(WIDGET_KEY, undefined);