@code-yeongyu/senpi 2026.9.23-5 → 2026.9.24-2

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 (315) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/bundle/chunks/{anthropic-messages-77YBORJ5.js → anthropic-messages-UPLQFNTT.js} +2 -2
  3. package/dist/bundle/chunks/{app-server-command-BGT65PGC.js → app-server-command-UHPJ2C4D.js} +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-PSESFNHN.js → azure-openai-responses-XAR2E66I.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-WXIRFRXY.js → chunk-2PLPSKHD.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-7PANH3NB.js → chunk-3WBSBDBX.js} +1 -1
  7. package/dist/bundle/chunks/{chunk-BBOQ5H4W.js → chunk-6WBYI25N.js} +1 -1
  8. package/dist/bundle/chunks/{chunk-RG3UEFSF.js → chunk-7DY7UYLL.js} +1 -1
  9. package/dist/bundle/chunks/{chunk-VKBY4F76.js → chunk-BSOJHK4W.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-3XHWW7SQ.js → chunk-CLZVNQW3.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-ORCF262V.js → chunk-EJKCBRYK.js} +3 -3
  12. package/dist/bundle/chunks/chunk-J7IUURQ6.js +8 -0
  13. package/dist/bundle/chunks/{chunk-PSMTQDII.js → chunk-JRQSHZPP.js} +15 -9
  14. package/dist/bundle/chunks/{chunk-DUV3UFKX.js → chunk-MKAM7IRH.js} +1 -1
  15. package/dist/bundle/chunks/chunk-MO2U7YRX.js +11 -0
  16. package/dist/bundle/chunks/{chunk-ZEFQYQOU.js → chunk-NGHOUIPR.js} +1 -1
  17. package/dist/bundle/chunks/{chunk-XDSQYM4F.js → chunk-NKVUDCGZ.js} +2 -2
  18. package/dist/bundle/chunks/{chunk-J3QXPP4T.js → chunk-ONR57UMO.js} +1 -1
  19. package/dist/bundle/chunks/{chunk-TQDWU3ZQ.js → chunk-SYQVC7UM.js} +1 -1
  20. package/dist/bundle/chunks/chunk-TTHMOL5G.js +2 -0
  21. package/dist/bundle/chunks/{chunk-NNHFMZD5.js → chunk-UBPMXBOJ.js} +1 -1
  22. package/dist/bundle/chunks/chunk-WASCMT6Y.js +2 -0
  23. package/dist/bundle/chunks/{chunk-EN6KDFY2.js → chunk-WISJJQ4K.js} +1 -1
  24. package/dist/bundle/chunks/{chunk-IVYZMSFY.js → chunk-WL5EQYNL.js} +1 -1
  25. package/dist/bundle/chunks/{chunk-LC6SZTVE.js → chunk-WTSAB6AE.js} +1 -1
  26. package/dist/bundle/chunks/{chunk-HKE42SWX.js → chunk-Y54V65MS.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-3RN6BFG2.js → chunk-YBC274GY.js} +4 -4
  28. package/dist/bundle/chunks/{chunk-RRSND33J.js → chunk-YKU45B65.js} +54 -54
  29. package/dist/bundle/chunks/{chunk-WUYBEF7C.js → chunk-YWO3OBYK.js} +1 -1
  30. package/dist/bundle/chunks/cli-main-O5Y3TBID.js +3 -0
  31. package/dist/bundle/chunks/{google-generative-ai-YJHSZAY5.js → google-generative-ai-B5QMFONL.js} +1 -1
  32. package/dist/bundle/chunks/{google-vertex-JTFWEDNJ.js → google-vertex-O2TGMVWF.js} +1 -1
  33. package/dist/bundle/chunks/{help-fast-path-QXVCHTP3.js → help-fast-path-Y33OIZBU.js} +1 -1
  34. package/dist/bundle/chunks/{host-command-3PUZYQOK.js → host-command-WJOL27Q7.js} +1 -1
  35. package/dist/bundle/chunks/{host-lifecycle-OHPSU5VU.js → host-lifecycle-YBFXYFZP.js} +1 -1
  36. package/dist/bundle/chunks/{interactive-host-runtime-57LEAJPU.js → interactive-host-runtime-XVTF3NUD.js} +1 -1
  37. package/dist/bundle/chunks/interactive-mode-OO3NGM4G.js +2 -0
  38. package/dist/bundle/chunks/{list-tips-Z62FXPOJ.js → list-tips-EBRNBPBM.js} +1 -1
  39. package/dist/bundle/chunks/{mistral-conversations-VJPMPQ5T.js → mistral-conversations-AS3SAWPA.js} +1 -1
  40. package/dist/bundle/chunks/{multi-session-host-GFSDQQUJ.js → multi-session-host-6MKBBOKF.js} +1 -1
  41. package/dist/bundle/chunks/{openai-codex-responses-IQ35QACK.js → openai-codex-responses-CK7T4WNM.js} +1 -1
  42. package/dist/bundle/chunks/{openai-completions-74OLE55U.js → openai-completions-OPQKN7FH.js} +3 -3
  43. package/dist/bundle/chunks/openai-responses-QHWM3KPO.js +2 -0
  44. package/dist/bundle/chunks/{openrouter-images-T4GY3JYM.js → openrouter-images-MW5TXV7L.js} +1 -1
  45. package/dist/bundle/chunks/{package-manager-cli-J7244EJE.js → package-manager-cli-BMEWLAI2.js} +1 -1
  46. package/dist/bundle/chunks/{rotation-stream-CZT4TRPD.js → rotation-stream-ZFA6ELXJ.js} +1 -1
  47. package/dist/bundle/chunks/{rpc-mode-75CRTY24.js → rpc-mode-5653CV65.js} +1 -1
  48. package/dist/bundle/chunks/{session-picker-ZIBANFBQ.js → session-picker-PPYK56TA.js} +1 -1
  49. package/dist/bundle/chunks/session-worker.js +265 -259
  50. package/dist/bundle/cli.js +1 -1
  51. package/dist/bundle/index.js +1 -1
  52. package/dist/bundle/rpc-entry.js +1 -1
  53. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  54. package/dist/core/agent-session-runtime.js +13 -0
  55. package/dist/core/agent-session-runtime.js.map +1 -1
  56. package/dist/core/agent-session.d.ts +28 -0
  57. package/dist/core/agent-session.d.ts.map +1 -1
  58. package/dist/core/agent-session.js +75 -12
  59. package/dist/core/agent-session.js.map +1 -1
  60. package/dist/core/dynamic-prompt/build.d.ts +6 -1
  61. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  62. package/dist/core/dynamic-prompt/build.js +0 -7
  63. package/dist/core/dynamic-prompt/build.js.map +1 -1
  64. package/dist/core/environment-context.d.ts +32 -0
  65. package/dist/core/environment-context.d.ts.map +1 -0
  66. package/dist/core/environment-context.js +63 -0
  67. package/dist/core/environment-context.js.map +1 -0
  68. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.js +1 -15
  70. package/dist/core/extensions/builtin/anthropic-subscription/session-sync.js.map +1 -1
  71. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +3 -0
  72. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
  73. package/dist/core/extensions/builtin/goal/cache-warm.d.ts +19 -2
  74. package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
  75. package/dist/core/extensions/builtin/goal/cache-warm.js +28 -2
  76. package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
  77. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  78. package/dist/core/extensions/builtin/goal/monitor-continuation.js +4 -2
  79. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  80. package/dist/core/extensions/builtin/goal/parked-wait.js +2 -0
  81. package/dist/core/extensions/builtin/goal/parked-wait.js.map +1 -1
  82. package/dist/core/extensions/builtin/goal/prompt.js +1 -1
  83. package/dist/core/extensions/builtin/goal/prompt.js.map +1 -1
  84. package/dist/core/extensions/builtin/herdr/herdr-state.d.ts +5 -0
  85. package/dist/core/extensions/builtin/herdr/herdr-state.d.ts.map +1 -1
  86. package/dist/core/extensions/builtin/herdr/herdr-state.js +28 -3
  87. package/dist/core/extensions/builtin/herdr/herdr-state.js.map +1 -1
  88. package/dist/core/extensions/builtin/herdr/index.d.ts.map +1 -1
  89. package/dist/core/extensions/builtin/herdr/index.js +7 -1
  90. package/dist/core/extensions/builtin/herdr/index.js.map +1 -1
  91. package/dist/core/extensions/builtin/hooks/index.d.ts.map +1 -1
  92. package/dist/core/extensions/builtin/hooks/index.js +3 -15
  93. package/dist/core/extensions/builtin/hooks/index.js.map +1 -1
  94. package/dist/core/extensions/builtin/hooks/stop-lifecycle.d.ts +26 -0
  95. package/dist/core/extensions/builtin/hooks/stop-lifecycle.d.ts.map +1 -0
  96. package/dist/core/extensions/builtin/hooks/stop-lifecycle.js +88 -0
  97. package/dist/core/extensions/builtin/hooks/stop-lifecycle.js.map +1 -0
  98. package/dist/core/extensions/builtin/recommended-models/index.d.ts +1 -1
  99. package/dist/core/extensions/builtin/recommended-models/index.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/recommended-models/index.js +28 -10
  101. package/dist/core/extensions/builtin/recommended-models/index.js.map +1 -1
  102. package/dist/core/extensions/builtin/rules/commands.d.ts.map +1 -1
  103. package/dist/core/extensions/builtin/rules/commands.js +5 -1
  104. package/dist/core/extensions/builtin/rules/commands.js.map +1 -1
  105. package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
  106. package/dist/core/extensions/builtin/rules/index.js +25 -3
  107. package/dist/core/extensions/builtin/rules/index.js.map +1 -1
  108. package/dist/core/extensions/builtin/rules/rules/constants.d.ts.map +1 -1
  109. package/dist/core/extensions/builtin/rules/rules/constants.js +22 -14
  110. package/dist/core/extensions/builtin/rules/rules/constants.js.map +1 -1
  111. package/dist/core/extensions/builtin/rules/rules/engine.d.ts.map +1 -1
  112. package/dist/core/extensions/builtin/rules/rules/engine.js +39 -9
  113. package/dist/core/extensions/builtin/rules/rules/engine.js.map +1 -1
  114. package/dist/core/extensions/builtin/rules/rules/finder.js +3 -0
  115. package/dist/core/extensions/builtin/rules/rules/finder.js.map +1 -1
  116. package/dist/core/extensions/builtin/rules/rules/project-root.d.ts +17 -0
  117. package/dist/core/extensions/builtin/rules/rules/project-root.d.ts.map +1 -1
  118. package/dist/core/extensions/builtin/rules/rules/project-root.js +67 -5
  119. package/dist/core/extensions/builtin/rules/rules/project-root.js.map +1 -1
  120. package/dist/core/extensions/builtin/rules/rules/types.d.ts +2 -2
  121. package/dist/core/extensions/builtin/rules/rules/types.d.ts.map +1 -1
  122. package/dist/core/extensions/builtin/rules/rules/types.js.map +1 -1
  123. package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts +3 -1
  124. package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts.map +1 -1
  125. package/dist/core/extensions/builtin/rules/ui/rules-banner.js +1 -1
  126. package/dist/core/extensions/builtin/rules/ui/rules-banner.js.map +1 -1
  127. package/dist/core/extensions/builtin/todotools/todo-storage.d.ts.map +1 -1
  128. package/dist/core/extensions/builtin/todotools/todo-storage.js +10 -2
  129. package/dist/core/extensions/builtin/todotools/todo-storage.js.map +1 -1
  130. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
  131. package/dist/core/extensions/builtin/todotools/tools/todo.js +2 -1
  132. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
  133. package/dist/core/extensions/builtin/websearch/websearch/config.d.ts.map +1 -1
  134. package/dist/core/extensions/builtin/websearch/websearch/config.js +2 -0
  135. package/dist/core/extensions/builtin/websearch/websearch/config.js.map +1 -1
  136. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts.map +1 -1
  137. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +2 -0
  138. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js.map +1 -1
  139. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.d.ts +3 -0
  140. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.d.ts.map +1 -0
  141. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.js +34 -0
  142. package/dist/core/extensions/builtin/websearch/websearch/providers/kagi.js.map +1 -0
  143. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.d.ts +3 -0
  144. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.d.ts.map +1 -0
  145. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.js +22 -0
  146. package/dist/core/extensions/builtin/websearch/websearch/providers/serpdive.js.map +1 -0
  147. package/dist/core/extensions/builtin/websearch/websearch/providers.d.ts.map +1 -1
  148. package/dist/core/extensions/builtin/websearch/websearch/providers.js +4 -0
  149. package/dist/core/extensions/builtin/websearch/websearch/providers.js.map +1 -1
  150. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +1 -1
  151. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -1
  152. package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -1
  153. package/dist/core/session-discovery.d.ts +9 -3
  154. package/dist/core/session-discovery.d.ts.map +1 -1
  155. package/dist/core/session-discovery.js +19 -8
  156. package/dist/core/session-discovery.js.map +1 -1
  157. package/dist/core/session-manager.d.ts.map +1 -1
  158. package/dist/core/session-manager.js +8 -4
  159. package/dist/core/session-manager.js.map +1 -1
  160. package/dist/core/session-summary-cache.d.ts +16 -3
  161. package/dist/core/session-summary-cache.d.ts.map +1 -1
  162. package/dist/core/session-summary-cache.js +19 -3
  163. package/dist/core/session-summary-cache.js.map +1 -1
  164. package/dist/core/session-summary-index-file.d.ts +38 -0
  165. package/dist/core/session-summary-index-file.d.ts.map +1 -0
  166. package/dist/core/session-summary-index-file.js +119 -0
  167. package/dist/core/session-summary-index-file.js.map +1 -0
  168. package/dist/core/session-summary-index.d.ts +52 -0
  169. package/dist/core/session-summary-index.d.ts.map +1 -0
  170. package/dist/core/session-summary-index.js +157 -0
  171. package/dist/core/session-summary-index.js.map +1 -0
  172. package/dist/core/session-summary.d.ts +21 -2
  173. package/dist/core/session-summary.d.ts.map +1 -1
  174. package/dist/core/session-summary.js +53 -14
  175. package/dist/core/session-summary.js.map +1 -1
  176. package/dist/core/timings.d.ts +1 -1
  177. package/dist/core/timings.d.ts.map +1 -1
  178. package/dist/core/timings.js.map +1 -1
  179. package/dist/core/tools/renderers/read.d.ts.map +1 -1
  180. package/dist/core/tools/renderers/read.js +7 -2
  181. package/dist/core/tools/renderers/read.js.map +1 -1
  182. package/dist/core/tools/renderers/skill-read-path.d.ts +9 -0
  183. package/dist/core/tools/renderers/skill-read-path.d.ts.map +1 -0
  184. package/dist/core/tools/renderers/skill-read-path.js +49 -0
  185. package/dist/core/tools/renderers/skill-read-path.js.map +1 -0
  186. package/dist/main.d.ts.map +1 -1
  187. package/dist/main.js +7 -0
  188. package/dist/main.js.map +1 -1
  189. package/dist/modes/interactive/components/exploration-call.d.ts +1 -1
  190. package/dist/modes/interactive/components/exploration-call.d.ts.map +1 -1
  191. package/dist/modes/interactive/components/exploration-call.js +3 -1
  192. package/dist/modes/interactive/components/exploration-call.js.map +1 -1
  193. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  194. package/dist/modes/interactive/components/session-selector-search.js +32 -16
  195. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  196. package/dist/modes/interactive/components/session-selector-tree.d.ts +32 -0
  197. package/dist/modes/interactive/components/session-selector-tree.d.ts.map +1 -0
  198. package/dist/modes/interactive/components/session-selector-tree.js +82 -0
  199. package/dist/modes/interactive/components/session-selector-tree.js.map +1 -0
  200. package/dist/modes/interactive/components/session-selector.d.ts +1 -0
  201. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/session-selector.js +6 -71
  203. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  204. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  205. package/dist/modes/interactive/interactive-mode.js +4 -1
  206. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  207. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +32 -0
  208. package/node_modules/@code-yeongyu/senpi-codemode/README.md +8 -4
  209. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  210. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/AGENTS.md +1 -0
  211. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/code-preview.ts +31 -0
  212. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-code.ts +34 -131
  213. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js-ast.ts +65 -0
  214. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js-layout.ts +90 -0
  215. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js-mask.ts +178 -0
  216. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-js.ts +100 -0
  217. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-python-script.ts +127 -0
  218. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/display-python.ts +150 -0
  219. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-request.ts +18 -4
  220. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +1 -1
  221. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +9 -25
  222. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +16 -9
  223. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts +1 -1
  224. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  225. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +22 -2
  226. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  227. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  228. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +3 -1
  229. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  230. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.d.ts +6 -0
  231. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.d.ts.map +1 -1
  232. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.js +6 -19
  233. package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.js.map +1 -1
  234. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +8 -0
  235. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  236. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  237. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  238. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts.map +1 -1
  239. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js +8 -35
  240. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js.map +1 -1
  241. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +10 -6
  243. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  244. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  245. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +4 -3
  246. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  247. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  248. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +53 -1
  249. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  250. package/node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.js +1 -1
  251. package/node_modules/@earendil-works/pi-ai/dist/api/openrouter-images.js.map +1 -1
  252. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +30 -0
  253. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  254. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +30 -0
  255. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  256. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +2 -1
  257. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  258. package/node_modules/@earendil-works/pi-ai/dist/index.js +2 -1
  259. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  260. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +6 -0
  261. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  262. package/node_modules/@earendil-works/pi-ai/dist/models.js +15 -0
  263. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  264. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts +17 -0
  265. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts.map +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.js +4 -1
  267. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.js.map +1 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  269. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  270. package/node_modules/@earendil-works/pi-ai/dist/providers/data/chatgpt-subscription.json +1 -1
  271. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  272. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
  274. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax-cn.json +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax.json +1 -1
  276. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai-cn.json +1 -1
  277. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai.json +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  279. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
  280. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  281. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  282. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  283. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/providers/data/venice.json +1 -1
  285. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  286. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +6 -0
  287. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  288. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  289. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts +30 -0
  290. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  291. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js +71 -14
  292. package/node_modules/@earendil-works/pi-ai/dist/utils/prompt-cache-ttl.js.map +1 -1
  293. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.d.ts +30 -0
  294. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.d.ts.map +1 -0
  295. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.js +71 -0
  296. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-name-match.js.map +1 -0
  297. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  298. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  299. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  300. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +5 -0
  301. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +1 -1
  302. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +7 -2
  303. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -1
  304. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  305. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  306. package/node_modules/@earendil-works/pi-tui/dist/index.js +1 -1
  307. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  308. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  309. package/package.json +7 -7
  310. package/dist/bundle/chunks/chunk-KLDLZHHS.js +0 -11
  311. package/dist/bundle/chunks/chunk-LTIMMSDM.js +0 -8
  312. package/dist/bundle/chunks/chunk-XYM54ZWK.js +0 -2
  313. package/dist/bundle/chunks/cli-main-W55CWPEI.js +0 -3
  314. package/dist/bundle/chunks/interactive-mode-EDJZ4CSY.js +0 -2
  315. package/dist/bundle/chunks/openai-responses-7IGZSW33.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/herdr/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { closeSync, openSync, readdirSync, readFileSync, readSync } from \"node:fs\";\nimport { createConnection, type Socket } from \"node:net\";\nimport { join, win32 } from \"node:path\";\nimport { debuglog } from \"node:util\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { isTerminalMonitorStateEvent, TERMINAL_MONITOR_STATE_EVENT } from \"../monitor-state-event.ts\";\nimport { HerdrClient, type HerdrMethod } from \"./herdr-client.ts\";\nimport { initialHerdrState, isHerdrBlockedEvent, reduceHerdrState, selectHerdrReport } from \"./herdr-state.ts\";\n\nexport interface HerdrDependencies {\n\tgetLoadedExtensionPaths: (ctx: ExtensionContext) => readonly string[];\n\treadHeader: (path: string) => string;\n\tnow: () => number;\n\tconnect: (path: string) => Socket;\n\tdebug?: (message: string) => void;\n}\n\nexport default function herdrExtension(pi: ExtensionAPI): void {\n\tcreateHerdrExtension({\n\t\tgetLoadedExtensionPaths: (ctx) => ctx.loadedExtensionPaths ?? [],\n\t\treadHeader: (path) => {\n\t\t\tconst file = openSync(path, \"r\");\n\t\t\ttry {\n\t\t\t\tconst header = Buffer.alloc(400);\n\t\t\t\tconst length = readSync(file, header, 0, header.length, 0);\n\t\t\t\treturn header.toString(\"utf8\", 0, length);\n\t\t\t} finally {\n\t\t\t\tcloseSync(file);\n\t\t\t}\n\t\t},\n\t\tnow: Date.now,\n\t\tconnect: createConnection,\n\t})(pi);\n}\n\n/** Read host-owned discovery state only after all extensions have loaded. */\nexport function createHerdrExtension(deps: HerdrDependencies) {\n\treturn (pi: Pick<ExtensionAPI, \"on\" | \"events\">): void => {\n\t\tconst debug = deps.debug ?? debuglog(\"senpi:herdr\");\n\t\tlet client: HerdrClient | undefined;\n\t\tlet bound: ExtensionContext[\"sessionManager\"] | undefined;\n\t\tlet state = initialHerdrState();\n\t\tlet stopped = false;\n\t\tlet deferred = false;\n\t\tlet lastReport: string | undefined;\n\t\tlet title: string | undefined;\n\t\tlet poll: ReturnType<typeof setInterval> | undefined;\n\t\tconst subscriptions: Array<() => void> = [];\n\t\tconst pending = new Set<Promise<boolean>>();\n\t\tconst owns = (ctx: ExtensionContext) => !stopped && bound === ctx.sessionManager;\n\t\tconst sessionRef = () => {\n\t\t\tconst path = bound?.getSessionFile();\n\t\t\treturn path ? { agent_session_path: path } : { agent_session_id: bound?.getSessionId() };\n\t\t};\n\t\tfunction send(method: HerdrMethod, params: Record<string, unknown>): Promise<boolean> {\n\t\t\tif (!client) return Promise.resolve(false);\n\t\t\tconst work = client.send(method, params).then(\n\t\t\t\t() => true,\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tdebug(error instanceof Error ? error.message : \"Herdr transport failed\");\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t);\n\t\t\tpending.add(work);\n\t\t\tvoid work.then(() => pending.delete(work));\n\t\t\treturn work;\n\t\t}\n\t\tasync function publish(): Promise<void> {\n\t\t\tif (!bound || stopped) return;\n\t\t\tconst report = selectHerdrReport(state);\n\t\t\tconst key = JSON.stringify(report);\n\t\t\tif (lastReport === key) return;\n\t\t\tlastReport = key;\n\t\t\tif (!(await send(\"pane.report_agent\", { agent: \"pi\", ...report, ...sessionRef() })) && lastReport === key) {\n\t\t\t\tlastReport = undefined;\n\t\t\t}\n\t\t}\n\t\tasync function reportTitle(ctx: ExtensionContext): Promise<void> {\n\t\t\tconst next = ctx.sessionManager.getSessionName() ?? \"\";\n\t\t\tif (title === next) return;\n\t\t\ttitle = next;\n\t\t\tif (!(await send(\"pane.report_metadata\", { title: next, display_agent: next })) && title === next)\n\t\t\t\ttitle = undefined;\n\t\t}\n\t\tfunction refreshChildren(ctx: ExtensionContext): void {\n\t\t\tstate = reduceHerdrState(state, { type: \"children\", count: countRunningChildTasks(ctx, debug) });\n\t\t}\n\n\t\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\t\tif (stopped || deferred || bound || ctx.mode !== \"tui\") return;\n\t\t\tconst socketPath = process.env.HERDR_SOCKET_PATH;\n\t\t\tconst paneId = process.env.HERDR_PANE_ID;\n\t\t\tif (process.env.HERDR_ENV !== \"1\" || !socketPath || !paneId) return;\n\t\t\tif (hasUserReporter(deps, ctx, debug)) {\n\t\t\t\tdeferred = true;\n\t\t\t\tdebug(\"Herdr builtin deferred to a loaded user reporter\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tbound = ctx.sessionManager;\n\t\t\tclient = new HerdrClient(socketPath, paneId, deps);\n\t\t\tstate = reduceHerdrState(state, { type: \"turn\", active: !ctx.isIdle() });\n\t\t\trefreshChildren(ctx);\n\t\t\tsubscriptions.push(\n\t\t\t\tpi.events.on(\"herdr:blocked\", (data) => {\n\t\t\t\t\tif (stopped || !isHerdrBlockedEvent(data)) return;\n\t\t\t\t\tstate = reduceHerdrState(state, { type: \"blocked\", ...data });\n\t\t\t\t\treturn publish();\n\t\t\t\t}),\n\t\t\t);\n\t\t\tsubscriptions.push(\n\t\t\t\tpi.events.on(TERMINAL_MONITOR_STATE_EVENT, (data) => {\n\t\t\t\t\tif (stopped || !isTerminalMonitorStateEvent(data)) return;\n\t\t\t\t\tstate = reduceHerdrState(state, { type: \"monitors\", count: data.activeCount });\n\t\t\t\t\treturn publish();\n\t\t\t\t}),\n\t\t\t);\n\t\t\tpoll = setInterval(() => {\n\t\t\t\trefreshChildren(ctx);\n\t\t\t\tvoid publish();\n\t\t\t}, 4000);\n\t\t\tpoll.unref();\n\t\t\tawait Promise.all([\n\t\t\t\treportTitle(ctx),\n\t\t\t\tsend(\"pane.report_agent_session\", { agent: \"pi\", ...sessionRef(), session_start_source: _event.reason }),\n\t\t\t\tpublish(),\n\t\t\t]);\n\t\t});\n\t\tpi.on(\"session_info_changed\", (_event, ctx) => {\n\t\t\tif (owns(ctx)) return reportTitle(ctx);\n\t\t});\n\t\tpi.on(\"agent_start\", (_event, ctx) => {\n\t\t\tif (!owns(ctx)) return;\n\t\t\tstate = reduceHerdrState(state, { type: \"turn\", active: true });\n\t\t\treturn publish();\n\t\t});\n\t\tpi.on(\"agent_settled\", (_event, ctx) => {\n\t\t\tif (!owns(ctx)) return;\n\t\t\tstate = reduceHerdrState(state, { type: \"turn\", active: !ctx.isIdle() });\n\t\t\trefreshChildren(ctx);\n\t\t\treturn publish();\n\t\t});\n\t\tpi.on(\"session_shutdown\", async (event, ctx) => {\n\t\t\tif (!owns(ctx)) return;\n\t\t\tstopped = true;\n\t\t\tif (poll) clearInterval(poll);\n\t\t\tfor (const unsubscribe of subscriptions) unsubscribe();\n\t\t\t// Drain before the host builds the successor runtime, or releases the pane.\n\t\t\tawait Promise.all(pending);\n\t\t\tif (event.reason === \"quit\") await send(\"pane.release_agent\", { agent: \"pi\" });\n\t\t});\n\t};\n}\n\nfunction hasUserReporter(deps: HerdrDependencies, ctx: ExtensionContext, debug: (message: string) => void): boolean {\n\treturn deps.getLoadedExtensionPaths(ctx).some((path) => {\n\t\tif (!/^herdr-.*\\.(ts|js|mjs)$/.test(win32.basename(path))) return false;\n\t\ttry {\n\t\t\treturn !Buffer.from(deps.readHeader(path)).subarray(0, 400).includes(\"HERDR_INTEGRATION_ID=\");\n\t\t} catch {\n\t\t\t// An unreadable loaded reporter cannot safely be classified as managed.\n\t\t\tdebug(\"Herdr reporter header unavailable; treating it as user-authored\");\n\t\t\treturn true;\n\t\t}\n\t});\n}\n\nfunction countRunningChildTasks(ctx: ExtensionContext, debug: (message: string) => void): number {\n\tconst directory = join(ctx.cwd, \".omo\", \"senpi-task\", \"tasks\");\n\tlet entries: string[];\n\ttry {\n\t\tentries = readdirSync(directory);\n\t} catch (error) {\n\t\tif (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\"))\n\t\t\tdebug(\"Herdr child-task directory unavailable\");\n\t\treturn 0;\n\t}\n\tlet count = 0;\n\tfor (const file of entries) {\n\t\tif (!file.endsWith(\".json\")) continue;\n\t\ttry {\n\t\t\tconst record: unknown = JSON.parse(readFileSync(join(directory, file), \"utf8\"));\n\t\t\tif (\n\t\t\t\ttypeof record !== \"object\" ||\n\t\t\t\trecord === null ||\n\t\t\t\t!(\"status\" in record) ||\n\t\t\t\t(record.status !== \"running\" && record.status !== \"pending\")\n\t\t\t)\n\t\t\t\tcontinue;\n\t\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\t\tif (\n\t\t\t\t(\"root_session_id\" in record && record.root_session_id === sessionId) ||\n\t\t\t\t(\"parent_session_id\" in record && record.parent_session_id === sessionId)\n\t\t\t)\n\t\t\t\tcount++;\n\t\t} catch {\n\t\t\t// Task records are an external, concurrently-written boundary. Retry on the next poll.\n\t\t\tdebug(\"Herdr ignored an unreadable or partial child-task record\");\n\t\t}\n\t}\n\treturn count;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/herdr/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { closeSync, openSync, readdirSync, readFileSync, readSync } from \"node:fs\";\nimport { createConnection, type Socket } from \"node:net\";\nimport { join, win32 } from \"node:path\";\nimport { debuglog } from \"node:util\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport {\n\tisTerminalMonitorStateEvent,\n\tisWakeSourceStateEvent,\n\tTERMINAL_MONITOR_STATE_EVENT,\n\tWAKE_SOURCE_STATE_EVENT,\n} from \"../monitor-state-event.ts\";\nimport { HerdrClient, type HerdrMethod } from \"./herdr-client.ts\";\nimport { initialHerdrState, isHerdrBlockedEvent, reduceHerdrState, selectHerdrReport } from \"./herdr-state.ts\";\n\nexport interface HerdrDependencies {\n\tgetLoadedExtensionPaths: (ctx: ExtensionContext) => readonly string[];\n\treadHeader: (path: string) => string;\n\tnow: () => number;\n\tconnect: (path: string) => Socket;\n\tdebug?: (message: string) => void;\n}\n\nexport default function herdrExtension(pi: ExtensionAPI): void {\n\tcreateHerdrExtension({\n\t\tgetLoadedExtensionPaths: (ctx) => ctx.loadedExtensionPaths ?? [],\n\t\treadHeader: (path) => {\n\t\t\tconst file = openSync(path, \"r\");\n\t\t\ttry {\n\t\t\t\tconst header = Buffer.alloc(400);\n\t\t\t\tconst length = readSync(file, header, 0, header.length, 0);\n\t\t\t\treturn header.toString(\"utf8\", 0, length);\n\t\t\t} finally {\n\t\t\t\tcloseSync(file);\n\t\t\t}\n\t\t},\n\t\tnow: Date.now,\n\t\tconnect: createConnection,\n\t})(pi);\n}\n\n/** Read host-owned discovery state only after all extensions have loaded. */\nexport function createHerdrExtension(deps: HerdrDependencies) {\n\treturn (pi: Pick<ExtensionAPI, \"on\" | \"events\">): void => {\n\t\tconst debug = deps.debug ?? debuglog(\"senpi:herdr\");\n\t\tlet client: HerdrClient | undefined;\n\t\tlet bound: ExtensionContext[\"sessionManager\"] | undefined;\n\t\tlet state = initialHerdrState();\n\t\tlet stopped = false;\n\t\tlet deferred = false;\n\t\tlet lastReport: string | undefined;\n\t\tlet title: string | undefined;\n\t\tlet poll: ReturnType<typeof setInterval> | undefined;\n\t\tconst subscriptions: Array<() => void> = [];\n\t\tconst pending = new Set<Promise<boolean>>();\n\t\tconst owns = (ctx: ExtensionContext) => !stopped && bound === ctx.sessionManager;\n\t\tconst sessionRef = () => {\n\t\t\tconst path = bound?.getSessionFile();\n\t\t\treturn path ? { agent_session_path: path } : { agent_session_id: bound?.getSessionId() };\n\t\t};\n\t\tfunction send(method: HerdrMethod, params: Record<string, unknown>): Promise<boolean> {\n\t\t\tif (!client) return Promise.resolve(false);\n\t\t\tconst work = client.send(method, params).then(\n\t\t\t\t() => true,\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tdebug(error instanceof Error ? error.message : \"Herdr transport failed\");\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t);\n\t\t\tpending.add(work);\n\t\t\tvoid work.then(() => pending.delete(work));\n\t\t\treturn work;\n\t\t}\n\t\tasync function publish(): Promise<void> {\n\t\t\tif (!bound || stopped) return;\n\t\t\tconst report = selectHerdrReport(state);\n\t\t\tconst key = JSON.stringify(report);\n\t\t\tif (lastReport === key) return;\n\t\t\tlastReport = key;\n\t\t\tif (!(await send(\"pane.report_agent\", { agent: \"pi\", ...report, ...sessionRef() })) && lastReport === key) {\n\t\t\t\tlastReport = undefined;\n\t\t\t}\n\t\t}\n\t\tasync function reportTitle(ctx: ExtensionContext): Promise<void> {\n\t\t\tconst next = ctx.sessionManager.getSessionName() ?? \"\";\n\t\t\tif (title === next) return;\n\t\t\ttitle = next;\n\t\t\tif (!(await send(\"pane.report_metadata\", { title: next, display_agent: next })) && title === next)\n\t\t\t\ttitle = undefined;\n\t\t}\n\t\tfunction refreshChildren(ctx: ExtensionContext): void {\n\t\t\tstate = reduceHerdrState(state, { type: \"children\", count: countRunningChildTasks(ctx, debug) });\n\t\t}\n\n\t\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\t\tif (stopped || deferred || bound || ctx.mode !== \"tui\") return;\n\t\t\tconst socketPath = process.env.HERDR_SOCKET_PATH;\n\t\t\tconst paneId = process.env.HERDR_PANE_ID;\n\t\t\tif (process.env.HERDR_ENV !== \"1\" || !socketPath || !paneId) return;\n\t\t\tif (hasUserReporter(deps, ctx, debug)) {\n\t\t\t\tdeferred = true;\n\t\t\t\tdebug(\"Herdr builtin deferred to a loaded user reporter\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tbound = ctx.sessionManager;\n\t\t\tclient = new HerdrClient(socketPath, paneId, deps);\n\t\t\tstate = reduceHerdrState(state, { type: \"turn\", active: !ctx.isIdle() });\n\t\t\trefreshChildren(ctx);\n\t\t\tsubscriptions.push(\n\t\t\t\tpi.events.on(\"herdr:blocked\", (data) => {\n\t\t\t\t\tif (stopped || !isHerdrBlockedEvent(data)) return;\n\t\t\t\t\tstate = reduceHerdrState(state, { type: \"blocked\", ...data });\n\t\t\t\t\treturn publish();\n\t\t\t\t}),\n\t\t\t);\n\t\t\tsubscriptions.push(\n\t\t\t\tpi.events.on(TERMINAL_MONITOR_STATE_EVENT, (data) => {\n\t\t\t\t\tif (stopped || !isTerminalMonitorStateEvent(data)) return;\n\t\t\t\t\tstate = reduceHerdrState(state, { type: \"monitors\", count: data.activeCount });\n\t\t\t\t\treturn publish();\n\t\t\t\t}),\n\t\t\t);\n\t\t\tsubscriptions.push(\n\t\t\t\tpi.events.on(WAKE_SOURCE_STATE_EVENT, (data) => {\n\t\t\t\t\tif (stopped || !isWakeSourceStateEvent(data)) return;\n\t\t\t\t\tstate = reduceHerdrState(state, { type: \"wake-source\", source: data.source, count: data.activeCount });\n\t\t\t\t\treturn publish();\n\t\t\t\t}),\n\t\t\t);\n\t\t\tpoll = setInterval(() => {\n\t\t\t\trefreshChildren(ctx);\n\t\t\t\tvoid publish();\n\t\t\t}, 4000);\n\t\t\tpoll.unref();\n\t\t\tawait Promise.all([\n\t\t\t\treportTitle(ctx),\n\t\t\t\tsend(\"pane.report_agent_session\", { agent: \"pi\", ...sessionRef(), session_start_source: _event.reason }),\n\t\t\t\tpublish(),\n\t\t\t]);\n\t\t});\n\t\tpi.on(\"session_info_changed\", (_event, ctx) => {\n\t\t\tif (owns(ctx)) return reportTitle(ctx);\n\t\t});\n\t\tpi.on(\"agent_start\", (_event, ctx) => {\n\t\t\tif (!owns(ctx)) return;\n\t\t\tstate = reduceHerdrState(state, { type: \"turn\", active: true });\n\t\t\treturn publish();\n\t\t});\n\t\tpi.on(\"agent_settled\", (_event, ctx) => {\n\t\t\tif (!owns(ctx)) return;\n\t\t\tstate = reduceHerdrState(state, { type: \"turn\", active: !ctx.isIdle() });\n\t\t\trefreshChildren(ctx);\n\t\t\treturn publish();\n\t\t});\n\t\tpi.on(\"session_shutdown\", async (event, ctx) => {\n\t\t\tif (!owns(ctx)) return;\n\t\t\tstopped = true;\n\t\t\tif (poll) clearInterval(poll);\n\t\t\tfor (const unsubscribe of subscriptions) unsubscribe();\n\t\t\t// Drain before the host builds the successor runtime, or releases the pane.\n\t\t\tawait Promise.all(pending);\n\t\t\tif (event.reason === \"quit\") await send(\"pane.release_agent\", { agent: \"pi\" });\n\t\t});\n\t};\n}\n\nfunction hasUserReporter(deps: HerdrDependencies, ctx: ExtensionContext, debug: (message: string) => void): boolean {\n\treturn deps.getLoadedExtensionPaths(ctx).some((path) => {\n\t\tif (!/^herdr-.*\\.(ts|js|mjs)$/.test(win32.basename(path))) return false;\n\t\ttry {\n\t\t\treturn !Buffer.from(deps.readHeader(path)).subarray(0, 400).includes(\"HERDR_INTEGRATION_ID=\");\n\t\t} catch {\n\t\t\t// An unreadable loaded reporter cannot safely be classified as managed.\n\t\t\tdebug(\"Herdr reporter header unavailable; treating it as user-authored\");\n\t\t\treturn true;\n\t\t}\n\t});\n}\n\nfunction countRunningChildTasks(ctx: ExtensionContext, debug: (message: string) => void): number {\n\tconst directory = join(ctx.cwd, \".omo\", \"senpi-task\", \"tasks\");\n\tlet entries: string[];\n\ttry {\n\t\tentries = readdirSync(directory);\n\t} catch (error) {\n\t\tif (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\"))\n\t\t\tdebug(\"Herdr child-task directory unavailable\");\n\t\treturn 0;\n\t}\n\tlet count = 0;\n\tfor (const file of entries) {\n\t\tif (!file.endsWith(\".json\")) continue;\n\t\ttry {\n\t\t\tconst record: unknown = JSON.parse(readFileSync(join(directory, file), \"utf8\"));\n\t\t\tif (\n\t\t\t\ttypeof record !== \"object\" ||\n\t\t\t\trecord === null ||\n\t\t\t\t!(\"status\" in record) ||\n\t\t\t\t(record.status !== \"running\" && record.status !== \"pending\")\n\t\t\t)\n\t\t\t\tcontinue;\n\t\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\t\tif (\n\t\t\t\t(\"root_session_id\" in record && record.root_session_id === sessionId) ||\n\t\t\t\t(\"parent_session_id\" in record && record.parent_session_id === sessionId)\n\t\t\t)\n\t\t\t\tcount++;\n\t\t} catch {\n\t\t\t// Task records are an external, concurrently-written boundary. Retry on the next poll.\n\t\t\tdebug(\"Herdr ignored an unreadable or partial child-task record\");\n\t\t}\n\t}\n\treturn count;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA+B,YAAY,EAAuC,MAAM,gBAAgB,CAAC;AA+CrH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACX,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAqQ7D;AAmBD,OAAO,EACN,qBAAqB,EACrB,yBAAyB,EACzB,6BAA6B,GAC7B,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA+B,YAAY,EAAuC,MAAM,gBAAgB,CAAC;AA+CrH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACX,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAwP7D;AAmBD,OAAO,EACN,qBAAqB,EACrB,yBAAyB,EACzB,6BAA6B,GAC7B,MAAM,YAAY,CAAC"}
@@ -6,7 +6,7 @@ import { loadHookConfigSources, loadHookConfigSourcesAsync } from "./config-load
6
6
  import { dispatchHookEvent, runningHookHandlersStatusLabel } from "./dispatcher.js";
7
7
  import { buildNotificationHookInput, buildPostCompactHookInput, buildPreCompactHookInput, buildSessionStartHookInput, dispatchLifecycleHookEvent, dispatchNotificationHookEvent, notificationResultDetails, postCompactResultDetails, preCompactResultDetails, recordLifecycleHookResult, sessionBeforeCompactResult, sessionStartResultDetails, } from "./lifecycle-adapter.js";
8
8
  import { appendSystemMessages, buildUserPromptHookInput, formatPromptContextMessage, HOOK_CUSTOM_MESSAGE_TYPE, promptBlockReasonFromResult, promptContextFromResult, safeDiagnosticDetails, } from "./prompt-adapter.js";
9
- import { applyStopHookResult, buildStopHookInput, createStopTurnTracker } from "./stop-adapter.js";
9
+ import { registerStopLifecycle } from "./stop-lifecycle.js";
10
10
  import { applyPostToolUseResult, applyPreToolUseResult, buildPostToolUseHookInput, buildPreToolUseHookInput, toolContextsFromResult, } from "./tool-adapter.js";
11
11
  import { emptyHookTrustState } from "./trust.js";
12
12
  import { FileHookStateStorage } from "./trust-storage.js";
@@ -14,7 +14,6 @@ export { parseHookConfig } from "./schema.js";
14
14
  export default function hooksExtension(pi) {
15
15
  const pendingPromptContexts = [];
16
16
  const pendingPreToolContexts = new Map();
17
- const stopTurnTracker = createStopTurnTracker();
18
17
  const refreshState = (ctx) => {
19
18
  const sources = ctx.getLoadedHookSources?.() ?? fallbackHookSources(ctx.cwd);
20
19
  const parsed = loadHookConfigSources({
@@ -38,6 +37,7 @@ export default function hooksExtension(pi) {
38
37
  const trust = mergeTrustStates(storage.read("global"), ctx.isProjectTrusted() ? storage.read("project") : emptyHookTrustState());
39
38
  return { parsed, trust, storage };
40
39
  };
40
+ const stopLifecycle = registerStopLifecycle(pi, { refreshState });
41
41
  for (const channel of [ASK_USER_ASKED_EVENT, ASK_USER_SETTLED_EVENT]) {
42
42
  pi.events.on(channel, async (data) => {
43
43
  const event = data;
@@ -101,7 +101,7 @@ export default function hooksExtension(pi) {
101
101
  pi.on("input", async (event, ctx) => {
102
102
  if (event.source === "extension")
103
103
  return undefined;
104
- stopTurnTracker.reset();
104
+ stopLifecycle.resetTurn();
105
105
  pendingPromptContexts.splice(0);
106
106
  const state = refreshState(ctx);
107
107
  const input = buildUserPromptHookInput({
@@ -242,18 +242,6 @@ export default function hooksExtension(pi) {
242
242
  recordLifecycleHookResult(pi, "PostCompact", postCompactResultDetails(result));
243
243
  return undefined;
244
244
  });
245
- pi.on("agent_end", async (event, ctx) => {
246
- const state = refreshState(ctx);
247
- const result = await dispatchHookEvent({
248
- cwd: ctx.cwd,
249
- handlers: state.parsed.executableHandlers,
250
- input: buildStopHookInput(event, ctx),
251
- signal: ctx.signal,
252
- trustOptions: { platform: process.platform },
253
- trustState: state.trust,
254
- });
255
- await applyStopHookResult(pi, ctx, result, stopTurnTracker.turnKey(ctx));
256
- });
257
245
  registerHooksCommand(pi, refreshState);
258
246
  }
259
247
  function mergeTrustStates(globalState, projectState) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport type { BeforeAgentStartEventResult, ExtensionAPI, ExtensionContext, LoadedHookSources } from \"../../types.ts\";\nimport { formatResultText } from \"../ask-user/format.ts\";\nimport {\n\tASK_USER_ASKED_EVENT,\n\tASK_USER_SETTLED_EVENT,\n\ttype AskUserAskedEvent,\n\ttype AskUserSettledEvent,\n} from \"../ask-user/notify.ts\";\nimport { registerHooksCommand } from \"./command.ts\";\nimport { loadHookConfigSources, loadHookConfigSourcesAsync } from \"./config-loader.ts\";\nimport { dispatchHookEvent, runningHookHandlersStatusLabel } from \"./dispatcher.ts\";\nimport {\n\tbuildNotificationHookInput,\n\tbuildPostCompactHookInput,\n\tbuildPreCompactHookInput,\n\tbuildSessionStartHookInput,\n\tdispatchLifecycleHookEvent,\n\tdispatchNotificationHookEvent,\n\tnotificationResultDetails,\n\tpostCompactResultDetails,\n\tpreCompactResultDetails,\n\trecordLifecycleHookResult,\n\tsessionBeforeCompactResult,\n\tsessionStartResultDetails,\n} from \"./lifecycle-adapter.ts\";\nimport {\n\tappendSystemMessages,\n\tbuildUserPromptHookInput,\n\tformatPromptContextMessage,\n\tHOOK_CUSTOM_MESSAGE_TYPE,\n\ttype PendingPromptHookContext,\n\tpromptBlockReasonFromResult,\n\tpromptContextFromResult,\n\tsafeDiagnosticDetails,\n} from \"./prompt-adapter.ts\";\nimport { applyStopHookResult, buildStopHookInput, createStopTurnTracker } from \"./stop-adapter.ts\";\nimport {\n\tapplyPostToolUseResult,\n\tapplyPreToolUseResult,\n\tbuildPostToolUseHookInput,\n\tbuildPreToolUseHookInput,\n\ttoolContextsFromResult,\n} from \"./tool-adapter.ts\";\nimport { emptyHookTrustState } from \"./trust.ts\";\nimport { FileHookStateStorage } from \"./trust-storage.ts\";\nimport type { HookTrustState } from \"./types.ts\";\n\nexport { parseHookConfig } from \"./schema.ts\";\nexport type {\n\tCommandHookConfig,\n\tExecutableHookHandler,\n\tHookDiagnostic,\n\tHookDiagnosticCode,\n\tHookInputWire,\n\tHookOutputWire,\n\tHookRuntimeState,\n\tHookSourceMetadata,\n\tHookTrustEntry,\n\tHookTrustState,\n\tParsedHookConfig,\n\tSupportedHookEvent,\n\tUnsupportedKnownHookEvent,\n} from \"./types.ts\";\n\nexport default function hooksExtension(pi: ExtensionAPI): void {\n\tconst pendingPromptContexts: PendingPromptHookContext[] = [];\n\tconst pendingPreToolContexts = new Map<string, readonly string[]>();\n\tconst stopTurnTracker = createStopTurnTracker();\n\n\tconst refreshState = (ctx: ExtensionContext) => {\n\t\tconst sources = ctx.getLoadedHookSources?.() ?? fallbackHookSources(ctx.cwd);\n\t\tconst parsed = loadHookConfigSources({\n\t\t\tagentDir: sources.agentDir,\n\t\t\tcwd: sources.cwd,\n\t\t\tfileSystem: {\n\t\t\t\treadTextFile(path) {\n\t\t\t\t\treturn existsSync(path) ? readFileSync(path, \"utf-8\") : undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\tglobalHookSourcePaths: sources.globalHookSourcePaths,\n\t\t\tglobalHooksPath: sources.globalHooksPath,\n\t\t\tglobalSettingsHooks: sources.globalSettingsHooks,\n\t\t\tpreSessionHookSourcePaths: sources.preSessionHookSourcePaths,\n\t\t\tprojectHookSourcePaths: sources.projectHookSourcePaths,\n\t\t\tprojectHooksPath: sources.projectHooksPath,\n\t\t\tprojectSettingsHooks: sources.projectSettingsHooks,\n\t\t\truntimeHookSourcePaths: sources.runtimeHookSourcePaths,\n\t\t});\n\t\tconst storage = new FileHookStateStorage({ agentDir: sources.agentDir, cwd: sources.cwd });\n\t\tconst trust = mergeTrustStates(\n\t\t\tstorage.read(\"global\"),\n\t\t\tctx.isProjectTrusted() ? storage.read(\"project\") : emptyHookTrustState(),\n\t\t);\n\t\treturn { parsed, trust, storage };\n\t};\n\n\tfor (const channel of [ASK_USER_ASKED_EVENT, ASK_USER_SETTLED_EVENT]) {\n\t\tpi.events.on(channel, async (data) => {\n\t\t\tconst event = data as AskUserAskedEvent | AskUserSettledEvent;\n\t\t\tconst { ctx, request, variant } = event;\n\t\t\tconst response = \"response\" in event ? event.response : undefined;\n\t\t\tconst headers = request.questions.map((question) => question.header).join(\", \");\n\t\t\t// Capture session identity before asynchronous I/O or a session switch.\n\t\t\tconst input = buildNotificationHookInput(\n\t\t\t\t{\n\t\t\t\t\tkind:\n\t\t\t\t\t\tresponse === undefined\n\t\t\t\t\t\t\t? \"ask-user-asked\"\n\t\t\t\t\t\t\t: response.status === \"timed_out\"\n\t\t\t\t\t\t\t\t? \"ask-user-timeout\"\n\t\t\t\t\t\t\t\t: \"ask-user-settled\",\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tresponse === undefined\n\t\t\t\t\t\t\t? `Question asked (${headers})`\n\t\t\t\t\t\t\t: response.status === \"timed_out\"\n\t\t\t\t\t\t\t\t? `Question timed out (${headers}): ${formatResultText(variant, response, request.questions)}`\n\t\t\t\t\t\t\t\t: `Question ${response.status} (${headers})`,\n\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\tsource: \"ask-user\",\n\t\t\t\t\tstatus: response?.status ?? \"pending\",\n\t\t\t\t\ttitle: headers,\n\t\t\t\t},\n\t\t\t\tctx,\n\t\t\t);\n\t\t\tconst sources = ctx.getLoadedHookSources?.() ?? fallbackHookSources(ctx.cwd);\n\t\t\tconst parsed = await loadHookConfigSourcesAsync(sources);\n\t\t\tconst handlers = parsed.executableHandlers.filter((handler) => handler.event === \"Notification\");\n\t\t\tif (handlers.length === 0) return;\n\t\t\tconst storage = new FileHookStateStorage({ agentDir: sources.agentDir, cwd: sources.cwd });\n\t\t\tconst [globalTrust, projectTrust] = await Promise.all([\n\t\t\t\tstorage.readAsync(\"global\"),\n\t\t\t\tctx.isProjectTrusted() ? storage.readAsync(\"project\") : emptyHookTrustState(),\n\t\t\t]);\n\t\t\tconst result = await dispatchNotificationHookEvent({\n\t\t\t\tcwd: ctx.cwd,\n\t\t\t\thandlers,\n\t\t\t\tinput,\n\t\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\t\ttrustState: mergeTrustStates(globalTrust, projectTrust),\n\t\t\t});\n\t\t\tconst details = notificationResultDetails(result);\n\t\t\trecordLifecycleHookResult(pi, \"Notification\", {\n\t\t\t\t...details,\n\t\t\t\tdiagnostics: [...parsed.diagnostics, ...details.diagnostics],\n\t\t\t});\n\t\t});\n\t}\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst input = buildSessionStartHookInput(event, ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput,\n\t\t\tmatcherInputs: [\"SessionStart\", event.reason],\n\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\trecordLifecycleHookResult(pi, \"SessionStart\", sessionStartResultDetails(result));\n\t});\n\n\tpi.on(\"input\", async (event, ctx) => {\n\t\tif (event.source === \"extension\") return undefined;\n\t\tstopTurnTracker.reset();\n\t\tpendingPromptContexts.splice(0);\n\t\tconst state = refreshState(ctx);\n\t\tconst input = buildUserPromptHookInput({\n\t\t\tcwd: ctx.cwd,\n\t\t\tpermissionMode: \"default\",\n\t\t\tprompt: event.text,\n\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\ttranscriptPath: ctx.sessionManager.getSessionFile(),\n\t\t});\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput,\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tif (result.decision.kind === \"block\") {\n\t\t\tconst reason = promptBlockReasonFromResult(result);\n\t\t\tctx.ui.notify(reason, \"warning\");\n\t\t\tpi.sendMessage(\n\t\t\t\t{\n\t\t\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\t\t\tcontent: reason,\n\t\t\t\t\tdisplay: false,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tdecision: \"block\",\n\t\t\t\t\t\tevent: \"UserPromptSubmit\",\n\t\t\t\t\t\tsourcePath: result.decision.source.sourcePath,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ triggerTurn: false },\n\t\t\t);\n\t\t\treturn { action: \"handled\" };\n\t\t}\n\t\tif (ctx.isIdle()) {\n\t\t\tconst pending = promptContextFromResult(result);\n\t\t\tif (pending !== undefined) {\n\t\t\t\tpendingPromptContexts.push(pending);\n\t\t\t}\n\t\t}\n\t\treturn { action: \"continue\" };\n\t});\n\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\tconst pending = pendingPromptContexts.shift();\n\t\tif (pending === undefined) return undefined;\n\n\t\tconst messageContent = formatPromptContextMessage(pending);\n\t\tconst systemPrompt = appendSystemMessages(event.systemPrompt, pending.systemMessages);\n\t\tif (messageContent === undefined && systemPrompt === event.systemPrompt) return undefined;\n\n\t\tconst result: BeforeAgentStartEventResult = {};\n\t\tif (messageContent !== undefined) {\n\t\t\tresult.message = {\n\t\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\t\tcontent: messageContent,\n\t\t\t\tdisplay: false,\n\t\t\t\tdetails: {\n\t\t\t\t\tevent: \"UserPromptSubmit\",\n\t\t\t\t\tdiagnostics: pending.diagnostics.map(safeDiagnosticDetails),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (systemPrompt !== event.systemPrompt) {\n\t\t\tresult.systemPrompt = systemPrompt;\n\t\t}\n\t\treturn result;\n\t});\n\n\tpi.on(\"tool_call\", async (event, ctx) => {\n\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPreToolUseHookInput(event, ctx),\n\t\t\tonRunningHandlersChange: (running) => {\n\t\t\t\tif (running.length === 0) return;\n\t\t\t\tctx.updateToolHookStatus?.(runningHookHandlersStatusLabel(running));\n\t\t\t},\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tconst toolResult = applyPreToolUseResult(event, result);\n\t\tif (toolResult?.block) {\n\t\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\t\treturn toolResult;\n\t\t}\n\t\tconst contexts = toolContextsFromResult(result);\n\t\tif (contexts.length > 0) {\n\t\t\tpendingPreToolContexts.set(event.toolCallId, contexts);\n\t\t}\n\t\treturn toolResult;\n\t});\n\n\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\tconst preToolContexts = pendingPreToolContexts.get(event.toolCallId) ?? [];\n\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPostToolUseHookInput(event, ctx),\n\t\t\tonRunningHandlersChange: (running) => {\n\t\t\t\tif (running.length === 0) return;\n\t\t\t\tctx.updateToolHookStatus?.(runningHookHandlersStatusLabel(running));\n\t\t\t},\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\treturn applyPostToolUseResult(event, result, preToolContexts);\n\t});\n\n\tpi.on(\"session_before_compact\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPreCompactHookInput(event, ctx),\n\t\t\tmatcherInputs: [\"PreCompact\", event.reason],\n\t\t\tsignal: event.signal,\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tconst details = preCompactResultDetails(result);\n\t\trecordLifecycleHookResult(pi, \"PreCompact\", details, { compactionRequestId: event.requestId });\n\t\treturn sessionBeforeCompactResult(details);\n\t});\n\n\tpi.on(\"session_compact\", async (event, ctx) => {\n\t\tif (!event.accepted) return undefined;\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPostCompactHookInput(event, ctx),\n\t\t\tmatcherInputs: [\"PostCompact\", event.reason],\n\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\trecordLifecycleHookResult(pi, \"PostCompact\", postCompactResultDetails(result));\n\t\treturn undefined;\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildStopHookInput(event, ctx),\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tawait applyStopHookResult(pi, ctx, result, stopTurnTracker.turnKey(ctx));\n\t});\n\n\tregisterHooksCommand(pi, refreshState);\n}\n\nfunction mergeTrustStates(globalState: HookTrustState, projectState: HookTrustState): HookTrustState {\n\treturn { version: 1, hooks: { ...globalState.hooks, ...projectState.hooks } };\n}\n\nfunction fallbackHookSources(cwd: string): LoadedHookSources {\n\treturn {\n\t\tagentDir: cwd,\n\t\tcwd,\n\t\tglobalHookSourcePaths: [],\n\t\tglobalHooksPath: `${cwd}/hooks.json`,\n\t\tpreSessionHookSourcePaths: [],\n\t\tprojectHookSourcePaths: [],\n\t\tprojectHooksPath: `${cwd}/.senpi/hooks.json`,\n\t\truntimeHookSourcePaths: [],\n\t};\n}\n\nexport {\n\tSUPPORTED_HOOK_EVENTS,\n\tUNSUPPORTED_HANDLER_TYPES,\n\tUNSUPPORTED_KNOWN_HOOK_EVENTS,\n} from \"./types.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport type { BeforeAgentStartEventResult, ExtensionAPI, ExtensionContext, LoadedHookSources } from \"../../types.ts\";\nimport { formatResultText } from \"../ask-user/format.ts\";\nimport {\n\tASK_USER_ASKED_EVENT,\n\tASK_USER_SETTLED_EVENT,\n\ttype AskUserAskedEvent,\n\ttype AskUserSettledEvent,\n} from \"../ask-user/notify.ts\";\nimport { registerHooksCommand } from \"./command.ts\";\nimport { loadHookConfigSources, loadHookConfigSourcesAsync } from \"./config-loader.ts\";\nimport { dispatchHookEvent, runningHookHandlersStatusLabel } from \"./dispatcher.ts\";\nimport {\n\tbuildNotificationHookInput,\n\tbuildPostCompactHookInput,\n\tbuildPreCompactHookInput,\n\tbuildSessionStartHookInput,\n\tdispatchLifecycleHookEvent,\n\tdispatchNotificationHookEvent,\n\tnotificationResultDetails,\n\tpostCompactResultDetails,\n\tpreCompactResultDetails,\n\trecordLifecycleHookResult,\n\tsessionBeforeCompactResult,\n\tsessionStartResultDetails,\n} from \"./lifecycle-adapter.ts\";\nimport {\n\tappendSystemMessages,\n\tbuildUserPromptHookInput,\n\tformatPromptContextMessage,\n\tHOOK_CUSTOM_MESSAGE_TYPE,\n\ttype PendingPromptHookContext,\n\tpromptBlockReasonFromResult,\n\tpromptContextFromResult,\n\tsafeDiagnosticDetails,\n} from \"./prompt-adapter.ts\";\nimport { registerStopLifecycle } from \"./stop-lifecycle.ts\";\nimport {\n\tapplyPostToolUseResult,\n\tapplyPreToolUseResult,\n\tbuildPostToolUseHookInput,\n\tbuildPreToolUseHookInput,\n\ttoolContextsFromResult,\n} from \"./tool-adapter.ts\";\nimport { emptyHookTrustState } from \"./trust.ts\";\nimport { FileHookStateStorage } from \"./trust-storage.ts\";\nimport type { HookTrustState } from \"./types.ts\";\n\nexport { parseHookConfig } from \"./schema.ts\";\nexport type {\n\tCommandHookConfig,\n\tExecutableHookHandler,\n\tHookDiagnostic,\n\tHookDiagnosticCode,\n\tHookInputWire,\n\tHookOutputWire,\n\tHookRuntimeState,\n\tHookSourceMetadata,\n\tHookTrustEntry,\n\tHookTrustState,\n\tParsedHookConfig,\n\tSupportedHookEvent,\n\tUnsupportedKnownHookEvent,\n} from \"./types.ts\";\n\nexport default function hooksExtension(pi: ExtensionAPI): void {\n\tconst pendingPromptContexts: PendingPromptHookContext[] = [];\n\tconst pendingPreToolContexts = new Map<string, readonly string[]>();\n\n\tconst refreshState = (ctx: ExtensionContext) => {\n\t\tconst sources = ctx.getLoadedHookSources?.() ?? fallbackHookSources(ctx.cwd);\n\t\tconst parsed = loadHookConfigSources({\n\t\t\tagentDir: sources.agentDir,\n\t\t\tcwd: sources.cwd,\n\t\t\tfileSystem: {\n\t\t\t\treadTextFile(path) {\n\t\t\t\t\treturn existsSync(path) ? readFileSync(path, \"utf-8\") : undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\tglobalHookSourcePaths: sources.globalHookSourcePaths,\n\t\t\tglobalHooksPath: sources.globalHooksPath,\n\t\t\tglobalSettingsHooks: sources.globalSettingsHooks,\n\t\t\tpreSessionHookSourcePaths: sources.preSessionHookSourcePaths,\n\t\t\tprojectHookSourcePaths: sources.projectHookSourcePaths,\n\t\t\tprojectHooksPath: sources.projectHooksPath,\n\t\t\tprojectSettingsHooks: sources.projectSettingsHooks,\n\t\t\truntimeHookSourcePaths: sources.runtimeHookSourcePaths,\n\t\t});\n\t\tconst storage = new FileHookStateStorage({ agentDir: sources.agentDir, cwd: sources.cwd });\n\t\tconst trust = mergeTrustStates(\n\t\t\tstorage.read(\"global\"),\n\t\t\tctx.isProjectTrusted() ? storage.read(\"project\") : emptyHookTrustState(),\n\t\t);\n\t\treturn { parsed, trust, storage };\n\t};\n\tconst stopLifecycle = registerStopLifecycle(pi, { refreshState });\n\n\tfor (const channel of [ASK_USER_ASKED_EVENT, ASK_USER_SETTLED_EVENT]) {\n\t\tpi.events.on(channel, async (data) => {\n\t\t\tconst event = data as AskUserAskedEvent | AskUserSettledEvent;\n\t\t\tconst { ctx, request, variant } = event;\n\t\t\tconst response = \"response\" in event ? event.response : undefined;\n\t\t\tconst headers = request.questions.map((question) => question.header).join(\", \");\n\t\t\t// Capture session identity before asynchronous I/O or a session switch.\n\t\t\tconst input = buildNotificationHookInput(\n\t\t\t\t{\n\t\t\t\t\tkind:\n\t\t\t\t\t\tresponse === undefined\n\t\t\t\t\t\t\t? \"ask-user-asked\"\n\t\t\t\t\t\t\t: response.status === \"timed_out\"\n\t\t\t\t\t\t\t\t? \"ask-user-timeout\"\n\t\t\t\t\t\t\t\t: \"ask-user-settled\",\n\t\t\t\t\tmessage:\n\t\t\t\t\t\tresponse === undefined\n\t\t\t\t\t\t\t? `Question asked (${headers})`\n\t\t\t\t\t\t\t: response.status === \"timed_out\"\n\t\t\t\t\t\t\t\t? `Question timed out (${headers}): ${formatResultText(variant, response, request.questions)}`\n\t\t\t\t\t\t\t\t: `Question ${response.status} (${headers})`,\n\t\t\t\t\trequestId: request.requestId,\n\t\t\t\t\tsource: \"ask-user\",\n\t\t\t\t\tstatus: response?.status ?? \"pending\",\n\t\t\t\t\ttitle: headers,\n\t\t\t\t},\n\t\t\t\tctx,\n\t\t\t);\n\t\t\tconst sources = ctx.getLoadedHookSources?.() ?? fallbackHookSources(ctx.cwd);\n\t\t\tconst parsed = await loadHookConfigSourcesAsync(sources);\n\t\t\tconst handlers = parsed.executableHandlers.filter((handler) => handler.event === \"Notification\");\n\t\t\tif (handlers.length === 0) return;\n\t\t\tconst storage = new FileHookStateStorage({ agentDir: sources.agentDir, cwd: sources.cwd });\n\t\t\tconst [globalTrust, projectTrust] = await Promise.all([\n\t\t\t\tstorage.readAsync(\"global\"),\n\t\t\t\tctx.isProjectTrusted() ? storage.readAsync(\"project\") : emptyHookTrustState(),\n\t\t\t]);\n\t\t\tconst result = await dispatchNotificationHookEvent({\n\t\t\t\tcwd: ctx.cwd,\n\t\t\t\thandlers,\n\t\t\t\tinput,\n\t\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\t\ttrustState: mergeTrustStates(globalTrust, projectTrust),\n\t\t\t});\n\t\t\tconst details = notificationResultDetails(result);\n\t\t\trecordLifecycleHookResult(pi, \"Notification\", {\n\t\t\t\t...details,\n\t\t\t\tdiagnostics: [...parsed.diagnostics, ...details.diagnostics],\n\t\t\t});\n\t\t});\n\t}\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst input = buildSessionStartHookInput(event, ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput,\n\t\t\tmatcherInputs: [\"SessionStart\", event.reason],\n\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\trecordLifecycleHookResult(pi, \"SessionStart\", sessionStartResultDetails(result));\n\t});\n\n\tpi.on(\"input\", async (event, ctx) => {\n\t\tif (event.source === \"extension\") return undefined;\n\t\tstopLifecycle.resetTurn();\n\t\tpendingPromptContexts.splice(0);\n\t\tconst state = refreshState(ctx);\n\t\tconst input = buildUserPromptHookInput({\n\t\t\tcwd: ctx.cwd,\n\t\t\tpermissionMode: \"default\",\n\t\t\tprompt: event.text,\n\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\ttranscriptPath: ctx.sessionManager.getSessionFile(),\n\t\t});\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput,\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tif (result.decision.kind === \"block\") {\n\t\t\tconst reason = promptBlockReasonFromResult(result);\n\t\t\tctx.ui.notify(reason, \"warning\");\n\t\t\tpi.sendMessage(\n\t\t\t\t{\n\t\t\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\t\t\tcontent: reason,\n\t\t\t\t\tdisplay: false,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tdecision: \"block\",\n\t\t\t\t\t\tevent: \"UserPromptSubmit\",\n\t\t\t\t\t\tsourcePath: result.decision.source.sourcePath,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ triggerTurn: false },\n\t\t\t);\n\t\t\treturn { action: \"handled\" };\n\t\t}\n\t\tif (ctx.isIdle()) {\n\t\t\tconst pending = promptContextFromResult(result);\n\t\t\tif (pending !== undefined) {\n\t\t\t\tpendingPromptContexts.push(pending);\n\t\t\t}\n\t\t}\n\t\treturn { action: \"continue\" };\n\t});\n\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\tconst pending = pendingPromptContexts.shift();\n\t\tif (pending === undefined) return undefined;\n\n\t\tconst messageContent = formatPromptContextMessage(pending);\n\t\tconst systemPrompt = appendSystemMessages(event.systemPrompt, pending.systemMessages);\n\t\tif (messageContent === undefined && systemPrompt === event.systemPrompt) return undefined;\n\n\t\tconst result: BeforeAgentStartEventResult = {};\n\t\tif (messageContent !== undefined) {\n\t\t\tresult.message = {\n\t\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\t\tcontent: messageContent,\n\t\t\t\tdisplay: false,\n\t\t\t\tdetails: {\n\t\t\t\t\tevent: \"UserPromptSubmit\",\n\t\t\t\t\tdiagnostics: pending.diagnostics.map(safeDiagnosticDetails),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (systemPrompt !== event.systemPrompt) {\n\t\t\tresult.systemPrompt = systemPrompt;\n\t\t}\n\t\treturn result;\n\t});\n\n\tpi.on(\"tool_call\", async (event, ctx) => {\n\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPreToolUseHookInput(event, ctx),\n\t\t\tonRunningHandlersChange: (running) => {\n\t\t\t\tif (running.length === 0) return;\n\t\t\t\tctx.updateToolHookStatus?.(runningHookHandlersStatusLabel(running));\n\t\t\t},\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tconst toolResult = applyPreToolUseResult(event, result);\n\t\tif (toolResult?.block) {\n\t\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\t\treturn toolResult;\n\t\t}\n\t\tconst contexts = toolContextsFromResult(result);\n\t\tif (contexts.length > 0) {\n\t\t\tpendingPreToolContexts.set(event.toolCallId, contexts);\n\t\t}\n\t\treturn toolResult;\n\t});\n\n\tpi.on(\"tool_result\", async (event, ctx) => {\n\t\tconst preToolContexts = pendingPreToolContexts.get(event.toolCallId) ?? [];\n\t\tpendingPreToolContexts.delete(event.toolCallId);\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPostToolUseHookInput(event, ctx),\n\t\t\tonRunningHandlersChange: (running) => {\n\t\t\t\tif (running.length === 0) return;\n\t\t\t\tctx.updateToolHookStatus?.(runningHookHandlersStatusLabel(running));\n\t\t\t},\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\treturn applyPostToolUseResult(event, result, preToolContexts);\n\t});\n\n\tpi.on(\"session_before_compact\", async (event, ctx) => {\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPreCompactHookInput(event, ctx),\n\t\t\tmatcherInputs: [\"PreCompact\", event.reason],\n\t\t\tsignal: event.signal,\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tconst details = preCompactResultDetails(result);\n\t\trecordLifecycleHookResult(pi, \"PreCompact\", details, { compactionRequestId: event.requestId });\n\t\treturn sessionBeforeCompactResult(details);\n\t});\n\n\tpi.on(\"session_compact\", async (event, ctx) => {\n\t\tif (!event.accepted) return undefined;\n\t\tconst state = refreshState(ctx);\n\t\tconst result = await dispatchLifecycleHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput: buildPostCompactHookInput(event, ctx),\n\t\t\tmatcherInputs: [\"PostCompact\", event.reason],\n\t\t\t...(ctx.signal === undefined ? {} : { signal: ctx.signal }),\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\trecordLifecycleHookResult(pi, \"PostCompact\", postCompactResultDetails(result));\n\t\treturn undefined;\n\t});\n\n\tregisterHooksCommand(pi, refreshState);\n}\n\nfunction mergeTrustStates(globalState: HookTrustState, projectState: HookTrustState): HookTrustState {\n\treturn { version: 1, hooks: { ...globalState.hooks, ...projectState.hooks } };\n}\n\nfunction fallbackHookSources(cwd: string): LoadedHookSources {\n\treturn {\n\t\tagentDir: cwd,\n\t\tcwd,\n\t\tglobalHookSourcePaths: [],\n\t\tglobalHooksPath: `${cwd}/hooks.json`,\n\t\tpreSessionHookSourcePaths: [],\n\t\tprojectHookSourcePaths: [],\n\t\tprojectHooksPath: `${cwd}/.senpi/hooks.json`,\n\t\truntimeHookSourcePaths: [],\n\t};\n}\n\nexport {\n\tSUPPORTED_HOOK_EVENTS,\n\tUNSUPPORTED_HANDLER_TYPES,\n\tUNSUPPORTED_KNOWN_HOOK_EVENTS,\n} from \"./types.ts\";\n"]}
@@ -0,0 +1,26 @@
1
+ import type { ExtensionAPI, ExtensionContext } from "../../types.ts";
2
+ import type { HookTrustState, ParsedHookConfig } from "./types.ts";
3
+ /**
4
+ * Background work usually clears its wake source and wakes the session in the same
5
+ * completion handler, in either order. A drained live set therefore waits this long for
6
+ * the wake turn before Stop reports the session quiet; a turn that starts first cancels it.
7
+ */
8
+ export declare const STOP_DRAIN_GRACE_MS = 2000;
9
+ export type StopLifecycleDeps = {
10
+ readonly refreshState: (ctx: ExtensionContext) => {
11
+ readonly parsed: ParsedHookConfig;
12
+ readonly trust: HookTrustState;
13
+ };
14
+ };
15
+ export type StopLifecycle = {
16
+ readonly resetTurn: () => void;
17
+ };
18
+ /**
19
+ * Dispatches the Stop hook when the session actually stops. A turn that ends while a
20
+ * background wake source is live (subagent task, DAG run, terminal monitor, background bash
21
+ * session, detached eval cell, loop-guard hold) has handed the session to work that wakes it
22
+ * again, so its Stop waits: the wake turn's own end reports it, or the drain does when the
23
+ * work clears without waking the session.
24
+ */
25
+ export declare function registerStopLifecycle(pi: ExtensionAPI, deps: StopLifecycleDeps): StopLifecycle;
26
+ //# sourceMappingURL=stop-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-lifecycle.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/stop-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKrE,OAAO,KAAK,EAAiB,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAElF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AAUzC,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK;QACjD,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;QAClC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;KAC/B,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAsE9F"}
@@ -0,0 +1,88 @@
1
+ import { isStaleExtensionContextError } from "../goal/stale-context.js";
2
+ import { isWakeSourceStateEvent, WAKE_SOURCE_STATE_EVENT } from "../monitor-state-event.js";
3
+ import { dispatchHookEvent } from "./dispatcher.js";
4
+ import { applyStopHookResult, buildStopHookInput, createStopTurnTracker } from "./stop-adapter.js";
5
+ /**
6
+ * Background work usually clears its wake source and wakes the session in the same
7
+ * completion handler, in either order. A drained live set therefore waits this long for
8
+ * the wake turn before Stop reports the session quiet; a turn that starts first cancels it.
9
+ */
10
+ export const STOP_DRAIN_GRACE_MS = 2_000;
11
+ /** A pending question is the user's turn, which is exactly what Stop reports. */
12
+ const USER_TURN_WAKE_SOURCE = "ask-user";
13
+ /**
14
+ * Dispatches the Stop hook when the session actually stops. A turn that ends while a
15
+ * background wake source is live (subagent task, DAG run, terminal monitor, background bash
16
+ * session, detached eval cell, loop-guard hold) has handed the session to work that wakes it
17
+ * again, so its Stop waits: the wake turn's own end reports it, or the drain does when the
18
+ * work clears without waking the session.
19
+ */
20
+ export function registerStopLifecycle(pi, deps) {
21
+ const turnTracker = createStopTurnTracker();
22
+ const backgroundWork = new Map();
23
+ let pending;
24
+ let drainTimer;
25
+ async function dispatchStop({ ctx, input }) {
26
+ const state = deps.refreshState(ctx);
27
+ const result = await dispatchHookEvent({
28
+ cwd: ctx.cwd,
29
+ handlers: state.parsed.executableHandlers,
30
+ input,
31
+ signal: ctx.signal,
32
+ trustOptions: { platform: process.platform },
33
+ trustState: state.trust,
34
+ });
35
+ await applyStopHookResult(pi, ctx, result, turnTracker.turnKey(ctx));
36
+ }
37
+ function clearDrainTimer() {
38
+ if (drainTimer === undefined)
39
+ return;
40
+ clearTimeout(drainTimer);
41
+ drainTimer = undefined;
42
+ }
43
+ function dropPending() {
44
+ clearDrainTimer();
45
+ pending = undefined;
46
+ }
47
+ function dispatchPendingIfQuiet() {
48
+ drainTimer = undefined;
49
+ const stop = pending;
50
+ if (stop === undefined || backgroundWork.size > 0)
51
+ return;
52
+ // A wake turn that is already running or queued reports its own Stop when it ends.
53
+ if (!stop.ctx.isIdle() || stop.ctx.hasPendingMessages())
54
+ return;
55
+ pending = undefined;
56
+ dispatchStop(stop).catch((error) => {
57
+ if (isStaleExtensionContextError(error))
58
+ return;
59
+ stop.ctx.ui.notify(`Stop hook dispatch failed: ${error instanceof Error ? error.message : String(error)}`, "error");
60
+ });
61
+ }
62
+ pi.events.on(WAKE_SOURCE_STATE_EVENT, (data) => {
63
+ if (!isWakeSourceStateEvent(data) || data.source === USER_TURN_WAKE_SOURCE)
64
+ return;
65
+ if (data.activeCount > 0)
66
+ backgroundWork.set(data.source, data.activeCount);
67
+ else
68
+ backgroundWork.delete(data.source);
69
+ clearDrainTimer();
70
+ if (backgroundWork.size > 0 || pending === undefined)
71
+ return;
72
+ drainTimer = setTimeout(dispatchPendingIfQuiet, STOP_DRAIN_GRACE_MS);
73
+ drainTimer.unref();
74
+ });
75
+ pi.on("agent_end", async (event, ctx) => {
76
+ const stop = { ctx, input: buildStopHookInput(event, ctx) };
77
+ if (backgroundWork.size > 0) {
78
+ pending = stop;
79
+ return;
80
+ }
81
+ dropPending();
82
+ await dispatchStop(stop);
83
+ });
84
+ pi.on("agent_start", () => dropPending());
85
+ pi.on("session_shutdown", () => dropPending());
86
+ return { resetTurn: () => turnTracker.reset() };
87
+ }
88
+ //# sourceMappingURL=stop-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-lifecycle.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/stop-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { isStaleExtensionContextError } from \"../goal/stale-context.ts\";\nimport { isWakeSourceStateEvent, WAKE_SOURCE_STATE_EVENT } from \"../monitor-state-event.ts\";\nimport { dispatchHookEvent } from \"./dispatcher.ts\";\nimport { applyStopHookResult, buildStopHookInput, createStopTurnTracker } from \"./stop-adapter.ts\";\nimport type { HookInputWire, HookTrustState, ParsedHookConfig } from \"./types.ts\";\n\n/**\n * Background work usually clears its wake source and wakes the session in the same\n * completion handler, in either order. A drained live set therefore waits this long for\n * the wake turn before Stop reports the session quiet; a turn that starts first cancels it.\n */\nexport const STOP_DRAIN_GRACE_MS = 2_000;\n\n/** A pending question is the user's turn, which is exactly what Stop reports. */\nconst USER_TURN_WAKE_SOURCE = \"ask-user\";\n\ntype PendingStop = {\n\treadonly ctx: ExtensionContext;\n\treadonly input: HookInputWire;\n};\n\nexport type StopLifecycleDeps = {\n\treadonly refreshState: (ctx: ExtensionContext) => {\n\t\treadonly parsed: ParsedHookConfig;\n\t\treadonly trust: HookTrustState;\n\t};\n};\n\nexport type StopLifecycle = {\n\treadonly resetTurn: () => void;\n};\n\n/**\n * Dispatches the Stop hook when the session actually stops. A turn that ends while a\n * background wake source is live (subagent task, DAG run, terminal monitor, background bash\n * session, detached eval cell, loop-guard hold) has handed the session to work that wakes it\n * again, so its Stop waits: the wake turn's own end reports it, or the drain does when the\n * work clears without waking the session.\n */\nexport function registerStopLifecycle(pi: ExtensionAPI, deps: StopLifecycleDeps): StopLifecycle {\n\tconst turnTracker = createStopTurnTracker();\n\tconst backgroundWork = new Map<string, number>();\n\tlet pending: PendingStop | undefined;\n\tlet drainTimer: ReturnType<typeof setTimeout> | undefined;\n\n\tasync function dispatchStop({ ctx, input }: PendingStop): Promise<void> {\n\t\tconst state = deps.refreshState(ctx);\n\t\tconst result = await dispatchHookEvent({\n\t\t\tcwd: ctx.cwd,\n\t\t\thandlers: state.parsed.executableHandlers,\n\t\t\tinput,\n\t\t\tsignal: ctx.signal,\n\t\t\ttrustOptions: { platform: process.platform },\n\t\t\ttrustState: state.trust,\n\t\t});\n\t\tawait applyStopHookResult(pi, ctx, result, turnTracker.turnKey(ctx));\n\t}\n\n\tfunction clearDrainTimer(): void {\n\t\tif (drainTimer === undefined) return;\n\t\tclearTimeout(drainTimer);\n\t\tdrainTimer = undefined;\n\t}\n\n\tfunction dropPending(): void {\n\t\tclearDrainTimer();\n\t\tpending = undefined;\n\t}\n\n\tfunction dispatchPendingIfQuiet(): void {\n\t\tdrainTimer = undefined;\n\t\tconst stop = pending;\n\t\tif (stop === undefined || backgroundWork.size > 0) return;\n\t\t// A wake turn that is already running or queued reports its own Stop when it ends.\n\t\tif (!stop.ctx.isIdle() || stop.ctx.hasPendingMessages()) return;\n\t\tpending = undefined;\n\t\tdispatchStop(stop).catch((error: unknown) => {\n\t\t\tif (isStaleExtensionContextError(error)) return;\n\t\t\tstop.ctx.ui.notify(\n\t\t\t\t`Stop hook dispatch failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\"error\",\n\t\t\t);\n\t\t});\n\t}\n\n\tpi.events.on(WAKE_SOURCE_STATE_EVENT, (data) => {\n\t\tif (!isWakeSourceStateEvent(data) || data.source === USER_TURN_WAKE_SOURCE) return;\n\t\tif (data.activeCount > 0) backgroundWork.set(data.source, data.activeCount);\n\t\telse backgroundWork.delete(data.source);\n\t\tclearDrainTimer();\n\t\tif (backgroundWork.size > 0 || pending === undefined) return;\n\t\tdrainTimer = setTimeout(dispatchPendingIfQuiet, STOP_DRAIN_GRACE_MS);\n\t\tdrainTimer.unref();\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\tconst stop = { ctx, input: buildStopHookInput(event, ctx) };\n\t\tif (backgroundWork.size > 0) {\n\t\t\tpending = stop;\n\t\t\treturn;\n\t\t}\n\t\tdropPending();\n\t\tawait dispatchStop(stop);\n\t});\n\n\tpi.on(\"agent_start\", () => dropPending());\n\tpi.on(\"session_shutdown\", () => dropPending());\n\n\treturn { resetTurn: () => turnTracker.reset() };\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { ExtensionAPI } from "../../types.ts";
2
- export declare const RECOMMENDED_DEFAULT_MODELS: readonly [readonly ["kimi-k3", "max"], readonly ["gpt-6-astra", "high"], readonly ["gpt-6-sol", "medium"], readonly ["gpt-5.6-sol", "medium"], readonly ["claude-fable-5-1", "high"], readonly ["claude-opus-5-5", "max"], readonly ["glm-5.2", "max"]];
2
+ export declare const RECOMMENDED_DEFAULT_MODELS: readonly [readonly ["claude-opus-5-5", "medium", readonly ["anthropic-subscription", "anthropic", "anthropic-api", "github-copilot", "opencode"]], readonly ["claude-fable-5-1", "xhigh", readonly ["anthropic-subscription", "anthropic", "anthropic-api", "github-copilot", "opencode"]], readonly ["kimi-k3", "max", readonly ["kimi-coding", "kimi-for-coding", "moonshotai", "opencode-go"]], readonly ["gpt-6-astra", "xhigh", readonly ["chatgpt-subscription", "openai", "github-copilot", "opencode"]], readonly ["gpt-6-sol", "medium", readonly ["chatgpt-subscription", "openai", "github-copilot", "opencode"]], readonly ["glm-5.3", "max", readonly ["zai-coding-plan", "opencode-go"]]];
3
3
  export declare function canonicalModelId(modelId: string): string;
4
4
  export default function recommendedModelsExtension(pi: ExtensionAPI): void;
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/recommended-models/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAuC,MAAM,gBAAgB,CAAC;AAWxF,eAAO,MAAM,0BAA0B,yPAQ6B,CAAC;AAWrE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAcxD;AAwCD,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA6EzE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/recommended-models/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAuC,MAAM,gBAAgB,CAAC;AA0BxF,eAAO,MAAM,0BAA0B,yqBAOgD,CAAC;AAWxF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAcxD;AA8CD,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA6EzE"}
@@ -7,16 +7,29 @@ const AUTO_SWITCH_PROVENANCE = new Set([
7
7
  "first-available",
8
8
  ]);
9
9
  const MODEL_ID_SUFFIXES = ["-ultrafast", "-unlocked", "-256k", "-fast"];
10
+ // Provider lanes ranked like the category and model-profile chains: the subscription lane first.
11
+ // A shipped rung is served ONLY by its ranked lanes, so gateway aggregators (opengateway,
12
+ // openrouter, vercel-ai-gateway) and other resellers are never pulled in. A `recommendedModels`
13
+ // override id outside this table carries no ranking and any provider may serve it.
14
+ const CLAUDE_PROVIDERS = [
15
+ "anthropic-subscription",
16
+ "anthropic",
17
+ "anthropic-api",
18
+ "github-copilot",
19
+ "opencode",
20
+ ];
21
+ const KIMI_PROVIDERS = ["kimi-coding", "kimi-for-coding", "moonshotai", "opencode-go"];
22
+ const GPT_PROVIDERS = ["chatgpt-subscription", "openai", "github-copilot", "opencode"];
23
+ const GLM_PROVIDERS = ["zai-coding-plan", "opencode-go"];
10
24
  export const RECOMMENDED_DEFAULT_MODELS = [
11
- ["kimi-k3", "max"],
12
- ["gpt-6-astra", "high"],
13
- ["gpt-6-sol", "medium"],
14
- ["gpt-5.6-sol", "medium"],
15
- ["claude-fable-5-1", "high"],
16
- ["claude-opus-5-5", "max"],
17
- ["glm-5.2", "max"],
25
+ ["claude-opus-5-5", "medium", CLAUDE_PROVIDERS],
26
+ ["claude-fable-5-1", "xhigh", CLAUDE_PROVIDERS],
27
+ ["kimi-k3", "max", KIMI_PROVIDERS],
28
+ ["gpt-6-astra", "xhigh", GPT_PROVIDERS],
29
+ ["gpt-6-sol", "medium", GPT_PROVIDERS],
30
+ ["glm-5.3", "max", GLM_PROVIDERS],
18
31
  ];
19
- const DEFAULT_RECOMMENDATIONS = RECOMMENDED_DEFAULT_MODELS.map(([modelId, thinkingLevel]) => ({ modelId, thinkingLevel }));
32
+ const DEFAULT_RECOMMENDATIONS = RECOMMENDED_DEFAULT_MODELS.map(([modelId, thinkingLevel, providers]) => ({ modelId, thinkingLevel, providers }));
20
33
  const DEFAULT_RECOMMENDATIONS_BY_MODEL_ID = new Map(DEFAULT_RECOMMENDATIONS.map((recommendation) => [recommendation.modelId, recommendation]));
21
34
  export function canonicalModelId(modelId) {
22
35
  let canonical = modelId.toLowerCase();
@@ -40,12 +53,17 @@ function recommendationsFor(configuredModelIds) {
40
53
  return configuredModelIds
41
54
  .map(canonicalModelId)
42
55
  .filter((modelId) => modelId.length > 0)
43
- .map((modelId) => DEFAULT_RECOMMENDATIONS_BY_MODEL_ID.get(modelId) ?? { modelId, thinkingLevel: "medium" });
56
+ .map((modelId) => DEFAULT_RECOMMENDATIONS_BY_MODEL_ID.get(modelId) ?? { modelId, thinkingLevel: "medium", providers: [] });
44
57
  }
45
58
  function findAvailableRecommendation(recommendations, ctx) {
46
59
  const available = ctx.modelRegistry.getAvailable().filter((model) => ctx.modelRegistry.hasConfiguredAuth(model));
47
60
  for (const recommendation of recommendations) {
48
- const model = available.find((candidate) => canonicalModelId(candidate.id) === recommendation.modelId);
61
+ const candidates = available.filter((candidate) => canonicalModelId(candidate.id) === recommendation.modelId);
62
+ const model = recommendation.providers.length === 0
63
+ ? candidates[0]
64
+ : recommendation.providers
65
+ .map((provider) => candidates.find((candidate) => candidate.provider === provider))
66
+ .find((candidate) => candidate !== undefined);
49
67
  if (model) {
50
68
  return { recommendation, model };
51
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/recommended-models/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAG/D,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAC1C,yFAAyF;AACzF,qFAAqF;AACrF,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAA2D;IAChG,kBAAkB;IAClB,iBAAiB;CACjB,CAAC,CAAC;AACH,MAAM,iBAAiB,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,CAAU,CAAC;AAEjF,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACzC,CAAC,SAAS,EAAE,KAAK,CAAC;IAClB,CAAC,aAAa,EAAE,MAAM,CAAC;IACvB,CAAC,WAAW,EAAE,QAAQ,CAAC;IACvB,CAAC,aAAa,EAAE,QAAQ,CAAC;IACzB,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAC5B,CAAC,iBAAiB,EAAE,KAAK,CAAC;IAC1B,CAAC,SAAS,EAAE,KAAK,CAAC;CACiD,CAAC;AAIrE,MAAM,uBAAuB,GAAgC,0BAA0B,CAAC,GAAG,CAC1F,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAC1D,CAAC;AACF,MAAM,mCAAmC,GAAG,IAAI,GAAG,CAClD,uBAAuB,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CACzF,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC/C,IAAI,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACtC,IAAI,cAAc,GAAG,IAAI,CAAC;IAC1B,OAAO,cAAc,EAAE,CAAC;QACvB,cAAc,GAAG,KAAK,CAAC;QACvB,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE,CAAC;YACxC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC/C,cAAc,GAAG,IAAI,CAAC;gBACtB,MAAM;YACP,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AACnD,CAAC;AAED,SAAS,kBAAkB,CAAC,kBAAwC;IACnE,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,uBAAuB,CAAC;IAChC,CAAC;IACD,OAAO,kBAAkB;SACvB,GAAG,CAAC,gBAAgB,CAAC;SACrB,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;SACvC,GAAG,CACH,CAAC,OAAO,EAAoB,EAAE,CAC7B,mCAAmC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,CACzF,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CACnC,eAA4C,EAC5C,GAAqB;IAErB,MAAM,SAAS,GAAG,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;IACjH,KAAK,MAAM,cAAc,IAAI,eAAe,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,cAAc,CAAC,OAAO,CAAC,CAAC;QACvG,IAAI,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;QAClC,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,KAA6B,EAAE,eAA4C;IACjG,OAAO,CACN,KAAK,KAAK,SAAS;QACnB,eAAe,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,cAAc,CAAC,OAAO,CAAC,CAC/F,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,KAA6B;IAChE,OAAO,0BAA0B,KAAK,EAAE,EAAE,IAAI,QAAQ,yEAAyE,CAAC;AACjI,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAAC,EAAgB;IAClE,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE;QAC1B,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,mDAAmD;KAChE,CAAC,CAAC;IAEH,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAC/B,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,eAAe,GAAgC,uBAAuB,CAAC;IAE3E,MAAM,mCAAmC,GAAG,CAAC,GAAqB,EAAQ,EAAE;QAC3E,IAAI,YAAY,IAAI,2BAA2B,CAAC,eAAe,EAAE,GAAG,CAAC,EAAE,CAAC;YACvE,OAAO;QACR,CAAC;QACD,YAAY,GAAG,IAAI,CAAC;QACpB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,0BAA0B,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IACjE,CAAC,CAAC;IAEF,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC3C,IAAI,WAAW,EAAE,CAAC;YACjB,OAAO;QACR,CAAC;QACD,WAAW,GAAG,IAAI,CAAC;QAEnB,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxD,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,mBAAmB,KAAK,IAAI,CAAC;QACxG,eAAe,GAAG,kBAAkB,CAAC,eAAe,CAAC,oBAAoB,EAAE,CAAC,CAAC;QAC7E,aAAa;YACZ,GAAG,CAAC,IAAI,KAAK,YAAY;gBACzB,KAAK,CAAC,sBAAsB,KAAK,SAAS;gBAC1C,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1D,IAAI,QAAQ,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC;YAC7E,OAAO;QACR,CAAC;QAED,MAAM,MAAM,GAAG,2BAA2B,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,mCAAmC,CAAC,GAAG,CAAC,CAAC;YACzC,OAAO;QACR,CAAC;QAED,MAAM,gBAAgB,GAAG,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC;QAC5C,kBAAkB,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7G,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,mCAAmC,CAAC,GAAG,CAAC,CAAC;gBACzC,OAAO;YACR,CAAC;YACD,IAAI,gBAAgB,EAAE,CAAC;gBACtB,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;YAC1D,CAAC;iBAAM,CAAC;gBACP,EAAE,CAAC,uBAAuB,CAAC,MAAM,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;YACjE,CAAC;YACD,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,kCAAkC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9E,CAAC;gBAAS,CAAC;YACV,kBAAkB,GAAG,KAAK,CAAC;QAC5B,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACpC,IAAI,CAAC,WAAW,IAAI,QAAQ,IAAI,QAAQ,IAAI,kBAAkB,IAAI,CAAC,aAAa,EAAE,CAAC;YAClF,OAAO;QACR,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YACxD,QAAQ,GAAG,IAAI,CAAC;YAChB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE,CAAC;YAClD,mCAAmC,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { SettingsManager } from \"../../../settings-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext, SessionStartEvent } from \"../../types.ts\";\n\nconst FLAG_NAME = \"no-recommended-models\";\n// Only implicit fallbacks auto-switch. A `settings` provenance means the user explicitly\n// configured a system default model, which must be respected rather than overridden.\nconst AUTO_SWITCH_PROVENANCE = new Set<NonNullable<SessionStartEvent[\"initialModelProvenance\"]>>([\n\t\"provider-default\",\n\t\"first-available\",\n]);\nconst MODEL_ID_SUFFIXES = [\"-ultrafast\", \"-unlocked\", \"-256k\", \"-fast\"] as const;\n\nexport const RECOMMENDED_DEFAULT_MODELS = [\n\t[\"kimi-k3\", \"max\"],\n\t[\"gpt-6-astra\", \"high\"],\n\t[\"gpt-6-sol\", \"medium\"],\n\t[\"gpt-5.6-sol\", \"medium\"],\n\t[\"claude-fable-5-1\", \"high\"],\n\t[\"claude-opus-5-5\", \"max\"],\n\t[\"glm-5.2\", \"max\"],\n] as const satisfies ReadonlyArray<readonly [string, ThinkingLevel]>;\n\ntype RecommendedModel = { modelId: string; thinkingLevel: ThinkingLevel };\n\nconst DEFAULT_RECOMMENDATIONS: readonly RecommendedModel[] = RECOMMENDED_DEFAULT_MODELS.map(\n\t([modelId, thinkingLevel]) => ({ modelId, thinkingLevel }),\n);\nconst DEFAULT_RECOMMENDATIONS_BY_MODEL_ID = new Map(\n\tDEFAULT_RECOMMENDATIONS.map((recommendation) => [recommendation.modelId, recommendation]),\n);\n\nexport function canonicalModelId(modelId: string): string {\n\tlet canonical = modelId.toLowerCase();\n\tlet strippedSuffix = true;\n\twhile (strippedSuffix) {\n\t\tstrippedSuffix = false;\n\t\tfor (const suffix of MODEL_ID_SUFFIXES) {\n\t\t\tif (canonical.endsWith(suffix)) {\n\t\t\t\tcanonical = canonical.slice(0, -suffix.length);\n\t\t\t\tstrippedSuffix = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn canonical === \"k3\" ? \"kimi-k3\" : canonical;\n}\n\nfunction recommendationsFor(configuredModelIds: string[] | undefined): readonly RecommendedModel[] {\n\tif (configuredModelIds === undefined) {\n\t\treturn DEFAULT_RECOMMENDATIONS;\n\t}\n\treturn configuredModelIds\n\t\t.map(canonicalModelId)\n\t\t.filter((modelId) => modelId.length > 0)\n\t\t.map(\n\t\t\t(modelId): RecommendedModel =>\n\t\t\t\tDEFAULT_RECOMMENDATIONS_BY_MODEL_ID.get(modelId) ?? { modelId, thinkingLevel: \"medium\" },\n\t\t);\n}\n\nfunction findAvailableRecommendation(\n\trecommendations: readonly RecommendedModel[],\n\tctx: ExtensionContext,\n): { recommendation: RecommendedModel; model: Model<Api> } | undefined {\n\tconst available = ctx.modelRegistry.getAvailable().filter((model) => ctx.modelRegistry.hasConfiguredAuth(model));\n\tfor (const recommendation of recommendations) {\n\t\tconst model = available.find((candidate) => canonicalModelId(candidate.id) === recommendation.modelId);\n\t\tif (model) {\n\t\t\treturn { recommendation, model };\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction isRecommended(model: Model<Api> | undefined, recommendations: readonly RecommendedModel[]): boolean {\n\treturn (\n\t\tmodel !== undefined &&\n\t\trecommendations.some((recommendation) => canonicalModelId(model.id) === recommendation.modelId)\n\t);\n}\n\nfunction nonRecommendedModelWarning(model: Model<Api> | undefined): string {\n\treturn `Non-recommended model '${model?.id ?? \"<none>\"}': odd behavior is the default state; a working session is the anomaly.`;\n}\n\nexport default function recommendedModelsExtension(pi: ExtensionAPI): void {\n\tpi.registerFlag(FLAG_NAME, {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable recommended model selection for this run.\",\n\t});\n\n\tlet initialized = false;\n\tlet disabled = false;\n\tlet disarmed = false;\n\tlet automaticSelection = false;\n\tlet warningShown = false;\n\tlet canAutoSwitch = false;\n\tlet recommendations: readonly RecommendedModel[] = DEFAULT_RECOMMENDATIONS;\n\n\tconst warnWhenNoRecommendationIsAvailable = (ctx: ExtensionContext): void => {\n\t\tif (warningShown || findAvailableRecommendation(recommendations, ctx)) {\n\t\t\treturn;\n\t\t}\n\t\twarningShown = true;\n\t\tctx.ui.notify(nonRecommendedModelWarning(ctx.model), \"warning\");\n\t};\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tif (initialized) {\n\t\t\treturn;\n\t\t}\n\t\tinitialized = true;\n\n\t\tconst settingsManager = SettingsManager.create(ctx.cwd);\n\t\tdisabled = pi.getFlag(FLAG_NAME) === true || settingsManager.getWarnings().offRecommendedModel === true;\n\t\trecommendations = recommendationsFor(settingsManager.getRecommendedModels());\n\t\tcanAutoSwitch =\n\t\t\tctx.mode !== \"app-server\" &&\n\t\t\tevent.initialModelProvenance !== undefined &&\n\t\t\tAUTO_SWITCH_PROVENANCE.has(event.initialModelProvenance);\n\t\tif (disabled || !canAutoSwitch || isRecommended(ctx.model, recommendations)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst target = findAvailableRecommendation(recommendations, ctx);\n\t\tif (!target) {\n\t\t\twarnWhenNoRecommendationIsAvailable(ctx);\n\t\t\treturn;\n\t\t}\n\n\t\tconst persistAsDefault = ctx.mode === \"tui\";\n\t\tautomaticSelection = true;\n\t\ttry {\n\t\t\tconst switched = persistAsDefault ? await pi.setModel(target.model) : await pi.setSessionModel(target.model);\n\t\t\tif (!switched) {\n\t\t\t\twarnWhenNoRecommendationIsAvailable(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (persistAsDefault) {\n\t\t\t\tpi.setThinkingLevel(target.recommendation.thinkingLevel);\n\t\t\t} else {\n\t\t\t\tpi.setSessionThinkingLevel(target.recommendation.thinkingLevel);\n\t\t\t}\n\t\t\tctx.ui.notify(`Switched to recommended model '${target.model.id}'.`, \"info\");\n\t\t} finally {\n\t\t\tautomaticSelection = false;\n\t\t}\n\t});\n\n\tpi.on(\"model_select\", (event, ctx) => {\n\t\tif (!initialized || disabled || disarmed || automaticSelection || !canAutoSwitch) {\n\t\t\treturn;\n\t\t}\n\t\tif (event.source === \"set\" || event.source === \"cycle\") {\n\t\t\tdisarmed = true;\n\t\t\treturn;\n\t\t}\n\t\tif (!isRecommended(event.model, recommendations)) {\n\t\t\twarnWhenNoRecommendationIsAvailable(ctx);\n\t\t}\n\t});\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/recommended-models/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { SettingsManager } from \"../../../settings-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext, SessionStartEvent } from \"../../types.ts\";\n\nconst FLAG_NAME = \"no-recommended-models\";\n// Only implicit fallbacks auto-switch. A `settings` provenance means the user explicitly\n// configured a system default model, which must be respected rather than overridden.\nconst AUTO_SWITCH_PROVENANCE = new Set<NonNullable<SessionStartEvent[\"initialModelProvenance\"]>>([\n\t\"provider-default\",\n\t\"first-available\",\n]);\nconst MODEL_ID_SUFFIXES = [\"-ultrafast\", \"-unlocked\", \"-256k\", \"-fast\"] as const;\n\n// Provider lanes ranked like the category and model-profile chains: the subscription lane first.\n// A shipped rung is served ONLY by its ranked lanes, so gateway aggregators (opengateway,\n// openrouter, vercel-ai-gateway) and other resellers are never pulled in. A `recommendedModels`\n// override id outside this table carries no ranking and any provider may serve it.\nconst CLAUDE_PROVIDERS = [\n\t\"anthropic-subscription\",\n\t\"anthropic\",\n\t\"anthropic-api\",\n\t\"github-copilot\",\n\t\"opencode\",\n] as const;\nconst KIMI_PROVIDERS = [\"kimi-coding\", \"kimi-for-coding\", \"moonshotai\", \"opencode-go\"] as const;\nconst GPT_PROVIDERS = [\"chatgpt-subscription\", \"openai\", \"github-copilot\", \"opencode\"] as const;\nconst GLM_PROVIDERS = [\"zai-coding-plan\", \"opencode-go\"] as const;\n\nexport const RECOMMENDED_DEFAULT_MODELS = [\n\t[\"claude-opus-5-5\", \"medium\", CLAUDE_PROVIDERS],\n\t[\"claude-fable-5-1\", \"xhigh\", CLAUDE_PROVIDERS],\n\t[\"kimi-k3\", \"max\", KIMI_PROVIDERS],\n\t[\"gpt-6-astra\", \"xhigh\", GPT_PROVIDERS],\n\t[\"gpt-6-sol\", \"medium\", GPT_PROVIDERS],\n\t[\"glm-5.3\", \"max\", GLM_PROVIDERS],\n] as const satisfies ReadonlyArray<readonly [string, ThinkingLevel, readonly string[]]>;\n\ntype RecommendedModel = { modelId: string; thinkingLevel: ThinkingLevel; providers: readonly string[] };\n\nconst DEFAULT_RECOMMENDATIONS: readonly RecommendedModel[] = RECOMMENDED_DEFAULT_MODELS.map(\n\t([modelId, thinkingLevel, providers]) => ({ modelId, thinkingLevel, providers }),\n);\nconst DEFAULT_RECOMMENDATIONS_BY_MODEL_ID = new Map(\n\tDEFAULT_RECOMMENDATIONS.map((recommendation) => [recommendation.modelId, recommendation]),\n);\n\nexport function canonicalModelId(modelId: string): string {\n\tlet canonical = modelId.toLowerCase();\n\tlet strippedSuffix = true;\n\twhile (strippedSuffix) {\n\t\tstrippedSuffix = false;\n\t\tfor (const suffix of MODEL_ID_SUFFIXES) {\n\t\t\tif (canonical.endsWith(suffix)) {\n\t\t\t\tcanonical = canonical.slice(0, -suffix.length);\n\t\t\t\tstrippedSuffix = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn canonical === \"k3\" ? \"kimi-k3\" : canonical;\n}\n\nfunction recommendationsFor(configuredModelIds: string[] | undefined): readonly RecommendedModel[] {\n\tif (configuredModelIds === undefined) {\n\t\treturn DEFAULT_RECOMMENDATIONS;\n\t}\n\treturn configuredModelIds\n\t\t.map(canonicalModelId)\n\t\t.filter((modelId) => modelId.length > 0)\n\t\t.map(\n\t\t\t(modelId): RecommendedModel =>\n\t\t\t\tDEFAULT_RECOMMENDATIONS_BY_MODEL_ID.get(modelId) ?? { modelId, thinkingLevel: \"medium\", providers: [] },\n\t\t);\n}\n\nfunction findAvailableRecommendation(\n\trecommendations: readonly RecommendedModel[],\n\tctx: ExtensionContext,\n): { recommendation: RecommendedModel; model: Model<Api> } | undefined {\n\tconst available = ctx.modelRegistry.getAvailable().filter((model) => ctx.modelRegistry.hasConfiguredAuth(model));\n\tfor (const recommendation of recommendations) {\n\t\tconst candidates = available.filter((candidate) => canonicalModelId(candidate.id) === recommendation.modelId);\n\t\tconst model =\n\t\t\trecommendation.providers.length === 0\n\t\t\t\t? candidates[0]\n\t\t\t\t: recommendation.providers\n\t\t\t\t\t\t.map((provider) => candidates.find((candidate) => candidate.provider === provider))\n\t\t\t\t\t\t.find((candidate) => candidate !== undefined);\n\t\tif (model) {\n\t\t\treturn { recommendation, model };\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction isRecommended(model: Model<Api> | undefined, recommendations: readonly RecommendedModel[]): boolean {\n\treturn (\n\t\tmodel !== undefined &&\n\t\trecommendations.some((recommendation) => canonicalModelId(model.id) === recommendation.modelId)\n\t);\n}\n\nfunction nonRecommendedModelWarning(model: Model<Api> | undefined): string {\n\treturn `Non-recommended model '${model?.id ?? \"<none>\"}': odd behavior is the default state; a working session is the anomaly.`;\n}\n\nexport default function recommendedModelsExtension(pi: ExtensionAPI): void {\n\tpi.registerFlag(FLAG_NAME, {\n\t\ttype: \"boolean\",\n\t\tdefault: false,\n\t\tdescription: \"Disable recommended model selection for this run.\",\n\t});\n\n\tlet initialized = false;\n\tlet disabled = false;\n\tlet disarmed = false;\n\tlet automaticSelection = false;\n\tlet warningShown = false;\n\tlet canAutoSwitch = false;\n\tlet recommendations: readonly RecommendedModel[] = DEFAULT_RECOMMENDATIONS;\n\n\tconst warnWhenNoRecommendationIsAvailable = (ctx: ExtensionContext): void => {\n\t\tif (warningShown || findAvailableRecommendation(recommendations, ctx)) {\n\t\t\treturn;\n\t\t}\n\t\twarningShown = true;\n\t\tctx.ui.notify(nonRecommendedModelWarning(ctx.model), \"warning\");\n\t};\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tif (initialized) {\n\t\t\treturn;\n\t\t}\n\t\tinitialized = true;\n\n\t\tconst settingsManager = SettingsManager.create(ctx.cwd);\n\t\tdisabled = pi.getFlag(FLAG_NAME) === true || settingsManager.getWarnings().offRecommendedModel === true;\n\t\trecommendations = recommendationsFor(settingsManager.getRecommendedModels());\n\t\tcanAutoSwitch =\n\t\t\tctx.mode !== \"app-server\" &&\n\t\t\tevent.initialModelProvenance !== undefined &&\n\t\t\tAUTO_SWITCH_PROVENANCE.has(event.initialModelProvenance);\n\t\tif (disabled || !canAutoSwitch || isRecommended(ctx.model, recommendations)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst target = findAvailableRecommendation(recommendations, ctx);\n\t\tif (!target) {\n\t\t\twarnWhenNoRecommendationIsAvailable(ctx);\n\t\t\treturn;\n\t\t}\n\n\t\tconst persistAsDefault = ctx.mode === \"tui\";\n\t\tautomaticSelection = true;\n\t\ttry {\n\t\t\tconst switched = persistAsDefault ? await pi.setModel(target.model) : await pi.setSessionModel(target.model);\n\t\t\tif (!switched) {\n\t\t\t\twarnWhenNoRecommendationIsAvailable(ctx);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (persistAsDefault) {\n\t\t\t\tpi.setThinkingLevel(target.recommendation.thinkingLevel);\n\t\t\t} else {\n\t\t\t\tpi.setSessionThinkingLevel(target.recommendation.thinkingLevel);\n\t\t\t}\n\t\t\tctx.ui.notify(`Switched to recommended model '${target.model.id}'.`, \"info\");\n\t\t} finally {\n\t\t\tautomaticSelection = false;\n\t\t}\n\t});\n\n\tpi.on(\"model_select\", (event, ctx) => {\n\t\tif (!initialized || disabled || disarmed || automaticSelection || !canAutoSwitch) {\n\t\t\treturn;\n\t\t}\n\t\tif (event.source === \"set\" || event.source === \"cycle\") {\n\t\t\tdisarmed = true;\n\t\t\treturn;\n\t\t}\n\t\tif (!isRecommended(event.model, recommendations)) {\n\t\t\twarnWhenNoRecommendationIsAvailable(ctx);\n\t\t}\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/rules/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;AAE5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAKhD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAwD5E"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/rules/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;AAE5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAKhD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA6D5E"}
@@ -22,7 +22,11 @@ export function registerSlashCommands(pi, engine) {
22
22
  return;
23
23
  }
24
24
  if (subcommand === "show") {
25
- const id = tokens[1] ?? "";
25
+ const id = tokens[1];
26
+ if (id === undefined) {
27
+ notify(ctx, "Rule ID is required", "error");
28
+ return;
29
+ }
26
30
  const rule = findRuleById(loaded.rules, id);
27
31
  if (rule === null) {
28
32
  notify(ctx, `Rule not found: ${id}`, "error");
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/rules/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\n\nimport type { Engine } from \"./rules/engine.ts\";\nimport type { LoadedRule, MatchReason, RuleDiagnostic } from \"./rules/types.ts\";\n\nconst RULE_SUBCOMMANDS = [\"list\", \"show\", \"paths\", \"status\"] as const;\n\nexport function registerSlashCommands(pi: ExtensionAPI, engine: Engine): void {\n\tpi.registerCommand(\"rules\", {\n\t\tdescription: \"Inspect loaded pi-rules.\",\n\t\tgetArgumentCompletions: (prefix) => {\n\t\t\tconst completions = RULE_SUBCOMMANDS.filter((subcommand) => subcommand.startsWith(prefix)).map(\n\t\t\t\t(subcommand) => ({\n\t\t\t\t\tvalue: subcommand,\n\t\t\t\t\tlabel: subcommand,\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn completions.length > 0 ? completions : null;\n\t\t},\n\t\thandler: async (args, ctx) => {\n\t\t\tconst tokens = args.trim().length === 0 ? [] : args.trim().split(/\\s+/);\n\t\t\tconst subcommand = tokens[0] ?? \"\";\n\t\t\tconst loaded = engine.loadStaticRules(ctx.cwd);\n\n\t\t\tif (subcommand === \"\" || subcommand === \"status\") {\n\t\t\t\tnotify(ctx, buildSummaryText(loaded.rules, loaded.diagnostics));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (subcommand === \"list\") {\n\t\t\t\tnotify(ctx, formatRuleList(loaded.rules));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (subcommand === \"show\") {\n\t\t\t\tconst id = tokens[1] ?? \"\";\n\t\t\t\tconst rule = findRuleById(loaded.rules, id);\n\t\t\t\tif (rule === null) {\n\t\t\t\t\tnotify(ctx, `Rule not found: ${id}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tnotify(ctx, rule.body);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (subcommand === \"paths\") {\n\t\t\t\tnotify(ctx, loaded.rules.map((rule) => rule.path).join(\"\\n\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tnotify(ctx, `Unknown /rules subcommand: ${subcommand}`, \"error\");\n\t\t},\n\t});\n\n\tpi.registerCommand(\"reload-rules\", {\n\t\tdescription: \"Reload pi-rules for the current session.\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tengine.resetSession(ctx.cwd);\n\t\t\tconst loaded = engine.loadStaticRules(ctx.cwd);\n\t\t\tnotify(ctx, buildReloadText(loaded.rules, loaded.diagnostics));\n\t\t},\n\t});\n}\n\nfunction notify(ctx: ExtensionCommandContext, message: string, severity: \"info\" | \"warning\" | \"error\" = \"info\"): void {\n\tctx.ui.notify(message, severity);\n}\n\nfunction buildSummaryText(rules: ReadonlyArray<LoadedRule>, diagnostics: ReadonlyArray<RuleDiagnostic>): string {\n\treturn appendDiagnostics(`pi-rules: ${rules.length} rules from ${countSources(rules)} sources`, diagnostics);\n}\n\nfunction buildReloadText(rules: ReadonlyArray<LoadedRule>, diagnostics: ReadonlyArray<RuleDiagnostic>): string {\n\treturn appendDiagnostics(`Reloaded ${rules.length} rules from ${countSources(rules)} sources`, diagnostics);\n}\n\nfunction appendDiagnostics(text: string, diagnostics: ReadonlyArray<RuleDiagnostic>): string {\n\treturn diagnostics.length === 0 ? text : `${text}, ${diagnostics.length} diagnostics`;\n}\n\nfunction countSources(rules: ReadonlyArray<LoadedRule>): number {\n\treturn new Set(rules.map((rule) => rule.source)).size;\n}\n\nfunction formatRuleList(rules: ReadonlyArray<LoadedRule>): string {\n\treturn rules\n\t\t.map((rule) => `${rule.relativePath} [${rule.source}, ${formatMatchReason(rule.matchReason)}]`)\n\t\t.join(\"\\n\");\n}\n\nfunction formatMatchReason(matchReason: MatchReason): string {\n\tif (typeof matchReason === \"string\") {\n\t\treturn matchReason;\n\t}\n\tif (matchReason.kind === \"no-match\") {\n\t\treturn matchReason.kind;\n\t}\n\n\treturn `${matchReason.kind}:${matchReason.pattern}`;\n}\n\nfunction findRuleById(rules: ReadonlyArray<LoadedRule>, id: string): LoadedRule | null {\n\tconst exactMatch = rules.find((rule) => rule.relativePath === id);\n\tif (exactMatch !== undefined) {\n\t\treturn exactMatch;\n\t}\n\n\tconst suffixMatches = rules.filter((rule) => rule.relativePath.endsWith(id));\n\treturn suffixMatches.length === 1 ? (suffixMatches[0] ?? null) : null;\n}\n"]}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/rules/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\n\nimport type { Engine } from \"./rules/engine.ts\";\nimport type { LoadedRule, MatchReason, RuleDiagnostic } from \"./rules/types.ts\";\n\nconst RULE_SUBCOMMANDS = [\"list\", \"show\", \"paths\", \"status\"] as const;\n\nexport function registerSlashCommands(pi: ExtensionAPI, engine: Engine): void {\n\tpi.registerCommand(\"rules\", {\n\t\tdescription: \"Inspect loaded pi-rules.\",\n\t\tgetArgumentCompletions: (prefix) => {\n\t\t\tconst completions = RULE_SUBCOMMANDS.filter((subcommand) => subcommand.startsWith(prefix)).map(\n\t\t\t\t(subcommand) => ({\n\t\t\t\t\tvalue: subcommand,\n\t\t\t\t\tlabel: subcommand,\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn completions.length > 0 ? completions : null;\n\t\t},\n\t\thandler: async (args, ctx) => {\n\t\t\tconst tokens = args.trim().length === 0 ? [] : args.trim().split(/\\s+/);\n\t\t\tconst subcommand = tokens[0] ?? \"\";\n\t\t\tconst loaded = engine.loadStaticRules(ctx.cwd);\n\n\t\t\tif (subcommand === \"\" || subcommand === \"status\") {\n\t\t\t\tnotify(ctx, buildSummaryText(loaded.rules, loaded.diagnostics));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (subcommand === \"list\") {\n\t\t\t\tnotify(ctx, formatRuleList(loaded.rules));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (subcommand === \"show\") {\n\t\t\t\tconst id = tokens[1];\n\t\t\t\tif (id === undefined) {\n\t\t\t\t\tnotify(ctx, \"Rule ID is required\", \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst rule = findRuleById(loaded.rules, id);\n\t\t\t\tif (rule === null) {\n\t\t\t\t\tnotify(ctx, `Rule not found: ${id}`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tnotify(ctx, rule.body);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (subcommand === \"paths\") {\n\t\t\t\tnotify(ctx, loaded.rules.map((rule) => rule.path).join(\"\\n\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tnotify(ctx, `Unknown /rules subcommand: ${subcommand}`, \"error\");\n\t\t},\n\t});\n\n\tpi.registerCommand(\"reload-rules\", {\n\t\tdescription: \"Reload pi-rules for the current session.\",\n\t\thandler: async (_args, ctx) => {\n\t\t\tengine.resetSession(ctx.cwd);\n\t\t\tconst loaded = engine.loadStaticRules(ctx.cwd);\n\t\t\tnotify(ctx, buildReloadText(loaded.rules, loaded.diagnostics));\n\t\t},\n\t});\n}\n\nfunction notify(ctx: ExtensionCommandContext, message: string, severity: \"info\" | \"warning\" | \"error\" = \"info\"): void {\n\tctx.ui.notify(message, severity);\n}\n\nfunction buildSummaryText(rules: ReadonlyArray<LoadedRule>, diagnostics: ReadonlyArray<RuleDiagnostic>): string {\n\treturn appendDiagnostics(`pi-rules: ${rules.length} rules from ${countSources(rules)} sources`, diagnostics);\n}\n\nfunction buildReloadText(rules: ReadonlyArray<LoadedRule>, diagnostics: ReadonlyArray<RuleDiagnostic>): string {\n\treturn appendDiagnostics(`Reloaded ${rules.length} rules from ${countSources(rules)} sources`, diagnostics);\n}\n\nfunction appendDiagnostics(text: string, diagnostics: ReadonlyArray<RuleDiagnostic>): string {\n\treturn diagnostics.length === 0 ? text : `${text}, ${diagnostics.length} diagnostics`;\n}\n\nfunction countSources(rules: ReadonlyArray<LoadedRule>): number {\n\treturn new Set(rules.map((rule) => rule.source)).size;\n}\n\nfunction formatRuleList(rules: ReadonlyArray<LoadedRule>): string {\n\treturn rules\n\t\t.map((rule) => `${rule.relativePath} [${rule.source}, ${formatMatchReason(rule.matchReason)}]`)\n\t\t.join(\"\\n\");\n}\n\nfunction formatMatchReason(matchReason: MatchReason): string {\n\tif (typeof matchReason === \"string\") {\n\t\treturn matchReason;\n\t}\n\tif (matchReason.kind === \"no-match\") {\n\t\treturn matchReason.kind;\n\t}\n\n\treturn `${matchReason.kind}:${matchReason.pattern}`;\n}\n\nfunction findRuleById(rules: ReadonlyArray<LoadedRule>, id: string): LoadedRule | null {\n\tconst exactMatch = rules.find((rule) => rule.relativePath === id);\n\tif (exactMatch !== undefined) {\n\t\treturn exactMatch;\n\t}\n\n\tconst suffixMatches = rules.filter((rule) => rule.relativePath.endsWith(id));\n\treturn suffixMatches.length === 1 ? (suffixMatches[0] ?? null) : null;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/rules/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAgBnD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA2I/D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/rules/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAgBnD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAiK/D"}