@caupulican/pi-adaptative 0.81.32 → 0.81.37

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 (339) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/bundled-resources/extensions/tmux-agent-manager/README.md +69 -0
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +53 -0
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -0
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +1282 -0
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -0
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +1453 -0
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/templates/builder-validator.json +14 -0
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/templates/claude-trio.json +32 -0
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/templates/full-provider-review.json +15 -0
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/templates/provider-prompt-smoke.json +14 -0
  12. package/dist/bundled-resources/prompts/extensionify.md +5 -4
  13. package/dist/bundled-resources/prompts/skillify.md +5 -5
  14. package/dist/bundled-resources/skills/pi-harness-learning/SKILL.md +6 -3
  15. package/dist/cli/args.d.ts.map +1 -1
  16. package/dist/cli/args.js +10 -8
  17. package/dist/cli/args.js.map +1 -1
  18. package/dist/config.d.ts +5 -1
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +10 -2
  21. package/dist/config.js.map +1 -1
  22. package/dist/core/agent-session.d.ts +12 -0
  23. package/dist/core/agent-session.d.ts.map +1 -1
  24. package/dist/core/agent-session.js +42 -2
  25. package/dist/core/agent-session.js.map +1 -1
  26. package/dist/core/autonomy/approval-gate.d.ts.map +1 -1
  27. package/dist/core/autonomy/approval-gate.js +2 -0
  28. package/dist/core/autonomy/approval-gate.js.map +1 -1
  29. package/dist/core/autonomy/foreground-envelope.d.ts.map +1 -1
  30. package/dist/core/autonomy/foreground-envelope.js +2 -0
  31. package/dist/core/autonomy/foreground-envelope.js.map +1 -1
  32. package/dist/core/autonomy/gates.d.ts.map +1 -1
  33. package/dist/core/autonomy/gates.js +9 -2
  34. package/dist/core/autonomy/gates.js.map +1 -1
  35. package/dist/core/autonomy/risk-assessment.d.ts.map +1 -1
  36. package/dist/core/autonomy/risk-assessment.js +2 -0
  37. package/dist/core/autonomy/risk-assessment.js.map +1 -1
  38. package/dist/core/background-lane-controller.d.ts +12 -3
  39. package/dist/core/background-lane-controller.d.ts.map +1 -1
  40. package/dist/core/background-lane-controller.js +67 -26
  41. package/dist/core/background-lane-controller.js.map +1 -1
  42. package/dist/core/bash-execution-controller.d.ts +9 -4
  43. package/dist/core/bash-execution-controller.d.ts.map +1 -1
  44. package/dist/core/bash-execution-controller.js +7 -6
  45. package/dist/core/bash-execution-controller.js.map +1 -1
  46. package/dist/core/bash-executor.d.ts +2 -0
  47. package/dist/core/bash-executor.d.ts.map +1 -1
  48. package/dist/core/bash-executor.js +10 -5
  49. package/dist/core/bash-executor.js.map +1 -1
  50. package/dist/core/context/context-store-retention.d.ts +4 -1
  51. package/dist/core/context/context-store-retention.d.ts.map +1 -1
  52. package/dist/core/context/context-store-retention.js +42 -151
  53. package/dist/core/context/context-store-retention.js.map +1 -1
  54. package/dist/core/context-pipeline.d.ts.map +1 -1
  55. package/dist/core/context-pipeline.js +6 -6
  56. package/dist/core/context-pipeline.js.map +1 -1
  57. package/dist/core/default-tool-surface.d.ts +7 -0
  58. package/dist/core/default-tool-surface.d.ts.map +1 -1
  59. package/dist/core/default-tool-surface.js +29 -10
  60. package/dist/core/default-tool-surface.js.map +1 -1
  61. package/dist/core/doctor.d.ts +10 -10
  62. package/dist/core/doctor.d.ts.map +1 -1
  63. package/dist/core/doctor.js +30 -20
  64. package/dist/core/doctor.js.map +1 -1
  65. package/dist/core/exec.d.ts +2 -0
  66. package/dist/core/exec.d.ts.map +1 -1
  67. package/dist/core/exec.js +26 -39
  68. package/dist/core/exec.js.map +1 -1
  69. package/dist/core/extensions/loader.d.ts +9 -2
  70. package/dist/core/extensions/loader.d.ts.map +1 -1
  71. package/dist/core/extensions/loader.js +105 -21
  72. package/dist/core/extensions/loader.js.map +1 -1
  73. package/dist/core/extensions/types.d.ts +13 -3
  74. package/dist/core/extensions/types.d.ts.map +1 -1
  75. package/dist/core/extensions/types.js +3 -0
  76. package/dist/core/extensions/types.js.map +1 -1
  77. package/dist/core/footer-data-provider.d.ts.map +1 -1
  78. package/dist/core/footer-data-provider.js +2 -0
  79. package/dist/core/footer-data-provider.js.map +1 -1
  80. package/dist/core/goals/goal-state.d.ts +10 -0
  81. package/dist/core/goals/goal-state.d.ts.map +1 -1
  82. package/dist/core/goals/goal-state.js +37 -0
  83. package/dist/core/goals/goal-state.js.map +1 -1
  84. package/dist/core/goals/goal-tool-core.d.ts +11 -0
  85. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  86. package/dist/core/goals/goal-tool-core.js +51 -1
  87. package/dist/core/goals/goal-tool-core.js.map +1 -1
  88. package/dist/core/improvement-loop.d.ts.map +1 -1
  89. package/dist/core/improvement-loop.js +26 -5
  90. package/dist/core/improvement-loop.js.map +1 -1
  91. package/dist/core/memory/memory-manager.d.ts.map +1 -1
  92. package/dist/core/memory/memory-manager.js +1 -0
  93. package/dist/core/memory/memory-manager.js.map +1 -1
  94. package/dist/core/model-capability.d.ts.map +1 -1
  95. package/dist/core/model-capability.js +2 -0
  96. package/dist/core/model-capability.js.map +1 -1
  97. package/dist/core/model-router/tool-escalation.d.ts.map +1 -1
  98. package/dist/core/model-router/tool-escalation.js +17 -3
  99. package/dist/core/model-router/tool-escalation.js.map +1 -1
  100. package/dist/core/models/fitness-store.d.ts.map +1 -1
  101. package/dist/core/models/fitness-store.js +1 -1
  102. package/dist/core/models/fitness-store.js.map +1 -1
  103. package/dist/core/models/local-runtime.d.ts +6 -4
  104. package/dist/core/models/local-runtime.d.ts.map +1 -1
  105. package/dist/core/models/local-runtime.js +108 -36
  106. package/dist/core/models/local-runtime.js.map +1 -1
  107. package/dist/core/output-guard.d.ts.map +1 -1
  108. package/dist/core/output-guard.js +23 -8
  109. package/dist/core/output-guard.js.map +1 -1
  110. package/dist/core/package-manager.d.ts.map +1 -1
  111. package/dist/core/package-manager.js +44 -59
  112. package/dist/core/package-manager.js.map +1 -1
  113. package/dist/core/profile-resource-selection.d.ts +16 -0
  114. package/dist/core/profile-resource-selection.d.ts.map +1 -1
  115. package/dist/core/profile-resource-selection.js +41 -0
  116. package/dist/core/profile-resource-selection.js.map +1 -1
  117. package/dist/core/python-runtime.d.ts +46 -0
  118. package/dist/core/python-runtime.d.ts.map +1 -0
  119. package/dist/core/python-runtime.js +157 -0
  120. package/dist/core/python-runtime.js.map +1 -0
  121. package/dist/core/reflection-controller.d.ts.map +1 -1
  122. package/dist/core/reflection-controller.js +18 -1
  123. package/dist/core/reflection-controller.js.map +1 -1
  124. package/dist/core/reload-blockers.d.ts +1 -0
  125. package/dist/core/reload-blockers.d.ts.map +1 -1
  126. package/dist/core/reload-blockers.js +6 -2
  127. package/dist/core/reload-blockers.js.map +1 -1
  128. package/dist/core/resource-loader.d.ts +2 -0
  129. package/dist/core/resource-loader.d.ts.map +1 -1
  130. package/dist/core/resource-loader.js +50 -28
  131. package/dist/core/resource-loader.js.map +1 -1
  132. package/dist/core/runtime-builder.d.ts +4 -0
  133. package/dist/core/runtime-builder.d.ts.map +1 -1
  134. package/dist/core/runtime-builder.js +31 -9
  135. package/dist/core/runtime-builder.js.map +1 -1
  136. package/dist/core/security/untrusted-boundary.d.ts +2 -2
  137. package/dist/core/security/untrusted-boundary.d.ts.map +1 -1
  138. package/dist/core/security/untrusted-boundary.js +4 -3
  139. package/dist/core/security/untrusted-boundary.js.map +1 -1
  140. package/dist/core/settings-manager.d.ts.map +1 -1
  141. package/dist/core/settings-manager.js +3 -1
  142. package/dist/core/settings-manager.js.map +1 -1
  143. package/dist/core/slash-commands.d.ts.map +1 -1
  144. package/dist/core/slash-commands.js +9 -1
  145. package/dist/core/slash-commands.js.map +1 -1
  146. package/dist/core/system-prompt.d.ts.map +1 -1
  147. package/dist/core/system-prompt.js +13 -2
  148. package/dist/core/system-prompt.js.map +1 -1
  149. package/dist/core/tasks/session-task-state.d.ts +10 -0
  150. package/dist/core/tasks/session-task-state.d.ts.map +1 -0
  151. package/dist/core/tasks/session-task-state.js +29 -0
  152. package/dist/core/tasks/session-task-state.js.map +1 -0
  153. package/dist/core/tasks/task-command.d.ts +30 -0
  154. package/dist/core/tasks/task-command.d.ts.map +1 -0
  155. package/dist/core/tasks/task-command.js +79 -0
  156. package/dist/core/tasks/task-command.js.map +1 -0
  157. package/dist/core/tasks/task-state.d.ts +71 -0
  158. package/dist/core/tasks/task-state.d.ts.map +1 -0
  159. package/dist/core/tasks/task-state.js +372 -0
  160. package/dist/core/tasks/task-state.js.map +1 -0
  161. package/dist/core/tool-selection/tool-selection-controller.d.ts.map +1 -1
  162. package/dist/core/tool-selection/tool-selection-controller.js +1 -1
  163. package/dist/core/tool-selection/tool-selection-controller.js.map +1 -1
  164. package/dist/core/toolkit/script-runner.d.ts.map +1 -1
  165. package/dist/core/toolkit/script-runner.js +58 -24
  166. package/dist/core/toolkit/script-runner.js.map +1 -1
  167. package/dist/core/tools/bash.d.ts +20 -2
  168. package/dist/core/tools/bash.d.ts.map +1 -1
  169. package/dist/core/tools/bash.js +132 -220
  170. package/dist/core/tools/bash.js.map +1 -1
  171. package/dist/core/tools/extensionify.d.ts +2 -1
  172. package/dist/core/tools/extensionify.d.ts.map +1 -1
  173. package/dist/core/tools/extensionify.js +11 -8
  174. package/dist/core/tools/extensionify.js.map +1 -1
  175. package/dist/core/tools/find.d.ts.map +1 -1
  176. package/dist/core/tools/find.js +57 -48
  177. package/dist/core/tools/find.js.map +1 -1
  178. package/dist/core/tools/git-filter.d.ts.map +1 -1
  179. package/dist/core/tools/git-filter.js +20 -32
  180. package/dist/core/tools/git-filter.js.map +1 -1
  181. package/dist/core/tools/goal.d.ts +1 -1
  182. package/dist/core/tools/goal.d.ts.map +1 -1
  183. package/dist/core/tools/goal.js +10 -3
  184. package/dist/core/tools/goal.js.map +1 -1
  185. package/dist/core/tools/grep.d.ts.map +1 -1
  186. package/dist/core/tools/grep.js +92 -80
  187. package/dist/core/tools/grep.js.map +1 -1
  188. package/dist/core/tools/index.d.ts +9 -6
  189. package/dist/core/tools/index.d.ts.map +1 -1
  190. package/dist/core/tools/index.js +24 -9
  191. package/dist/core/tools/index.js.map +1 -1
  192. package/dist/core/tools/output-accumulator.d.ts +2 -0
  193. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  194. package/dist/core/tools/output-accumulator.js +7 -4
  195. package/dist/core/tools/output-accumulator.js.map +1 -1
  196. package/dist/core/tools/python.d.ts +64 -0
  197. package/dist/core/tools/python.d.ts.map +1 -0
  198. package/dist/core/tools/python.js +241 -0
  199. package/dist/core/tools/python.js.map +1 -0
  200. package/dist/core/tools/read.d.ts.map +1 -1
  201. package/dist/core/tools/read.js +4 -3
  202. package/dist/core/tools/read.js.map +1 -1
  203. package/dist/core/tools/shell-contract-router.d.ts +13 -0
  204. package/dist/core/tools/shell-contract-router.d.ts.map +1 -0
  205. package/dist/core/tools/shell-contract-router.js +295 -0
  206. package/dist/core/tools/shell-contract-router.js.map +1 -0
  207. package/dist/core/tools/task-steps.d.ts +46 -0
  208. package/dist/core/tools/task-steps.d.ts.map +1 -0
  209. package/dist/core/tools/task-steps.js +160 -0
  210. package/dist/core/tools/task-steps.js.map +1 -0
  211. package/dist/index.d.ts +2 -1
  212. package/dist/index.d.ts.map +1 -1
  213. package/dist/index.js +2 -1
  214. package/dist/index.js.map +1 -1
  215. package/dist/main.d.ts +2 -0
  216. package/dist/main.d.ts.map +1 -1
  217. package/dist/main.js +23 -4
  218. package/dist/main.js.map +1 -1
  219. package/dist/migrations.d.ts.map +1 -1
  220. package/dist/migrations.js +18 -4
  221. package/dist/migrations.js.map +1 -1
  222. package/dist/modes/interactive/auth-dialogs-controller.d.ts +10 -0
  223. package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
  224. package/dist/modes/interactive/auth-dialogs-controller.js +94 -27
  225. package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
  226. package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -1
  227. package/dist/modes/interactive/auto-learn-controller.js +2 -1
  228. package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
  229. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -0
  230. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  231. package/dist/modes/interactive/components/bordered-loader.js +8 -0
  232. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  233. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  234. package/dist/modes/interactive/components/extension-editor.js +6 -15
  235. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  236. package/dist/modes/interactive/components/login-dialog.d.ts +3 -1
  237. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  238. package/dist/modes/interactive/components/login-dialog.js +20 -8
  239. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  240. package/dist/modes/interactive/components/profile-resource-editor.d.ts +4 -1
  241. package/dist/modes/interactive/components/profile-resource-editor.d.ts.map +1 -1
  242. package/dist/modes/interactive/components/profile-resource-editor.js +22 -39
  243. package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
  244. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  245. package/dist/modes/interactive/components/session-selector.js +1 -1
  246. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  247. package/dist/modes/interactive/config-backup.d.ts +1 -0
  248. package/dist/modes/interactive/config-backup.d.ts.map +1 -1
  249. package/dist/modes/interactive/config-backup.js +14 -3
  250. package/dist/modes/interactive/config-backup.js.map +1 -1
  251. package/dist/modes/interactive/editor-overlay-host.d.ts +12 -0
  252. package/dist/modes/interactive/editor-overlay-host.d.ts.map +1 -1
  253. package/dist/modes/interactive/editor-overlay-host.js +55 -0
  254. package/dist/modes/interactive/editor-overlay-host.js.map +1 -1
  255. package/dist/modes/interactive/extension-ui-host.d.ts +2 -1
  256. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
  257. package/dist/modes/interactive/extension-ui-host.js +161 -96
  258. package/dist/modes/interactive/extension-ui-host.js.map +1 -1
  259. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  260. package/dist/modes/interactive/external-editor.js +23 -28
  261. package/dist/modes/interactive/external-editor.js.map +1 -1
  262. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  263. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  264. package/dist/modes/interactive/interactive-mode.js +26 -8
  265. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  266. package/dist/modes/interactive/profile-menu-controller.d.ts +5 -1
  267. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
  268. package/dist/modes/interactive/profile-menu-controller.js +118 -24
  269. package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
  270. package/dist/modes/interactive/resource-shell-commands.d.ts +1 -0
  271. package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -1
  272. package/dist/modes/interactive/resource-shell-commands.js +5 -1
  273. package/dist/modes/interactive/resource-shell-commands.js.map +1 -1
  274. package/dist/modes/interactive/session-flow-commands.d.ts +10 -0
  275. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  276. package/dist/modes/interactive/session-flow-commands.js +143 -7
  277. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  278. package/dist/modes/interactive/session-io-commands.d.ts.map +1 -1
  279. package/dist/modes/interactive/session-io-commands.js +80 -50
  280. package/dist/modes/interactive/session-io-commands.js.map +1 -1
  281. package/dist/modes/interactive/startup-checks.d.ts.map +1 -1
  282. package/dist/modes/interactive/startup-checks.js +14 -17
  283. package/dist/modes/interactive/startup-checks.js.map +1 -1
  284. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  285. package/dist/modes/rpc/rpc-client.js +20 -19
  286. package/dist/modes/rpc/rpc-client.js.map +1 -1
  287. package/dist/package-manager-cli.d.ts.map +1 -1
  288. package/dist/package-manager-cli.js +10 -19
  289. package/dist/package-manager-cli.js.map +1 -1
  290. package/dist/utils/child-process.d.ts +13 -7
  291. package/dist/utils/child-process.d.ts.map +1 -1
  292. package/dist/utils/child-process.js +56 -3
  293. package/dist/utils/child-process.js.map +1 -1
  294. package/dist/utils/clipboard-image.d.ts.map +1 -1
  295. package/dist/utils/clipboard-image.js +3 -2
  296. package/dist/utils/clipboard-image.js.map +1 -1
  297. package/dist/utils/clipboard.d.ts.map +1 -1
  298. package/dist/utils/clipboard.js +17 -10
  299. package/dist/utils/clipboard.js.map +1 -1
  300. package/dist/utils/external-editor-command.d.ts +8 -0
  301. package/dist/utils/external-editor-command.d.ts.map +1 -0
  302. package/dist/utils/external-editor-command.js +60 -0
  303. package/dist/utils/external-editor-command.js.map +1 -0
  304. package/dist/utils/paths.d.ts.map +1 -1
  305. package/dist/utils/paths.js +10 -2
  306. package/dist/utils/paths.js.map +1 -1
  307. package/dist/utils/shell.d.ts +6 -8
  308. package/dist/utils/shell.d.ts.map +1 -1
  309. package/dist/utils/shell.js +61 -70
  310. package/dist/utils/shell.js.map +1 -1
  311. package/dist/utils/tools-manager.d.ts +23 -3
  312. package/dist/utils/tools-manager.d.ts.map +1 -1
  313. package/dist/utils/tools-manager.js +117 -21
  314. package/dist/utils/tools-manager.js.map +1 -1
  315. package/dist/utils/work-directory.d.ts +36 -0
  316. package/dist/utils/work-directory.d.ts.map +1 -0
  317. package/dist/utils/work-directory.js +462 -0
  318. package/dist/utils/work-directory.js.map +1 -0
  319. package/docs/index.md +4 -0
  320. package/docs/python.md +43 -0
  321. package/docs/resources.md +2 -2
  322. package/docs/rpc.md +1 -1
  323. package/docs/settings.md +7 -3
  324. package/docs/task-steps.md +90 -0
  325. package/docs/termux.md +7 -0
  326. package/docs/tmux-agent-manager.md +48 -0
  327. package/docs/usage.md +5 -6
  328. package/docs/windows.md +104 -8
  329. package/docs/work-directory.md +41 -0
  330. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  331. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  332. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  333. package/examples/extensions/sandbox/package-lock.json +2 -2
  334. package/examples/extensions/sandbox/package.json +1 -1
  335. package/examples/extensions/with-deps/package-lock.json +2 -2
  336. package/examples/extensions/with-deps/package.json +1 -1
  337. package/npm-shrinkwrap.json +32 -37
  338. package/package.json +9 -7
  339. package/scripts/postinstall-python-runtime.mjs +20 -0
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-builder.d.ts","sourceRoot":"","sources":["../../src/core/runtime-builder.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Runtime build & reload: the session's tool-registry assembly and the self-modification-safe\n * extension reload path. Owns building the base tool definitions, wrapping them into the live tool\n * registry (`_refreshToolRegistry`), constructing the {@link ExtensionRunner} for a rebuilt runtime\n * (`_buildRuntime`), and the repo's self-modification safety crown jewel: the preflight-guarded\n * `reload()` with its snapshot / doctor / commit-or-rollback sequence, plus the single-extension\n * live load/unload/reconcile operations that rebuild the runtime in place.\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns ONLY the tool-registry\n * state — the base tool definitions, the wrapped tool registry, the definition registry, and the\n * per-tool prompt snippet/guideline maps. Everything else the build & reload touch — the live\n * {@link ExtensionRunner}, the agent's tool/system-prompt state, the base system prompt, the\n * resource loader, the session/settings managers, the model registry, the profile tool filter and\n * its warning sinks, the requested-active-tool-names request, the memory subsystem, and the many\n * host callbacks the rebuilt tools/runtime are wired to — is reached through narrow deps accessors\n * that read and write the SAME storage the host owns today.\n *\n * Snapshot-ownership boundary (deliberate, load-bearing for reload safety): the reload snapshot\n * spans state owned by OTHER collaborators — the extension runner and its ref, `agent.state.tools`\n * / `agent.state.systemPrompt`, and `_baseSystemPrompt`. Those are captured and restored through\n * {@link RuntimeBuilderDeps} get/set accessors so save/restore mutate exactly the host/agent fields\n * they mutated before extraction; only the five tool-registry maps are captured by direct field\n * reference here (this builder owns them). The `_extensionRunnerRef.current` update folds into\n * {@link RuntimeBuilderDeps.setExtensionRunner} (the same field-then-ref pattern the host used at\n * every assignment site), so no observer runs between the two writes.\n *\n * Host-binding boundary (deliberate): `_bindExtensionCore` — which exposes the SESSION's own public\n * surface (sendMessage, setModel, compact, abort, reload, …) to the extension runner — stays\n * host-side and is invoked from {@link buildRuntime} via {@link RuntimeBuilderDeps.bindExtensionCore};\n * it is host identity, not build logic, and moving it would only re-export ~30 host methods through\n * deps to hand them straight back. The host keeps one-line delegations for the public reload /\n * load / unload / reconcile API and for `getAllTools` / `getToolDefinition`, and a private\n * `_refreshToolRegistry` delegation for its internal callers.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { isAbsolute, join } from \"node:path\";\nimport type { Agent, AgentContext, AgentMessage, AgentTool, ThinkingLevel } from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, Model, Usage } from \"@caupulican/pi-ai\";\nimport type {\n\tIsolatedCompletionOptions,\n\tIsolatedCompletionResult,\n\tWorkerDelegationRunOutcome,\n} from \"./agent-session.ts\";\nimport type { WorkerResult } from \"./autonomy/contracts.ts\";\nimport type { LaneRecord } from \"./autonomy/lane-tracker.ts\";\nimport type { ArtifactStore } from \"./context/context-artifacts.ts\";\nimport type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from \"./context/memory-diagnostics.ts\";\nimport type { ContextGcReport } from \"./context-gc.ts\";\nimport { DEFAULT_ACTIVE_TOOL_NAMES } from \"./default-tool-surface.ts\";\nimport { createCoreDiagnosticsToolDefinitions } from \"./extensions/builtin.ts\";\nimport {\n\ttype ContextUsage,\n\ttype Extension,\n\ttype ExtensionCommandContextActions,\n\ttype ExtensionErrorListener,\n\tExtensionRunner,\n\ttype ExtensionUIContext,\n\ttype ShutdownHandler,\n\ttype ToolDefinition,\n\ttype ToolInfo,\n\twrapRegisteredTools,\n} from \"./extensions/index.ts\";\nimport { disposeExtensionEventSubscriptions } from \"./extensions/loader.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport type { GoalState } from \"./goals/goal-state.ts\";\nimport type { MemoryManager } from \"./memory/memory-manager.ts\";\nimport type { MemoryControllerReloadSnapshot } from \"./memory-controller.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport { resolveCliModel } from \"./model-resolver.ts\";\nimport { evaluateSurfaceFitness } from \"./model-router/fitness-gate.ts\";\nimport { FitnessStore } from \"./models/fitness-store.ts\";\nimport type { ProfileFilterReloadSnapshot } from \"./profile-filter-controller.ts\";\nimport type { ModelFitnessReport } from \"./research/model-fitness.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { ScoutController } from \"./scout-controller.ts\";\nimport {\n\tmatchesResourceProfilePattern,\n\ttype ResourceProfileFilterSettings,\n\ttype SettingsManager,\n} from \"./settings-manager.ts\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.ts\";\nimport {\n\tbuildReflexUserPrompt,\n\tparseReflexPlan,\n\tREFLEX_INTERPRETER_SYSTEM_PROMPT,\n} from \"./toolkit/reflex-interpreter.ts\";\nimport { executeToolkitScript } from \"./toolkit/script-runner.ts\";\nimport { createContextScoutToolDefinition } from \"./tools/context-scout.ts\";\nimport { createDelegateToolDefinition } from \"./tools/delegate.ts\";\nimport { createDelegateStatusToolDefinition } from \"./tools/delegate-status.ts\";\nimport { createFindTool } from \"./tools/find.ts\";\nimport { createGoalToolDefinition } from \"./tools/goal.ts\";\nimport { createGrepTool } from \"./tools/grep.ts\";\nimport { createAllToolDefinitions } from \"./tools/index.ts\";\nimport { createModelFitnessToolDefinition } from \"./tools/model-fitness.ts\";\nimport { createReadTool } from \"./tools/read.ts\";\nimport { createRunToolkitScriptToolDefinition } from \"./tools/run-toolkit-script.ts\";\nimport { createToolDefinitionFromAgentTool } from \"./tools/tool-definition-wrapper.ts\";\n\ninterface ToolDefinitionEntry {\n\tdefinition: ToolDefinition;\n\tsourceInfo: SourceInfo;\n}\n\ninterface ReloadRuntimeSnapshot {\n\textensionRunner: ExtensionRunner;\n\tsettings: ReturnType<SettingsManager[\"createReloadSnapshot\"]>;\n\tmodelRegistry: ReturnType<ModelRegistry[\"createReloadSnapshot\"]>;\n\tmodel: Model<Api>;\n\tthinkingLevel: ThinkingLevel;\n\tsessionLeafId: string | null;\n\ttoolProfileFilter: Required<ResourceProfileFilterSettings> | undefined;\n\trequestedActiveToolNames: string[] | undefined;\n\tmemory: MemoryControllerReloadSnapshot;\n\tprofileFilter: ProfileFilterReloadSnapshot;\n\tunboundToolGrantWarnings: string[];\n\tbaseToolDefinitions: Map<string, ToolDefinition>;\n\ttoolRegistry: Map<string, AgentTool>;\n\ttoolDefinitions: Map<string, ToolDefinitionEntry>;\n\ttoolPromptSnippets: Map<string, string>;\n\ttoolPromptGuidelines: Map<string, string[]>;\n\tagentTools: AgentTool[];\n\tagentSystemPrompt: string;\n\tbaseSystemPrompt: string;\n}\n\nexport interface RuntimeBuilderDeps {\n\t/** Live agent — the snapshot/doctor read and restore its `state.tools` / `state.systemPrompt`. */\n\tgetAgent(): Agent;\n\t/** Workspace root, passed to the tool-definition factory and the extension runner. */\n\tgetCwd(): string;\n\t/** Agent state root, including the host-keyed fitness store. */\n\tgetAgentDir(): string;\n\t/** Session log, passed to the extension runner. */\n\tgetSessionManager(): SessionManager;\n\t/** Tool/shell/toolkit/resource settings + reload target (settingsManager.reload()). */\n\tgetSettingsManager(): SettingsManager;\n\t/** Model registry, passed to the extension runner and profile model re-resolution. */\n\tgetModelRegistry(): ModelRegistry;\n\t/** Session-scoped provider/model quota exhaustion guard. */\n\tisModelExhausted(model: Model<Api>): boolean;\n\t/** Extension/skill/prompt/theme discovery + the reload/commit/rollback generation swap. */\n\tgetResourceLoader(): ResourceLoader;\n\n\t/** Live extension runner (host-owned; pervasive). */\n\tgetExtensionRunner(): ExtensionRunner;\n\t/** Store the extension runner AND update the Agent's mutable `_extensionRunnerRef.current` (both together). */\n\tsetExtensionRunner(runner: ExtensionRunner): void;\n\t/** Base (extension-free) system prompt; captured/restored by the reload snapshot. */\n\tgetBaseSystemPrompt(): string;\n\tsetBaseSystemPrompt(prompt: string): void;\n\n\t/** SDK-provided plain tools, synthesized into the registry alongside built-ins. */\n\tgetCustomTools(): ToolDefinition[];\n\t/** Optional plain-tool override; when set, the built-in factory + core diagnostics are skipped. */\n\tgetBaseToolsOverride(): Record<string, AgentTool> | undefined;\n\t/** Pre-filter tool REQUEST (never the capability/profile-filtered active set) preserved across a rebuild. */\n\tgetRequestedActiveToolNames(): string[] | undefined;\n\tsetRequestedActiveToolNames(names: string[] | undefined): void;\n\n\t/** Resource-profile tool allow/block filter + the raw allow/exclude sets applied during registry build. */\n\tgetToolProfileFilter(): Required<ResourceProfileFilterSettings> | undefined;\n\tsetToolProfileFilter(filter: Required<ResourceProfileFilterSettings> | undefined): void;\n\tgetAllowedToolNames(): Set<string> | undefined;\n\tgetExcludedToolNames(): Set<string> | undefined;\n\t/** Re-derive the profile tool filter from freshly reloaded settings (reload only). */\n\tderiveToolProfileFilter(): Required<ResourceProfileFilterSettings>;\n\t/** True when a tool/command name survives the active profile's allow/block + user allow/exclude. */\n\tisToolOrCommandAllowedByProfile(name: string): boolean;\n\t/** Filter the loaded extensions through the active resource profile (records inert/denied warnings host-side). */\n\tfilterExtensionsForRuntime(extensions: Extension[]): Extension[];\n\t/** Sink for the G13 unbound-profile-tool-grant warnings surfaced in /context. */\n\tsetUnboundToolGrantWarnings(warnings: string[]): void;\n\tgetUnboundToolGrantWarnings(): string[];\n\tcreateProfileFilterReloadSnapshot(): ProfileFilterReloadSnapshot;\n\trestoreProfileFilterReloadSnapshot(snapshot: ProfileFilterReloadSnapshot): void;\n\n\t/** Currently-active tool names (reads agent.state.tools; the pre-filter fallback for a rebuild). */\n\tgetActiveToolNames(): string[];\n\t/** Apply the recomputed active set (capability filter + companion auto-activation live here). */\n\tsetActiveToolsByName(toolNames: string[]): void;\n\t/** Normalize a tool's prompt snippet / guidelines through the system-prompt builder. */\n\tnormalizePromptSnippet(text: string | undefined): string | undefined;\n\tnormalizePromptGuidelines(guidelines: string[] | undefined): string[];\n\n\t/** Wire the session's own public surface into a freshly-built runner (host identity; stays host-side). */\n\tbindExtensionCore(runner: ExtensionRunner): void;\n\t/** Re-apply UI context / mode / command-context / error subscription to a runner. */\n\tapplyExtensionBindings(runner: ExtensionRunner): void;\n\t/** Re-run resource discovery for the active extensions (reload only). */\n\textendResourcesFromExtensions(reason: \"startup\" | \"reload\"): Promise<void>;\n\t/** Re-apply the active profile's model/thinking from reloaded settings (reload only). */\n\treapplyActiveProfileModelSettings(): Promise<void>;\n\t/** Notify extensions-changed listeners after a single-extension live op. */\n\tnotifyExtensionsChanged(): void;\n\n\t/** Session-scoped tool-output artifact store for artifact-producing tools and artifact_retrieve (gated on the profile). */\n\tgetToolArtifactStore(): ArtifactStore;\n\n\t/** Live memory manager — its provider tools join the registry. */\n\tgetMemoryManager(): MemoryManager;\n\t/** Memory retrieval + prompt-inclusion diagnostics for the core diagnostics tool. */\n\tgetMemoryAuditDiagnostics(): { retrieval: MemoryRetrievalDiagnostics; promptInclusion: MemoryPromptInclusionReport };\n\t/** Drop extension-contributed pending memory providers before a reload re-registers them. */\n\tclearPendingMemoryProviders(): void;\n\tcreateMemoryReloadSnapshot(): MemoryControllerReloadSnapshot;\n\trestoreMemoryReloadSnapshot(snapshot: MemoryControllerReloadSnapshot): void;\n\t/** (Re)derive the memory subsystem from reloaded settings/providers. */\n\tinitializeMemory(): Promise<void>;\n\n\t/** Goal-tool state accessors. */\n\tgetGoalStateSnapshot(): GoalState | undefined;\n\tsaveGoalStateSnapshot(state: GoalState): string;\n\t/** Context-gc report for the core diagnostics tool. */\n\tgetContextGcReport(messages: AgentMessage[]): ContextGcReport;\n\t/** Non-blocking worker-delegation starter for the delegate tool. */\n\tstartWorkerDelegation(request: {\n\t\tinstructions: string;\n\t\tsystemPrompt?: string;\n\t\tmemoryRead?: boolean;\n\t}): { started: false; skipReason: string } | { started: true; record: LaneRecord };\n\tgetWorkerLaneRecords(): LaneRecord[];\n\tgetWorkerResultSnapshots(): WorkerResult[];\n\t/** Worker-delegation runner for SDK/test through-completion calls. */\n\trunWorkerDelegationOnce(request: {\n\t\tinstructions: string;\n\t\tsystemPrompt?: string;\n\t\tmemoryRead?: boolean;\n\t}): Promise<WorkerDelegationRunOutcome>;\n\t/** Model-fitness probe for the model_fitness tool. */\n\trunModelFitness(args: {\n\t\tmodel: string;\n\t\ttrials?: number;\n\t}): Promise<{ started: true; model: string; report: ModelFitnessReport } | { started: false; skipReason: string }>;\n\t/** Fitness-gated reflex-brain model resolver (run_toolkit_script interpretation). */\n\tresolveCurationModelIfFit(): Model<Api> | undefined;\n\t/** One-shot, tool-less LLM call — the reflex-brain interpreter rides this. */\n\trunIsolatedCompletion(opts: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;\n\t/** Roll reflex-brain spend into spawned-usage accounting. */\n\taddSpawnedUsage(\n\t\tusage: Usage,\n\t\topts?: { label?: string; sourceSessionId?: string; reportId?: string },\n\t): string | undefined;\n\n\t/** Post-rebuild doctor helpers (validate the rebuilt runtime can render a context). */\n\tcreateAgentContextSnapshot(): AgentContext;\n\tgetContextUsage(): ContextUsage | undefined;\n\n\t/** Reload/live-op preflight refusal guards (identical refusal behavior; host-checked). */\n\tisStreaming(): boolean;\n\tisCompacting(): boolean;\n\n\t/** Extension bindings present — gate for re-emitting session_start on reload. */\n\tgetExtensionUIContext(): ExtensionUIContext | undefined;\n\tgetExtensionCommandContextActions(): ExtensionCommandContextActions | undefined;\n\tgetExtensionShutdownHandler(): ShutdownHandler | undefined;\n\tgetExtensionErrorListener(): ExtensionErrorListener | undefined;\n}\n\n/**\n * Owns the tool-registry build and the self-modification-safe extension reload extracted from\n * {@link AgentSession}. See the module header for the snapshot-ownership and host-binding boundaries.\n */\nexport class RuntimeBuilder {\n\t// Tool registry for extension getTools/setTools\n\tprivate _toolRegistry: Map<string, AgentTool> = new Map();\n\tprivate _toolDefinitions: Map<string, ToolDefinitionEntry> = new Map();\n\tprivate _toolPromptSnippets: Map<string, string> = new Map();\n\tprivate _toolPromptGuidelines: Map<string, string[]> = new Map();\n\tprivate _baseToolDefinitions: Map<string, ToolDefinition> = new Map();\n\tprivate _reloadPromise: Promise<void> | undefined;\n\tprivate _reloadRequested = false;\n\n\tprivate readonly deps: RuntimeBuilderDeps;\n\n\tconstructor(deps: RuntimeBuilderDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate async _runContextScout(\n\t\tquery: string,\n\t\tmaxTurns: number | undefined,\n\t\tartifactStore: ArtifactStore | undefined,\n\t) {\n\t\tconst cwd = this.deps.getCwd();\n\t\tconst controller = new ScoutController({\n\t\t\tresolveScoutModel: async () =>\n\t\t\t\tresolveScoutModel(\n\t\t\t\t\tthis.deps.getModelRegistry(),\n\t\t\t\t\tthis.deps.getSettingsManager().getScoutSettings().model,\n\t\t\t\t\tthis.deps.getAgentDir(),\n\t\t\t\t\t(model) => this.deps.isModelExhausted(model),\n\t\t\t\t),\n\t\t\tgetCwd: () => cwd,\n\t\t\tbuildReadOnlyTools: (toolCwd) => [\n\t\t\t\tcreateReadTool(toolCwd),\n\t\t\t\tcreateGrepTool(toolCwd, { artifactStore }),\n\t\t\t\tcreateFindTool(toolCwd, { artifactStore }),\n\t\t\t],\n\t\t\tstreamFn: this.deps.getAgent().streamFn,\n\t\t\tfileExists: (path) => existsSync(resolveCwdPath(cwd, path)),\n\t\t\tcountLines: (path) => countFileLines(resolveCwdPath(cwd, path)),\n\t\t});\n\t\treturn controller.run(query, maxTurns);\n\t}\n\n\t/** Whether a tool name is present in the live wrapped registry. */\n\thasTool(name: string): boolean {\n\t\treturn this._toolRegistry.has(name);\n\t}\n\n\t/** The live wrapped tool for a name, if registered (activation lookup). */\n\tgetRegisteredTool(name: string): AgentTool | undefined {\n\t\treturn this._toolRegistry.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt snippet, if any. */\n\tgetToolPromptSnippet(name: string): string | undefined {\n\t\treturn this._toolPromptSnippets.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt guidelines, if any. */\n\tgetToolPromptGuidelines(name: string): string[] | undefined {\n\t\treturn this._toolPromptGuidelines.get(name);\n\t}\n\n\t/**\n\t * Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.\n\t */\n\tgetAllTools(): ToolInfo[] {\n\t\treturn Array.from(this._toolDefinitions.values()).map(({ definition, sourceInfo }) => ({\n\t\t\tname: definition.name,\n\t\t\tdescription: definition.description,\n\t\t\tparameters: definition.parameters,\n\t\t\tpromptGuidelines: definition.promptGuidelines,\n\t\t\tsourceInfo,\n\t\t}));\n\t}\n\n\tgetToolDefinition(name: string): ToolDefinition | undefined {\n\t\treturn this._toolDefinitions.get(name)?.definition;\n\t}\n\n\trefreshToolRegistry(options?: { activeToolNames?: string[]; includeAllExtensionTools?: boolean }): void {\n\t\tconst previousRegistryNames = new Set(this._toolRegistry.keys());\n\t\t// Re-derive from the pre-filter REQUEST, never from agent.state.tools: the active set is\n\t\t// capability/profile-filtered, so feeding it back through setActiveToolsByName would\n\t\t// permanently shrink what a later switch to a larger model (or permissive profile) restores.\n\t\tconst previousActiveToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\tconst allowedToolNames = this.deps.getAllowedToolNames();\n\t\tconst excludedToolNames = this.deps.getExcludedToolNames();\n\t\tconst toolProfileFilter = this.deps.getToolProfileFilter();\n\t\tconst isAllowedTool = (name: string): boolean => {\n\t\t\tif (allowedToolNames && !allowedToolNames.has(name)) return false;\n\t\t\tif (excludedToolNames?.has(name)) return false;\n\t\t\tif (!toolProfileFilter) return true;\n\t\t\tif (toolProfileFilter.allow.length > 0 && !matchesResourceProfilePattern(name, toolProfileFilter.allow)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (matchesResourceProfilePattern(name, toolProfileFilter.block)) return false;\n\t\t\treturn true;\n\t\t};\n\n\t\tconst registeredTools = this.deps.getExtensionRunner().getAllRegisteredTools();\n\t\tconst allCustomTools = [\n\t\t\t...registeredTools,\n\t\t\t...this.deps.getCustomTools().map((definition) => ({\n\t\t\t\tdefinition,\n\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t})),\n\t\t\t// Memory subsystem provider tools (e.g. file-store's `memory` tool).\n\t\t\t...this.deps\n\t\t\t\t.getMemoryManager()\n\t\t\t\t.getToolDefinitions()\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<memory:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t\t})),\n\t\t].filter((tool) => isAllowedTool(tool.definition.name));\n\t\tconst definitionRegistry = new Map<string, ToolDefinitionEntry>(\n\t\t\tArray.from(this._baseToolDefinitions.entries())\n\t\t\t\t.filter(([name]) => isAllowedTool(name))\n\t\t\t\t.map(([name, definition]) => [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tdefinition,\n\t\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, { source: \"builtin\" }),\n\t\t\t\t\t},\n\t\t\t\t]),\n\t\t);\n\t\tfor (const tool of allCustomTools) {\n\t\t\tdefinitionRegistry.set(tool.definition.name, {\n\t\t\t\tdefinition: tool.definition,\n\t\t\t\tsourceInfo: tool.sourceInfo,\n\t\t\t});\n\t\t}\n\t\tthis._toolDefinitions = definitionRegistry;\n\t\tthis._toolPromptSnippets = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst snippet = this.deps.normalizePromptSnippet(definition.promptSnippet);\n\t\t\t\t\treturn snippet ? ([definition.name, snippet] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string] => entry !== undefined),\n\t\t);\n\t\tthis._toolPromptGuidelines = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst guidelines = this.deps.normalizePromptGuidelines(definition.promptGuidelines);\n\t\t\t\t\treturn guidelines.length > 0 ? ([definition.name, guidelines] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string[]] => entry !== undefined),\n\t\t);\n\t\tconst runner = this.deps.getExtensionRunner();\n\t\tconst wrappedExtensionTools = wrapRegisteredTools(allCustomTools, runner);\n\t\tconst wrappedBuiltInTools = wrapRegisteredTools(\n\t\t\tArray.from(this._baseToolDefinitions.values())\n\t\t\t\t.filter((definition) => isAllowedTool(definition.name))\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${definition.name}>`, { source: \"builtin\" }),\n\t\t\t\t})),\n\t\t\trunner,\n\t\t);\n\n\t\tconst toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));\n\t\tfor (const tool of wrappedExtensionTools as AgentTool[]) {\n\t\t\ttoolRegistry.set(tool.name, tool);\n\t\t}\n\t\tthis._toolRegistry = toolRegistry;\n\n\t\tconst requestedBase = options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames];\n\t\tconst nextActiveToolNames = requestedBase.filter((name) => isAllowedTool(name));\n\n\t\tconst persistentAutoActivated: string[] = [];\n\t\tif (allowedToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (allowedToolNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tpersistentAutoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (options?.includeAllExtensionTools) {\n\t\t\tfor (const tool of wrappedExtensionTools) {\n\t\t\t\tnextActiveToolNames.push(tool.name);\n\t\t\t\tpersistentAutoActivated.push(tool.name);\n\t\t\t}\n\t\t} else if (!options?.activeToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!previousRegistryNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tpersistentAutoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Strict UAC: the active profile is the COMPLETE grant, so a tool the profile names\n\t\t// explicitly is itself a request for that tool — it must ACTIVATE from the registry even\n\t\t// if the session never requested it. Without this, activation is only ever the requested\n\t\t// defaults ∩ allow-list, and a profile granting non-default tools (a search-only profile's\n\t\t// grep/find) yields an empty or truncated tool set on load and /reload. A blanket \"*\"\n\t\t// stays grant-only: activation then still derives from the request/defaults above.\n\t\tconst explicitAllowPatterns = toolProfileFilter?.allow.filter((pattern) => pattern !== \"*\") ?? [];\n\t\tif (explicitAllowPatterns.length > 0) {\n\t\t\tconst boundPatterns = new Set<string>();\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!isAllowedTool(toolName)) continue;\n\t\t\t\tfor (const pattern of explicitAllowPatterns) {\n\t\t\t\t\tif (matchesResourceProfilePattern(toolName, [pattern])) boundPatterns.add(pattern);\n\t\t\t\t}\n\t\t\t\tif (matchesResourceProfilePattern(toolName, explicitAllowPatterns)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// G13: an explicit grant that binds to NO registered tool is a silent no-op — typo'd\n\t\t\t// name, or the owning extension is not granted/loaded. Surface it.\n\t\t\tthis.deps.setUnboundToolGrantWarnings(\n\t\t\t\texplicitAllowPatterns\n\t\t\t\t\t.filter((pattern) => !boundPatterns.has(pattern))\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(pattern) =>\n\t\t\t\t\t\t\t`profile tool grant \"${pattern}\" binds to no registered tool (typo, or the owning extension is not granted/loaded)`,\n\t\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.deps.setUnboundToolGrantWarnings([]);\n\t\t}\n\n\t\t// artifact_retrieve companion auto-activation is enforced inside\n\t\t// setActiveToolsByName() itself (not duplicated here), so every activation path --\n\t\t// including the public, extension-exposed setActiveTools() -- gets the same\n\t\t// guarantee, not just this settings/profile refresh flow.\n\t\tthis.deps.setActiveToolsByName([...new Set(nextActiveToolNames)]);\n\t\t// setActiveToolsByName just stored the profile-filtered ACTIVE set as the request; restore\n\t\t// the true pre-filter request (plus non-profile auto-activations) so an internal refresh can\n\t\t// never permanently narrow it. Explicit profile grants are generation-local activations: if\n\t\t// profile A names grep and profile B later grants \"*\", A must not pin grep into B's request.\n\t\tthis.deps.setRequestedActiveToolNames([...new Set([...requestedBase, ...persistentAutoActivated])]);\n\t}\n\n\tprivate _createReloadRuntimeSnapshot(): ReloadRuntimeSnapshot {\n\t\tconst agent = this.deps.getAgent();\n\t\tconst toolProfileFilter = this.deps.getToolProfileFilter();\n\t\tconst requestedActiveToolNames = this.deps.getRequestedActiveToolNames();\n\t\treturn {\n\t\t\textensionRunner: this.deps.getExtensionRunner(),\n\t\t\tsettings: this.deps.getSettingsManager().createReloadSnapshot(),\n\t\t\tmodelRegistry: this.deps.getModelRegistry().createReloadSnapshot(),\n\t\t\tmodel: agent.state.model,\n\t\t\tthinkingLevel: agent.state.thinkingLevel,\n\t\t\tsessionLeafId: this.deps.getSessionManager().getLeafId(),\n\t\t\ttoolProfileFilter: toolProfileFilter\n\t\t\t\t? { allow: [...toolProfileFilter.allow], block: [...toolProfileFilter.block] }\n\t\t\t\t: undefined,\n\t\t\trequestedActiveToolNames: requestedActiveToolNames ? [...requestedActiveToolNames] : undefined,\n\t\t\tmemory: this.deps.createMemoryReloadSnapshot(),\n\t\t\tprofileFilter: this.deps.createProfileFilterReloadSnapshot(),\n\t\t\tunboundToolGrantWarnings: [...this.deps.getUnboundToolGrantWarnings()],\n\t\t\tbaseToolDefinitions: this._baseToolDefinitions,\n\t\t\ttoolRegistry: this._toolRegistry,\n\t\t\ttoolDefinitions: this._toolDefinitions,\n\t\t\ttoolPromptSnippets: this._toolPromptSnippets,\n\t\t\ttoolPromptGuidelines: this._toolPromptGuidelines,\n\t\t\tagentTools: agent.state.tools,\n\t\t\tagentSystemPrompt: agent.state.systemPrompt,\n\t\t\tbaseSystemPrompt: this.deps.getBaseSystemPrompt(),\n\t\t};\n\t}\n\n\tprivate _restoreReloadRuntimeSnapshot(snapshot: ReloadRuntimeSnapshot): void {\n\t\tthis.deps.getSettingsManager().restoreReloadSnapshot(snapshot.settings);\n\t\tthis.deps.getModelRegistry().restoreReloadSnapshot(snapshot.modelRegistry);\n\t\tthis.deps.setToolProfileFilter(\n\t\t\tsnapshot.toolProfileFilter\n\t\t\t\t? { allow: [...snapshot.toolProfileFilter.allow], block: [...snapshot.toolProfileFilter.block] }\n\t\t\t\t: undefined,\n\t\t);\n\t\tthis.deps.setRequestedActiveToolNames(\n\t\t\tsnapshot.requestedActiveToolNames ? [...snapshot.requestedActiveToolNames] : undefined,\n\t\t);\n\t\tthis.deps.restoreMemoryReloadSnapshot(snapshot.memory);\n\t\tthis.deps.restoreProfileFilterReloadSnapshot(snapshot.profileFilter);\n\t\tthis.deps.setUnboundToolGrantWarnings([...snapshot.unboundToolGrantWarnings]);\n\t\t// setExtensionRunner restores both _extensionRunner and _extensionRunnerRef.current together\n\t\t// (the same field-then-ref pair the host wrote at every assignment site); nothing reads the\n\t\t// ref between the two writes, so folding them is unobservable.\n\t\tthis.deps.setExtensionRunner(snapshot.extensionRunner);\n\t\tthis._baseToolDefinitions = snapshot.baseToolDefinitions;\n\t\tthis._toolRegistry = snapshot.toolRegistry;\n\t\tthis._toolDefinitions = snapshot.toolDefinitions;\n\t\tthis._toolPromptSnippets = snapshot.toolPromptSnippets;\n\t\tthis._toolPromptGuidelines = snapshot.toolPromptGuidelines;\n\t\tconst agent = this.deps.getAgent();\n\t\tagent.state.model = snapshot.model;\n\t\tagent.state.thinkingLevel = snapshot.thinkingLevel;\n\t\tagent.state.tools = snapshot.agentTools;\n\t\tagent.state.systemPrompt = snapshot.agentSystemPrompt;\n\t\tthis.deps.setBaseSystemPrompt(snapshot.baseSystemPrompt);\n\t\tconst sessionManager = this.deps.getSessionManager();\n\t\tif (snapshot.sessionLeafId === null) {\n\t\t\tsessionManager.resetLeaf();\n\t\t} else {\n\t\t\tsessionManager.branch(snapshot.sessionLeafId);\n\t\t}\n\t\tthis.deps.applyExtensionBindings(snapshot.extensionRunner);\n\t}\n\n\tprivate _doctorReloadRuntime(): void {\n\t\tconst extensionErrors = this.deps.getResourceLoader().getExtensions().errors;\n\t\tif (extensionErrors.length > 0) {\n\t\t\tconst summary = extensionErrors\n\t\t\t\t.slice(0, 6)\n\t\t\t\t.map((error) => `${error.path}: ${error.error}`)\n\t\t\t\t.join(\"; \");\n\t\t\tthrow new Error(`Extension reload failed doctor: ${summary}`);\n\t\t}\n\n\t\tconst missingActiveTools = this.deps.getActiveToolNames().filter((name) => !this._toolRegistry.has(name));\n\t\tif (missingActiveTools.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Extension reload failed doctor: active tool(s) missing after reload: ${missingActiveTools.join(\", \")}`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const tool of this.deps.getAgent().state.tools) {\n\t\t\tif (!this._toolDefinitions.has(tool.name)) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: tool ${tool.name} missing from definition registry`);\n\t\t\t}\n\t\t}\n\n\t\tthis.deps.createAgentContextSnapshot();\n\t\tthis.deps.getContextUsage();\n\t}\n\n\tbuildRuntime(options: {\n\t\tactiveToolNames?: string[];\n\t\tflagValues?: Map<string, boolean | string>;\n\t\tincludeAllExtensionTools?: boolean;\n\t\tonError?: ExtensionErrorListener;\n\t}): (() => void) | undefined {\n\t\tconst settingsManager = this.deps.getSettingsManager();\n\t\tconst autoResizeImages = settingsManager.getImageAutoResize();\n\t\tconst shellCommandPrefix = settingsManager.getShellCommandPrefix();\n\t\tconst shellPath = settingsManager.getShellPath();\n\t\tconst baseToolsOverride = this.deps.getBaseToolsOverride();\n\t\t// Artifact-producing tools must not emit a \"Full output: artifact tool-output:<id>\" handle\n\t\t// that nothing can resolve. If artifact_retrieve is explicitly excluded/blocked/outside\n\t\t// an active allowlist, don't hand grep/find/run_toolkit_script an artifact store at all:\n\t\t// they fall back to their bounded preview/truncation behavior, with no payload/meta files\n\t\t// ever written and no retrieval promise made.\n\t\tconst toolArtifactStore = this.deps.isToolOrCommandAllowedByProfile(\"artifact_retrieve\")\n\t\t\t? this.deps.getToolArtifactStore()\n\t\t\t: undefined;\n\t\tconst baseToolDefinitions = baseToolsOverride\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(baseToolsOverride).map(([name, tool]) => [name, createToolDefinitionFromAgentTool(tool)]),\n\t\t\t\t)\n\t\t\t: createAllToolDefinitions(this.deps.getCwd(), {\n\t\t\t\t\tread: { autoResizeImages },\n\t\t\t\t\tbash: { commandPrefix: shellCommandPrefix, shellPath },\n\t\t\t\t\tgrep: { artifactStore: toolArtifactStore },\n\t\t\t\t\tfind: { artifactStore: toolArtifactStore },\n\t\t\t\t\tartifact_retrieve: { artifactStore: toolArtifactStore },\n\t\t\t\t});\n\n\t\tthis._baseToolDefinitions = new Map(\n\t\t\tObject.entries(baseToolDefinitions).map(([name, tool]) => [name, tool as ToolDefinition]),\n\t\t);\n\t\tif (!baseToolsOverride) {\n\t\t\tfor (const definition of createCoreDiagnosticsToolDefinitions(\n\t\t\t\t() => this.deps.getActiveToolNames(),\n\t\t\t\t() => this.getAllTools(),\n\t\t\t\t(messages) => this.deps.getContextGcReport(messages),\n\t\t\t\t() => this.deps.getMemoryAuditDiagnostics(),\n\t\t\t)) {\n\t\t\t\tthis._baseToolDefinitions.set(definition.name, definition);\n\t\t\t}\n\t\t\tconst goalToolDefinition = createGoalToolDefinition({\n\t\t\t\tgetGoalState: () => this.deps.getGoalStateSnapshot(),\n\t\t\t\tsaveGoalState: (state) => {\n\t\t\t\t\tthis.deps.saveGoalStateSnapshot(state);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(goalToolDefinition.name, goalToolDefinition);\n\t\t\tconst delegateToolDefinition = createDelegateToolDefinition({\n\t\t\t\tstartWorkerDelegation: (args) => this.deps.startWorkerDelegation(args),\n\t\t\t\trunWorkerDelegation: (args) => this.deps.runWorkerDelegationOnce(args),\n\t\t\t});\n\t\t\tconst delegateStatusToolDefinition = createDelegateStatusToolDefinition({\n\t\t\t\tgetLaneRecords: () => this.deps.getWorkerLaneRecords(),\n\t\t\t\tgetWorkerResultSnapshots: () => this.deps.getWorkerResultSnapshots(),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(delegateToolDefinition.name, delegateToolDefinition);\n\t\t\tthis._baseToolDefinitions.set(delegateStatusToolDefinition.name, delegateStatusToolDefinition);\n\t\t\t// Registered but not default-active: probes spend tokens on the probed model, so\n\t\t\t// activation is an explicit choice (settings/profile/setActiveTools or /autonomy fitness).\n\t\t\tconst modelFitnessToolDefinition = createModelFitnessToolDefinition({\n\t\t\t\trunProbe: (args) => this.deps.runModelFitness(args),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(modelFitnessToolDefinition.name, modelFitnessToolDefinition);\n\t\t\tif (settingsManager.getScoutSettings().enabled) {\n\t\t\t\tconst contextScoutToolDefinition = createContextScoutToolDefinition({\n\t\t\t\t\trunScout: (input) => this._runContextScout(input.query, input.maxTurns, toolArtifactStore),\n\t\t\t\t});\n\t\t\t\tthis._baseToolDefinitions.set(contextScoutToolDefinition.name, contextScoutToolDefinition);\n\t\t\t}\n\t\t\tconst runToolkitScriptToolDefinition = createRunToolkitScriptToolDefinition({\n\t\t\t\tgetScripts: () => this.deps.getSettingsManager().getToolkitScripts(),\n\t\t\t\texecute: (script, scriptArgs) => executeToolkitScript({ script, scriptArgs, cwd: this.deps.getCwd() }),\n\t\t\t\tartifactStore: toolArtifactStore,\n\t\t\t\t// Reflex brain (fitness-gated local model): resolves ambiguous requests into a\n\t\t\t\t// registry pick. Best-effort — absent/unfit brain keeps the shortlist behavior.\n\t\t\t\tinterpret: async (request, scripts) => {\n\t\t\t\t\tconst model = this.deps.resolveCurationModelIfFit();\n\t\t\t\t\tif (!model) return undefined;\n\t\t\t\t\tconst completion = await this.deps.runIsolatedCompletion({\n\t\t\t\t\t\tsystemPrompt: REFLEX_INTERPRETER_SYSTEM_PROMPT,\n\t\t\t\t\t\tmessages: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: buildReflexUserPrompt(request, scripts) }],\n\t\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\t\t\tmaxTokens: 256,\n\t\t\t\t\t\tcacheRetention: \"short\",\n\t\t\t\t\t});\n\t\t\t\t\tif (completion.usage.cost.total > 0 || completion.usage.totalTokens > 0) {\n\t\t\t\t\t\tthis.deps.addSpawnedUsage(completion.usage, { label: \"toolkit-brain\" });\n\t\t\t\t\t}\n\t\t\t\t\treturn parseReflexPlan(completion.text);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(runToolkitScriptToolDefinition.name, runToolkitScriptToolDefinition);\n\t\t}\n\n\t\tconst extensionsResult = this.deps.getResourceLoader().getExtensions();\n\t\tif (options.flagValues) {\n\t\t\tfor (const [name, value] of options.flagValues) {\n\t\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\t}\n\t\t}\n\t\tconst extensions = this.deps.filterExtensionsForRuntime(extensionsResult.extensions);\n\t\tconst runtimeExtensionPaths = new Set(extensions.map((extension) => extension.path));\n\t\textensionsResult.runtime.pendingProviderRegistrations =\n\t\t\textensionsResult.runtime.pendingProviderRegistrations.filter((registration) =>\n\t\t\t\truntimeExtensionPaths.has(registration.extensionPath),\n\t\t\t);\n\n\t\tconst runner = new ExtensionRunner(\n\t\t\textensions,\n\t\t\textensionsResult.runtime,\n\t\t\tthis.deps.getCwd(),\n\t\t\tthis.deps.getSessionManager(),\n\t\t\tthis.deps.getModelRegistry(),\n\t\t);\n\t\tconst offBuildErrors = options.onError ? runner.onError(options.onError) : undefined;\n\t\tthis.deps.setExtensionRunner(runner);\n\t\ttry {\n\t\t\tthis.deps.bindExtensionCore(runner);\n\t\t} catch (error) {\n\t\t\toffBuildErrors?.();\n\t\t\tthrow error;\n\t\t}\n\t\tthis.deps.applyExtensionBindings(runner);\n\n\t\tconst defaultActiveToolNames = baseToolsOverride\n\t\t\t? Object.keys(baseToolsOverride)\n\t\t\t: [...DEFAULT_ACTIVE_TOOL_NAMES, ...(settingsManager.getScoutSettings().enabled ? [\"context_scout\"] : [])];\n\t\tconst baseActiveToolNames = options.activeToolNames ?? defaultActiveToolNames;\n\t\tthis.refreshToolRegistry({\n\t\t\tactiveToolNames: baseActiveToolNames,\n\t\t\tincludeAllExtensionTools: options.includeAllExtensionTools,\n\t\t});\n\t\treturn offBuildErrors;\n\t}\n\n\treload(): Promise<void> {\n\t\tif (this._reloadPromise) {\n\t\t\t// State can change while a generation is being validated. Coalesce any number of\n\t\t\t// overlapping requests into one follow-up generation instead of silently treating a\n\t\t\t// later profile/settings mutation as part of the already-snapshotted generation.\n\t\t\tthis._reloadRequested = true;\n\t\t\treturn this._reloadPromise;\n\t\t}\n\t\tconst reloadPromise = this._drainReloadRequests();\n\t\tthis._reloadPromise = reloadPromise;\n\t\treturn reloadPromise;\n\t}\n\n\tprivate async _drainReloadRequests(): Promise<void> {\n\t\tlet finalError: unknown;\n\t\ttry {\n\t\t\tdo {\n\t\t\t\tthis._reloadRequested = false;\n\t\t\t\ttry {\n\t\t\t\t\tawait this._reloadOnce();\n\t\t\t\t\tfinalError = undefined;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfinalError = error;\n\t\t\t\t}\n\t\t\t} while (this._reloadRequested);\n\t\t\tif (finalError !== undefined) throw finalError;\n\t\t} finally {\n\t\t\tthis._reloadPromise = undefined;\n\t\t\tthis._reloadRequested = false;\n\t\t}\n\t}\n\n\tprivate async _reloadOnce(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reload while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reload while context compaction or branch summarization is active\");\n\t\t}\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\tconst snapshot = this._createReloadRuntimeSnapshot();\n\t\t// Preserve the pre-filter tool REQUEST across the rebuild, not the capability/profile-filtered\n\t\t// active set — otherwise a reload under a small model permanently shrinks the restorable set.\n\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\tconst previousExtensionProviderNames = previousRunner.getRegisteredProviderNames();\n\t\tconst reloadErrors: string[] = [];\n\t\tlet newRunner: ExtensionRunner | undefined;\n\t\tlet offReloadErrors: (() => void) | undefined;\n\t\ttry {\n\t\t\tawait this.deps.getSettingsManager().reload();\n\t\t\t// Re-derive the resource-profile tool filter from the freshly reloaded settings.\n\t\t\t// Unlike skills/prompts/themes (which re-filter through the resource loader on every\n\t\t\t// reload), the tool filter is held on the session, so without this a live edit to the\n\t\t\t// active profile's tools allow/block — or switching the active profile — would not\n\t\t\t// apply on /reload and allowed tools would stay missing.\n\t\t\tthis.deps.setToolProfileFilter(this.deps.deriveToolProfileFilter());\n\t\t\t// Resource discovery must consume this exact settings generation. A second settings read here\n\t\t\t// could combine profile state from one generation with resources from the next.\n\t\t\tawait this.deps.getResourceLoader().reload({\n\t\t\t\tfailOnExtensionErrors: true,\n\t\t\t\tdeferExtensionDispose: true,\n\t\t\t\tskipSettingsReload: true,\n\t\t\t});\n\t\t\t// Replace the previous extension-owned provider generation before binding the new one. The\n\t\t\t// bulk refresh also preserves API/OAuth streams for surviving non-extension providers.\n\t\t\tthis.deps.getModelRegistry().unregisterProviders(previousExtensionProviderNames);\n\t\t\toffReloadErrors = this.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t\tonError: (error) => {\n\t\t\t\t\treloadErrors.push(`${error.extensionPath} ${error.event}: ${error.error}`);\n\t\t\t\t},\n\t\t\t});\n\t\t\tnewRunner = this.deps.getExtensionRunner();\n\t\t\t// Extensions are now bound and their queued providers/models are registered, so a profile may\n\t\t\t// safely select a model contributed by an extension granted in that same profile generation.\n\t\t\tawait this.deps.reapplyActiveProfileModelSettings();\n\t\t\t// Model capability and system-prompt/tool exposure must reflect the newly selected model.\n\t\t\tthis.refreshToolRegistry({ activeToolNames, includeAllExtensionTools: true });\n\t\t\ttry {\n\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t// Reload starts memory providers fresh; loaded extensions re-register below.\n\t\t\t\tthis.deps.clearPendingMemoryProviders();\n\t\t\t\tconst hasBindings =\n\t\t\t\t\tthis.deps.getExtensionUIContext() ||\n\t\t\t\t\tthis.deps.getExtensionCommandContextActions() ||\n\t\t\t\t\tthis.deps.getExtensionShutdownHandler() ||\n\t\t\t\t\tthis.deps.getExtensionErrorListener();\n\t\t\t\tif (hasBindings) {\n\t\t\t\t\tawait newRunner.emit({ type: \"session_start\", reason: \"reload\" });\n\t\t\t\t\tawait this.deps.extendResourcesFromExtensions(\"reload\");\n\t\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\toffReloadErrors?.();\n\t\t\t\toffReloadErrors = undefined;\n\t\t\t}\n\t\t\tif (reloadErrors.length > 0) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: ${reloadErrors.slice(0, 6).join(\"; \")}`);\n\t\t\t}\n\t\t\tawait emitSessionShutdownEvent(previousRunner, { type: \"session_shutdown\", reason: \"reload\" });\n\t\t\tpreviousRunner.invalidate();\n\t\t\tawait this.deps.getResourceLoader().commitReload?.();\n\t\t\t// Re-derive the memory subsystem from the reloaded settings/providers.\n\t\t\tawait this.deps.initializeMemory();\n\t\t} catch (error) {\n\t\t\toffReloadErrors?.();\n\t\t\tif (newRunner && newRunner !== previousRunner) {\n\t\t\t\tnewRunner.invalidate(\n\t\t\t\t\t\"This extension ctx was discarded because reload failed and Pi restored the previous valid runtime.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait this.deps.getResourceLoader().rollbackReload?.();\n\t\t\tthis._restoreReloadRuntimeSnapshot(snapshot);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Unload a single extension without full reload.\n\t * Runs the extension's session_shutdown lifecycle, unregisters its providers,\n\t * disposes its event subscriptions, and rebuilds the runtime.\n\t * Falls back to full reload on error.\n\t */\n\tasync unloadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot unload extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot unload extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst ext = this.deps.getResourceLoader().getLoadedExtension(extensionPath);\n\t\tif (!ext) {\n\t\t\treturn; // Nothing to unload\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Run session_shutdown lifecycle for this extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(ext, { type: \"session_shutdown\", reason: \"unload\" });\n\n\t\t\t// Unregister its providers (keyed by the extension's own path, as registered)\n\t\t\tconst runtime = this.deps.getResourceLoader().getExtensions().runtime;\n\t\t\tconst ownedMemoryProviders = runtime.memoryProvidersByExtension.get(ext.path) ?? new Set();\n\t\t\tconst ownedContextMemoryProviders = runtime.contextMemoryProvidersByExtension.get(ext.path) ?? new Set();\n\t\t\tfor (const name of runtime.getProvidersForExtension(ext.path)) {\n\t\t\t\truntime.unregisterProvider(name, ext.path);\n\t\t\t}\n\n\t\t\t// Dispose its event subscriptions and run disposers\n\t\t\tawait disposeExtensionEventSubscriptions([ext]);\n\n\t\t\t// Remove from loaded extensions\n\t\t\tthis.deps.getResourceLoader().removeLoadedExtension(extensionPath);\n\n\t\t\t// Rebuild runtime with new extension set\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tpreviousRunner.invalidate();\n\t\t\tconst memorySnapshot = this.deps.createMemoryReloadSnapshot();\n\t\t\tthis.deps.restoreMemoryReloadSnapshot({\n\t\t\t\t...memorySnapshot,\n\t\t\t\tpendingMemoryProviders: memorySnapshot.pendingMemoryProviders.filter(\n\t\t\t\t\t(provider) => !ownedMemoryProviders.has(provider),\n\t\t\t\t),\n\t\t\t\tpendingContextMemoryProviders: memorySnapshot.pendingContextMemoryProviders.filter(\n\t\t\t\t\t(provider) => !ownedContextMemoryProviders.has(provider),\n\t\t\t\t),\n\t\t\t});\n\t\t\truntime.memoryProvidersByExtension.delete(ext.path);\n\t\t\truntime.contextMemoryProvidersByExtension.delete(ext.path);\n\t\t\tawait this.deps.initializeMemory();\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Load a single extension without full reload.\n\t * Loads the extension with fresh import, rebuilds the runtime,\n\t * and runs the extension's session_start lifecycle.\n\t * Falls back to full reload on error.\n\t */\n\tasync loadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot load extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot load extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Load the extension with fresh import\n\t\t\tconst { extension, error } = await this.deps.getResourceLoader().loadSingleExtension(extensionPath);\n\t\t\tif (error || !extension) {\n\t\t\t\tthrow new Error(error || `Failed to load extension: ${extensionPath}`);\n\t\t\t}\n\n\t\t\t// Rebuild runtime to aggregate tools/commands/handlers/providers\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\n\t\t\t// Run session_start lifecycle for the new extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(extension, { type: \"session_start\", reason: \"load\" });\n\t\t\t// Activate newly registered legacy/context providers immediately. Reinitialization also\n\t\t\t// refreshes provider tools and preserves all providers owned by existing extensions.\n\t\t\tawait this.deps.initializeMemory();\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Reconcile loaded extensions with the active profile.\n\t * Loads extensions that should be enabled but aren't, and unloads extensions that shouldn't be.\n\t * Falls back to full reload if any individual load/unload fails.\n\t */\n\tasync reconcileLoadedExtensions(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while context compaction or branch summarization is active\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Get all discoverable extension paths\n\t\t\tconst allDiscoverablePaths = await this.deps.getResourceLoader().getDiscoverableExtensionPaths();\n\n\t\t\t// Get the target enabled set based on profile filters\n\t\t\tconst targetEnabledSet = new Set<string>();\n\t\t\tfor (const path of allDiscoverablePaths) {\n\t\t\t\tif (this.deps.getSettingsManager().isResourceAllowedByProfile(\"extensions\", path)) {\n\t\t\t\t\ttargetEnabledSet.add(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get currently loaded set\n\t\t\tconst loadedExtensions = this.deps.getResourceLoader().getExtensions().extensions;\n\t\t\tconst loadedSet = new Set<string>();\n\t\t\tfor (const ext of loadedExtensions) {\n\t\t\t\tloadedSet.add(ext.path);\n\t\t\t}\n\n\t\t\t// Collect unloads and loads\n\t\t\tconst toUnload: string[] = [];\n\t\t\tconst toLoad: string[] = [];\n\n\t\t\tfor (const path of loadedSet) {\n\t\t\t\tif (!targetEnabledSet.has(path)) {\n\t\t\t\t\ttoUnload.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of targetEnabledSet) {\n\t\t\t\tif (!loadedSet.has(path)) {\n\t\t\t\t\ttoLoad.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply unloads first, then loads, to minimize churn\n\t\t\t// Collect errors but continue through all operations\n\t\t\tconst errors: Error[] = [];\n\n\t\t\tfor (const path of toUnload) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.unloadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of toLoad) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.loadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If any errors occurred, throw the first one (already fell back to full reload in load/unload)\n\t\t\tif (errors.length > 0) {\n\t\t\t\tthrow errors[0];\n\t\t\t}\n\n\t\t\t// Single notification at the end\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\nexport async function resolveScoutModel(\n\tmodelRegistry: ModelRegistry,\n\tmodelSetting: string,\n\tagentDir: string,\n\tisModelExhausted: (model: Model<Api>) => boolean = () => false,\n) {\n\tconst model =\n\t\tmodelSetting === \"auto\"\n\t\t\t? findFastContextModel(modelRegistry)\n\t\t\t: resolveCliModel({ cliModel: modelSetting, modelRegistry }).model;\n\tif (!model) {\n\t\treturn { failure: `no scout model matched ${modelSetting}` };\n\t}\n\tif (isModelExhausted(model)) {\n\t\treturn { failure: `${model.provider}/${model.id} exhausted: quota` };\n\t}\n\tif (modelSetting === \"auto\") {\n\t\tconst modelRef = `${model.provider}/${model.id}`;\n\t\tconst fitness = FitnessStore.forAgentDir(agentDir)\n\t\t\t.getForHost()\n\t\t\t.find((entry) => entry.model === modelRef);\n\t\tconst verdict = evaluateSurfaceFitness(\"scout_auto\", fitness?.report);\n\t\tif (!verdict.fit) {\n\t\t\treturn verdict.reason === \"unprobed\"\n\t\t\t\t? { failure: `${modelRef} unprobed — run /fitness before auto-selection` }\n\t\t\t\t: { failure: `${modelRef} unfit (${verdict.lane} ${verdict.succeeded}/${verdict.total})` };\n\t\t}\n\t}\n\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\tif (!auth.ok) {\n\t\treturn { failure: auth.error ?? `no usable auth for scout model ${model.provider}/${model.id}` };\n\t}\n\treturn { model, apiKey: auth.apiKey, headers: auth.headers };\n}\n\nfunction findFastContextModel(modelRegistry: ModelRegistry) {\n\treturn modelRegistry.getAll().find((model) => {\n\t\tconst text = `${model.provider}/${model.id} ${model.name}`.toLowerCase();\n\t\treturn text.includes(\"fastcontext\");\n\t});\n}\n\nfunction resolveCwdPath(cwd: string, path: string): string {\n\treturn isAbsolute(path) ? path : join(cwd, path);\n}\n\nfunction countFileLines(path: string): number | undefined {\n\ttry {\n\t\treturn readFileSync(path, \"utf8\").split(/\\r?\\n/).length;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"runtime-builder.d.ts","sourceRoot":"","sources":["../../src/core/runtime-builder.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Runtime build & reload: the session's tool-registry assembly and the self-modification-safe\n * extension reload path. Owns building the base tool definitions, wrapping them into the live tool\n * registry (`_refreshToolRegistry`), constructing the {@link ExtensionRunner} for a rebuilt runtime\n * (`_buildRuntime`), and the repo's self-modification safety crown jewel: the preflight-guarded\n * `reload()` with its snapshot / doctor / commit-or-rollback sequence, plus the single-extension\n * live load/unload/reconcile operations that rebuild the runtime in place.\n *\n * Extracted verbatim from agent-session.ts (god-file decomposition). Owns ONLY the tool-registry\n * state — the base tool definitions, the wrapped tool registry, the definition registry, and the\n * per-tool prompt snippet/guideline maps. Everything else the build & reload touch — the live\n * {@link ExtensionRunner}, the agent's tool/system-prompt state, the base system prompt, the\n * resource loader, the session/settings managers, the model registry, the profile tool filter and\n * its warning sinks, the requested-active-tool-names request, the memory subsystem, and the many\n * host callbacks the rebuilt tools/runtime are wired to — is reached through narrow deps accessors\n * that read and write the SAME storage the host owns today.\n *\n * Snapshot-ownership boundary (deliberate, load-bearing for reload safety): the reload snapshot\n * spans state owned by OTHER collaborators — the extension runner and its ref, `agent.state.tools`\n * / `agent.state.systemPrompt`, and `_baseSystemPrompt`. Those are captured and restored through\n * {@link RuntimeBuilderDeps} get/set accessors so save/restore mutate exactly the host/agent fields\n * they mutated before extraction; only the five tool-registry maps are captured by direct field\n * reference here (this builder owns them). The `_extensionRunnerRef.current` update folds into\n * {@link RuntimeBuilderDeps.setExtensionRunner} (the same field-then-ref pattern the host used at\n * every assignment site), so no observer runs between the two writes.\n *\n * Host-binding boundary (deliberate): `_bindExtensionCore` — which exposes the SESSION's own public\n * surface (sendMessage, setModel, compact, abort, reload, …) to the extension runner — stays\n * host-side and is invoked from {@link buildRuntime} via {@link RuntimeBuilderDeps.bindExtensionCore};\n * it is host identity, not build logic, and moving it would only re-export ~30 host methods through\n * deps to hand them straight back. The host keeps one-line delegations for the public reload /\n * load / unload / reconcile API and for `getAllTools` / `getToolDefinition`, and a private\n * `_refreshToolRegistry` delegation for its internal callers.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { isAbsolute, join } from \"node:path\";\nimport type { Agent, AgentContext, AgentMessage, AgentTool, ThinkingLevel } from \"@caupulican/pi-agent-core\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, Model, Usage } from \"@caupulican/pi-ai\";\nimport type {\n\tIsolatedCompletionOptions,\n\tIsolatedCompletionResult,\n\tWorkerDelegationRunOutcome,\n} from \"./agent-session.ts\";\nimport type { WorkerResult } from \"./autonomy/contracts.ts\";\nimport type { LaneRecord } from \"./autonomy/lane-tracker.ts\";\nimport type { ArtifactStore } from \"./context/context-artifacts.ts\";\nimport type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from \"./context/memory-diagnostics.ts\";\nimport type { ContextGcReport } from \"./context-gc.ts\";\nimport { DEFAULT_ACTIVE_TOOL_NAMES, mapToolNamesForPlatform } from \"./default-tool-surface.ts\";\nimport { createCoreDiagnosticsToolDefinitions } from \"./extensions/builtin.ts\";\nimport {\n\ttype ContextUsage,\n\ttype Extension,\n\ttype ExtensionCommandContextActions,\n\ttype ExtensionErrorListener,\n\tExtensionRunner,\n\ttype ExtensionUIContext,\n\ttype ShutdownHandler,\n\ttype ToolDefinition,\n\ttype ToolInfo,\n\twrapRegisteredTools,\n} from \"./extensions/index.ts\";\nimport { disposeExtensionEventSubscriptions } from \"./extensions/loader.ts\";\nimport { emitSessionShutdownEvent } from \"./extensions/runner.ts\";\nimport type { GoalState } from \"./goals/goal-state.ts\";\nimport type { MemoryManager } from \"./memory/memory-manager.ts\";\nimport type { MemoryControllerReloadSnapshot } from \"./memory-controller.ts\";\nimport type { ModelRegistry } from \"./model-registry.ts\";\nimport { resolveCliModel } from \"./model-resolver.ts\";\nimport { evaluateSurfaceFitness } from \"./model-router/fitness-gate.ts\";\nimport { FitnessStore } from \"./models/fitness-store.ts\";\nimport type { ProfileFilterReloadSnapshot } from \"./profile-filter-controller.ts\";\nimport type { ModelFitnessReport } from \"./research/model-fitness.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { ScoutController } from \"./scout-controller.ts\";\nimport {\n\tmatchesResourceProfilePattern,\n\ttype ResourceProfileFilterSettings,\n\ttype SettingsManager,\n} from \"./settings-manager.ts\";\nimport { createSyntheticSourceInfo, type SourceInfo } from \"./source-info.ts\";\nimport type { TaskStepsState } from \"./tasks/task-state.ts\";\nimport {\n\tbuildReflexUserPrompt,\n\tparseReflexPlan,\n\tREFLEX_INTERPRETER_SYSTEM_PROMPT,\n} from \"./toolkit/reflex-interpreter.ts\";\nimport { executeToolkitScript } from \"./toolkit/script-runner.ts\";\nimport { createContextScoutToolDefinition } from \"./tools/context-scout.ts\";\nimport { createDelegateToolDefinition } from \"./tools/delegate.ts\";\nimport { createDelegateStatusToolDefinition } from \"./tools/delegate-status.ts\";\nimport { createFindTool } from \"./tools/find.ts\";\nimport { createGoalToolDefinition } from \"./tools/goal.ts\";\nimport { createGrepTool } from \"./tools/grep.ts\";\nimport { createAllToolDefinitions } from \"./tools/index.ts\";\nimport { createModelFitnessToolDefinition } from \"./tools/model-fitness.ts\";\nimport { createReadTool } from \"./tools/read.ts\";\nimport { createRunToolkitScriptToolDefinition } from \"./tools/run-toolkit-script.ts\";\nimport { createTaskStepsToolDefinition } from \"./tools/task-steps.ts\";\nimport { createToolDefinitionFromAgentTool } from \"./tools/tool-definition-wrapper.ts\";\n\ninterface ToolDefinitionEntry {\n\tdefinition: ToolDefinition;\n\tsourceInfo: SourceInfo;\n}\n\ninterface ReloadRuntimeSnapshot {\n\textensionRunner: ExtensionRunner;\n\tsettings: ReturnType<SettingsManager[\"createReloadSnapshot\"]>;\n\tmodelRegistry: ReturnType<ModelRegistry[\"createReloadSnapshot\"]>;\n\tmodel: Model<Api>;\n\tthinkingLevel: ThinkingLevel;\n\tsessionLeafId: string | null;\n\ttoolProfileFilter: Required<ResourceProfileFilterSettings> | undefined;\n\trequestedActiveToolNames: string[] | undefined;\n\tmemory: MemoryControllerReloadSnapshot;\n\tprofileFilter: ProfileFilterReloadSnapshot;\n\tunboundToolGrantWarnings: string[];\n\tbaseToolDefinitions: Map<string, ToolDefinition>;\n\ttoolRegistry: Map<string, AgentTool>;\n\ttoolDefinitions: Map<string, ToolDefinitionEntry>;\n\ttoolPromptSnippets: Map<string, string>;\n\ttoolPromptGuidelines: Map<string, string[]>;\n\tagentTools: AgentTool[];\n\tagentSystemPrompt: string;\n\tbaseSystemPrompt: string;\n}\n\nexport interface RuntimeBuilderDeps {\n\t/** Live agent — the snapshot/doctor read and restore its `state.tools` / `state.systemPrompt`. */\n\tgetAgent(): Agent;\n\t/** Workspace root, passed to the tool-definition factory and the extension runner. */\n\tgetCwd(): string;\n\t/** Agent state root, including the host-keyed fitness store. */\n\tgetAgentDir(): string;\n\t/** Session log, passed to the extension runner. */\n\tgetSessionManager(): SessionManager;\n\t/** Tool/shell/toolkit/resource settings + reload target (settingsManager.reload()). */\n\tgetSettingsManager(): SettingsManager;\n\t/** Model registry, passed to the extension runner and profile model re-resolution. */\n\tgetModelRegistry(): ModelRegistry;\n\t/** Session-scoped provider/model quota exhaustion guard. */\n\tisModelExhausted(model: Model<Api>): boolean;\n\t/** Extension/skill/prompt/theme discovery + the reload/commit/rollback generation swap. */\n\tgetResourceLoader(): ResourceLoader;\n\n\t/** Live extension runner (host-owned; pervasive). */\n\tgetExtensionRunner(): ExtensionRunner;\n\t/** Store the extension runner AND update the Agent's mutable `_extensionRunnerRef.current` (both together). */\n\tsetExtensionRunner(runner: ExtensionRunner): void;\n\t/** Base (extension-free) system prompt; captured/restored by the reload snapshot. */\n\tgetBaseSystemPrompt(): string;\n\tsetBaseSystemPrompt(prompt: string): void;\n\n\t/** SDK-provided plain tools, synthesized into the registry alongside built-ins. */\n\tgetCustomTools(): ToolDefinition[];\n\t/** Optional plain-tool override; when set, the built-in factory + core diagnostics are skipped. */\n\tgetBaseToolsOverride(): Record<string, AgentTool> | undefined;\n\t/** Pre-filter tool REQUEST (never the capability/profile-filtered active set) preserved across a rebuild. */\n\tgetRequestedActiveToolNames(): string[] | undefined;\n\tsetRequestedActiveToolNames(names: string[] | undefined): void;\n\n\t/** Resource-profile tool allow/block filter + the raw allow/exclude sets applied during registry build. */\n\tgetToolProfileFilter(): Required<ResourceProfileFilterSettings> | undefined;\n\tsetToolProfileFilter(filter: Required<ResourceProfileFilterSettings> | undefined): void;\n\tgetAllowedToolNames(): Set<string> | undefined;\n\tgetExcludedToolNames(): Set<string> | undefined;\n\t/** Re-derive the profile tool filter from freshly reloaded settings (reload only). */\n\tderiveToolProfileFilter(): Required<ResourceProfileFilterSettings>;\n\t/** True when a tool/command name survives the active profile's allow/block + user allow/exclude. */\n\tisToolOrCommandAllowedByProfile(name: string): boolean;\n\t/** Filter the loaded extensions through the active resource profile (records inert/denied warnings host-side). */\n\tfilterExtensionsForRuntime(extensions: Extension[]): Extension[];\n\t/** Sink for the G13 unbound-profile-tool-grant warnings surfaced in /context. */\n\tsetUnboundToolGrantWarnings(warnings: string[]): void;\n\tgetUnboundToolGrantWarnings(): string[];\n\tcreateProfileFilterReloadSnapshot(): ProfileFilterReloadSnapshot;\n\trestoreProfileFilterReloadSnapshot(snapshot: ProfileFilterReloadSnapshot): void;\n\n\t/** Currently-active tool names (reads agent.state.tools; the pre-filter fallback for a rebuild). */\n\tgetActiveToolNames(): string[];\n\t/** Apply the recomputed active set (capability filter + companion auto-activation live here). */\n\tsetActiveToolsByName(toolNames: string[]): void;\n\t/** Normalize a tool's prompt snippet / guidelines through the system-prompt builder. */\n\tnormalizePromptSnippet(text: string | undefined): string | undefined;\n\tnormalizePromptGuidelines(guidelines: string[] | undefined): string[];\n\n\t/** Wire the session's own public surface into a freshly-built runner (host identity; stays host-side). */\n\tbindExtensionCore(runner: ExtensionRunner): void;\n\t/** Re-apply UI context / mode / command-context / error subscription to a runner. */\n\tapplyExtensionBindings(runner: ExtensionRunner): void;\n\t/** Re-run resource discovery for the active extensions (reload only). */\n\textendResourcesFromExtensions(reason: \"startup\" | \"reload\"): Promise<void>;\n\t/** Re-apply the active profile's model/thinking from reloaded settings (reload only). */\n\treapplyActiveProfileModelSettings(): Promise<void>;\n\t/** Notify extensions-changed listeners after a single-extension live op. */\n\tnotifyExtensionsChanged(): void;\n\n\t/** Session-scoped tool-output artifact store for artifact-producing tools and artifact_retrieve (gated on the profile). */\n\tgetToolArtifactStore(): ArtifactStore;\n\n\t/** Live memory manager — its provider tools join the registry. */\n\tgetMemoryManager(): MemoryManager;\n\t/** Memory retrieval + prompt-inclusion diagnostics for the core diagnostics tool. */\n\tgetMemoryAuditDiagnostics(): { retrieval: MemoryRetrievalDiagnostics; promptInclusion: MemoryPromptInclusionReport };\n\t/** Drop extension-contributed pending memory providers before a reload re-registers them. */\n\tclearPendingMemoryProviders(): void;\n\tcreateMemoryReloadSnapshot(): MemoryControllerReloadSnapshot;\n\trestoreMemoryReloadSnapshot(snapshot: MemoryControllerReloadSnapshot): void;\n\t/** (Re)derive the memory subsystem from reloaded settings/providers. */\n\tinitializeMemory(): Promise<void>;\n\n\t/** Goal-tool state accessors. */\n\tgetGoalStateSnapshot(): GoalState | undefined;\n\tsaveGoalStateSnapshot(state: GoalState): string;\n\t/** Native task-step state accessors. */\n\tgetTaskStepsStateSnapshot(): TaskStepsState | undefined;\n\tsaveTaskStepsStateSnapshot(state: TaskStepsState): string;\n\t/** Context-gc report for the core diagnostics tool. */\n\tgetContextGcReport(messages: AgentMessage[]): ContextGcReport;\n\t/** Non-blocking worker-delegation starter for the delegate tool. */\n\tstartWorkerDelegation(request: {\n\t\tinstructions: string;\n\t\tsystemPrompt?: string;\n\t\tmemoryRead?: boolean;\n\t}): { started: false; skipReason: string } | { started: true; record: LaneRecord };\n\tgetWorkerLaneRecords(): LaneRecord[];\n\tgetWorkerResultSnapshots(): WorkerResult[];\n\t/** Worker-delegation runner for SDK/test through-completion calls. */\n\trunWorkerDelegationOnce(request: {\n\t\tinstructions: string;\n\t\tsystemPrompt?: string;\n\t\tmemoryRead?: boolean;\n\t}): Promise<WorkerDelegationRunOutcome>;\n\t/** Model-fitness probe for the model_fitness tool. */\n\trunModelFitness(args: {\n\t\tmodel: string;\n\t\ttrials?: number;\n\t}): Promise<{ started: true; model: string; report: ModelFitnessReport } | { started: false; skipReason: string }>;\n\t/** Fitness-gated reflex-brain model resolver (run_toolkit_script interpretation). */\n\tresolveCurationModelIfFit(): Model<Api> | undefined;\n\t/** One-shot, tool-less LLM call — the reflex-brain interpreter rides this. */\n\trunIsolatedCompletion(opts: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;\n\t/** Roll reflex-brain spend into spawned-usage accounting. */\n\taddSpawnedUsage(\n\t\tusage: Usage,\n\t\topts?: { label?: string; sourceSessionId?: string; reportId?: string },\n\t): string | undefined;\n\n\t/** Post-rebuild doctor helpers (validate the rebuilt runtime can render a context). */\n\tcreateAgentContextSnapshot(): AgentContext;\n\tgetContextUsage(): ContextUsage | undefined;\n\n\t/** Reload/live-op preflight refusal guards (identical refusal behavior; host-checked). */\n\tisStreaming(): boolean;\n\tisCompacting(): boolean;\n\n\t/** Extension bindings present — gate for re-emitting session_start on reload. */\n\tgetExtensionUIContext(): ExtensionUIContext | undefined;\n\tgetExtensionCommandContextActions(): ExtensionCommandContextActions | undefined;\n\tgetExtensionShutdownHandler(): ShutdownHandler | undefined;\n\tgetExtensionErrorListener(): ExtensionErrorListener | undefined;\n}\n\n/**\n * Owns the tool-registry build and the self-modification-safe extension reload extracted from\n * {@link AgentSession}. See the module header for the snapshot-ownership and host-binding boundaries.\n */\nexport class RuntimeBuilder {\n\t// Tool registry for extension getTools/setTools\n\tprivate _toolRegistry: Map<string, AgentTool> = new Map();\n\tprivate _toolDefinitions: Map<string, ToolDefinitionEntry> = new Map();\n\tprivate _toolPromptSnippets: Map<string, string> = new Map();\n\tprivate _toolPromptGuidelines: Map<string, string[]> = new Map();\n\tprivate _baseToolDefinitions: Map<string, ToolDefinition> = new Map();\n\tprivate _reloadPromise: Promise<void> | undefined;\n\tprivate _reloadRequested = false;\n\n\tprivate readonly deps: RuntimeBuilderDeps;\n\n\tconstructor(deps: RuntimeBuilderDeps) {\n\t\tthis.deps = deps;\n\t}\n\n\tprivate async _runContextScout(\n\t\tquery: string,\n\t\tmaxTurns: number | undefined,\n\t\tartifactStore: ArtifactStore | undefined,\n\t) {\n\t\tconst cwd = this.deps.getCwd();\n\t\tconst controller = new ScoutController({\n\t\t\tresolveScoutModel: async () =>\n\t\t\t\tresolveScoutModel(\n\t\t\t\t\tthis.deps.getModelRegistry(),\n\t\t\t\t\tthis.deps.getSettingsManager().getScoutSettings().model,\n\t\t\t\t\tthis.deps.getAgentDir(),\n\t\t\t\t\t(model) => this.deps.isModelExhausted(model),\n\t\t\t\t),\n\t\t\tgetCwd: () => cwd,\n\t\t\tbuildReadOnlyTools: (toolCwd) => [\n\t\t\t\tcreateReadTool(toolCwd),\n\t\t\t\tcreateGrepTool(toolCwd, { artifactStore }),\n\t\t\t\tcreateFindTool(toolCwd, { artifactStore }),\n\t\t\t],\n\t\t\tstreamFn: this.deps.getAgent().streamFn,\n\t\t\tfileExists: (path) => existsSync(resolveCwdPath(cwd, path)),\n\t\t\tcountLines: (path) => countFileLines(resolveCwdPath(cwd, path)),\n\t\t});\n\t\treturn controller.run(query, maxTurns);\n\t}\n\n\t/** Whether a tool name is present in the live wrapped registry. */\n\thasTool(name: string): boolean {\n\t\treturn this._toolRegistry.has(name);\n\t}\n\n\t/** The live wrapped tool for a name, if registered (activation lookup). */\n\tgetRegisteredTool(name: string): AgentTool | undefined {\n\t\treturn this._toolRegistry.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt snippet, if any. */\n\tgetToolPromptSnippet(name: string): string | undefined {\n\t\treturn this._toolPromptSnippets.get(name);\n\t}\n\n\t/** A registered tool's normalized prompt guidelines, if any. */\n\tgetToolPromptGuidelines(name: string): string[] | undefined {\n\t\treturn this._toolPromptGuidelines.get(name);\n\t}\n\n\t/**\n\t * Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.\n\t */\n\tgetAllTools(): ToolInfo[] {\n\t\treturn Array.from(this._toolDefinitions.values()).map(({ definition, sourceInfo }) => ({\n\t\t\tname: definition.name,\n\t\t\tdescription: definition.description,\n\t\t\tparameters: definition.parameters,\n\t\t\tpromptGuidelines: definition.promptGuidelines,\n\t\t\tsourceInfo,\n\t\t}));\n\t}\n\n\tgetToolDefinition(name: string): ToolDefinition | undefined {\n\t\treturn this._toolDefinitions.get(name)?.definition;\n\t}\n\n\trefreshToolRegistry(options?: { activeToolNames?: string[]; includeAllExtensionTools?: boolean }): void {\n\t\tconst previousRegistryNames = new Set(this._toolRegistry.keys());\n\t\t// Re-derive from the pre-filter REQUEST, never from agent.state.tools: the active set is\n\t\t// capability/profile-filtered, so feeding it back through setActiveToolsByName would\n\t\t// permanently shrink what a later switch to a larger model (or permissive profile) restores.\n\t\tconst previousActiveToolNames = mapToolNamesForPlatform(\n\t\t\tthis.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames(),\n\t\t);\n\t\tconst configuredAllowedToolNames = this.deps.getAllowedToolNames();\n\t\tconst allowedToolNames = configuredAllowedToolNames\n\t\t\t? new Set(mapToolNamesForPlatform([...configuredAllowedToolNames]))\n\t\t\t: undefined;\n\t\tconst configuredExcludedToolNames = this.deps.getExcludedToolNames();\n\t\tconst excludedToolNames = configuredExcludedToolNames\n\t\t\t? new Set(mapToolNamesForPlatform([...configuredExcludedToolNames]))\n\t\t\t: undefined;\n\t\tconst configuredToolProfileFilter = this.deps.getToolProfileFilter();\n\t\tconst toolProfileFilter = configuredToolProfileFilter\n\t\t\t? {\n\t\t\t\t\tallow: mapToolNamesForPlatform(configuredToolProfileFilter.allow),\n\t\t\t\t\tblock: mapToolNamesForPlatform(configuredToolProfileFilter.block),\n\t\t\t\t}\n\t\t\t: undefined;\n\t\tconst isAllowedTool = (name: string): boolean => {\n\t\t\tif (allowedToolNames && !allowedToolNames.has(name)) return false;\n\t\t\tif (excludedToolNames?.has(name)) return false;\n\t\t\tif (!toolProfileFilter) return true;\n\t\t\tif (toolProfileFilter.allow.length > 0 && !matchesResourceProfilePattern(name, toolProfileFilter.allow)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (matchesResourceProfilePattern(name, toolProfileFilter.block)) return false;\n\t\t\treturn true;\n\t\t};\n\n\t\tconst registeredTools = this.deps.getExtensionRunner().getAllRegisteredTools();\n\t\tconst allCustomTools = [\n\t\t\t...registeredTools,\n\t\t\t...this.deps.getCustomTools().map((definition) => ({\n\t\t\t\tdefinition,\n\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t})),\n\t\t\t// Memory subsystem provider tools (e.g. file-store's `memory` tool).\n\t\t\t...this.deps\n\t\t\t\t.getMemoryManager()\n\t\t\t\t.getToolDefinitions()\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<memory:${definition.name}>`, { source: \"sdk\" }),\n\t\t\t\t})),\n\t\t].filter((tool) => isAllowedTool(tool.definition.name));\n\t\tconst definitionRegistry = new Map<string, ToolDefinitionEntry>(\n\t\t\tArray.from(this._baseToolDefinitions.entries())\n\t\t\t\t.filter(([name]) => isAllowedTool(name))\n\t\t\t\t.map(([name, definition]) => [\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\tdefinition,\n\t\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, { source: \"builtin\" }),\n\t\t\t\t\t},\n\t\t\t\t]),\n\t\t);\n\t\tfor (const tool of allCustomTools) {\n\t\t\tdefinitionRegistry.set(tool.definition.name, {\n\t\t\t\tdefinition: tool.definition,\n\t\t\t\tsourceInfo: tool.sourceInfo,\n\t\t\t});\n\t\t}\n\t\tthis._toolDefinitions = definitionRegistry;\n\t\tthis._toolPromptSnippets = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst snippet = this.deps.normalizePromptSnippet(definition.promptSnippet);\n\t\t\t\t\treturn snippet ? ([definition.name, snippet] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string] => entry !== undefined),\n\t\t);\n\t\tthis._toolPromptGuidelines = new Map(\n\t\t\tArray.from(definitionRegistry.values())\n\t\t\t\t.map(({ definition }) => {\n\t\t\t\t\tconst guidelines = this.deps.normalizePromptGuidelines(definition.promptGuidelines);\n\t\t\t\t\treturn guidelines.length > 0 ? ([definition.name, guidelines] as const) : undefined;\n\t\t\t\t})\n\t\t\t\t.filter((entry): entry is readonly [string, string[]] => entry !== undefined),\n\t\t);\n\t\tconst runner = this.deps.getExtensionRunner();\n\t\tconst wrappedExtensionTools = wrapRegisteredTools(allCustomTools, runner);\n\t\tconst wrappedBuiltInTools = wrapRegisteredTools(\n\t\t\tArray.from(this._baseToolDefinitions.values())\n\t\t\t\t.filter((definition) => isAllowedTool(definition.name))\n\t\t\t\t.map((definition) => ({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tsourceInfo: createSyntheticSourceInfo(`<builtin:${definition.name}>`, { source: \"builtin\" }),\n\t\t\t\t})),\n\t\t\trunner,\n\t\t);\n\n\t\tconst toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));\n\t\tfor (const tool of wrappedExtensionTools as AgentTool[]) {\n\t\t\ttoolRegistry.set(tool.name, tool);\n\t\t}\n\t\tthis._toolRegistry = toolRegistry;\n\n\t\tconst requestedBase = options?.activeToolNames\n\t\t\t? mapToolNamesForPlatform(options.activeToolNames)\n\t\t\t: [...previousActiveToolNames];\n\t\tconst nextActiveToolNames = requestedBase.filter((name) => isAllowedTool(name));\n\n\t\tconst persistentAutoActivated: string[] = [];\n\t\tif (allowedToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (allowedToolNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tpersistentAutoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (options?.includeAllExtensionTools) {\n\t\t\tfor (const tool of wrappedExtensionTools) {\n\t\t\t\tnextActiveToolNames.push(tool.name);\n\t\t\t\tpersistentAutoActivated.push(tool.name);\n\t\t\t}\n\t\t} else if (!options?.activeToolNames) {\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!previousRegistryNames.has(toolName)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t\tpersistentAutoActivated.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Strict UAC: the active profile is the COMPLETE grant, so a tool the profile names\n\t\t// explicitly is itself a request for that tool — it must ACTIVATE from the registry even\n\t\t// if the session never requested it. Without this, activation is only ever the requested\n\t\t// defaults ∩ allow-list, and a profile granting non-default tools (a search-only profile's\n\t\t// grep/find) yields an empty or truncated tool set on load and /reload. A blanket \"*\"\n\t\t// stays grant-only: activation then still derives from the request/defaults above.\n\t\tconst explicitAllowPatterns = toolProfileFilter?.allow.filter((pattern) => pattern !== \"*\") ?? [];\n\t\tif (explicitAllowPatterns.length > 0) {\n\t\t\tconst boundPatterns = new Set<string>();\n\t\t\tfor (const toolName of this._toolRegistry.keys()) {\n\t\t\t\tif (!isAllowedTool(toolName)) continue;\n\t\t\t\tfor (const pattern of explicitAllowPatterns) {\n\t\t\t\t\tif (matchesResourceProfilePattern(toolName, [pattern])) boundPatterns.add(pattern);\n\t\t\t\t}\n\t\t\t\tif (matchesResourceProfilePattern(toolName, explicitAllowPatterns)) {\n\t\t\t\t\tnextActiveToolNames.push(toolName);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// G13: an explicit grant that binds to NO registered tool is a silent no-op — typo'd\n\t\t\t// name, or the owning extension is not granted/loaded. Surface it.\n\t\t\tthis.deps.setUnboundToolGrantWarnings(\n\t\t\t\texplicitAllowPatterns\n\t\t\t\t\t.filter((pattern) => !boundPatterns.has(pattern))\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(pattern) =>\n\t\t\t\t\t\t\t`profile tool grant \"${pattern}\" binds to no registered tool (typo, or the owning extension is not granted/loaded)`,\n\t\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.deps.setUnboundToolGrantWarnings([]);\n\t\t}\n\n\t\t// artifact_retrieve companion auto-activation is enforced inside\n\t\t// setActiveToolsByName() itself (not duplicated here), so every activation path --\n\t\t// including the public, extension-exposed setActiveTools() -- gets the same\n\t\t// guarantee, not just this settings/profile refresh flow.\n\t\tthis.deps.setActiveToolsByName([...new Set(nextActiveToolNames)]);\n\t\t// setActiveToolsByName just stored the profile-filtered ACTIVE set as the request; restore\n\t\t// the true pre-filter request (plus non-profile auto-activations) so an internal refresh can\n\t\t// never permanently narrow it. Explicit profile grants are generation-local activations: if\n\t\t// profile A names grep and profile B later grants \"*\", A must not pin grep into B's request.\n\t\tthis.deps.setRequestedActiveToolNames([...new Set([...requestedBase, ...persistentAutoActivated])]);\n\t}\n\n\tprivate _createReloadRuntimeSnapshot(): ReloadRuntimeSnapshot {\n\t\tconst agent = this.deps.getAgent();\n\t\tconst toolProfileFilter = this.deps.getToolProfileFilter();\n\t\tconst requestedActiveToolNames = this.deps.getRequestedActiveToolNames();\n\t\treturn {\n\t\t\textensionRunner: this.deps.getExtensionRunner(),\n\t\t\tsettings: this.deps.getSettingsManager().createReloadSnapshot(),\n\t\t\tmodelRegistry: this.deps.getModelRegistry().createReloadSnapshot(),\n\t\t\tmodel: agent.state.model,\n\t\t\tthinkingLevel: agent.state.thinkingLevel,\n\t\t\tsessionLeafId: this.deps.getSessionManager().getLeafId(),\n\t\t\ttoolProfileFilter: toolProfileFilter\n\t\t\t\t? { allow: [...toolProfileFilter.allow], block: [...toolProfileFilter.block] }\n\t\t\t\t: undefined,\n\t\t\trequestedActiveToolNames: requestedActiveToolNames ? [...requestedActiveToolNames] : undefined,\n\t\t\tmemory: this.deps.createMemoryReloadSnapshot(),\n\t\t\tprofileFilter: this.deps.createProfileFilterReloadSnapshot(),\n\t\t\tunboundToolGrantWarnings: [...this.deps.getUnboundToolGrantWarnings()],\n\t\t\tbaseToolDefinitions: this._baseToolDefinitions,\n\t\t\ttoolRegistry: this._toolRegistry,\n\t\t\ttoolDefinitions: this._toolDefinitions,\n\t\t\ttoolPromptSnippets: this._toolPromptSnippets,\n\t\t\ttoolPromptGuidelines: this._toolPromptGuidelines,\n\t\t\tagentTools: agent.state.tools,\n\t\t\tagentSystemPrompt: agent.state.systemPrompt,\n\t\t\tbaseSystemPrompt: this.deps.getBaseSystemPrompt(),\n\t\t};\n\t}\n\n\tprivate _restoreReloadRuntimeSnapshot(snapshot: ReloadRuntimeSnapshot): void {\n\t\tthis.deps.getSettingsManager().restoreReloadSnapshot(snapshot.settings);\n\t\tthis.deps.getModelRegistry().restoreReloadSnapshot(snapshot.modelRegistry);\n\t\tthis.deps.setToolProfileFilter(\n\t\t\tsnapshot.toolProfileFilter\n\t\t\t\t? { allow: [...snapshot.toolProfileFilter.allow], block: [...snapshot.toolProfileFilter.block] }\n\t\t\t\t: undefined,\n\t\t);\n\t\tthis.deps.setRequestedActiveToolNames(\n\t\t\tsnapshot.requestedActiveToolNames ? [...snapshot.requestedActiveToolNames] : undefined,\n\t\t);\n\t\tthis.deps.restoreMemoryReloadSnapshot(snapshot.memory);\n\t\tthis.deps.restoreProfileFilterReloadSnapshot(snapshot.profileFilter);\n\t\tthis.deps.setUnboundToolGrantWarnings([...snapshot.unboundToolGrantWarnings]);\n\t\t// setExtensionRunner restores both _extensionRunner and _extensionRunnerRef.current together\n\t\t// (the same field-then-ref pair the host wrote at every assignment site); nothing reads the\n\t\t// ref between the two writes, so folding them is unobservable.\n\t\tthis.deps.setExtensionRunner(snapshot.extensionRunner);\n\t\tthis._baseToolDefinitions = snapshot.baseToolDefinitions;\n\t\tthis._toolRegistry = snapshot.toolRegistry;\n\t\tthis._toolDefinitions = snapshot.toolDefinitions;\n\t\tthis._toolPromptSnippets = snapshot.toolPromptSnippets;\n\t\tthis._toolPromptGuidelines = snapshot.toolPromptGuidelines;\n\t\tconst agent = this.deps.getAgent();\n\t\tagent.state.model = snapshot.model;\n\t\tagent.state.thinkingLevel = snapshot.thinkingLevel;\n\t\tagent.state.tools = snapshot.agentTools;\n\t\tagent.state.systemPrompt = snapshot.agentSystemPrompt;\n\t\tthis.deps.setBaseSystemPrompt(snapshot.baseSystemPrompt);\n\t\tconst sessionManager = this.deps.getSessionManager();\n\t\tif (snapshot.sessionLeafId === null) {\n\t\t\tsessionManager.resetLeaf();\n\t\t} else {\n\t\t\tsessionManager.branch(snapshot.sessionLeafId);\n\t\t}\n\t\tthis.deps.applyExtensionBindings(snapshot.extensionRunner);\n\t}\n\n\tprivate _doctorReloadRuntime(): void {\n\t\tconst extensionErrors = this.deps.getResourceLoader().getExtensions().errors;\n\t\tif (extensionErrors.length > 0) {\n\t\t\tconst summary = extensionErrors\n\t\t\t\t.slice(0, 6)\n\t\t\t\t.map((error) => `${error.path}: ${error.error}`)\n\t\t\t\t.join(\"; \");\n\t\t\tthrow new Error(`Extension reload failed doctor: ${summary}`);\n\t\t}\n\n\t\tconst missingActiveTools = this.deps.getActiveToolNames().filter((name) => !this._toolRegistry.has(name));\n\t\tif (missingActiveTools.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Extension reload failed doctor: active tool(s) missing after reload: ${missingActiveTools.join(\", \")}`,\n\t\t\t);\n\t\t}\n\n\t\tfor (const tool of this.deps.getAgent().state.tools) {\n\t\t\tif (!this._toolDefinitions.has(tool.name)) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: tool ${tool.name} missing from definition registry`);\n\t\t\t}\n\t\t}\n\n\t\tthis.deps.createAgentContextSnapshot();\n\t\tthis.deps.getContextUsage();\n\t}\n\n\tbuildRuntime(options: {\n\t\tactiveToolNames?: string[];\n\t\tflagValues?: Map<string, boolean | string>;\n\t\tincludeAllExtensionTools?: boolean;\n\t\tonError?: ExtensionErrorListener;\n\t}): (() => void) | undefined {\n\t\tconst settingsManager = this.deps.getSettingsManager();\n\t\tconst autoResizeImages = settingsManager.getImageAutoResize();\n\t\tconst shellCommandPrefix = settingsManager.getShellCommandPrefix();\n\t\tconst shellPath = settingsManager.getShellPath();\n\t\tconst baseToolsOverride = this.deps.getBaseToolsOverride();\n\t\t// Artifact-producing tools must not emit a \"Full output: artifact tool-output:<id>\" handle\n\t\t// that nothing can resolve. If artifact_retrieve is explicitly excluded/blocked/outside\n\t\t// an active allowlist, don't hand grep/find/run_toolkit_script an artifact store at all:\n\t\t// they fall back to their bounded preview/truncation behavior, with no payload/meta files\n\t\t// ever written and no retrieval promise made.\n\t\tconst toolArtifactStore = this.deps.isToolOrCommandAllowedByProfile(\"artifact_retrieve\")\n\t\t\t? this.deps.getToolArtifactStore()\n\t\t\t: undefined;\n\t\tconst baseToolDefinitions = baseToolsOverride\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(baseToolsOverride).map(([name, tool]) => [name, createToolDefinitionFromAgentTool(tool)]),\n\t\t\t\t)\n\t\t\t: createAllToolDefinitions(this.deps.getCwd(), {\n\t\t\t\t\tread: { autoResizeImages },\n\t\t\t\t\tbash: { commandPrefix: shellCommandPrefix, shellPath },\n\t\t\t\t\tgrep: { artifactStore: toolArtifactStore },\n\t\t\t\t\tfind: { artifactStore: toolArtifactStore },\n\t\t\t\t\tartifact_retrieve: { artifactStore: toolArtifactStore },\n\t\t\t\t});\n\n\t\tthis._baseToolDefinitions = new Map(\n\t\t\tObject.entries(baseToolDefinitions).map(([name, tool]) => [name, tool as ToolDefinition]),\n\t\t);\n\t\tif (!baseToolsOverride) {\n\t\t\tfor (const definition of createCoreDiagnosticsToolDefinitions(\n\t\t\t\t() => this.deps.getActiveToolNames(),\n\t\t\t\t() => this.getAllTools(),\n\t\t\t\t(messages) => this.deps.getContextGcReport(messages),\n\t\t\t\t() => this.deps.getMemoryAuditDiagnostics(),\n\t\t\t)) {\n\t\t\t\tthis._baseToolDefinitions.set(definition.name, definition);\n\t\t\t}\n\t\t\tconst goalToolDefinition = createGoalToolDefinition({\n\t\t\t\tgetGoalState: () => this.deps.getGoalStateSnapshot(),\n\t\t\t\tsaveGoalState: (state) => {\n\t\t\t\t\tthis.deps.saveGoalStateSnapshot(state);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(goalToolDefinition.name, goalToolDefinition);\n\t\t\tconst taskStepsToolDefinition = createTaskStepsToolDefinition({\n\t\t\t\tgetTaskStepsState: () => this.deps.getTaskStepsStateSnapshot(),\n\t\t\t\tsaveTaskStepsState: (state) => {\n\t\t\t\t\tthis.deps.saveTaskStepsStateSnapshot(state);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(taskStepsToolDefinition.name, taskStepsToolDefinition);\n\t\t\tconst delegateToolDefinition = createDelegateToolDefinition({\n\t\t\t\tstartWorkerDelegation: (args) => this.deps.startWorkerDelegation(args),\n\t\t\t\trunWorkerDelegation: (args) => this.deps.runWorkerDelegationOnce(args),\n\t\t\t});\n\t\t\tconst delegateStatusToolDefinition = createDelegateStatusToolDefinition({\n\t\t\t\tgetLaneRecords: () => this.deps.getWorkerLaneRecords(),\n\t\t\t\tgetWorkerResultSnapshots: () => this.deps.getWorkerResultSnapshots(),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(delegateToolDefinition.name, delegateToolDefinition);\n\t\t\tthis._baseToolDefinitions.set(delegateStatusToolDefinition.name, delegateStatusToolDefinition);\n\t\t\t// Registered but not default-active: probes spend tokens on the probed model, so\n\t\t\t// activation is an explicit choice (settings/profile/setActiveTools or /autonomy fitness).\n\t\t\tconst modelFitnessToolDefinition = createModelFitnessToolDefinition({\n\t\t\t\trunProbe: (args) => this.deps.runModelFitness(args),\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(modelFitnessToolDefinition.name, modelFitnessToolDefinition);\n\t\t\tif (settingsManager.getScoutSettings().enabled) {\n\t\t\t\tconst contextScoutToolDefinition = createContextScoutToolDefinition({\n\t\t\t\t\trunScout: (input) => this._runContextScout(input.query, input.maxTurns, toolArtifactStore),\n\t\t\t\t});\n\t\t\t\tthis._baseToolDefinitions.set(contextScoutToolDefinition.name, contextScoutToolDefinition);\n\t\t\t}\n\t\t\tconst runToolkitScriptToolDefinition = createRunToolkitScriptToolDefinition({\n\t\t\t\tgetScripts: () => this.deps.getSettingsManager().getToolkitScripts(),\n\t\t\t\texecute: (script, scriptArgs) => executeToolkitScript({ script, scriptArgs, cwd: this.deps.getCwd() }),\n\t\t\t\tartifactStore: toolArtifactStore,\n\t\t\t\t// Reflex brain (fitness-gated local model): resolves ambiguous requests into a\n\t\t\t\t// registry pick. Best-effort — absent/unfit brain keeps the shortlist behavior.\n\t\t\t\tinterpret: async (request, scripts) => {\n\t\t\t\t\tconst model = this.deps.resolveCurationModelIfFit();\n\t\t\t\t\tif (!model) return undefined;\n\t\t\t\t\tconst completion = await this.deps.runIsolatedCompletion({\n\t\t\t\t\t\tsystemPrompt: REFLEX_INTERPRETER_SYSTEM_PROMPT,\n\t\t\t\t\t\tmessages: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: buildReflexUserPrompt(request, scripts) }],\n\t\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\t\t\tmaxTokens: 256,\n\t\t\t\t\t\tcacheRetention: \"short\",\n\t\t\t\t\t});\n\t\t\t\t\tif (completion.usage.cost.total > 0 || completion.usage.totalTokens > 0) {\n\t\t\t\t\t\tthis.deps.addSpawnedUsage(completion.usage, { label: \"toolkit-brain\" });\n\t\t\t\t\t}\n\t\t\t\t\treturn parseReflexPlan(completion.text);\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis._baseToolDefinitions.set(runToolkitScriptToolDefinition.name, runToolkitScriptToolDefinition);\n\t\t}\n\n\t\tconst extensionsResult = this.deps.getResourceLoader().getExtensions();\n\t\tif (options.flagValues) {\n\t\t\tfor (const [name, value] of options.flagValues) {\n\t\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\t}\n\t\t}\n\t\tconst extensions = this.deps.filterExtensionsForRuntime(extensionsResult.extensions);\n\t\tconst runtimeExtensionPaths = new Set(extensions.map((extension) => extension.path));\n\t\textensionsResult.runtime.pendingProviderRegistrations =\n\t\t\textensionsResult.runtime.pendingProviderRegistrations.filter((registration) =>\n\t\t\t\truntimeExtensionPaths.has(registration.extensionPath),\n\t\t\t);\n\n\t\tconst runner = new ExtensionRunner(\n\t\t\textensions,\n\t\t\textensionsResult.runtime,\n\t\t\tthis.deps.getCwd(),\n\t\t\tthis.deps.getSessionManager(),\n\t\t\tthis.deps.getModelRegistry(),\n\t\t);\n\t\tconst offBuildErrors = options.onError ? runner.onError(options.onError) : undefined;\n\t\tthis.deps.setExtensionRunner(runner);\n\t\ttry {\n\t\t\tthis.deps.bindExtensionCore(runner);\n\t\t} catch (error) {\n\t\t\toffBuildErrors?.();\n\t\t\tthrow error;\n\t\t}\n\t\tthis.deps.applyExtensionBindings(runner);\n\n\t\tconst defaultActiveToolNames = mapToolNamesForPlatform(\n\t\t\tbaseToolsOverride\n\t\t\t\t? Object.keys(baseToolsOverride)\n\t\t\t\t: [...DEFAULT_ACTIVE_TOOL_NAMES, ...(settingsManager.getScoutSettings().enabled ? [\"context_scout\"] : [])],\n\t\t);\n\t\tconst baseActiveToolNames = mapToolNamesForPlatform(options.activeToolNames ?? defaultActiveToolNames);\n\t\tthis.refreshToolRegistry({\n\t\t\tactiveToolNames: baseActiveToolNames,\n\t\t\tincludeAllExtensionTools: options.includeAllExtensionTools,\n\t\t});\n\t\treturn offBuildErrors;\n\t}\n\n\treload(): Promise<void> {\n\t\tif (this._reloadPromise) {\n\t\t\t// State can change while a generation is being validated. Coalesce any number of\n\t\t\t// overlapping requests into one follow-up generation instead of silently treating a\n\t\t\t// later profile/settings mutation as part of the already-snapshotted generation.\n\t\t\tthis._reloadRequested = true;\n\t\t\treturn this._reloadPromise;\n\t\t}\n\t\tconst reloadPromise = this._drainReloadRequests();\n\t\tthis._reloadPromise = reloadPromise;\n\t\treturn reloadPromise;\n\t}\n\n\tprivate async _drainReloadRequests(): Promise<void> {\n\t\tlet finalError: unknown;\n\t\ttry {\n\t\t\tdo {\n\t\t\t\tthis._reloadRequested = false;\n\t\t\t\ttry {\n\t\t\t\t\tawait this._reloadOnce();\n\t\t\t\t\tfinalError = undefined;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfinalError = error;\n\t\t\t\t}\n\t\t\t} while (this._reloadRequested);\n\t\t\tif (finalError !== undefined) throw finalError;\n\t\t} finally {\n\t\t\tthis._reloadPromise = undefined;\n\t\t\tthis._reloadRequested = false;\n\t\t}\n\t}\n\n\tprivate async _reloadOnce(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reload while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reload while context compaction or branch summarization is active\");\n\t\t}\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\tconst snapshot = this._createReloadRuntimeSnapshot();\n\t\t// Preserve the pre-filter tool REQUEST across the rebuild, not the capability/profile-filtered\n\t\t// active set — otherwise a reload under a small model permanently shrinks the restorable set.\n\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\tconst previousExtensionProviderNames = previousRunner.getRegisteredProviderNames();\n\t\tconst reloadErrors: string[] = [];\n\t\tlet newRunner: ExtensionRunner | undefined;\n\t\tlet offReloadErrors: (() => void) | undefined;\n\t\ttry {\n\t\t\tawait this.deps.getSettingsManager().reload();\n\t\t\t// Re-derive the resource-profile tool filter from the freshly reloaded settings.\n\t\t\t// Unlike skills/prompts/themes (which re-filter through the resource loader on every\n\t\t\t// reload), the tool filter is held on the session, so without this a live edit to the\n\t\t\t// active profile's tools allow/block — or switching the active profile — would not\n\t\t\t// apply on /reload and allowed tools would stay missing.\n\t\t\tthis.deps.setToolProfileFilter(this.deps.deriveToolProfileFilter());\n\t\t\t// Resource discovery must consume this exact settings generation. A second settings read here\n\t\t\t// could combine profile state from one generation with resources from the next.\n\t\t\tawait this.deps.getResourceLoader().reload({\n\t\t\t\tfailOnExtensionErrors: true,\n\t\t\t\tdeferExtensionDispose: true,\n\t\t\t\tskipSettingsReload: true,\n\t\t\t});\n\t\t\t// Replace the previous extension-owned provider generation before binding the new one. The\n\t\t\t// bulk refresh also preserves API/OAuth streams for surviving non-extension providers.\n\t\t\tthis.deps.getModelRegistry().unregisterProviders(previousExtensionProviderNames);\n\t\t\toffReloadErrors = this.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t\tonError: (error) => {\n\t\t\t\t\treloadErrors.push(`${error.extensionPath} ${error.event}: ${error.error}`);\n\t\t\t\t},\n\t\t\t});\n\t\t\tnewRunner = this.deps.getExtensionRunner();\n\t\t\t// Extensions are now bound and their queued providers/models are registered, so a profile may\n\t\t\t// safely select a model contributed by an extension granted in that same profile generation.\n\t\t\tawait this.deps.reapplyActiveProfileModelSettings();\n\t\t\t// Model capability and system-prompt/tool exposure must reflect the newly selected model.\n\t\t\tthis.refreshToolRegistry({ activeToolNames, includeAllExtensionTools: true });\n\t\t\ttry {\n\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t// Reload starts memory providers fresh; loaded extensions re-register below.\n\t\t\t\tthis.deps.clearPendingMemoryProviders();\n\t\t\t\tconst hasBindings =\n\t\t\t\t\tthis.deps.getExtensionUIContext() ||\n\t\t\t\t\tthis.deps.getExtensionCommandContextActions() ||\n\t\t\t\t\tthis.deps.getExtensionShutdownHandler() ||\n\t\t\t\t\tthis.deps.getExtensionErrorListener();\n\t\t\t\tif (hasBindings) {\n\t\t\t\t\tawait newRunner.emit({ type: \"session_start\", reason: \"reload\" });\n\t\t\t\t\tawait this.deps.extendResourcesFromExtensions(\"reload\");\n\t\t\t\t\tthis._doctorReloadRuntime();\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\toffReloadErrors?.();\n\t\t\t\toffReloadErrors = undefined;\n\t\t\t}\n\t\t\tif (reloadErrors.length > 0) {\n\t\t\t\tthrow new Error(`Extension reload failed doctor: ${reloadErrors.slice(0, 6).join(\"; \")}`);\n\t\t\t}\n\t\t\tawait emitSessionShutdownEvent(previousRunner, { type: \"session_shutdown\", reason: \"reload\" });\n\t\t\tpreviousRunner.invalidate();\n\t\t\tawait this.deps.getResourceLoader().commitReload?.();\n\t\t\t// Re-derive the memory subsystem from the reloaded settings/providers.\n\t\t\tawait this.deps.initializeMemory();\n\t\t} catch (error) {\n\t\t\toffReloadErrors?.();\n\t\t\tif (newRunner && newRunner !== previousRunner) {\n\t\t\t\tnewRunner.invalidate(\n\t\t\t\t\t\"This extension ctx was discarded because reload failed and Pi restored the previous valid runtime.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait this.deps.getResourceLoader().rollbackReload?.();\n\t\t\tthis._restoreReloadRuntimeSnapshot(snapshot);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Unload a single extension without full reload.\n\t * Runs the extension's session_shutdown lifecycle, unregisters its providers,\n\t * disposes its event subscriptions, and rebuilds the runtime.\n\t * Falls back to full reload on error.\n\t */\n\tasync unloadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot unload extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot unload extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst ext = this.deps.getResourceLoader().getLoadedExtension(extensionPath);\n\t\tif (!ext) {\n\t\t\treturn; // Nothing to unload\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Run session_shutdown lifecycle for this extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(ext, { type: \"session_shutdown\", reason: \"unload\" });\n\n\t\t\t// Unregister its providers (keyed by the extension's own path, as registered)\n\t\t\tconst runtime = this.deps.getResourceLoader().getExtensions().runtime;\n\t\t\tconst ownedMemoryProviders = runtime.memoryProvidersByExtension.get(ext.path) ?? new Set();\n\t\t\tconst ownedContextMemoryProviders = runtime.contextMemoryProvidersByExtension.get(ext.path) ?? new Set();\n\t\t\tfor (const name of runtime.getProvidersForExtension(ext.path)) {\n\t\t\t\truntime.unregisterProvider(name, ext.path);\n\t\t\t}\n\n\t\t\t// Dispose its event subscriptions and run disposers\n\t\t\tawait disposeExtensionEventSubscriptions([ext]);\n\n\t\t\t// Remove from loaded extensions\n\t\t\tthis.deps.getResourceLoader().removeLoadedExtension(extensionPath);\n\n\t\t\t// Rebuild runtime with new extension set\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\t\t\tpreviousRunner.invalidate();\n\t\t\tconst memorySnapshot = this.deps.createMemoryReloadSnapshot();\n\t\t\tthis.deps.restoreMemoryReloadSnapshot({\n\t\t\t\t...memorySnapshot,\n\t\t\t\tpendingMemoryProviders: memorySnapshot.pendingMemoryProviders.filter(\n\t\t\t\t\t(provider) => !ownedMemoryProviders.has(provider),\n\t\t\t\t),\n\t\t\t\tpendingContextMemoryProviders: memorySnapshot.pendingContextMemoryProviders.filter(\n\t\t\t\t\t(provider) => !ownedContextMemoryProviders.has(provider),\n\t\t\t\t),\n\t\t\t});\n\t\t\truntime.memoryProvidersByExtension.delete(ext.path);\n\t\t\truntime.contextMemoryProvidersByExtension.delete(ext.path);\n\t\t\tawait this.deps.initializeMemory();\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Load a single extension without full reload.\n\t * Loads the extension with fresh import, rebuilds the runtime,\n\t * and runs the extension's session_start lifecycle.\n\t * Falls back to full reload on error.\n\t */\n\tasync loadExtensionLive(extensionPath: string): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot load extension while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot load extension while context compaction or branch summarization is active\");\n\t\t}\n\n\t\tconst previousRunner = this.deps.getExtensionRunner();\n\t\ttry {\n\t\t\t// Load the extension with fresh import\n\t\t\tconst { extension, error } = await this.deps.getResourceLoader().loadSingleExtension(extensionPath);\n\t\t\tif (error || !extension) {\n\t\t\t\tthrow new Error(error || `Failed to load extension: ${extensionPath}`);\n\t\t\t}\n\n\t\t\t// Rebuild runtime to aggregate tools/commands/handlers/providers\n\t\t\tconst activeToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();\n\t\t\tconst previousFlagValues = previousRunner.getFlagValues();\n\t\t\tthis.buildRuntime({\n\t\t\t\tactiveToolNames,\n\t\t\t\tflagValues: previousFlagValues,\n\t\t\t\tincludeAllExtensionTools: true,\n\t\t\t});\n\n\t\t\t// Run session_start lifecycle for the new extension only\n\t\t\tawait this.deps.getExtensionRunner().emitToExtension(extension, { type: \"session_start\", reason: \"load\" });\n\t\t\t// Activate newly registered legacy/context providers immediately. Reinitialization also\n\t\t\t// refreshes provider tools and preserves all providers owned by existing extensions.\n\t\t\tawait this.deps.initializeMemory();\n\n\t\t\t// Notify extensions-changed listeners\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Reconcile loaded extensions with the active profile.\n\t * Loads extensions that should be enabled but aren't, and unloads extensions that shouldn't be.\n\t * Falls back to full reload if any individual load/unload fails.\n\t */\n\tasync reconcileLoadedExtensions(): Promise<void> {\n\t\tif (this.deps.isStreaming()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while the agent is streaming or a tool call is active\");\n\t\t}\n\t\tif (this.deps.isCompacting()) {\n\t\t\tthrow new Error(\"Cannot reconcile extensions while context compaction or branch summarization is active\");\n\t\t}\n\n\t\ttry {\n\t\t\t// Get all discoverable extension paths\n\t\t\tconst allDiscoverablePaths = await this.deps.getResourceLoader().getDiscoverableExtensionPaths();\n\n\t\t\t// Get the target enabled set based on profile filters\n\t\t\tconst targetEnabledSet = new Set<string>();\n\t\t\tfor (const path of allDiscoverablePaths) {\n\t\t\t\tif (this.deps.getSettingsManager().isResourceAllowedByProfile(\"extensions\", path)) {\n\t\t\t\t\ttargetEnabledSet.add(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get currently loaded set\n\t\t\tconst loadedExtensions = this.deps.getResourceLoader().getExtensions().extensions;\n\t\t\tconst loadedSet = new Set<string>();\n\t\t\tfor (const ext of loadedExtensions) {\n\t\t\t\tloadedSet.add(ext.path);\n\t\t\t}\n\n\t\t\t// Collect unloads and loads\n\t\t\tconst toUnload: string[] = [];\n\t\t\tconst toLoad: string[] = [];\n\n\t\t\tfor (const path of loadedSet) {\n\t\t\t\tif (!targetEnabledSet.has(path)) {\n\t\t\t\t\ttoUnload.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of targetEnabledSet) {\n\t\t\t\tif (!loadedSet.has(path)) {\n\t\t\t\t\ttoLoad.push(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply unloads first, then loads, to minimize churn\n\t\t\t// Collect errors but continue through all operations\n\t\t\tconst errors: Error[] = [];\n\n\t\t\tfor (const path of toUnload) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.unloadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const path of toLoad) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.loadExtensionLive(path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If any errors occurred, throw the first one (already fell back to full reload in load/unload)\n\t\t\tif (errors.length > 0) {\n\t\t\t\tthrow errors[0];\n\t\t\t}\n\n\t\t\t// Single notification at the end\n\t\t\tthis.deps.notifyExtensionsChanged();\n\t\t} catch (error) {\n\t\t\t// Fall back to full reload on error\n\t\t\ttry {\n\t\t\t\tawait this.reload();\n\t\t\t} catch {\n\t\t\t\t// Suppress nested error; original error will be thrown below\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n\nexport async function resolveScoutModel(\n\tmodelRegistry: ModelRegistry,\n\tmodelSetting: string,\n\tagentDir: string,\n\tisModelExhausted: (model: Model<Api>) => boolean = () => false,\n) {\n\tconst model =\n\t\tmodelSetting === \"auto\"\n\t\t\t? findFastContextModel(modelRegistry)\n\t\t\t: resolveCliModel({ cliModel: modelSetting, modelRegistry }).model;\n\tif (!model) {\n\t\treturn { failure: `no scout model matched ${modelSetting}` };\n\t}\n\tif (isModelExhausted(model)) {\n\t\treturn { failure: `${model.provider}/${model.id} exhausted: quota` };\n\t}\n\tif (modelSetting === \"auto\") {\n\t\tconst modelRef = `${model.provider}/${model.id}`;\n\t\tconst fitness = FitnessStore.forAgentDir(agentDir)\n\t\t\t.getForHost()\n\t\t\t.find((entry) => entry.model === modelRef);\n\t\tconst verdict = evaluateSurfaceFitness(\"scout_auto\", fitness?.report);\n\t\tif (!verdict.fit) {\n\t\t\treturn verdict.reason === \"unprobed\"\n\t\t\t\t? { failure: `${modelRef} unprobed — run /fitness before auto-selection` }\n\t\t\t\t: { failure: `${modelRef} unfit (${verdict.lane} ${verdict.succeeded}/${verdict.total})` };\n\t\t}\n\t}\n\tconst auth = await modelRegistry.getApiKeyAndHeaders(model);\n\tif (!auth.ok) {\n\t\treturn { failure: auth.error ?? `no usable auth for scout model ${model.provider}/${model.id}` };\n\t}\n\treturn { model, apiKey: auth.apiKey, headers: auth.headers };\n}\n\nfunction findFastContextModel(modelRegistry: ModelRegistry) {\n\treturn modelRegistry.getAll().find((model) => {\n\t\tconst text = `${model.provider}/${model.id} ${model.name}`.toLowerCase();\n\t\treturn text.includes(\"fastcontext\");\n\t});\n}\n\nfunction resolveCwdPath(cwd: string, path: string): string {\n\treturn isAbsolute(path) ? path : join(cwd, path);\n}\n\nfunction countFileLines(path: string): number | undefined {\n\ttry {\n\t\treturn readFileSync(path, \"utf8\").split(/\\r?\\n/).length;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"]}
@@ -34,7 +34,7 @@
34
34
  */
35
35
  import { existsSync, readFileSync } from "node:fs";
36
36
  import { isAbsolute, join } from "node:path";
37
- import { DEFAULT_ACTIVE_TOOL_NAMES } from "./default-tool-surface.js";
37
+ import { DEFAULT_ACTIVE_TOOL_NAMES, mapToolNamesForPlatform } from "./default-tool-surface.js";
38
38
  import { createCoreDiagnosticsToolDefinitions } from "./extensions/builtin.js";
39
39
  import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
40
40
  import { disposeExtensionEventSubscriptions } from "./extensions/loader.js";
@@ -57,6 +57,7 @@ import { createAllToolDefinitions } from "./tools/index.js";
57
57
  import { createModelFitnessToolDefinition } from "./tools/model-fitness.js";
58
58
  import { createReadTool } from "./tools/read.js";
59
59
  import { createRunToolkitScriptToolDefinition } from "./tools/run-toolkit-script.js";
60
+ import { createTaskStepsToolDefinition } from "./tools/task-steps.js";
60
61
  import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
61
62
  /**
62
63
  * Owns the tool-registry build and the self-modification-safe extension reload extracted from
@@ -127,10 +128,22 @@ export class RuntimeBuilder {
127
128
  // Re-derive from the pre-filter REQUEST, never from agent.state.tools: the active set is
128
129
  // capability/profile-filtered, so feeding it back through setActiveToolsByName would
129
130
  // permanently shrink what a later switch to a larger model (or permissive profile) restores.
130
- const previousActiveToolNames = this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames();
131
- const allowedToolNames = this.deps.getAllowedToolNames();
132
- const excludedToolNames = this.deps.getExcludedToolNames();
133
- const toolProfileFilter = this.deps.getToolProfileFilter();
131
+ const previousActiveToolNames = mapToolNamesForPlatform(this.deps.getRequestedActiveToolNames() ?? this.deps.getActiveToolNames());
132
+ const configuredAllowedToolNames = this.deps.getAllowedToolNames();
133
+ const allowedToolNames = configuredAllowedToolNames
134
+ ? new Set(mapToolNamesForPlatform([...configuredAllowedToolNames]))
135
+ : undefined;
136
+ const configuredExcludedToolNames = this.deps.getExcludedToolNames();
137
+ const excludedToolNames = configuredExcludedToolNames
138
+ ? new Set(mapToolNamesForPlatform([...configuredExcludedToolNames]))
139
+ : undefined;
140
+ const configuredToolProfileFilter = this.deps.getToolProfileFilter();
141
+ const toolProfileFilter = configuredToolProfileFilter
142
+ ? {
143
+ allow: mapToolNamesForPlatform(configuredToolProfileFilter.allow),
144
+ block: mapToolNamesForPlatform(configuredToolProfileFilter.block),
145
+ }
146
+ : undefined;
134
147
  const isAllowedTool = (name) => {
135
148
  if (allowedToolNames && !allowedToolNames.has(name))
136
149
  return false;
@@ -202,7 +215,9 @@ export class RuntimeBuilder {
202
215
  toolRegistry.set(tool.name, tool);
203
216
  }
204
217
  this._toolRegistry = toolRegistry;
205
- const requestedBase = options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames];
218
+ const requestedBase = options?.activeToolNames
219
+ ? mapToolNamesForPlatform(options.activeToolNames)
220
+ : [...previousActiveToolNames];
206
221
  const nextActiveToolNames = requestedBase.filter((name) => isAllowedTool(name));
207
222
  const persistentAutoActivated = [];
208
223
  if (allowedToolNames) {
@@ -385,6 +400,13 @@ export class RuntimeBuilder {
385
400
  },
386
401
  });
387
402
  this._baseToolDefinitions.set(goalToolDefinition.name, goalToolDefinition);
403
+ const taskStepsToolDefinition = createTaskStepsToolDefinition({
404
+ getTaskStepsState: () => this.deps.getTaskStepsStateSnapshot(),
405
+ saveTaskStepsState: (state) => {
406
+ this.deps.saveTaskStepsStateSnapshot(state);
407
+ },
408
+ });
409
+ this._baseToolDefinitions.set(taskStepsToolDefinition.name, taskStepsToolDefinition);
388
410
  const delegateToolDefinition = createDelegateToolDefinition({
389
411
  startWorkerDelegation: (args) => this.deps.startWorkerDelegation(args),
390
412
  runWorkerDelegation: (args) => this.deps.runWorkerDelegationOnce(args),
@@ -460,10 +482,10 @@ export class RuntimeBuilder {
460
482
  throw error;
461
483
  }
462
484
  this.deps.applyExtensionBindings(runner);
463
- const defaultActiveToolNames = baseToolsOverride
485
+ const defaultActiveToolNames = mapToolNamesForPlatform(baseToolsOverride
464
486
  ? Object.keys(baseToolsOverride)
465
- : [...DEFAULT_ACTIVE_TOOL_NAMES, ...(settingsManager.getScoutSettings().enabled ? ["context_scout"] : [])];
466
- const baseActiveToolNames = options.activeToolNames ?? defaultActiveToolNames;
487
+ : [...DEFAULT_ACTIVE_TOOL_NAMES, ...(settingsManager.getScoutSettings().enabled ? ["context_scout"] : [])]);
488
+ const baseActiveToolNames = mapToolNamesForPlatform(options.activeToolNames ?? defaultActiveToolNames);
467
489
  this.refreshToolRegistry({
468
490
  activeToolNames: baseActiveToolNames,
469
491
  includeAllExtensionTools: options.includeAllExtensionTools,