@code-yeongyu/senpi 2026.7.25-2 → 2026.7.26

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 (463) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +1 -1
  3. package/dist/cli/args.d.ts +4 -16
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +9 -25
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/grok-neo-gate.d.ts +12 -0
  8. package/dist/cli/grok-neo-gate.d.ts.map +1 -0
  9. package/dist/cli/grok-neo-gate.js +18 -0
  10. package/dist/cli/grok-neo-gate.js.map +1 -0
  11. package/dist/cli-main.js +4 -0
  12. package/dist/cli-main.js.map +1 -1
  13. package/dist/cli.js +2 -0
  14. package/dist/cli.js.map +1 -1
  15. package/dist/core/agent-session-runtime.d.ts +2 -0
  16. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  17. package/dist/core/agent-session-runtime.js +33 -8
  18. package/dist/core/agent-session-runtime.js.map +1 -1
  19. package/dist/core/agent-session.d.ts +9 -3
  20. package/dist/core/agent-session.d.ts.map +1 -1
  21. package/dist/core/agent-session.js +179 -57
  22. package/dist/core/agent-session.js.map +1 -1
  23. package/dist/core/auth-providers.d.ts +2 -2
  24. package/dist/core/auth-providers.js +2 -2
  25. package/dist/core/auth-providers.js.map +1 -1
  26. package/dist/core/extensions/builtin/bash-timeout/timeout.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/bash-timeout/timeout.js +3 -2
  28. package/dist/core/extensions/builtin/bash-timeout/timeout.js.map +1 -1
  29. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/compaction/index.js +30 -2
  31. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  33. package/dist/core/extensions/builtin/compaction/speculative.js +28 -0
  34. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  35. package/dist/core/extensions/builtin/goal/command-registration.js +2 -2
  36. package/dist/core/extensions/builtin/goal/command-registration.js.map +1 -1
  37. package/dist/core/extensions/builtin/goal/format.d.ts +1 -1
  38. package/dist/core/extensions/builtin/goal/format.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/goal/format.js +9 -2
  40. package/dist/core/extensions/builtin/goal/format.js.map +1 -1
  41. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/goal/index.js +38 -23
  43. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  44. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +6 -0
  45. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -0
  46. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +19 -0
  47. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -0
  48. package/dist/core/extensions/builtin/goal/persistence.d.ts +6 -0
  49. package/dist/core/extensions/builtin/goal/persistence.d.ts.map +1 -0
  50. package/dist/core/extensions/builtin/goal/persistence.js +141 -0
  51. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -0
  52. package/dist/core/extensions/builtin/goal/store.d.ts +7 -3
  53. package/dist/core/extensions/builtin/goal/store.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/goal/store.js +66 -181
  55. package/dist/core/extensions/builtin/goal/store.js.map +1 -1
  56. package/dist/core/extensions/builtin/goal/tool-registration.d.ts +1 -0
  57. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/goal/tool-registration.js +26 -15
  59. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  60. package/dist/core/extensions/builtin/goal/transitions.d.ts +3 -0
  61. package/dist/core/extensions/builtin/goal/transitions.d.ts.map +1 -0
  62. package/dist/core/extensions/builtin/goal/transitions.js +45 -0
  63. package/dist/core/extensions/builtin/goal/transitions.js.map +1 -0
  64. package/dist/core/extensions/builtin/goal/types.d.ts +10 -4
  65. package/dist/core/extensions/builtin/goal/types.d.ts.map +1 -1
  66. package/dist/core/extensions/builtin/goal/types.js +2 -2
  67. package/dist/core/extensions/builtin/goal/types.js.map +1 -1
  68. package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/goal/ui.js +2 -0
  70. package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
  71. package/dist/core/extensions/builtin/goal/validation.d.ts +8 -1
  72. package/dist/core/extensions/builtin/goal/validation.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/goal/validation.js +24 -12
  74. package/dist/core/extensions/builtin/goal/validation.js.map +1 -1
  75. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  76. package/dist/core/extensions/builtin/index.js +0 -2
  77. package/dist/core/extensions/builtin/index.js.map +1 -1
  78. package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
  79. package/dist/core/extensions/builtin/mcp/index.js +8 -5
  80. package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
  81. package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
  82. package/dist/core/extensions/builtin/permission-system/parsers.js +1 -0
  83. package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
  84. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  85. package/dist/core/extensions/builtin/terminal/extension.js +32 -0
  86. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  87. package/dist/core/extensions/builtin/terminal/index.d.ts +1 -1
  88. package/dist/core/extensions/builtin/terminal/index.d.ts.map +1 -1
  89. package/dist/core/extensions/builtin/terminal/index.js +1 -1
  90. package/dist/core/extensions/builtin/terminal/index.js.map +1 -1
  91. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts +29 -0
  92. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -0
  93. package/dist/core/extensions/builtin/terminal/monitor-notify.js +185 -0
  94. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -0
  95. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +35 -0
  96. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -0
  97. package/dist/core/extensions/builtin/terminal/monitor-registry.js +98 -0
  98. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -0
  99. package/dist/core/extensions/builtin/terminal/notify.d.ts +9 -0
  100. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  101. package/dist/core/extensions/builtin/terminal/notify.js +30 -14
  102. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  103. package/dist/core/extensions/builtin/terminal/prompt.d.ts +1 -1
  104. package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
  105. package/dist/core/extensions/builtin/terminal/prompt.js +13 -5
  106. package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
  107. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +3 -12
  108. package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
  109. package/dist/core/extensions/builtin/terminal/runtime-session.js +4 -59
  110. package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
  111. package/dist/core/extensions/builtin/terminal/settings.d.ts +8 -0
  112. package/dist/core/extensions/builtin/terminal/settings.d.ts.map +1 -1
  113. package/dist/core/extensions/builtin/terminal/settings.js +16 -2
  114. package/dist/core/extensions/builtin/terminal/settings.js.map +1 -1
  115. package/dist/core/extensions/builtin/terminal/shared.d.ts +2 -2
  116. package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
  117. package/dist/core/extensions/builtin/terminal/shared.js +2 -1
  118. package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
  119. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts +10 -4
  120. package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
  121. package/dist/core/extensions/builtin/terminal/tools/bash-output.js +17 -96
  122. package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
  123. package/dist/core/extensions/builtin/terminal/tools/context.d.ts +7 -0
  124. package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
  125. package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
  126. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +41 -0
  127. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -0
  128. package/dist/core/extensions/builtin/terminal/tools/monitor.js +97 -0
  129. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -0
  130. package/dist/core/extensions/builtin/terminal/tools/render.d.ts +3 -0
  131. package/dist/core/extensions/builtin/terminal/tools/render.d.ts.map +1 -1
  132. package/dist/core/extensions/builtin/terminal/tools/render.js +5 -2
  133. package/dist/core/extensions/builtin/terminal/tools/render.js.map +1 -1
  134. package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts +19 -0
  135. package/dist/core/extensions/builtin/todotools/fuzzy-match.d.ts.map +1 -0
  136. package/dist/core/extensions/builtin/todotools/fuzzy-match.js +70 -0
  137. package/dist/core/extensions/builtin/todotools/fuzzy-match.js.map +1 -0
  138. package/dist/core/extensions/builtin/todotools/normalize.d.ts +8 -0
  139. package/dist/core/extensions/builtin/todotools/normalize.d.ts.map +1 -0
  140. package/dist/core/extensions/builtin/todotools/normalize.js +174 -0
  141. package/dist/core/extensions/builtin/todotools/normalize.js.map +1 -0
  142. package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -2
  143. package/dist/core/extensions/builtin/todotools/prompt.d.ts.map +1 -1
  144. package/dist/core/extensions/builtin/todotools/prompt.js +4 -2
  145. package/dist/core/extensions/builtin/todotools/prompt.js.map +1 -1
  146. package/dist/core/extensions/builtin/todotools/state.d.ts +9 -8
  147. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  148. package/dist/core/extensions/builtin/todotools/state.js +99 -48
  149. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  150. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts +1 -1
  151. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
  152. package/dist/core/extensions/builtin/todotools/tools/todo.js +65 -38
  153. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
  154. package/dist/core/extensions/loader.d.ts.map +1 -1
  155. package/dist/core/extensions/loader.js +12 -0
  156. package/dist/core/extensions/loader.js.map +1 -1
  157. package/dist/core/extensions/runner.d.ts +5 -0
  158. package/dist/core/extensions/runner.d.ts.map +1 -1
  159. package/dist/core/extensions/runner.js +12 -1
  160. package/dist/core/extensions/runner.js.map +1 -1
  161. package/dist/core/extensions/types.d.ts +23 -1
  162. package/dist/core/extensions/types.d.ts.map +1 -1
  163. package/dist/core/extensions/types.js.map +1 -1
  164. package/dist/core/keybindings.d.ts +0 -5
  165. package/dist/core/keybindings.d.ts.map +1 -1
  166. package/dist/core/keybindings.js +0 -2
  167. package/dist/core/keybindings.js.map +1 -1
  168. package/dist/core/messages.d.ts +32 -0
  169. package/dist/core/messages.d.ts.map +1 -1
  170. package/dist/core/messages.js +91 -0
  171. package/dist/core/messages.js.map +1 -1
  172. package/dist/core/model-resolver.d.ts +9 -1
  173. package/dist/core/model-resolver.d.ts.map +1 -1
  174. package/dist/core/model-resolver.js.map +1 -1
  175. package/dist/core/model-runtime.d.ts +2 -0
  176. package/dist/core/model-runtime.d.ts.map +1 -1
  177. package/dist/core/model-runtime.js +4 -3
  178. package/dist/core/model-runtime.js.map +1 -1
  179. package/dist/core/resource-loader.d.ts +9 -0
  180. package/dist/core/resource-loader.d.ts.map +1 -1
  181. package/dist/core/resource-loader.js +10 -2
  182. package/dist/core/resource-loader.js.map +1 -1
  183. package/dist/core/retry-fallback/cooldown.d.ts.map +1 -1
  184. package/dist/core/retry-fallback/cooldown.js +5 -0
  185. package/dist/core/retry-fallback/cooldown.js.map +1 -1
  186. package/dist/core/sdk.d.ts.map +1 -1
  187. package/dist/core/sdk.js +11 -35
  188. package/dist/core/sdk.js.map +1 -1
  189. package/dist/core/settings-manager.d.ts +5 -16
  190. package/dist/core/settings-manager.d.ts.map +1 -1
  191. package/dist/core/settings-manager.js +0 -13
  192. package/dist/core/settings-manager.js.map +1 -1
  193. package/dist/core/slash-commands.d.ts.map +1 -1
  194. package/dist/core/slash-commands.js +1 -0
  195. package/dist/core/slash-commands.js.map +1 -1
  196. package/dist/core/timings.d.ts +7 -2
  197. package/dist/core/timings.d.ts.map +1 -1
  198. package/dist/core/timings.js +11 -0
  199. package/dist/core/timings.js.map +1 -1
  200. package/dist/inspector-policy.d.ts +22 -0
  201. package/dist/inspector-policy.d.ts.map +1 -0
  202. package/dist/inspector-policy.js +84 -0
  203. package/dist/inspector-policy.js.map +1 -0
  204. package/dist/main.d.ts +6 -0
  205. package/dist/main.d.ts.map +1 -1
  206. package/dist/main.js +20 -23
  207. package/dist/main.js.map +1 -1
  208. package/dist/modes/app-server/runtime.d.ts.map +1 -1
  209. package/dist/modes/app-server/runtime.js +1 -0
  210. package/dist/modes/app-server/runtime.js.map +1 -1
  211. package/dist/modes/app-server/threads/goal-handlers.js +4 -2
  212. package/dist/modes/app-server/threads/goal-handlers.js.map +1 -1
  213. package/dist/modes/app-server/threads/goal-wire.d.ts.map +1 -1
  214. package/dist/modes/app-server/threads/goal-wire.js +1 -0
  215. package/dist/modes/app-server/threads/goal-wire.js.map +1 -1
  216. package/dist/modes/app-server/threads/handlers.d.ts +1 -0
  217. package/dist/modes/app-server/threads/handlers.d.ts.map +1 -1
  218. package/dist/modes/app-server/threads/handlers.js +2 -0
  219. package/dist/modes/app-server/threads/handlers.js.map +1 -1
  220. package/dist/modes/app-server/threads/turn-runtime.d.ts +1 -0
  221. package/dist/modes/app-server/threads/turn-runtime.d.ts.map +1 -1
  222. package/dist/modes/app-server/threads/turn-runtime.js.map +1 -1
  223. package/dist/modes/app-server/threads/turns.d.ts.map +1 -1
  224. package/dist/modes/app-server/threads/turns.js +47 -3
  225. package/dist/modes/app-server/threads/turns.js.map +1 -1
  226. package/dist/modes/interactive/components/status-indicator.d.ts +1 -0
  227. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  228. package/dist/modes/interactive/components/status-indicator.js +29 -4
  229. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  230. package/dist/modes/interactive/components/tool-execution.d.ts +5 -1
  231. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  232. package/dist/modes/interactive/components/tool-execution.js +43 -17
  233. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  234. package/dist/modes/interactive/grok/chrome-tokens.d.ts +22 -0
  235. package/dist/modes/interactive/grok/chrome-tokens.d.ts.map +1 -0
  236. package/dist/modes/interactive/grok/chrome-tokens.js +27 -0
  237. package/dist/modes/interactive/grok/chrome-tokens.js.map +1 -0
  238. package/dist/modes/interactive/grok/chrome.d.ts +51 -0
  239. package/dist/modes/interactive/grok/chrome.d.ts.map +1 -0
  240. package/dist/modes/interactive/grok/chrome.js +105 -0
  241. package/dist/modes/interactive/grok/chrome.js.map +1 -0
  242. package/dist/modes/interactive/grok/footer.d.ts +14 -0
  243. package/dist/modes/interactive/grok/footer.d.ts.map +1 -0
  244. package/dist/modes/interactive/grok/footer.js +27 -0
  245. package/dist/modes/interactive/grok/footer.js.map +1 -0
  246. package/dist/modes/interactive/grok/input-card.d.ts +9 -0
  247. package/dist/modes/interactive/grok/input-card.d.ts.map +1 -0
  248. package/dist/modes/interactive/grok/input-card.js +30 -0
  249. package/dist/modes/interactive/grok/input-card.js.map +1 -0
  250. package/dist/modes/interactive/grok/palette.d.ts +145 -0
  251. package/dist/modes/interactive/grok/palette.d.ts.map +1 -0
  252. package/dist/modes/interactive/grok/palette.js +92 -0
  253. package/dist/modes/interactive/grok/palette.js.map +1 -0
  254. package/dist/modes/interactive/grok/tool-row.d.ts +17 -0
  255. package/dist/modes/interactive/grok/tool-row.d.ts.map +1 -0
  256. package/dist/modes/interactive/grok/tool-row.js +26 -0
  257. package/dist/modes/interactive/grok/tool-row.js.map +1 -0
  258. package/dist/modes/interactive/grok/welcome-card.d.ts +10 -0
  259. package/dist/modes/interactive/grok/welcome-card.d.ts.map +1 -0
  260. package/dist/modes/interactive/grok/welcome-card.js +30 -0
  261. package/dist/modes/interactive/grok/welcome-card.js.map +1 -0
  262. package/dist/modes/interactive/interactive-mode.d.ts +5 -0
  263. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  264. package/dist/modes/interactive/interactive-mode.js +108 -52
  265. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  266. package/dist/modes/interactive/theme/grok-day.json +77 -0
  267. package/dist/modes/interactive/theme/grok-night.json +93 -0
  268. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  269. package/dist/modes/interactive/theme/theme.js +4 -0
  270. package/dist/modes/interactive/theme/theme.js.map +1 -1
  271. package/dist/modes/rpc/connection-handler.d.ts +3 -3
  272. package/dist/modes/rpc/connection-handler.js +6 -6
  273. package/dist/modes/rpc/connection-handler.js.map +1 -1
  274. package/dist/modes/rpc/custom-capability.d.ts +6 -7
  275. package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
  276. package/dist/modes/rpc/custom-capability.js +6 -7
  277. package/dist/modes/rpc/custom-capability.js.map +1 -1
  278. package/dist/modes/rpc/rpc-mode.d.ts +2 -2
  279. package/dist/modes/rpc/rpc-mode.js +5 -5
  280. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  281. package/dist/senpi +2 -0
  282. package/docs/docs.json +4 -0
  283. package/docs/environment-variables.md +1 -0
  284. package/docs/grok-neo.md +77 -0
  285. package/docs/keybindings.md +0 -1
  286. package/docs/settings.md +3 -3
  287. package/docs/terminal-tools.md +6 -3
  288. package/docs/usage.md +1 -1
  289. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +35 -0
  290. package/node_modules/@code-yeongyu/senpi-codemode/README.md +39 -19
  291. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  292. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/http-server.ts +6 -1
  293. package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/output-bridge.ts +0 -1
  294. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/eval-notifier.ts +40 -0
  295. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +46 -66
  296. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +5 -2
  297. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +2 -0
  298. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +19 -4
  299. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +7 -0
  300. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +8 -5
  301. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +23 -5
  302. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +322 -0
  303. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +253 -18
  304. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/interrupt-note.ts +58 -0
  305. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +28 -6
  306. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/status-events.ts +20 -0
  307. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +65 -22
  308. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  309. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +4 -41
  310. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  311. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +3 -0
  312. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  313. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
  314. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  315. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +10 -0
  316. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -0
  317. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +38 -0
  318. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -0
  319. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +5 -0
  320. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  321. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  322. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  323. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  324. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +135 -16
  325. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  326. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +1 -1
  327. package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
  328. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  329. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +1 -4
  330. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
  331. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts.map +1 -1
  332. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js +4 -3
  333. package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js.map +1 -1
  334. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +2 -2
  335. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  336. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +1 -0
  337. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  338. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +67 -31
  339. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  340. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -1
  341. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  342. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  343. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  344. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  345. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +10 -0
  346. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  347. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts +1 -1
  348. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts.map +1 -1
  349. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js +7 -3
  350. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js.map +1 -1
  351. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts +9 -0
  352. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.d.ts.map +1 -0
  353. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js +16 -0
  354. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-call-id.js.map +1 -0
  355. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  356. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  357. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +1 -0
  358. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -1
  359. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +35 -3
  360. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -1
  361. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +6 -0
  362. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  363. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  364. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +32 -0
  365. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +1 -1
  366. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +15 -7
  367. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +1 -1
  368. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  369. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  370. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  371. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  372. package/package.json +8 -8
  373. package/dist/cli/neo/build-argv.d.ts +0 -19
  374. package/dist/cli/neo/build-argv.d.ts.map +0 -1
  375. package/dist/cli/neo/build-argv.js +0 -84
  376. package/dist/cli/neo/build-argv.js.map +0 -1
  377. package/dist/cli/neo/daemon-launch.d.ts +0 -25
  378. package/dist/cli/neo/daemon-launch.d.ts.map +0 -1
  379. package/dist/cli/neo/daemon-launch.js +0 -97
  380. package/dist/cli/neo/daemon-launch.js.map +0 -1
  381. package/dist/cli/neo/gate.d.ts +0 -15
  382. package/dist/cli/neo/gate.d.ts.map +0 -1
  383. package/dist/cli/neo/gate.js +0 -21
  384. package/dist/cli/neo/gate.js.map +0 -1
  385. package/dist/cli/neo/launch.d.ts +0 -24
  386. package/dist/cli/neo/launch.d.ts.map +0 -1
  387. package/dist/cli/neo/launch.js +0 -66
  388. package/dist/cli/neo/launch.js.map +0 -1
  389. package/dist/cli/neo/platform.d.ts +0 -38
  390. package/dist/cli/neo/platform.d.ts.map +0 -1
  391. package/dist/cli/neo/platform.js +0 -54
  392. package/dist/cli/neo/platform.js.map +0 -1
  393. package/dist/cli/neo/resolve-binary.d.ts +0 -39
  394. package/dist/cli/neo/resolve-binary.d.ts.map +0 -1
  395. package/dist/cli/neo/resolve-binary.js +0 -66
  396. package/dist/cli/neo/resolve-binary.js.map +0 -1
  397. package/dist/core/extensions/builtin/session-observer/index.d.ts +0 -5
  398. package/dist/core/extensions/builtin/session-observer/index.d.ts.map +0 -1
  399. package/dist/core/extensions/builtin/session-observer/index.js +0 -36
  400. package/dist/core/extensions/builtin/session-observer/index.js.map +0 -1
  401. package/dist/core/extensions/builtin/session-observer/loader.d.ts +0 -3
  402. package/dist/core/extensions/builtin/session-observer/loader.d.ts.map +0 -1
  403. package/dist/core/extensions/builtin/session-observer/loader.js +0 -20
  404. package/dist/core/extensions/builtin/session-observer/loader.js.map +0 -1
  405. package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts +0 -7
  406. package/dist/core/extensions/builtin/session-observer/overlay-format.d.ts.map +0 -1
  407. package/dist/core/extensions/builtin/session-observer/overlay-format.js +0 -30
  408. package/dist/core/extensions/builtin/session-observer/overlay-format.js.map +0 -1
  409. package/dist/core/extensions/builtin/session-observer/overlay.d.ts +0 -51
  410. package/dist/core/extensions/builtin/session-observer/overlay.d.ts.map +0 -1
  411. package/dist/core/extensions/builtin/session-observer/overlay.js +0 -229
  412. package/dist/core/extensions/builtin/session-observer/overlay.js.map +0 -1
  413. package/dist/core/extensions/builtin/session-observer/scanner.d.ts +0 -10
  414. package/dist/core/extensions/builtin/session-observer/scanner.d.ts.map +0 -1
  415. package/dist/core/extensions/builtin/session-observer/scanner.js +0 -142
  416. package/dist/core/extensions/builtin/session-observer/scanner.js.map +0 -1
  417. package/dist/core/extensions/builtin/session-observer/text.d.ts +0 -7
  418. package/dist/core/extensions/builtin/session-observer/text.d.ts.map +0 -1
  419. package/dist/core/extensions/builtin/session-observer/text.js +0 -37
  420. package/dist/core/extensions/builtin/session-observer/text.js.map +0 -1
  421. package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts +0 -7
  422. package/dist/core/extensions/builtin/session-observer/transcript-entries.d.ts.map +0 -1
  423. package/dist/core/extensions/builtin/session-observer/transcript-entries.js +0 -71
  424. package/dist/core/extensions/builtin/session-observer/transcript-entries.js.map +0 -1
  425. package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts +0 -11
  426. package/dist/core/extensions/builtin/session-observer/transcript-format.d.ts.map +0 -1
  427. package/dist/core/extensions/builtin/session-observer/transcript-format.js +0 -65
  428. package/dist/core/extensions/builtin/session-observer/transcript-format.js.map +0 -1
  429. package/dist/core/extensions/builtin/session-observer/transcript.d.ts +0 -4
  430. package/dist/core/extensions/builtin/session-observer/transcript.d.ts.map +0 -1
  431. package/dist/core/extensions/builtin/session-observer/transcript.js +0 -81
  432. package/dist/core/extensions/builtin/session-observer/transcript.js.map +0 -1
  433. package/dist/core/extensions/builtin/session-observer/types.d.ts +0 -33
  434. package/dist/core/extensions/builtin/session-observer/types.d.ts.map +0 -1
  435. package/dist/core/extensions/builtin/session-observer/types.js +0 -2
  436. package/dist/core/extensions/builtin/session-observer/types.js.map +0 -1
  437. package/dist/modes/rpc/neo-daemon-child-worker.d.ts +0 -29
  438. package/dist/modes/rpc/neo-daemon-child-worker.d.ts.map +0 -1
  439. package/dist/modes/rpc/neo-daemon-child-worker.js +0 -95
  440. package/dist/modes/rpc/neo-daemon-child-worker.js.map +0 -1
  441. package/dist/modes/rpc/neo-daemon-mode.d.ts +0 -110
  442. package/dist/modes/rpc/neo-daemon-mode.d.ts.map +0 -1
  443. package/dist/modes/rpc/neo-daemon-mode.js +0 -267
  444. package/dist/modes/rpc/neo-daemon-mode.js.map +0 -1
  445. package/dist/modes/rpc/neo-daemon-protocol.d.ts +0 -50
  446. package/dist/modes/rpc/neo-daemon-protocol.d.ts.map +0 -1
  447. package/dist/modes/rpc/neo-daemon-protocol.js +0 -66
  448. package/dist/modes/rpc/neo-daemon-protocol.js.map +0 -1
  449. package/dist/modes/rpc/neo-daemon-registry.d.ts +0 -98
  450. package/dist/modes/rpc/neo-daemon-registry.d.ts.map +0 -1
  451. package/dist/modes/rpc/neo-daemon-registry.js +0 -209
  452. package/dist/modes/rpc/neo-daemon-registry.js.map +0 -1
  453. package/dist/modes/rpc/neo-runtime-options-argv.d.ts +0 -17
  454. package/dist/modes/rpc/neo-runtime-options-argv.d.ts.map +0 -1
  455. package/dist/modes/rpc/neo-runtime-options-argv.js +0 -79
  456. package/dist/modes/rpc/neo-runtime-options-argv.js.map +0 -1
  457. package/dist/modes/rpc/neo-runtime-options.d.ts +0 -84
  458. package/dist/modes/rpc/neo-runtime-options.d.ts.map +0 -1
  459. package/dist/modes/rpc/neo-runtime-options.js +0 -92
  460. package/dist/modes/rpc/neo-runtime-options.js.map +0 -1
  461. package/docs/neo.md +0 -111
  462. package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/runtime.ts +0 -258
  463. package/node_modules/@code-yeongyu/senpi-codemode/src/codemode/tools.ts +0 -106
@@ -46,6 +46,7 @@ import { generateSessionTitle, shouldSkipSessionTitle } from "./session-title-ge
46
46
  import { SessionWorkBarrier } from "./session-work-barrier.js";
47
47
  import { createSyntheticSourceInfo } from "./source-info.js";
48
48
  import { getSupportedThinkingLevels, supportsMax, supportsXhigh } from "./thinking-levels.js";
49
+ import { resetTimings, time } from "./timings.js";
49
50
  import { createLocalBashOperations } from "./tools/bash.js";
50
51
  import { createAllToolDefinitions } from "./tools/index.js";
51
52
  import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
@@ -169,6 +170,8 @@ function isSameOverflowSource(message, model, upstreamModelId) {
169
170
  // ============================================================================
170
171
  /** Thinking levels including native max (Opus 4.6 legacy / Opus 4.7 native). */
171
172
  const THINKING_LEVELS_WITH_MAX = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
173
+ /** Caps explicit skill expansion so one prompt cannot consume unbounded context. */
174
+ export const MAX_SKILL_EXPANSIONS_PER_PROMPT = 5;
172
175
  // ============================================================================
173
176
  // AgentSession Class
174
177
  // ============================================================================
@@ -221,6 +224,7 @@ export class AgentSession {
221
224
  this._retryPromise = undefined;
222
225
  this._retryResolve = undefined;
223
226
  this._userAbortPromise = undefined;
227
+ this._agentAbortSource = undefined;
224
228
  this._suppressQueuedContinuationAfterUserAbort = false;
225
229
  this._extensionEventSignal = undefined;
226
230
  // Bash execution state
@@ -854,7 +858,10 @@ export class AgentSession {
854
858
  if (providerDelayMs === undefined) {
855
859
  return true;
856
860
  }
857
- return providerDelayMs <= this.settingsManager.getProviderRetrySettings().maxRetryDelayMs;
861
+ if (providerDelayMs <= this.settingsManager.getProviderRetrySettings().maxRetryDelayMs) {
862
+ return true;
863
+ }
864
+ return this._retryFallback.canTryFallback();
858
865
  }
859
866
  async _processAgentEvent(event, signal) {
860
867
  // When a user message starts, check if it's from either queue and remove it BEFORE emitting
@@ -1093,7 +1100,19 @@ export class AgentSession {
1093
1100
  await this._extensionRunner.emit({ type: "agent_start" });
1094
1101
  }
1095
1102
  else if (event.type === "agent_end") {
1096
- await this._extensionRunner.emit({ type: "agent_end", messages: event.messages });
1103
+ const abortSource = this._agentAbortSource;
1104
+ const aborted = abortSource !== undefined || this._findLastAssistantInMessages(event.messages)?.stopReason === "aborted";
1105
+ try {
1106
+ await this._extensionRunner.emit({
1107
+ type: "agent_end",
1108
+ messages: event.messages,
1109
+ ...(aborted ? { aborted: true } : {}),
1110
+ ...(abortSource === undefined ? {} : { abortSource }),
1111
+ });
1112
+ }
1113
+ finally {
1114
+ this._agentAbortSource = undefined;
1115
+ }
1097
1116
  }
1098
1117
  else if (event.type === "turn_start") {
1099
1118
  const extensionEvent = {
@@ -1831,34 +1850,63 @@ export class AgentSession {
1831
1850
  }
1832
1851
  }
1833
1852
  /**
1834
- * Expand skill commands (/skill:name args) to their full content.
1835
- * Returns the expanded text, or the original text if not a skill command or skill not found.
1836
- * Emits errors via extension runner if file read fails.
1853
+ * Expand a leading run of skill commands (/skill:name /skill:other args) to their full content.
1854
+ * Returns the expanded text, or the original text if the first skill command is not found.
1855
+ * Emits errors via extension runner if file reads fail or the expansion cap is reached.
1837
1856
  */
1838
1857
  _expandSkillCommand(text) {
1839
1858
  if (!text.startsWith("/skill:"))
1840
1859
  return text;
1841
- const spaceIndex = text.indexOf(" ");
1842
- const skillName = spaceIndex === -1 ? text.slice(7) : text.slice(7, spaceIndex);
1843
- const args = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1).trim();
1844
- const skill = this.resourceLoader.getSkills().skills.find((s) => s.name === skillName);
1845
- if (!skill)
1846
- return text; // Unknown skill, pass through
1847
- try {
1848
- const content = readFileSync(skill.filePath, "utf-8");
1849
- const body = stripFrontmatter(content).trim();
1850
- const skillBlock = `<skill name="${skill.name}" location="${skill.filePath}">\nReferences are relative to ${skill.baseDir}.\n\n${body}\n</skill>`;
1851
- return args ? `${skillBlock}\n\n${args}` : skillBlock;
1852
- }
1853
- catch (err) {
1854
- // Emit error like extension commands do
1855
- this._extensionRunner.emitError({
1856
- extensionPath: skill.filePath,
1857
- event: "skill_expansion",
1858
- error: err instanceof Error ? err.message : String(err),
1859
- });
1860
- return text; // Return original on error
1860
+ const skills = this.resourceLoader.getSkills().skills;
1861
+ const expandedSkillNames = new Set();
1862
+ const skillBlocks = [];
1863
+ let tokenStart = 0;
1864
+ while (tokenStart < text.length) {
1865
+ let tokenEnd = tokenStart;
1866
+ while (tokenEnd < text.length && !/\s/.test(text[tokenEnd])) {
1867
+ tokenEnd += 1;
1868
+ }
1869
+ const token = text.slice(tokenStart, tokenEnd);
1870
+ if (!token.startsWith("/skill:"))
1871
+ break;
1872
+ const skillName = token.slice(7);
1873
+ const skill = skills.find((candidate) => candidate.name === skillName);
1874
+ if (!skill)
1875
+ break; // Unknown skills and everything after them remain literal text.
1876
+ if (!expandedSkillNames.has(skill.name)) {
1877
+ if (skillBlocks.length >= MAX_SKILL_EXPANSIONS_PER_PROMPT) {
1878
+ this._extensionRunner.emitError({
1879
+ extensionPath: "skill:expansion",
1880
+ event: "skill_expansion",
1881
+ error: `Expanded at most ${MAX_SKILL_EXPANSIONS_PER_PROMPT} skills; remaining skill commands were left as literal text.`,
1882
+ });
1883
+ break;
1884
+ }
1885
+ try {
1886
+ const content = readFileSync(skill.filePath, "utf-8");
1887
+ const body = stripFrontmatter(content).trim();
1888
+ skillBlocks.push(`<skill name="${skill.name}" location="${skill.filePath}">\nReferences are relative to ${skill.baseDir}.\n\n${body}\n</skill>`);
1889
+ expandedSkillNames.add(skill.name);
1890
+ }
1891
+ catch (err) {
1892
+ this._extensionRunner.emitError({
1893
+ extensionPath: skill.filePath,
1894
+ event: "skill_expansion",
1895
+ error: err instanceof Error ? err.message : String(err),
1896
+ });
1897
+ return text; // Return the original prompt when any skill file cannot be read.
1898
+ }
1899
+ }
1900
+ tokenStart = tokenEnd;
1901
+ while (tokenStart < text.length && /\s/.test(text[tokenStart])) {
1902
+ tokenStart += 1;
1903
+ }
1861
1904
  }
1905
+ if (skillBlocks.length === 0)
1906
+ return text;
1907
+ const args = text.slice(tokenStart).trim();
1908
+ const expandedSkills = skillBlocks.join("\n\n");
1909
+ return args ? `${expandedSkills}\n\n${args}` : expandedSkills;
1862
1910
  }
1863
1911
  /**
1864
1912
  * Queue a steering message while the agent is running.
@@ -2095,6 +2143,9 @@ export class AgentSession {
2095
2143
  /**
2096
2144
  * Send a user message to the agent. Always triggers a turn.
2097
2145
  * When the agent is streaming, use deliverAs to specify how to queue the message.
2146
+ * If the prompt path rejects before the message reaches a queue or a turn
2147
+ * (e.g. a required compaction that cannot complete), the message is retained
2148
+ * in the steering/followUp queue for later delivery and the error still propagates.
2098
2149
  *
2099
2150
  * @param content User message content (string or content array)
2100
2151
  * @param options.deliverAs Delivery mode when streaming: "steer" or "followUp"
@@ -2134,6 +2185,7 @@ export class AgentSession {
2134
2185
  // settles so callers observing session idle cannot race its provider turn.
2135
2186
  const waitForExistingSessionWork = this._sessionWorkBarrier.hasActiveWork;
2136
2187
  let finishSessionWork;
2188
+ let disposition;
2137
2189
  try {
2138
2190
  // Use prompt() with expandPromptTemplates: false to skip command handling and template expansion
2139
2191
  await this.prompt(text, {
@@ -2141,7 +2193,10 @@ export class AgentSession {
2141
2193
  streamingBehavior: options?.deliverAs,
2142
2194
  images,
2143
2195
  source: "extension",
2144
- promptDisposition: () => resolveBindingPromptReadiness?.(),
2196
+ promptDisposition: (nextDisposition) => {
2197
+ disposition = nextDisposition;
2198
+ resolveBindingPromptReadiness?.();
2199
+ },
2145
2200
  onSessionWorkReady: waitForExistingSessionWork
2146
2201
  ? () => {
2147
2202
  finishSessionWork ??= this._sessionWorkBarrier.begin();
@@ -2150,6 +2205,19 @@ export class AgentSession {
2150
2205
  sessionTitlePrompt: false,
2151
2206
  });
2152
2207
  }
2208
+ catch (error) {
2209
+ // Extension bindings invoke this method fire-and-forget, so a rejection
2210
+ // before prompt() accepted the message must not silently drop it.
2211
+ if (disposition === undefined) {
2212
+ if (options?.deliverAs === "steer") {
2213
+ await this._queueSteer(text, images);
2214
+ }
2215
+ else {
2216
+ await this._queueFollowUp(text, images);
2217
+ }
2218
+ }
2219
+ throw error;
2220
+ }
2153
2221
  finally {
2154
2222
  resolveBindingPromptReadiness?.();
2155
2223
  finishSessionWork?.();
@@ -2194,7 +2262,7 @@ export class AgentSession {
2194
2262
  */
2195
2263
  async abort() {
2196
2264
  this.abortCompaction();
2197
- await this._abortActiveAgentAndRetry();
2265
+ await this._abortActiveAgentAndRetry("user");
2198
2266
  }
2199
2267
  async waitForIdle() {
2200
2268
  if (this.isIdle) {
@@ -2562,7 +2630,7 @@ export class AgentSession {
2562
2630
  this._pendingCompactionAdmission = undefined;
2563
2631
  admission.finishSessionWork();
2564
2632
  }
2565
- async _abortActiveAgentAndRetry() {
2633
+ async _abortActiveAgentAndRetry(source) {
2566
2634
  this.abortRetry();
2567
2635
  this.abortBranchSummary();
2568
2636
  if (this._userAbortPromise) {
@@ -2572,6 +2640,7 @@ export class AgentSession {
2572
2640
  }
2573
2641
  if (this.isStreaming) {
2574
2642
  this._suppressQueuedContinuationAfterUserAbort = true;
2643
+ this._agentAbortSource = source;
2575
2644
  }
2576
2645
  const abortPromise = (async () => {
2577
2646
  this.agent.abort();
@@ -2601,7 +2670,7 @@ export class AgentSession {
2601
2670
  // Keep the session subscriber attached until the aborted run emits
2602
2671
  // agent_end. That event clears the active-run and retry state that
2603
2672
  // waitForIdle() depends on.
2604
- await this._abortActiveAgentAndRetry();
2673
+ await this._abortActiveAgentAndRetry("system");
2605
2674
  this._disconnectFromAgent();
2606
2675
  disconnected = true;
2607
2676
  this._emit({ type: "compaction_start", reason: "manual" });
@@ -3374,13 +3443,21 @@ export class AgentSession {
3374
3443
  this._claimCompactionController(autoCompactionController, "auto");
3375
3444
  const endBeforeExecution = () => {
3376
3445
  this._emit({ type: "compaction_start", reason });
3377
- if (reason === "overflow")
3446
+ if (reason === "overflow" && this._autoCompactionAbortController === autoCompactionController) {
3378
3447
  this._overflowRecoveryAttempted = false;
3448
+ }
3449
+ // A synchronous compaction_start listener can supersede this controller with a new
3450
+ // operation, which then owns its own start/end lifecycle; publishing another terminal
3451
+ // event here would be stale. A listener can instead abort this very controller, and
3452
+ // that still needs a terminal event: consumers open UI state on compaction_start and
3453
+ // close it only on compaction_end.
3454
+ if (this._autoCompactionAbortController !== autoCompactionController)
3455
+ return false;
3379
3456
  this._emit({
3380
3457
  type: "compaction_end",
3381
3458
  reason,
3382
3459
  result: undefined,
3383
- aborted: false,
3460
+ aborted: autoCompactionController.signal.aborted,
3384
3461
  willRetry: false,
3385
3462
  });
3386
3463
  return false;
@@ -3646,6 +3723,9 @@ export class AgentSession {
3646
3723
  getAllTools: () => this.getAllTools(),
3647
3724
  setActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),
3648
3725
  refreshTools: () => this._refreshToolRegistry(),
3726
+ registerRemovedToolHint: (name, hint) => {
3727
+ this.agent.removedToolHints[name] = hint;
3728
+ },
3649
3729
  getCommands,
3650
3730
  setModel: async (model) => {
3651
3731
  if (!this._modelRuntime.hasConfiguredAuth(model.provider))
@@ -3725,7 +3805,7 @@ export class AgentSession {
3725
3805
  let outcome = "failed";
3726
3806
  let disconnected = false;
3727
3807
  try {
3728
- await this._abortActiveAgentAndRetry();
3808
+ await this._abortActiveAgentAndRetry("system");
3729
3809
  this._disconnectFromAgent();
3730
3810
  disconnected = true;
3731
3811
  this._emit({ type: "compaction_start", reason: "extension" });
@@ -3923,22 +4003,49 @@ export class AgentSession {
3923
4003
  });
3924
4004
  }
3925
4005
  async reload(options) {
3926
- const previousFlagValues = this._extensionRunner.getFlagValues();
3927
- await emitSessionShutdownEvent(this._extensionRunner, { type: "session_shutdown", reason: "reload" });
4006
+ resetTimings("reload");
4007
+ const oldExtensionRunner = this._extensionRunner;
4008
+ const oldExtensionIdentities = oldExtensionRunner.getExtensionIdentities();
4009
+ const previousFlagValues = oldExtensionRunner.getFlagValues();
4010
+ await emitSessionShutdownEvent(oldExtensionRunner, { type: "session_shutdown", reason: "reload" });
4011
+ time("shutdown", "reload");
3928
4012
  await this.settingsManager.reload();
3929
4013
  this.syncQueueModesFromSettings();
3930
4014
  resetApiProviders();
4015
+ time("settings", "reload");
3931
4016
  await this._modelRuntime.reloadConfig();
4017
+ // Resolving both scopes from the completed refresh avoids two extra availability
4018
+ // scans, but only a snapshot from a SUCCESSFUL refresh may be trusted: refresh()
4019
+ // swallows availability errors, so a failed scan must fall back to the runtime and
4020
+ // keep the previous refresh-and-surface-the-error behavior.
4021
+ const refreshedModels = this._modelRuntime.hasFreshAvailabilitySnapshot()
4022
+ ? { getAvailable: async () => this._modelRuntime.getAvailableSnapshot() }
4023
+ : this._modelRuntime;
3932
4024
  this.setScopedModels(await resolveModelScope(getModelNarrowingPatterns({
3933
4025
  legacyEnabledPatterns: this.settingsManager.getEnabledModels(),
3934
- }), this._modelRuntime));
3935
- this.setFavoriteModels(await resolveModelScope(this.settingsManager.getFavoriteModels() ?? [], this._modelRuntime));
3936
- await this._resourceLoader.reload();
3937
- this._buildRuntime({
3938
- activeToolNames: this.getActiveToolNames(),
3939
- flagValues: previousFlagValues,
3940
- includeAllExtensionTools: true,
3941
- });
4026
+ }), refreshedModels));
4027
+ this.setFavoriteModels(await resolveModelScope(this.settingsManager.getFavoriteModels() ?? [], refreshedModels));
4028
+ time("models", "reload");
4029
+ await this._resourceLoader.reload({ settingsAlreadyReloadedFor: this.settingsManager });
4030
+ time("resources", "reload");
4031
+ try {
4032
+ this._buildRuntime({
4033
+ activeToolNames: this.getActiveToolNames(),
4034
+ flagValues: previousFlagValues,
4035
+ includeAllExtensionTools: true,
4036
+ });
4037
+ }
4038
+ finally {
4039
+ // An extension removed by this reload must be told even if the rebuild throws
4040
+ // (e.g. _refreshToolRegistry rejecting an extension's tool metadata): the new
4041
+ // runner is already installed without it, so nothing else would dispose it.
4042
+ const newExtensionResolvedPaths = new Set(this._extensionRunner.getExtensionIdentities().map((extension) => extension.resolvedPath));
4043
+ const removed = oldExtensionIdentities.filter((extension) => !newExtensionResolvedPaths.has(extension.resolvedPath));
4044
+ if (removed.length > 0) {
4045
+ await oldExtensionRunner.emit({ type: "session_extensions_removed", reason: "reload", removed });
4046
+ }
4047
+ time("runtime", "reload");
4048
+ }
3942
4049
  const hasBindings = this._extensionUIContext ||
3943
4050
  this._extensionCommandContextActions ||
3944
4051
  this._extensionShutdownHandler ||
@@ -3948,6 +4055,7 @@ export class AgentSession {
3948
4055
  await this._extensionRunner.emit({ type: "session_start", reason: "reload" });
3949
4056
  await this.extendResourcesFromExtensions("reload");
3950
4057
  }
4058
+ time("lifecycle", "reload");
3951
4059
  }
3952
4060
  // =========================================================================
3953
4061
  // Auto-Retry
@@ -4116,22 +4224,36 @@ export class AgentSession {
4116
4224
  const providerDelayMs = isRefusal || hardErrorFallback ? undefined : this._getProviderRetryDelayMs(errorMessage);
4117
4225
  const maxRetryDelayMs = this.settingsManager.getProviderRetrySettings().maxRetryDelayMs;
4118
4226
  if (providerDelayMs !== undefined && providerDelayMs > maxRetryDelayMs) {
4119
- this._emit({
4120
- type: "auto_retry_end",
4121
- success: false,
4122
- attempt: this._retryAttempt,
4123
- finalError: `Provider requested retry delay ${providerDelayMs}ms, exceeding configured maximum ${maxRetryDelayMs}ms`,
4124
- });
4125
- this._retryAttempt = 0;
4126
- this._resolveRetry();
4127
- return "not-handled";
4128
- }
4129
- if (!switchedFallback) {
4130
- switchedFallback = await this._retryFallback.tryFallback("transient", {
4131
- errorMessage,
4132
- retryAfterMs: providerDelayMs,
4133
- });
4227
+ // A wait this long means the model is unavailable rather than busy, so the
4228
+ // configured chain beats failing the turn. The switch is gated: the over-budget
4229
+ // branch above may have already switched on this same error, and hopping again
4230
+ // here would skip that candidate's own retry budget.
4231
+ if (!switchedFallback) {
4232
+ switchedFallback = await this._retryFallback.tryFallback("transient", {
4233
+ errorMessage,
4234
+ retryAfterMs: providerDelayMs,
4235
+ });
4236
+ if (switchedFallback) {
4237
+ this._retryAttempt = 1;
4238
+ }
4239
+ }
4240
+ if (!switchedFallback) {
4241
+ this._emit({
4242
+ type: "auto_retry_end",
4243
+ success: false,
4244
+ attempt: this._retryAttempt,
4245
+ finalError: `Provider requested retry delay ${providerDelayMs}ms, exceeding configured maximum ${maxRetryDelayMs}ms`,
4246
+ });
4247
+ this._retryAttempt = 0;
4248
+ this._resolveRetry();
4249
+ return "not-handled";
4250
+ }
4134
4251
  }
4252
+ // Transient failures stay on the same model until the retry budget is spent;
4253
+ // only the over-budget branch above switches the chain. Both branches that can
4254
+ // reach this point with a fallback already applied (hard-error, refusal) set
4255
+ // switchedFallback first and force providerDelayMs undefined, so no branch may
4256
+ // be reordered to fall through here expecting an implicit switch.
4135
4257
  const delayMs = switchedFallback ? 0 : (providerDelayMs ?? settings.baseDelayMs * 2 ** (this._retryAttempt - 1));
4136
4258
  // Prepare before auto_retry_start so an immediate Esc can cancel the retry sleep.
4137
4259
  this._retryAbortController = new AbortController();