@code-yeongyu/senpi 2026.9.12-3 → 2026.9.13-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 (270) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +3 -1
  3. package/dist/bun/cli.js +2 -3
  4. package/dist/bun/cli.js.map +1 -1
  5. package/dist/bun/runtime-modules.d.ts +3 -0
  6. package/dist/bun/runtime-modules.d.ts.map +1 -0
  7. package/dist/bun/runtime-modules.js +17 -0
  8. package/dist/bun/runtime-modules.js.map +1 -0
  9. package/dist/bun/runtime-setup.js +2 -5
  10. package/dist/bun/runtime-setup.js.map +1 -1
  11. package/dist/core/agent-session.d.ts +2 -2
  12. package/dist/core/agent-session.d.ts.map +1 -1
  13. package/dist/core/agent-session.js +38 -30
  14. package/dist/core/agent-session.js.map +1 -1
  15. package/dist/core/discovered-resource-scope.d.ts +23 -0
  16. package/dist/core/discovered-resource-scope.d.ts.map +1 -0
  17. package/dist/core/discovered-resource-scope.js +44 -0
  18. package/dist/core/discovered-resource-scope.js.map +1 -0
  19. package/dist/core/extensions/builtin/ask-user/notify.d.ts +24 -0
  20. package/dist/core/extensions/builtin/ask-user/notify.d.ts.map +1 -0
  21. package/dist/core/extensions/builtin/ask-user/notify.js +11 -0
  22. package/dist/core/extensions/builtin/ask-user/notify.js.map +1 -0
  23. package/dist/core/extensions/builtin/ask-user/registry.d.ts +2 -0
  24. package/dist/core/extensions/builtin/ask-user/registry.d.ts.map +1 -1
  25. package/dist/core/extensions/builtin/ask-user/registry.js.map +1 -1
  26. package/dist/core/extensions/builtin/ask-user/resume.d.ts +1 -1
  27. package/dist/core/extensions/builtin/ask-user/resume.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/ask-user/resume.js +10 -20
  29. package/dist/core/extensions/builtin/ask-user/resume.js.map +1 -1
  30. package/dist/core/extensions/builtin/ask-user/tool.d.ts +5 -2
  31. package/dist/core/extensions/builtin/ask-user/tool.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/ask-user/tool.js +41 -6
  33. package/dist/core/extensions/builtin/ask-user/tool.js.map +1 -1
  34. package/dist/core/extensions/builtin/goal/channel-state-subscriptions.d.ts +2 -1
  35. package/dist/core/extensions/builtin/goal/channel-state-subscriptions.d.ts.map +1 -1
  36. package/dist/core/extensions/builtin/goal/channel-state-subscriptions.js +1 -1
  37. package/dist/core/extensions/builtin/goal/channel-state-subscriptions.js.map +1 -1
  38. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/goal/monitor-continuation.js +27 -13
  40. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  41. package/dist/core/extensions/builtin/hooks/config-loader.d.ts +2 -0
  42. package/dist/core/extensions/builtin/hooks/config-loader.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/hooks/config-loader.js +27 -0
  44. package/dist/core/extensions/builtin/hooks/config-loader.js.map +1 -1
  45. package/dist/core/extensions/builtin/hooks/dispatcher.js +1 -0
  46. package/dist/core/extensions/builtin/hooks/dispatcher.js.map +1 -1
  47. package/dist/core/extensions/builtin/hooks/index.d.ts.map +1 -1
  48. package/dist/core/extensions/builtin/hooks/index.js +51 -2
  49. package/dist/core/extensions/builtin/hooks/index.js.map +1 -1
  50. package/dist/core/extensions/builtin/hooks/lifecycle-adapter.d.ts +18 -1
  51. package/dist/core/extensions/builtin/hooks/lifecycle-adapter.d.ts.map +1 -1
  52. package/dist/core/extensions/builtin/hooks/lifecycle-adapter.js +36 -1
  53. package/dist/core/extensions/builtin/hooks/lifecycle-adapter.js.map +1 -1
  54. package/dist/core/extensions/builtin/hooks/matcher.js +1 -0
  55. package/dist/core/extensions/builtin/hooks/matcher.js.map +1 -1
  56. package/dist/core/extensions/builtin/hooks/output-parser.js +6 -0
  57. package/dist/core/extensions/builtin/hooks/output-parser.js.map +1 -1
  58. package/dist/core/extensions/builtin/hooks/trust-storage.d.ts +2 -0
  59. package/dist/core/extensions/builtin/hooks/trust-storage.d.ts.map +1 -1
  60. package/dist/core/extensions/builtin/hooks/trust-storage.js +13 -0
  61. package/dist/core/extensions/builtin/hooks/trust-storage.js.map +1 -1
  62. package/dist/core/extensions/builtin/hooks/types.d.ts +14 -2
  63. package/dist/core/extensions/builtin/hooks/types.d.ts.map +1 -1
  64. package/dist/core/extensions/builtin/hooks/types.js +1 -1
  65. package/dist/core/extensions/builtin/hooks/types.js.map +1 -1
  66. package/dist/core/extensions/builtin/monitor-state-event.d.ts +1 -0
  67. package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
  69. package/dist/core/extensions/builtin/terminal/tools/bash.d.ts +1 -0
  70. package/dist/core/extensions/builtin/terminal/tools/bash.d.ts.map +1 -1
  71. package/dist/core/extensions/builtin/terminal/tools/bash.js +13 -2
  72. package/dist/core/extensions/builtin/terminal/tools/bash.js.map +1 -1
  73. package/dist/core/extensions/loader.d.ts.map +1 -1
  74. package/dist/core/extensions/loader.js +5 -1
  75. package/dist/core/extensions/loader.js.map +1 -1
  76. package/dist/core/extensions/runner.d.ts +5 -16
  77. package/dist/core/extensions/runner.d.ts.map +1 -1
  78. package/dist/core/extensions/runner.js +16 -5
  79. package/dist/core/extensions/runner.js.map +1 -1
  80. package/dist/core/extensions/types.d.ts +28 -5
  81. package/dist/core/extensions/types.d.ts.map +1 -1
  82. package/dist/core/extensions/types.js.map +1 -1
  83. package/dist/core/extensions/wrapper.d.ts +8 -3
  84. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  85. package/dist/core/extensions/wrapper.js +12 -6
  86. package/dist/core/extensions/wrapper.js.map +1 -1
  87. package/dist/core/keybindings.d.ts +8 -1
  88. package/dist/core/keybindings.d.ts.map +1 -1
  89. package/dist/core/keybindings.js +7 -1
  90. package/dist/core/keybindings.js.map +1 -1
  91. package/dist/core/package-manager.d.ts +4 -2
  92. package/dist/core/package-manager.d.ts.map +1 -1
  93. package/dist/core/package-manager.js +7 -2
  94. package/dist/core/package-manager.js.map +1 -1
  95. package/dist/core/pi-manifest.d.ts +2 -0
  96. package/dist/core/pi-manifest.d.ts.map +1 -1
  97. package/dist/core/pi-manifest.js +3 -0
  98. package/dist/core/pi-manifest.js.map +1 -1
  99. package/dist/core/resource-loader.d.ts +9 -0
  100. package/dist/core/resource-loader.d.ts.map +1 -1
  101. package/dist/core/resource-loader.js +69 -21
  102. package/dist/core/resource-loader.js.map +1 -1
  103. package/dist/core/settings-manager.d.ts +1 -0
  104. package/dist/core/settings-manager.d.ts.map +1 -1
  105. package/dist/core/settings-manager.js +1 -0
  106. package/dist/core/settings-manager.js.map +1 -1
  107. package/dist/core/settings-shapes.d.ts +1 -0
  108. package/dist/core/settings-shapes.d.ts.map +1 -1
  109. package/dist/core/settings-shapes.js.map +1 -1
  110. package/dist/core/source-info.d.ts +5 -1
  111. package/dist/core/source-info.d.ts.map +1 -1
  112. package/dist/core/source-info.js.map +1 -1
  113. package/dist/core/tools/bash.d.ts.map +1 -1
  114. package/dist/core/tools/bash.js +5 -0
  115. package/dist/core/tools/bash.js.map +1 -1
  116. package/dist/modes/app-server/server/skills.d.ts.map +1 -1
  117. package/dist/modes/app-server/server/skills.js +1 -0
  118. package/dist/modes/app-server/server/skills.js.map +1 -1
  119. package/dist/modes/interactive/components/ask-user-answer-chip.d.ts +17 -0
  120. package/dist/modes/interactive/components/ask-user-answer-chip.d.ts.map +1 -0
  121. package/dist/modes/interactive/components/ask-user-answer-chip.js +86 -0
  122. package/dist/modes/interactive/components/ask-user-answer-chip.js.map +1 -0
  123. package/dist/modes/interactive/components/ask-user-answer-key.d.ts +3 -1
  124. package/dist/modes/interactive/components/ask-user-answer-key.d.ts.map +1 -1
  125. package/dist/modes/interactive/components/ask-user-answer-key.js +11 -1
  126. package/dist/modes/interactive/components/ask-user-answer-key.js.map +1 -1
  127. package/dist/modes/interactive/components/ask-user-async-widget.d.ts +5 -2
  128. package/dist/modes/interactive/components/ask-user-async-widget.d.ts.map +1 -1
  129. package/dist/modes/interactive/components/ask-user-async-widget.js +18 -12
  130. package/dist/modes/interactive/components/ask-user-async-widget.js.map +1 -1
  131. package/dist/modes/interactive/components/ask-user-countdown.d.ts +8 -0
  132. package/dist/modes/interactive/components/ask-user-countdown.d.ts.map +1 -0
  133. package/dist/modes/interactive/components/ask-user-countdown.js +23 -0
  134. package/dist/modes/interactive/components/ask-user-countdown.js.map +1 -0
  135. package/dist/modes/interactive/components/ask-user-question-keys.d.ts.map +1 -1
  136. package/dist/modes/interactive/components/ask-user-question-keys.js +85 -17
  137. package/dist/modes/interactive/components/ask-user-question-keys.js.map +1 -1
  138. package/dist/modes/interactive/components/ask-user-question-render.d.ts.map +1 -1
  139. package/dist/modes/interactive/components/ask-user-question-render.js +22 -7
  140. package/dist/modes/interactive/components/ask-user-question-render.js.map +1 -1
  141. package/dist/modes/interactive/components/ask-user-question-state.d.ts +15 -0
  142. package/dist/modes/interactive/components/ask-user-question-state.d.ts.map +1 -1
  143. package/dist/modes/interactive/components/ask-user-question-state.js +57 -13
  144. package/dist/modes/interactive/components/ask-user-question-state.js.map +1 -1
  145. package/dist/modes/interactive/components/ask-user-question.d.ts +8 -2
  146. package/dist/modes/interactive/components/ask-user-question.d.ts.map +1 -1
  147. package/dist/modes/interactive/components/ask-user-question.js +16 -8
  148. package/dist/modes/interactive/components/ask-user-question.js.map +1 -1
  149. package/dist/modes/interactive/components/config-selector.d.ts +2 -1
  150. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  151. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  152. package/dist/modes/interactive/components/custom-editor.d.ts +2 -0
  153. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  154. package/dist/modes/interactive/components/custom-editor.js +10 -1
  155. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  156. package/dist/modes/interactive/components/loaded-resource-section.d.ts +14 -0
  157. package/dist/modes/interactive/components/loaded-resource-section.d.ts.map +1 -0
  158. package/dist/modes/interactive/components/loaded-resource-section.js +25 -0
  159. package/dist/modes/interactive/components/loaded-resource-section.js.map +1 -0
  160. package/dist/modes/interactive/components/user-message.d.ts +2 -1
  161. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  162. package/dist/modes/interactive/components/user-message.js +12 -2
  163. package/dist/modes/interactive/components/user-message.js.map +1 -1
  164. package/dist/modes/interactive/interactive-mode.d.ts +14 -11
  165. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  166. package/dist/modes/interactive/interactive-mode.js +263 -165
  167. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  168. package/dist/modes/interactive/loaded-resource-scopes.d.ts +28 -0
  169. package/dist/modes/interactive/loaded-resource-scopes.d.ts.map +1 -0
  170. package/dist/modes/interactive/loaded-resource-scopes.js +107 -0
  171. package/dist/modes/interactive/loaded-resource-scopes.js.map +1 -0
  172. package/dist/modes/interactive/tips/catalog/input-tips.d.ts +1 -1
  173. package/dist/modes/interactive/tips/catalog/input-tips.js +2 -2
  174. package/dist/modes/interactive/tips/catalog/input-tips.js.map +1 -1
  175. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
  176. package/dist/modes/rpc/host-lifecycle.js +7 -0
  177. package/dist/modes/rpc/host-lifecycle.js.map +1 -1
  178. package/dist/modes/rpc/session-worker.js +5 -0
  179. package/dist/modes/rpc/session-worker.js.map +1 -1
  180. package/docs/environment-variables.md +5 -1
  181. package/docs/extensions.md +43 -5
  182. package/docs/keybindings.md +5 -2
  183. package/docs/packages.md +17 -0
  184. package/docs/rpc.md +6 -3
  185. package/docs/settings.md +5 -1
  186. package/docs/tui.md +15 -3
  187. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +28 -0
  188. package/node_modules/@code-yeongyu/senpi-codemode/README.md +16 -4
  189. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  190. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +2 -0
  191. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/session-env.ts +6 -0
  192. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +6 -1
  193. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/run-eval-cell.ts +31 -12
  194. package/node_modules/@earendil-works/chord/package.json +1 -1
  195. package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.d.ts +1 -1
  196. package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.d.ts.map +1 -1
  197. package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.js +1 -1
  198. package/node_modules/@earendil-works/pi-agent-core/dist/harness/messages.js.map +1 -1
  199. package/node_modules/@earendil-works/pi-agent-core/package.json +4 -4
  200. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts +2 -0
  201. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts.map +1 -1
  202. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js +6 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js.map +1 -1
  204. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  205. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +55 -17
  206. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  207. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  208. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +2 -1
  209. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  210. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +2 -1
  211. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  212. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +9 -0
  213. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  214. package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.d.ts +30 -0
  215. package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.d.ts.map +1 -0
  216. package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.js +94 -0
  217. package/node_modules/@earendil-works/pi-ai/dist/api/responses-completion-grace.js.map +1 -0
  218. package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.d.ts +48 -0
  219. package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.d.ts.map +1 -0
  220. package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.js +104 -0
  221. package/node_modules/@earendil-works/pi-ai/dist/api/websocket-liveness.js.map +1 -0
  222. package/node_modules/@earendil-works/pi-ai/dist/devin-provider.d.ts +6 -0
  223. package/node_modules/@earendil-works/pi-ai/dist/devin-provider.d.ts.map +1 -0
  224. package/node_modules/@earendil-works/pi-ai/dist/devin-provider.js +4 -0
  225. package/node_modules/@earendil-works/pi-ai/dist/devin-provider.js.map +1 -0
  226. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  227. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  229. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  231. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +7 -3
  233. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  234. package/node_modules/@earendil-works/pi-ai/package.json +10 -2
  235. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  236. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  237. package/node_modules/@earendil-works/pi-tui/README.md +11 -3
  238. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +2 -1
  239. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  240. package/node_modules/@earendil-works/pi-tui/dist/index.js +1 -0
  241. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  242. package/node_modules/@earendil-works/pi-tui/dist/mouse-input.d.ts +37 -0
  243. package/node_modules/@earendil-works/pi-tui/dist/mouse-input.d.ts.map +1 -0
  244. package/node_modules/@earendil-works/pi-tui/dist/mouse-input.js +97 -0
  245. package/node_modules/@earendil-works/pi-tui/dist/mouse-input.js.map +1 -0
  246. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +2 -0
  247. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  248. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +38 -0
  249. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -1
  250. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +25 -1
  251. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  252. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +110 -4
  253. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  254. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.d.ts.map +1 -1
  255. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js +5 -50
  256. package/node_modules/@earendil-works/pi-tui/dist/tui-alt-screen.js.map +1 -1
  257. package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.d.ts +12 -0
  258. package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.d.ts.map +1 -1
  259. package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.js +129 -3
  260. package/node_modules/@earendil-works/pi-tui/dist/tui-main-screen.js.map +1 -1
  261. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +28 -0
  262. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  263. package/node_modules/@earendil-works/pi-tui/dist/tui.js +160 -0
  264. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  265. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  266. package/package.json +13 -9
  267. package/dist/bun/register-cursor-agent.d.ts +0 -2
  268. package/dist/bun/register-cursor-agent.d.ts.map +0 -1
  269. package/dist/bun/register-cursor-agent.js +0 -4
  270. package/dist/bun/register-cursor-agent.js.map +0 -1
@@ -1,8 +1,10 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
+ import { formatResultText } from "../ask-user/format.js";
3
+ import { ASK_USER_ASKED_EVENT, ASK_USER_SETTLED_EVENT, } from "../ask-user/notify.js";
2
4
  import { registerHooksCommand } from "./command.js";
3
- import { loadHookConfigSources } from "./config-loader.js";
5
+ import { loadHookConfigSources, loadHookConfigSourcesAsync } from "./config-loader.js";
4
6
  import { dispatchHookEvent, runningHookHandlersStatusLabel } from "./dispatcher.js";
5
- import { buildPostCompactHookInput, buildPreCompactHookInput, buildSessionStartHookInput, dispatchLifecycleHookEvent, postCompactResultDetails, preCompactResultDetails, recordLifecycleHookResult, sessionBeforeCompactResult, sessionStartResultDetails, } from "./lifecycle-adapter.js";
7
+ import { buildNotificationHookInput, buildPostCompactHookInput, buildPreCompactHookInput, buildSessionStartHookInput, dispatchLifecycleHookEvent, dispatchNotificationHookEvent, notificationResultDetails, postCompactResultDetails, preCompactResultDetails, recordLifecycleHookResult, sessionBeforeCompactResult, sessionStartResultDetails, } from "./lifecycle-adapter.js";
6
8
  import { appendSystemMessages, buildUserPromptHookInput, formatPromptContextMessage, HOOK_CUSTOM_MESSAGE_TYPE, promptBlockReasonFromResult, promptContextFromResult, safeDiagnosticDetails, } from "./prompt-adapter.js";
7
9
  import { applyStopHookResult, buildStopHookInput, createStopTurnTracker } from "./stop-adapter.js";
8
10
  import { applyPostToolUseResult, applyPreToolUseResult, buildPostToolUseHookInput, buildPreToolUseHookInput, toolContextsFromResult, } from "./tool-adapter.js";
@@ -36,6 +38,53 @@ export default function hooksExtension(pi) {
36
38
  const trust = mergeTrustStates(storage.read("global"), ctx.isProjectTrusted() ? storage.read("project") : emptyHookTrustState());
37
39
  return { parsed, trust, storage };
38
40
  };
41
+ for (const channel of [ASK_USER_ASKED_EVENT, ASK_USER_SETTLED_EVENT]) {
42
+ pi.events.on(channel, async (data) => {
43
+ const event = data;
44
+ const { ctx, request, variant } = event;
45
+ const response = "response" in event ? event.response : undefined;
46
+ const headers = request.questions.map((question) => question.header).join(", ");
47
+ // Capture session identity before asynchronous I/O or a session switch.
48
+ const input = buildNotificationHookInput({
49
+ kind: response === undefined
50
+ ? "ask-user-asked"
51
+ : response.status === "timed_out"
52
+ ? "ask-user-timeout"
53
+ : "ask-user-settled",
54
+ message: response === undefined
55
+ ? `Question asked (${headers})`
56
+ : response.status === "timed_out"
57
+ ? `Question timed out (${headers}): ${formatResultText(variant, response, request.questions)}`
58
+ : `Question ${response.status} (${headers})`,
59
+ requestId: request.requestId,
60
+ source: "ask-user",
61
+ status: response?.status ?? "pending",
62
+ title: headers,
63
+ }, ctx);
64
+ const sources = ctx.getLoadedHookSources?.() ?? fallbackHookSources(ctx.cwd);
65
+ const parsed = await loadHookConfigSourcesAsync(sources);
66
+ const handlers = parsed.executableHandlers.filter((handler) => handler.event === "Notification");
67
+ if (handlers.length === 0)
68
+ return;
69
+ const storage = new FileHookStateStorage({ agentDir: sources.agentDir, cwd: sources.cwd });
70
+ const [globalTrust, projectTrust] = await Promise.all([
71
+ storage.readAsync("global"),
72
+ ctx.isProjectTrusted() ? storage.readAsync("project") : emptyHookTrustState(),
73
+ ]);
74
+ const result = await dispatchNotificationHookEvent({
75
+ cwd: ctx.cwd,
76
+ handlers,
77
+ input,
78
+ ...(ctx.signal === undefined ? {} : { signal: ctx.signal }),
79
+ trustState: mergeTrustStates(globalTrust, projectTrust),
80
+ });
81
+ const details = notificationResultDetails(result);
82
+ recordLifecycleHookResult(pi, "Notification", {
83
+ ...details,
84
+ diagnostics: [...parsed.diagnostics, ...details.diagnostics],
85
+ });
86
+ });
87
+ }
39
88
  pi.on("session_start", async (event, ctx) => {
40
89
  const state = refreshState(ctx);
41
90
  const input = buildSessionStartHookInput(event, ctx);
@@ -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 { registerHooksCommand } from \"./command.ts\";\nimport { loadHookConfigSources } from \"./config-loader.ts\";\nimport { dispatchHookEvent, runningHookHandlersStatusLabel } from \"./dispatcher.ts\";\nimport {\n\tbuildPostCompactHookInput,\n\tbuildPreCompactHookInput,\n\tbuildSessionStartHookInput,\n\tdispatchLifecycleHookEvent,\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\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 { 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,7 +1,7 @@
1
1
  import type { ExtensionAPI, ExtensionContext, SessionBeforeCompactEvent, SessionBeforeCompactResult, SessionCompactEvent, SessionStartEvent } from "../../types.ts";
2
2
  import { type HookDispatchResult } from "./dispatcher.ts";
3
3
  import type { ExecutableHookHandler, HookDiagnostic, HookInputWire, HookTrustState } from "./types.ts";
4
- type LifecycleHookEvent = "SessionStart" | "PreCompact" | "PostCompact";
4
+ type LifecycleHookEvent = "SessionStart" | "PreCompact" | "PostCompact" | "Notification";
5
5
  type LifecycleDispatchOptions = {
6
6
  readonly cwd: string;
7
7
  readonly handlers: readonly ExecutableHookHandler[];
@@ -18,6 +18,23 @@ type LifecycleResultDetails = {
18
18
  };
19
19
  export declare function buildSessionStartHookInput(event: SessionStartEvent, ctx: ExtensionContext): HookInputWire;
20
20
  export declare function buildPreCompactHookInput(event: SessionBeforeCompactEvent, ctx: ExtensionContext): HookInputWire;
21
+ export type NotificationHookInput = {
22
+ readonly message: string;
23
+ readonly kind: string;
24
+ readonly title?: string;
25
+ readonly source?: string;
26
+ readonly requestId?: string;
27
+ readonly status?: string;
28
+ };
29
+ export declare function buildNotificationHookInput(input: NotificationHookInput, ctx: ExtensionContext): HookInputWire;
30
+ export declare function dispatchNotificationHookEvent(options: {
31
+ cwd: string;
32
+ handlers: readonly ExecutableHookHandler[];
33
+ input: HookInputWire;
34
+ signal?: AbortSignal;
35
+ trustState: HookTrustState;
36
+ }): Promise<HookDispatchResult | undefined>;
37
+ export declare function notificationResultDetails(result: HookDispatchResult | undefined): LifecycleResultDetails;
21
38
  export declare function buildPostCompactHookInput(event: SessionCompactEvent, ctx: ExtensionContext): HookInputWire;
22
39
  export declare function dispatchLifecycleHookEvent(options: LifecycleDispatchOptions): Promise<HookDispatchResult | undefined>;
23
40
  export declare function sessionStartResultDetails(result: HookDispatchResult | undefined): LifecycleResultDetails;
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-adapter.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/lifecycle-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,YAAY,EACZ,gBAAgB,EAChB,yBAAyB,EACzB,0BAA0B,EAC1B,mBAAmB,EACnB,iBAAiB,EACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAG7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEvG,KAAK,kBAAkB,GAAG,cAAc,GAAG,YAAY,GAAG,aAAa,CAAC;AAExE,KAAK,wBAAwB,GAAG;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;CACpC,CAAC;AAcF,KAAK,sBAAsB,GAAG;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAWzG;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,yBAAyB,EAAE,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAa/G;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,EAAE,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAa1G;AAED,wBAAsB,0BAA0B,CAC/C,OAAO,EAAE,wBAAwB,GAC/B,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAuBzC;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,sBAAsB,CAExG;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,sBAAsB,CActG;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,sBAAsB,CAEvG;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,sBAAsB,GAAG,0BAA0B,GAAG,SAAS,CAElH;AAED,wBAAgB,yBAAyB,CACxC,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,EACrC,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;IAAE,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,IAAI,CAiBN"}
1
+ {"version":3,"file":"lifecycle-adapter.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/lifecycle-adapter.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,39 @@ export function buildPreCompactHookInput(event, ctx) {
28
28
  ...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),
29
29
  };
30
30
  }
31
+ export function buildNotificationHookInput(input, ctx) {
32
+ const transcriptPath = ctx.sessionManager.getSessionFile();
33
+ return {
34
+ cwd: ctx.cwd,
35
+ event: "Notification",
36
+ hook_event_name: "Notification",
37
+ kind: input.kind,
38
+ message: input.message,
39
+ session_id: ctx.sessionManager.getSessionId(),
40
+ ...(input.title === undefined ? {} : { title: input.title }),
41
+ ...(input.source === undefined ? {} : { notification_source: input.source }),
42
+ ...(input.requestId === undefined ? {} : { request_id: input.requestId }),
43
+ ...(input.status === undefined ? {} : { status: input.status }),
44
+ ...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),
45
+ };
46
+ }
47
+ export async function dispatchNotificationHookEvent(options) {
48
+ return dispatchLifecycleHookEvent({
49
+ cwd: options.cwd,
50
+ handlers: options.handlers,
51
+ input: options.input,
52
+ matcherInputs: ["Notification"],
53
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
54
+ trustState: options.trustState,
55
+ });
56
+ }
57
+ export function notificationResultDetails(result) {
58
+ return {
59
+ cancel: false,
60
+ contexts: result?.summaries.flatMap((summary) => summary.output.additionalContext === undefined ? [] : [summary.output.additionalContext]) ?? [],
61
+ diagnostics: result === undefined ? [] : [...result.diagnostics, ...commandFailureDiagnostics("Notification", result)],
62
+ };
63
+ }
31
64
  export function buildPostCompactHookInput(event, ctx) {
32
65
  const transcriptPath = ctx.sessionManager.getSessionFile();
33
66
  return {
@@ -124,7 +157,9 @@ function selectLifecycleHandlers(options) {
124
157
  }, handler.source));
125
158
  continue;
126
159
  }
127
- const match = matchesLifecycleMatcher(handler, options.matcherInputs);
160
+ const match = handler.event === "Notification"
161
+ ? { diagnostics: [], matched: true }
162
+ : matchesLifecycleMatcher(handler, options.matcherInputs);
128
163
  diagnostics.push(...match.diagnostics);
129
164
  if (match.matched)
130
165
  matched.push(handler);
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle-adapter.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/lifecycle-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tExtensionAPI,\n\tExtensionContext,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeCompactResult,\n\tSessionCompactEvent,\n\tSessionStartEvent,\n} from \"../../types.ts\";\nimport { diagnostic } from \"./diagnostics.ts\";\nimport { dispatchHookEvent, type HookDispatchResult } from \"./dispatcher.ts\";\nimport { HOOK_CUSTOM_MESSAGE_TYPE, safeDiagnosticDetails } from \"./prompt-adapter.ts\";\nimport { createHookTrustEntry, hookTrustId, listHookTrustRecords } from \"./trust.ts\";\nimport type { ExecutableHookHandler, HookDiagnostic, HookInputWire, HookTrustState } from \"./types.ts\";\n\ntype LifecycleHookEvent = \"SessionStart\" | \"PreCompact\" | \"PostCompact\";\n\ntype LifecycleDispatchOptions = {\n\treadonly cwd: string;\n\treadonly handlers: readonly ExecutableHookHandler[];\n\treadonly input: HookInputWire;\n\treadonly matcherInputs: readonly string[];\n\treadonly signal?: AbortSignal;\n\treadonly trustState: HookTrustState;\n};\n\ntype LifecycleDispatchSelection = {\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly handlers: readonly ExecutableHookHandler[];\n};\n\ntype LifecycleHookOutput = {\n\treadonly additionalContext?: string;\n\treadonly customInstructions?: string;\n\treadonly decision?: string;\n\treadonly reason?: string;\n};\n\ntype LifecycleResultDetails = {\n\treadonly cancel: boolean;\n\treadonly contexts: readonly string[];\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly reason?: string;\n};\n\nexport function buildSessionStartHookInput(event: SessionStartEvent, ctx: ExtensionContext): HookInputWire {\n\tconst transcriptPath = ctx.sessionManager.getSessionFile();\n\treturn {\n\t\tcwd: ctx.cwd,\n\t\tevent: \"SessionStart\",\n\t\thook_event_name: \"SessionStart\",\n\t\treason: event.reason,\n\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\t...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),\n\t};\n}\n\nexport function buildPreCompactHookInput(event: SessionBeforeCompactEvent, ctx: ExtensionContext): HookInputWire {\n\tconst transcriptPath = ctx.sessionManager.getSessionFile();\n\treturn {\n\t\tcwd: ctx.cwd,\n\t\tevent: \"PreCompact\",\n\t\thook_event_name: \"PreCompact\",\n\t\treason: event.reason,\n\t\trequest_id: event.requestId,\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\twill_retry: event.willRetry,\n\t\t...(event.customInstructions === undefined ? {} : { custom_instructions: event.customInstructions }),\n\t\t...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),\n\t};\n}\n\nexport function buildPostCompactHookInput(event: SessionCompactEvent, ctx: ExtensionContext): HookInputWire {\n\tconst transcriptPath = ctx.sessionManager.getSessionFile();\n\treturn {\n\t\taccepted: event.accepted,\n\t\tcwd: ctx.cwd,\n\t\tevent: \"PostCompact\",\n\t\thook_event_name: \"PostCompact\",\n\t\treason: event.reason,\n\t\trequest_id: event.requestId,\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\twill_retry: event.willRetry,\n\t\t...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),\n\t};\n}\n\nexport async function dispatchLifecycleHookEvent(\n\toptions: LifecycleDispatchOptions,\n): Promise<HookDispatchResult | undefined> {\n\tconst selection = selectLifecycleHandlers(options);\n\tif (selection.handlers.length === 0 && selection.diagnostics.length === 0) return undefined;\n\tconst trustedHandlers = selection.handlers.map((handler) => stripLifecycleMatcher(handler));\n\tconst hooks: Record<string, ReturnType<typeof createHookTrustEntry>> = {};\n\tfor (const handler of trustedHandlers) {\n\t\thooks[hookTrustId(handler)] = createHookTrustEntry(handler, {\n\t\t\tplatform: process.platform,\n\t\t\tupdatedAt: \"2026-06-29T00:00:00.000Z\",\n\t\t});\n\t}\n\tconst result = await dispatchHookEvent({\n\t\tcwd: options.cwd,\n\t\thandlers: trustedHandlers,\n\t\tinput: options.input,\n\t\t...(options.signal === undefined ? {} : { signal: options.signal }),\n\t\ttrustOptions: { platform: process.platform },\n\t\ttrustState: { hooks, version: 1 },\n\t});\n\treturn {\n\t\t...result,\n\t\tdiagnostics: [...selection.diagnostics, ...result.diagnostics],\n\t};\n}\n\nexport function sessionStartResultDetails(result: HookDispatchResult | undefined): LifecycleResultDetails {\n\treturn lifecycleResultDetails(\"SessionStart\", result);\n}\n\nexport function preCompactResultDetails(result: HookDispatchResult | undefined): LifecycleResultDetails {\n\tconst details = lifecycleResultDetails(\"PreCompact\", result);\n\tif (details.cancel) return details;\n\tconst blocker = result?.summaries.find((summary) => {\n\t\tconst output = readLifecycleHookOutput(\"PreCompact\", summary.run.stdout);\n\t\treturn output?.decision === \"block\" || output?.decision === \"deny\";\n\t});\n\tif (blocker === undefined) return details;\n\tconst output = readLifecycleHookOutput(\"PreCompact\", blocker.run.stdout);\n\treturn {\n\t\t...details,\n\t\tcancel: true,\n\t\t...(output?.reason === undefined ? {} : { reason: output.reason }),\n\t};\n}\n\nexport function postCompactResultDetails(result: HookDispatchResult | undefined): LifecycleResultDetails {\n\treturn lifecycleResultDetails(\"PostCompact\", result);\n}\n\nexport function sessionBeforeCompactResult(details: LifecycleResultDetails): SessionBeforeCompactResult | undefined {\n\treturn details.cancel ? { cancel: true } : undefined;\n}\n\nexport function recordLifecycleHookResult(\n\tpi: Pick<ExtensionAPI, \"sendMessage\">,\n\tevent: LifecycleHookEvent,\n\tdetails: LifecycleResultDetails,\n\toptions?: { compactionRequestId?: string },\n): void {\n\tif (details.contexts.length === 0 && details.diagnostics.length === 0 && details.reason === undefined) return;\n\tconst content =\n\t\tdetails.contexts.length > 0 ? details.contexts.join(\"\\n\\n\") : (details.reason ?? `${event} hook diagnostics.`);\n\tpi.sendMessage(\n\t\t{\n\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\tcontent,\n\t\t\tdisplay: false,\n\t\t\tdetails: {\n\t\t\t\tevent,\n\t\t\t\tdiagnostics: details.diagnostics.map(safeDiagnosticDetails),\n\t\t\t\t...(options?.compactionRequestId === undefined ? {} : { compactionRequestId: options.compactionRequestId }),\n\t\t\t},\n\t\t},\n\t\t{ triggerTurn: false },\n\t);\n}\n\nfunction selectLifecycleHandlers(options: LifecycleDispatchOptions): LifecycleDispatchSelection {\n\tconst matched: ExecutableHookHandler[] = [];\n\tconst diagnostics: HookDiagnostic[] = [];\n\tfor (const handler of options.handlers) {\n\t\tif (handler.event !== options.input.event) continue;\n\t\tif (isInitialRuntimeSessionStart(handler, options.input)) {\n\t\t\tdiagnostics.push(\n\t\t\t\tdiagnostic(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"unsupported_event\",\n\t\t\t\t\t\tevent: \"SessionStart\",\n\t\t\t\t\t\tmessage: \"Runtime SessionStart hooks are loaded for reload or the next session only.\",\n\t\t\t\t\t\tpath: \"hooks.SessionStart\",\n\t\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t\t},\n\t\t\t\t\thandler.source,\n\t\t\t\t),\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tconst match = matchesLifecycleMatcher(handler, options.matcherInputs);\n\t\tdiagnostics.push(...match.diagnostics);\n\t\tif (match.matched) matched.push(handler);\n\t}\n\tconst trustRecords = listHookTrustRecords(matched, options.trustState, { platform: process.platform });\n\tconst trusted = matched.filter((_handler, index) => trustRecords[index]?.executable === true);\n\treturn { diagnostics, handlers: trusted };\n}\n\nfunction isInitialRuntimeSessionStart(handler: ExecutableHookHandler, input: HookInputWire): boolean {\n\treturn input.event === \"SessionStart\" && input.reason === \"startup\" && handler.source.discoveredAt === \"runtime\";\n}\n\nfunction matchesLifecycleMatcher(\n\thandler: ExecutableHookHandler,\n\tinputs: readonly string[],\n): { readonly diagnostics: readonly HookDiagnostic[]; readonly matched: boolean } {\n\tconst matcher = handler.matcher?.trim();\n\tif (matcher === undefined || matcher.length === 0 || matcher === \"*\") {\n\t\treturn { diagnostics: [], matched: true };\n\t}\n\tconst literalMatched = matcher\n\t\t.split(/[|,]/)\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length > 0)\n\t\t.some((part) => inputs.includes(part));\n\ttry {\n\t\tconst regex = new RegExp(matcher);\n\t\treturn { diagnostics: [], matched: literalMatched || inputs.some((input) => regex.test(input)) };\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) {\n\t\t\treturn {\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_matcher\",\n\t\t\t\t\t\t\tevent: handler.event,\n\t\t\t\t\t\t\tmessage: `Hook matcher is not a valid JavaScript regular expression: ${error.message}`,\n\t\t\t\t\t\t\tpath: `hooks.${handler.event}[${handler.groupIndex}].matcher`,\n\t\t\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\thandler.source,\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\tmatched: literalMatched,\n\t\t\t};\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction stripLifecycleMatcher(handler: ExecutableHookHandler): ExecutableHookHandler {\n\treturn {\n\t\tconfig: handler.config,\n\t\tevent: handler.event,\n\t\tgroupIndex: handler.groupIndex,\n\t\thandlerIndex: handler.handlerIndex,\n\t\tsource: handler.source,\n\t};\n}\n\nfunction lifecycleResultDetails(\n\tevent: LifecycleHookEvent,\n\tresult: HookDispatchResult | undefined,\n): LifecycleResultDetails {\n\tif (result === undefined) {\n\t\treturn { cancel: false, contexts: [], diagnostics: [] };\n\t}\n\tconst diagnostics = [...result.diagnostics, ...commandFailureDiagnostics(event, result)];\n\tconst contexts: string[] = [];\n\tfor (const summary of result.summaries) {\n\t\tconst output = readLifecycleHookOutput(event, summary.run.stdout);\n\t\tif (output?.additionalContext !== undefined && event !== \"PreCompact\") {\n\t\t\tcontexts.push(output.additionalContext);\n\t\t}\n\t\tif (event === \"PreCompact\") {\n\t\t\tdiagnostics.push(...preCompactUnsupportedDiagnostics(summary.handler, output));\n\t\t}\n\t}\n\tconst reason = event === \"PreCompact\" && result.decision.kind === \"block\" ? result.decision.reason : undefined;\n\treturn {\n\t\tcancel: event === \"PreCompact\" && result.decision.kind === \"block\",\n\t\tcontexts,\n\t\tdiagnostics,\n\t\t...(reason === undefined ? {} : { reason }),\n\t};\n}\n\nfunction commandFailureDiagnostics(event: LifecycleHookEvent, result: HookDispatchResult): readonly HookDiagnostic[] {\n\treturn result.summaries.flatMap((summary) => {\n\t\tif (summary.run.exitCode === 0 || (summary.run.exitCode === 2 && event === \"PreCompact\")) return [];\n\t\tconst status = summary.run.exitCode === null ? \"without an exit code\" : `with exit code ${summary.run.exitCode}`;\n\t\treturn [\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: \"invalid_root\",\n\t\t\t\t\tevent,\n\t\t\t\t\tmessage: `Hook command failed ${status}.`,\n\t\t\t\t\tpath: \"process.exitCode\",\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t},\n\t\t\t\tsummary.handler.source,\n\t\t\t),\n\t\t];\n\t});\n}\n\nfunction preCompactUnsupportedDiagnostics(\n\thandler: ExecutableHookHandler,\n\toutput: LifecycleHookOutput | undefined,\n): readonly HookDiagnostic[] {\n\tif (output === undefined) return [];\n\tconst diagnostics: HookDiagnostic[] = [];\n\tif (output.additionalContext !== undefined) {\n\t\tdiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: \"unsupported_field\",\n\t\t\t\t\tevent: \"PreCompact\",\n\t\t\t\t\tmessage: \"PreCompact additionalContext is diagnostic-only in builtin hooks v1.\",\n\t\t\t\t\tpath: \"stdout.hookSpecificOutput.additionalContext\",\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t},\n\t\t\t\thandler.source,\n\t\t\t),\n\t\t);\n\t}\n\tif (output.customInstructions !== undefined) {\n\t\tdiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: \"unsupported_field\",\n\t\t\t\t\tevent: \"PreCompact\",\n\t\t\t\t\tmessage: \"PreCompact customInstructions cannot mutate compaction in builtin hooks v1.\",\n\t\t\t\t\tpath: \"stdout.hookSpecificOutput.customInstructions\",\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t},\n\t\t\t\thandler.source,\n\t\t\t),\n\t\t);\n\t}\n\treturn diagnostics;\n}\n\nfunction readLifecycleHookOutput(event: LifecycleHookEvent, stdout: string): LifecycleHookOutput | undefined {\n\tconst trimmed = stdout.trim();\n\tif (trimmed.length === 0) return undefined;\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(trimmed);\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) return undefined;\n\t\tthrow error;\n\t}\n\tif (!isRecord(parsed)) return undefined;\n\tconst specific = isRecord(parsed.hookSpecificOutput) ? parsed.hookSpecificOutput : undefined;\n\tif (specific?.hookEventName !== undefined && specific.hookEventName !== event) return undefined;\n\treturn {\n\t\t...textField(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\"),\n\t\t...textField(specific?.customInstructions ?? parsed.customInstructions, \"customInstructions\"),\n\t\t...textField(parsed.decision, \"decision\"),\n\t\t...textField(specific?.permissionDecisionReason ?? parsed.reason, \"reason\"),\n\t};\n}\n\nfunction textField<K extends keyof LifecycleHookOutput>(\n\tvalue: unknown,\n\tkey: K,\n): Pick<LifecycleHookOutput, K> | Record<string, never> {\n\tif (typeof value !== \"string\") return {};\n\tconst trimmed = value.trim();\n\treturn trimmed.length === 0 ? {} : ({ [key]: trimmed } as Pick<LifecycleHookOutput, K>);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"]}
1
+ {"version":3,"file":"lifecycle-adapter.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/lifecycle-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tExtensionAPI,\n\tExtensionContext,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeCompactResult,\n\tSessionCompactEvent,\n\tSessionStartEvent,\n} from \"../../types.ts\";\nimport { diagnostic } from \"./diagnostics.ts\";\nimport { dispatchHookEvent, type HookDispatchResult } from \"./dispatcher.ts\";\nimport { HOOK_CUSTOM_MESSAGE_TYPE, safeDiagnosticDetails } from \"./prompt-adapter.ts\";\nimport { createHookTrustEntry, hookTrustId, listHookTrustRecords } from \"./trust.ts\";\nimport type { ExecutableHookHandler, HookDiagnostic, HookInputWire, HookTrustState } from \"./types.ts\";\n\ntype LifecycleHookEvent = \"SessionStart\" | \"PreCompact\" | \"PostCompact\" | \"Notification\";\n\ntype LifecycleDispatchOptions = {\n\treadonly cwd: string;\n\treadonly handlers: readonly ExecutableHookHandler[];\n\treadonly input: HookInputWire;\n\treadonly matcherInputs: readonly string[];\n\treadonly signal?: AbortSignal;\n\treadonly trustState: HookTrustState;\n};\n\ntype LifecycleDispatchSelection = {\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly handlers: readonly ExecutableHookHandler[];\n};\n\ntype LifecycleHookOutput = {\n\treadonly additionalContext?: string;\n\treadonly customInstructions?: string;\n\treadonly decision?: string;\n\treadonly reason?: string;\n};\n\ntype LifecycleResultDetails = {\n\treadonly cancel: boolean;\n\treadonly contexts: readonly string[];\n\treadonly diagnostics: readonly HookDiagnostic[];\n\treadonly reason?: string;\n};\n\nexport function buildSessionStartHookInput(event: SessionStartEvent, ctx: ExtensionContext): HookInputWire {\n\tconst transcriptPath = ctx.sessionManager.getSessionFile();\n\treturn {\n\t\tcwd: ctx.cwd,\n\t\tevent: \"SessionStart\",\n\t\thook_event_name: \"SessionStart\",\n\t\treason: event.reason,\n\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\t...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),\n\t};\n}\n\nexport function buildPreCompactHookInput(event: SessionBeforeCompactEvent, ctx: ExtensionContext): HookInputWire {\n\tconst transcriptPath = ctx.sessionManager.getSessionFile();\n\treturn {\n\t\tcwd: ctx.cwd,\n\t\tevent: \"PreCompact\",\n\t\thook_event_name: \"PreCompact\",\n\t\treason: event.reason,\n\t\trequest_id: event.requestId,\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\twill_retry: event.willRetry,\n\t\t...(event.customInstructions === undefined ? {} : { custom_instructions: event.customInstructions }),\n\t\t...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),\n\t};\n}\n\nexport type NotificationHookInput = {\n\treadonly message: string;\n\treadonly kind: string;\n\treadonly title?: string;\n\treadonly source?: string;\n\treadonly requestId?: string;\n\treadonly status?: string;\n};\n\nexport function buildNotificationHookInput(input: NotificationHookInput, ctx: ExtensionContext): HookInputWire {\n\tconst transcriptPath = ctx.sessionManager.getSessionFile();\n\treturn {\n\t\tcwd: ctx.cwd,\n\t\tevent: \"Notification\",\n\t\thook_event_name: \"Notification\",\n\t\tkind: input.kind,\n\t\tmessage: input.message,\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\t...(input.title === undefined ? {} : { title: input.title }),\n\t\t...(input.source === undefined ? {} : { notification_source: input.source }),\n\t\t...(input.requestId === undefined ? {} : { request_id: input.requestId }),\n\t\t...(input.status === undefined ? {} : { status: input.status }),\n\t\t...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),\n\t};\n}\n\nexport async function dispatchNotificationHookEvent(options: {\n\tcwd: string;\n\thandlers: readonly ExecutableHookHandler[];\n\tinput: HookInputWire;\n\tsignal?: AbortSignal;\n\ttrustState: HookTrustState;\n}): Promise<HookDispatchResult | undefined> {\n\treturn dispatchLifecycleHookEvent({\n\t\tcwd: options.cwd,\n\t\thandlers: options.handlers,\n\t\tinput: options.input,\n\t\tmatcherInputs: [\"Notification\"],\n\t\t...(options.signal === undefined ? {} : { signal: options.signal }),\n\t\ttrustState: options.trustState,\n\t});\n}\n\nexport function notificationResultDetails(result: HookDispatchResult | undefined): LifecycleResultDetails {\n\treturn {\n\t\tcancel: false,\n\t\tcontexts:\n\t\t\tresult?.summaries.flatMap((summary) =>\n\t\t\t\tsummary.output.additionalContext === undefined ? [] : [summary.output.additionalContext],\n\t\t\t) ?? [],\n\t\tdiagnostics:\n\t\t\tresult === undefined ? [] : [...result.diagnostics, ...commandFailureDiagnostics(\"Notification\", result)],\n\t};\n}\n\nexport function buildPostCompactHookInput(event: SessionCompactEvent, ctx: ExtensionContext): HookInputWire {\n\tconst transcriptPath = ctx.sessionManager.getSessionFile();\n\treturn {\n\t\taccepted: event.accepted,\n\t\tcwd: ctx.cwd,\n\t\tevent: \"PostCompact\",\n\t\thook_event_name: \"PostCompact\",\n\t\treason: event.reason,\n\t\trequest_id: event.requestId,\n\t\tsession_id: ctx.sessionManager.getSessionId(),\n\t\twill_retry: event.willRetry,\n\t\t...(transcriptPath === undefined ? {} : { transcript_path: transcriptPath }),\n\t};\n}\n\nexport async function dispatchLifecycleHookEvent(\n\toptions: LifecycleDispatchOptions,\n): Promise<HookDispatchResult | undefined> {\n\tconst selection = selectLifecycleHandlers(options);\n\tif (selection.handlers.length === 0 && selection.diagnostics.length === 0) return undefined;\n\tconst trustedHandlers = selection.handlers.map((handler) => stripLifecycleMatcher(handler));\n\tconst hooks: Record<string, ReturnType<typeof createHookTrustEntry>> = {};\n\tfor (const handler of trustedHandlers) {\n\t\thooks[hookTrustId(handler)] = createHookTrustEntry(handler, {\n\t\t\tplatform: process.platform,\n\t\t\tupdatedAt: \"2026-06-29T00:00:00.000Z\",\n\t\t});\n\t}\n\tconst result = await dispatchHookEvent({\n\t\tcwd: options.cwd,\n\t\thandlers: trustedHandlers,\n\t\tinput: options.input,\n\t\t...(options.signal === undefined ? {} : { signal: options.signal }),\n\t\ttrustOptions: { platform: process.platform },\n\t\ttrustState: { hooks, version: 1 },\n\t});\n\treturn {\n\t\t...result,\n\t\tdiagnostics: [...selection.diagnostics, ...result.diagnostics],\n\t};\n}\n\nexport function sessionStartResultDetails(result: HookDispatchResult | undefined): LifecycleResultDetails {\n\treturn lifecycleResultDetails(\"SessionStart\", result);\n}\n\nexport function preCompactResultDetails(result: HookDispatchResult | undefined): LifecycleResultDetails {\n\tconst details = lifecycleResultDetails(\"PreCompact\", result);\n\tif (details.cancel) return details;\n\tconst blocker = result?.summaries.find((summary) => {\n\t\tconst output = readLifecycleHookOutput(\"PreCompact\", summary.run.stdout);\n\t\treturn output?.decision === \"block\" || output?.decision === \"deny\";\n\t});\n\tif (blocker === undefined) return details;\n\tconst output = readLifecycleHookOutput(\"PreCompact\", blocker.run.stdout);\n\treturn {\n\t\t...details,\n\t\tcancel: true,\n\t\t...(output?.reason === undefined ? {} : { reason: output.reason }),\n\t};\n}\n\nexport function postCompactResultDetails(result: HookDispatchResult | undefined): LifecycleResultDetails {\n\treturn lifecycleResultDetails(\"PostCompact\", result);\n}\n\nexport function sessionBeforeCompactResult(details: LifecycleResultDetails): SessionBeforeCompactResult | undefined {\n\treturn details.cancel ? { cancel: true } : undefined;\n}\n\nexport function recordLifecycleHookResult(\n\tpi: Pick<ExtensionAPI, \"sendMessage\">,\n\tevent: LifecycleHookEvent,\n\tdetails: LifecycleResultDetails,\n\toptions?: { compactionRequestId?: string },\n): void {\n\tif (details.contexts.length === 0 && details.diagnostics.length === 0 && details.reason === undefined) return;\n\tconst content =\n\t\tdetails.contexts.length > 0 ? details.contexts.join(\"\\n\\n\") : (details.reason ?? `${event} hook diagnostics.`);\n\tpi.sendMessage(\n\t\t{\n\t\t\tcustomType: HOOK_CUSTOM_MESSAGE_TYPE,\n\t\t\tcontent,\n\t\t\tdisplay: false,\n\t\t\tdetails: {\n\t\t\t\tevent,\n\t\t\t\tdiagnostics: details.diagnostics.map(safeDiagnosticDetails),\n\t\t\t\t...(options?.compactionRequestId === undefined ? {} : { compactionRequestId: options.compactionRequestId }),\n\t\t\t},\n\t\t},\n\t\t{ triggerTurn: false },\n\t);\n}\n\nfunction selectLifecycleHandlers(options: LifecycleDispatchOptions): LifecycleDispatchSelection {\n\tconst matched: ExecutableHookHandler[] = [];\n\tconst diagnostics: HookDiagnostic[] = [];\n\tfor (const handler of options.handlers) {\n\t\tif (handler.event !== options.input.event) continue;\n\t\tif (isInitialRuntimeSessionStart(handler, options.input)) {\n\t\t\tdiagnostics.push(\n\t\t\t\tdiagnostic(\n\t\t\t\t\t{\n\t\t\t\t\t\tcode: \"unsupported_event\",\n\t\t\t\t\t\tevent: \"SessionStart\",\n\t\t\t\t\t\tmessage: \"Runtime SessionStart hooks are loaded for reload or the next session only.\",\n\t\t\t\t\t\tpath: \"hooks.SessionStart\",\n\t\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t\t},\n\t\t\t\t\thandler.source,\n\t\t\t\t),\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tconst match =\n\t\t\thandler.event === \"Notification\"\n\t\t\t\t? { diagnostics: [], matched: true }\n\t\t\t\t: matchesLifecycleMatcher(handler, options.matcherInputs);\n\t\tdiagnostics.push(...match.diagnostics);\n\t\tif (match.matched) matched.push(handler);\n\t}\n\tconst trustRecords = listHookTrustRecords(matched, options.trustState, { platform: process.platform });\n\tconst trusted = matched.filter((_handler, index) => trustRecords[index]?.executable === true);\n\treturn { diagnostics, handlers: trusted };\n}\n\nfunction isInitialRuntimeSessionStart(handler: ExecutableHookHandler, input: HookInputWire): boolean {\n\treturn input.event === \"SessionStart\" && input.reason === \"startup\" && handler.source.discoveredAt === \"runtime\";\n}\n\nfunction matchesLifecycleMatcher(\n\thandler: ExecutableHookHandler,\n\tinputs: readonly string[],\n): { readonly diagnostics: readonly HookDiagnostic[]; readonly matched: boolean } {\n\tconst matcher = handler.matcher?.trim();\n\tif (matcher === undefined || matcher.length === 0 || matcher === \"*\") {\n\t\treturn { diagnostics: [], matched: true };\n\t}\n\tconst literalMatched = matcher\n\t\t.split(/[|,]/)\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length > 0)\n\t\t.some((part) => inputs.includes(part));\n\ttry {\n\t\tconst regex = new RegExp(matcher);\n\t\treturn { diagnostics: [], matched: literalMatched || inputs.some((input) => regex.test(input)) };\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) {\n\t\t\treturn {\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_matcher\",\n\t\t\t\t\t\t\tevent: handler.event,\n\t\t\t\t\t\t\tmessage: `Hook matcher is not a valid JavaScript regular expression: ${error.message}`,\n\t\t\t\t\t\t\tpath: `hooks.${handler.event}[${handler.groupIndex}].matcher`,\n\t\t\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\thandler.source,\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\tmatched: literalMatched,\n\t\t\t};\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction stripLifecycleMatcher(handler: ExecutableHookHandler): ExecutableHookHandler {\n\treturn {\n\t\tconfig: handler.config,\n\t\tevent: handler.event,\n\t\tgroupIndex: handler.groupIndex,\n\t\thandlerIndex: handler.handlerIndex,\n\t\tsource: handler.source,\n\t};\n}\n\nfunction lifecycleResultDetails(\n\tevent: LifecycleHookEvent,\n\tresult: HookDispatchResult | undefined,\n): LifecycleResultDetails {\n\tif (result === undefined) {\n\t\treturn { cancel: false, contexts: [], diagnostics: [] };\n\t}\n\tconst diagnostics = [...result.diagnostics, ...commandFailureDiagnostics(event, result)];\n\tconst contexts: string[] = [];\n\tfor (const summary of result.summaries) {\n\t\tconst output = readLifecycleHookOutput(event, summary.run.stdout);\n\t\tif (output?.additionalContext !== undefined && event !== \"PreCompact\") {\n\t\t\tcontexts.push(output.additionalContext);\n\t\t}\n\t\tif (event === \"PreCompact\") {\n\t\t\tdiagnostics.push(...preCompactUnsupportedDiagnostics(summary.handler, output));\n\t\t}\n\t}\n\tconst reason = event === \"PreCompact\" && result.decision.kind === \"block\" ? result.decision.reason : undefined;\n\treturn {\n\t\tcancel: event === \"PreCompact\" && result.decision.kind === \"block\",\n\t\tcontexts,\n\t\tdiagnostics,\n\t\t...(reason === undefined ? {} : { reason }),\n\t};\n}\n\nfunction commandFailureDiagnostics(event: LifecycleHookEvent, result: HookDispatchResult): readonly HookDiagnostic[] {\n\treturn result.summaries.flatMap((summary) => {\n\t\tif (summary.run.exitCode === 0 || (summary.run.exitCode === 2 && event === \"PreCompact\")) return [];\n\t\tconst status = summary.run.exitCode === null ? \"without an exit code\" : `with exit code ${summary.run.exitCode}`;\n\t\treturn [\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: \"invalid_root\",\n\t\t\t\t\tevent,\n\t\t\t\t\tmessage: `Hook command failed ${status}.`,\n\t\t\t\t\tpath: \"process.exitCode\",\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t},\n\t\t\t\tsummary.handler.source,\n\t\t\t),\n\t\t];\n\t});\n}\n\nfunction preCompactUnsupportedDiagnostics(\n\thandler: ExecutableHookHandler,\n\toutput: LifecycleHookOutput | undefined,\n): readonly HookDiagnostic[] {\n\tif (output === undefined) return [];\n\tconst diagnostics: HookDiagnostic[] = [];\n\tif (output.additionalContext !== undefined) {\n\t\tdiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: \"unsupported_field\",\n\t\t\t\t\tevent: \"PreCompact\",\n\t\t\t\t\tmessage: \"PreCompact additionalContext is diagnostic-only in builtin hooks v1.\",\n\t\t\t\t\tpath: \"stdout.hookSpecificOutput.additionalContext\",\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t},\n\t\t\t\thandler.source,\n\t\t\t),\n\t\t);\n\t}\n\tif (output.customInstructions !== undefined) {\n\t\tdiagnostics.push(\n\t\t\tdiagnostic(\n\t\t\t\t{\n\t\t\t\t\tcode: \"unsupported_field\",\n\t\t\t\t\tevent: \"PreCompact\",\n\t\t\t\t\tmessage: \"PreCompact customInstructions cannot mutate compaction in builtin hooks v1.\",\n\t\t\t\t\tpath: \"stdout.hookSpecificOutput.customInstructions\",\n\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t},\n\t\t\t\thandler.source,\n\t\t\t),\n\t\t);\n\t}\n\treturn diagnostics;\n}\n\nfunction readLifecycleHookOutput(event: LifecycleHookEvent, stdout: string): LifecycleHookOutput | undefined {\n\tconst trimmed = stdout.trim();\n\tif (trimmed.length === 0) return undefined;\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(trimmed);\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) return undefined;\n\t\tthrow error;\n\t}\n\tif (!isRecord(parsed)) return undefined;\n\tconst specific = isRecord(parsed.hookSpecificOutput) ? parsed.hookSpecificOutput : undefined;\n\tif (specific?.hookEventName !== undefined && specific.hookEventName !== event) return undefined;\n\treturn {\n\t\t...textField(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\"),\n\t\t...textField(specific?.customInstructions ?? parsed.customInstructions, \"customInstructions\"),\n\t\t...textField(parsed.decision, \"decision\"),\n\t\t...textField(specific?.permissionDecisionReason ?? parsed.reason, \"reason\"),\n\t};\n}\n\nfunction textField<K extends keyof LifecycleHookOutput>(\n\tvalue: unknown,\n\tkey: K,\n): Pick<LifecycleHookOutput, K> | Record<string, never> {\n\tif (typeof value !== \"string\") return {};\n\tconst trimmed = value.trim();\n\treturn trimmed.length === 0 ? {} : ({ [key]: trimmed } as Pick<LifecycleHookOutput, K>);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"]}
@@ -41,6 +41,7 @@ function matcherSubject(input) {
41
41
  switch (input.event) {
42
42
  case "UserPromptSubmit":
43
43
  case "Stop":
44
+ case "Notification":
44
45
  return { kind: "ignored" };
45
46
  case "PreToolUse":
46
47
  case "PostToolUse":
@@ -1 +1 @@
1
- {"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/matcher.ts"],"names":[],"mappings":"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","sourcesContent":["import { diagnostic } from \"./diagnostics.ts\";\nimport type { ExecutableHookHandler, HookDiagnostic, HookInputWire } from \"./types.ts\";\n\nexport type HookMatcherResult = {\n\treadonly handlers: readonly ExecutableHookHandler[];\n\treadonly diagnostics: readonly HookDiagnostic[];\n};\n\ntype MatcherSubject = { readonly kind: \"ignored\" } | { readonly kind: \"inputs\"; readonly inputs: readonly string[] };\n\nconst TOOL_MATCHER_ALIASES: Readonly<Record<string, readonly string[]>> = {\n\tapply_patch: [\"ApplyPatch\", \"functions.apply_patch\"],\n\tbash: [\"Bash\", \"Shell\", \"shell\", \"exec_command\", \"functions.exec_command\"],\n\tcreate_goal: [\"CreateGoal\"],\n\tedit: [\"Edit\", \"MultiEdit\", \"multi_edit\"],\n\tfind: [\"Find\", \"Glob\", \"glob\", \"file_search\"],\n\tget_goal: [\"GetGoal\"],\n\tgrep: [\"Grep\", \"Search\", \"grep_app\"],\n\tls: [\"LS\", \"List\", \"list\"],\n\tread: [\"Read\", \"open\", \"read_file\"],\n\ttodo: [\"Todo\"],\n\ttodoread: [\"TodoRead\"],\n\ttodowrite: [\"TodoWrite\"],\n\tupdate_goal: [\"UpdateGoal\"],\n\tweb_search: [\"WebSearch\", \"web-search\"],\n\twebfetch: [\"WebFetch\", \"web_fetch\", \"web-fetch\"],\n\twrite: [\"Write\", \"write_file\"],\n} as const;\n\nexport function matchingHookHandlers(\n\tinput: HookInputWire,\n\thandlers: readonly ExecutableHookHandler[],\n): HookMatcherResult {\n\tconst subject = matcherSubject(input);\n\tconst selected: ExecutableHookHandler[] = [];\n\tconst diagnostics: HookDiagnostic[] = [];\n\n\tfor (const handler of handlers) {\n\t\tif (handler.event !== input.event) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (subject.kind === \"ignored\") {\n\t\t\tselected.push(handler);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst match = matchesMatcher(handler, subject.inputs);\n\t\tdiagnostics.push(...match.diagnostics);\n\t\tif (match.matched) {\n\t\t\tselected.push(handler);\n\t\t}\n\t}\n\n\treturn { handlers: selected, diagnostics };\n}\n\nfunction matcherSubject(input: HookInputWire): MatcherSubject {\n\tswitch (input.event) {\n\t\tcase \"UserPromptSubmit\":\n\t\tcase \"Stop\":\n\t\t\treturn { kind: \"ignored\" };\n\t\tcase \"PreToolUse\":\n\t\tcase \"PostToolUse\":\n\t\t\treturn { kind: \"inputs\", inputs: toolMatcherInputs(input.toolName) };\n\t\tcase \"SessionStart\":\n\t\tcase \"PreCompact\":\n\t\tcase \"PostCompact\":\n\t\t\treturn { kind: \"inputs\", inputs: [input.event] };\n\t}\n}\n\nfunction toolMatcherInputs(toolName: string): readonly string[] {\n\tconst values = new Set<string>();\n\taddMatcherInput(values, toolName);\n\n\tconst lowerToolName = toolName.toLowerCase();\n\taddMatcherInput(values, lowerToolName);\n\taddMatcherInput(values, toClaudeToolName(lowerToolName));\n\n\tfor (const alias of TOOL_MATCHER_ALIASES[lowerToolName] ?? []) {\n\t\taddMatcherInput(values, alias);\n\t}\n\n\treturn [...values];\n}\n\nfunction addMatcherInput(values: Set<string>, value: string): void {\n\tconst trimmed = value.trim();\n\tif (trimmed.length > 0) {\n\t\tvalues.add(trimmed);\n\t}\n}\n\nfunction toClaudeToolName(toolName: string): string {\n\treturn toolName\n\t\t.split(/[-_]/)\n\t\t.filter((part) => part.length > 0)\n\t\t.map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)\n\t\t.join(\"\");\n}\n\nfunction matchesMatcher(\n\thandler: ExecutableHookHandler,\n\tinputs: readonly string[],\n): { readonly matched: boolean; readonly diagnostics: readonly HookDiagnostic[] } {\n\tconst matcher = handler.matcher?.trim();\n\tif (matcher === undefined || matcher.length === 0 || matcher === \"*\") {\n\t\treturn { matched: true, diagnostics: [] };\n\t}\n\n\tconst literalMatched = matcher\n\t\t.split(/[|,]/)\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length > 0)\n\t\t.some((part) => inputs.includes(part));\n\n\ttry {\n\t\tconst regex = new RegExp(matcher);\n\t\treturn { matched: literalMatched || inputs.some((input) => regex.test(input)), diagnostics: [] };\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) {\n\t\t\treturn {\n\t\t\t\tmatched: literalMatched,\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_matcher\",\n\t\t\t\t\t\t\tevent: handler.event,\n\t\t\t\t\t\t\tmessage: `Hook matcher is not a valid JavaScript regular expression: ${error.message}`,\n\t\t\t\t\t\t\tpath: `hooks.${handler.event}[${handler.groupIndex}].matcher`,\n\t\t\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\thandler.source,\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t\tthrow error;\n\t}\n}\n"]}
1
+ {"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/matcher.ts"],"names":[],"mappings":"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","sourcesContent":["import { diagnostic } from \"./diagnostics.ts\";\nimport type { ExecutableHookHandler, HookDiagnostic, HookInputWire } from \"./types.ts\";\n\nexport type HookMatcherResult = {\n\treadonly handlers: readonly ExecutableHookHandler[];\n\treadonly diagnostics: readonly HookDiagnostic[];\n};\n\ntype MatcherSubject = { readonly kind: \"ignored\" } | { readonly kind: \"inputs\"; readonly inputs: readonly string[] };\n\nconst TOOL_MATCHER_ALIASES: Readonly<Record<string, readonly string[]>> = {\n\tapply_patch: [\"ApplyPatch\", \"functions.apply_patch\"],\n\tbash: [\"Bash\", \"Shell\", \"shell\", \"exec_command\", \"functions.exec_command\"],\n\tcreate_goal: [\"CreateGoal\"],\n\tedit: [\"Edit\", \"MultiEdit\", \"multi_edit\"],\n\tfind: [\"Find\", \"Glob\", \"glob\", \"file_search\"],\n\tget_goal: [\"GetGoal\"],\n\tgrep: [\"Grep\", \"Search\", \"grep_app\"],\n\tls: [\"LS\", \"List\", \"list\"],\n\tread: [\"Read\", \"open\", \"read_file\"],\n\ttodo: [\"Todo\"],\n\ttodoread: [\"TodoRead\"],\n\ttodowrite: [\"TodoWrite\"],\n\tupdate_goal: [\"UpdateGoal\"],\n\tweb_search: [\"WebSearch\", \"web-search\"],\n\twebfetch: [\"WebFetch\", \"web_fetch\", \"web-fetch\"],\n\twrite: [\"Write\", \"write_file\"],\n} as const;\n\nexport function matchingHookHandlers(\n\tinput: HookInputWire,\n\thandlers: readonly ExecutableHookHandler[],\n): HookMatcherResult {\n\tconst subject = matcherSubject(input);\n\tconst selected: ExecutableHookHandler[] = [];\n\tconst diagnostics: HookDiagnostic[] = [];\n\n\tfor (const handler of handlers) {\n\t\tif (handler.event !== input.event) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (subject.kind === \"ignored\") {\n\t\t\tselected.push(handler);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst match = matchesMatcher(handler, subject.inputs);\n\t\tdiagnostics.push(...match.diagnostics);\n\t\tif (match.matched) {\n\t\t\tselected.push(handler);\n\t\t}\n\t}\n\n\treturn { handlers: selected, diagnostics };\n}\n\nfunction matcherSubject(input: HookInputWire): MatcherSubject {\n\tswitch (input.event) {\n\t\tcase \"UserPromptSubmit\":\n\t\tcase \"Stop\":\n\t\tcase \"Notification\":\n\t\t\treturn { kind: \"ignored\" };\n\t\tcase \"PreToolUse\":\n\t\tcase \"PostToolUse\":\n\t\t\treturn { kind: \"inputs\", inputs: toolMatcherInputs(input.toolName) };\n\t\tcase \"SessionStart\":\n\t\tcase \"PreCompact\":\n\t\tcase \"PostCompact\":\n\t\t\treturn { kind: \"inputs\", inputs: [input.event] };\n\t}\n}\n\nfunction toolMatcherInputs(toolName: string): readonly string[] {\n\tconst values = new Set<string>();\n\taddMatcherInput(values, toolName);\n\n\tconst lowerToolName = toolName.toLowerCase();\n\taddMatcherInput(values, lowerToolName);\n\taddMatcherInput(values, toClaudeToolName(lowerToolName));\n\n\tfor (const alias of TOOL_MATCHER_ALIASES[lowerToolName] ?? []) {\n\t\taddMatcherInput(values, alias);\n\t}\n\n\treturn [...values];\n}\n\nfunction addMatcherInput(values: Set<string>, value: string): void {\n\tconst trimmed = value.trim();\n\tif (trimmed.length > 0) {\n\t\tvalues.add(trimmed);\n\t}\n}\n\nfunction toClaudeToolName(toolName: string): string {\n\treturn toolName\n\t\t.split(/[-_]/)\n\t\t.filter((part) => part.length > 0)\n\t\t.map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)\n\t\t.join(\"\");\n}\n\nfunction matchesMatcher(\n\thandler: ExecutableHookHandler,\n\tinputs: readonly string[],\n): { readonly matched: boolean; readonly diagnostics: readonly HookDiagnostic[] } {\n\tconst matcher = handler.matcher?.trim();\n\tif (matcher === undefined || matcher.length === 0 || matcher === \"*\") {\n\t\treturn { matched: true, diagnostics: [] };\n\t}\n\n\tconst literalMatched = matcher\n\t\t.split(/[|,]/)\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length > 0)\n\t\t.some((part) => inputs.includes(part));\n\n\ttry {\n\t\tconst regex = new RegExp(matcher);\n\t\treturn { matched: literalMatched || inputs.some((input) => regex.test(input)), diagnostics: [] };\n\t} catch (error) {\n\t\tif (error instanceof SyntaxError) {\n\t\t\treturn {\n\t\t\t\tmatched: literalMatched,\n\t\t\t\tdiagnostics: [\n\t\t\t\t\tdiagnostic(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcode: \"invalid_matcher\",\n\t\t\t\t\t\t\tevent: handler.event,\n\t\t\t\t\t\t\tmessage: `Hook matcher is not a valid JavaScript regular expression: ${error.message}`,\n\t\t\t\t\t\t\tpath: `hooks.${handler.event}[${handler.groupIndex}].matcher`,\n\t\t\t\t\t\t\tseverity: \"warning\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\thandler.source,\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t\tthrow error;\n\t}\n}\n"]}
@@ -95,6 +95,12 @@ function parseEvent(parsed, specific, state) {
95
95
  copyText(parsed.reason, "reason", state);
96
96
  copyText(specific?.additionalContext ?? parsed.additionalContext, "additionalContext", state);
97
97
  return;
98
+ case "Notification":
99
+ copyText(specific?.additionalContext ?? parsed.additionalContext, "additionalContext", state);
100
+ if (parsed.decision !== undefined) {
101
+ add(state, "unsupported_field", "stdout.decision", "Notification does not support decisions.", "warning");
102
+ }
103
+ return;
98
104
  case "SessionStart":
99
105
  copyText(specific?.additionalContext ?? parsed.additionalContext, "additionalContext", state);
100
106
  if (parsed.decision !== undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"output-parser.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/output-parser.ts"],"names":[],"mappings":"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","sourcesContent":["import { diagnostic } from \"./diagnostics.ts\";\nimport type { HookDiagnostic, HookSourceMetadata, SupportedHookEvent } from \"./types.ts\";\n\nexport type HookOutputParseInput = {\n\treadonly event: SupportedHookEvent;\n\treadonly exitCode: number;\n\treadonly stdout: string;\n\treadonly stderr: string;\n\treadonly source: HookSourceMetadata;\n};\n\ntype HookDecision = \"allow\" | \"approve\" | \"ask\" | \"block\" | \"deny\";\ntype MutableHookOutput = {\n\tdecision?: HookDecision;\n\treason?: string;\n\tadditionalContext?: string;\n\tupdatedInput?: unknown;\n\tupdatedToolOutput?: unknown;\n\tcontinue?: boolean;\n\tstopReason?: string;\n\tsuppressOutput?: boolean;\n\tsystemMessage?: string;\n};\n\nexport type ParsedHookOutput = {\n\treadonly output: Readonly<MutableHookOutput>;\n\treadonly diagnostics: readonly HookDiagnostic[];\n};\n\ntype ParseState = {\n\treadonly input: HookOutputParseInput;\n\treadonly output: MutableHookOutput;\n\treadonly diagnostics: HookDiagnostic[];\n};\n\nconst SYSTEM_MESSAGE_EVENTS = new Set<SupportedHookEvent>([\n\t\"PreToolUse\",\n\t\"PostToolUse\",\n\t\"UserPromptSubmit\",\n\t\"SessionStart\",\n\t\"Stop\",\n]);\n\nexport function parseHookOutput(input: HookOutputParseInput): ParsedHookOutput {\n\tconst state: ParseState = { input, output: {}, diagnostics: [] };\n\tconst stderr = text(input.stderr);\n\tif (input.exitCode === 2) {\n\t\treturn { output: { decision: \"block\", ...(stderr === undefined ? {} : { reason: stderr }) }, diagnostics: [] };\n\t}\n\tconst stdout = input.stdout.trim();\n\tif (stdout.length === 0) return parsedOutput(state);\n\tconst parsed = parseStdoutJson(stdout, state);\n\tif (!isRecord(parsed)) return parsedOutput(state);\n\tparseUniversal(parsed, state);\n\tconst specific = parseSpecific(parsed.hookSpecificOutput, state);\n\tif (specific === \"mismatched\" || specific === \"invalid\") return parsedOutput(state);\n\tparseEvent(parsed, specific, state);\n\treturn parsedOutput(state);\n}\n\nfunction parseStdoutJson(stdout: string, state: ParseState): unknown {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(stdout);\n\t\tif (isRecord(parsed)) return parsed;\n\t\tadd(state, \"invalid_root\", \"stdout\", \"Hook stdout JSON must be an object.\");\n\t} catch (error) {\n\t\tif (!(error instanceof SyntaxError)) throw error;\n\t\tadd(state, \"invalid_root\", \"stdout\", \"Hook stdout must be valid JSON.\");\n\t}\n\treturn undefined;\n}\n\nfunction parseUniversal(parsed: Record<string, unknown>, state: ParseState): void {\n\tif (typeof parsed.continue === \"boolean\") {\n\t\tstate.output.continue = parsed.continue;\n\t\tif (state.input.event === \"Stop\" && parsed.continue === false) state.output.decision = \"block\";\n\t}\n\tcopyText(parsed.stopReason, \"stopReason\", state);\n\tif (typeof parsed.suppressOutput === \"boolean\") state.output.suppressOutput = parsed.suppressOutput;\n\tif (parsed.systemMessage === undefined) return;\n\tif (SYSTEM_MESSAGE_EVENTS.has(state.input.event)) {\n\t\tcopyText(parsed.systemMessage, \"systemMessage\", state);\n\t\treturn;\n\t}\n\tadd(\n\t\tstate,\n\t\t\"unsupported_field\",\n\t\t\"stdout.systemMessage\",\n\t\t\"Hook systemMessage is not supported for this event.\",\n\t\t\"warning\",\n\t);\n}\n\nfunction parseSpecific(\n\tvalue: unknown,\n\tstate: ParseState,\n): Record<string, unknown> | \"invalid\" | \"mismatched\" | undefined {\n\tif (value === undefined) return undefined;\n\tif (!isRecord(value)) {\n\t\tadd(\n\t\t\tstate,\n\t\t\t\"invalid_event_config\",\n\t\t\t\"stdout.hookSpecificOutput\",\n\t\t\t\"Hook hookSpecificOutput field must be an object.\",\n\t\t);\n\t\treturn \"invalid\";\n\t}\n\tconst eventName = value.hookEventName;\n\tif (eventName === undefined || eventName === state.input.event) return value;\n\tadd(\n\t\tstate,\n\t\t\"invalid_event_config\",\n\t\t\"stdout.hookSpecificOutput.hookEventName\",\n\t\t`Hook output event ${String(eventName)} does not match ${state.input.event}.`,\n\t);\n\treturn \"mismatched\";\n}\n\nfunction parseEvent(\n\tparsed: Record<string, unknown>,\n\tspecific: Record<string, unknown> | undefined,\n\tstate: ParseState,\n): void {\n\tswitch (state.input.event) {\n\t\tcase \"PreToolUse\":\n\t\t\tparsePreToolUse(parsed, specific, state);\n\t\t\treturn;\n\t\tcase \"PostToolUse\":\n\t\t\tblockOnlyDecision(parsed.decision, \"PostToolUse\", state);\n\t\t\tcopyText(parsed.reason, \"reason\", state);\n\t\t\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\t\t\tcopyUnknown(specific?.updatedToolOutput ?? parsed.updatedToolOutput, \"updatedToolOutput\", state);\n\t\t\treturn;\n\t\tcase \"UserPromptSubmit\":\n\t\t\tblockOnlyDecision(parsed.decision, \"UserPromptSubmit\", state);\n\t\t\tcopyText(parsed.reason, \"reason\", state);\n\t\t\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\t\t\trejectPromptReplacement(specific, state);\n\t\t\treturn;\n\t\tcase \"Stop\":\n\t\t\tif (parsed.decision === \"block\") state.output.decision = \"block\";\n\t\t\telse if (parsed.decision !== undefined && parsed.decision !== \"continue\") {\n\t\t\t\tadd(\n\t\t\t\t\tstate,\n\t\t\t\t\t\"unsupported_field\",\n\t\t\t\t\t\"stdout.decision\",\n\t\t\t\t\t\"Stop only supports decision block or continue.\",\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tcopyText(parsed.reason, \"reason\", state);\n\t\t\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\t\t\treturn;\n\t\tcase \"SessionStart\":\n\t\t\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\t\t\tif (parsed.decision !== undefined) {\n\t\t\t\tadd(state, \"unsupported_field\", \"stdout.decision\", \"SessionStart does not support decisions.\", \"warning\");\n\t\t\t}\n\t\t\treturn;\n\t\tcase \"PreCompact\":\n\t\tcase \"PostCompact\":\n\t\t\treturn;\n\t}\n}\n\nfunction parsePreToolUse(\n\tparsed: Record<string, unknown>,\n\tspecific: Record<string, unknown> | undefined,\n\tstate: ParseState,\n): void {\n\tconst decision = preToolUseDecision(specific?.permissionDecision ?? parsed.decision);\n\tif (decision !== undefined) state.output.decision = decision;\n\tcopyText(specific?.permissionDecisionReason ?? parsed.reason, \"reason\", state);\n\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\tconst updatedInput = specific?.updatedInput ?? parsed.updatedInput;\n\tif (updatedInput === undefined) return;\n\tif (specific?.permissionDecision === \"allow\") {\n\t\tstate.output.updatedInput = updatedInput;\n\t\treturn;\n\t}\n\tadd(\n\t\tstate,\n\t\t\"unsupported_field\",\n\t\t\"stdout.hookSpecificOutput.updatedInput\",\n\t\t\"PreToolUse updatedInput is only applied when permissionDecision is allow.\",\n\t\t\"warning\",\n\t);\n}\n\nfunction blockOnlyDecision(value: unknown, event: string, state: ParseState): void {\n\tif (value === \"block\") state.output.decision = \"block\";\n\telse if (value !== undefined)\n\t\tadd(state, \"unsupported_field\", \"stdout.decision\", `${event} only supports decision block.`, \"warning\");\n}\n\nfunction rejectPromptReplacement(specific: Record<string, unknown> | undefined, state: ParseState): void {\n\tfor (const field of [\"prompt\", \"updatedPrompt\", \"replacementPrompt\"]) {\n\t\tif (specific !== undefined && Object.hasOwn(specific, field)) {\n\t\t\tadd(\n\t\t\t\tstate,\n\t\t\t\t\"unsupported_field\",\n\t\t\t\t`stdout.hookSpecificOutput.${field}`,\n\t\t\t\t\"UserPromptSubmit prompt replacement is not supported.\",\n\t\t\t\t\"warning\",\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction preToolUseDecision(value: unknown): HookDecision | undefined {\n\tif (value === \"allow\" || value === \"approve\" || value === \"ask\") return value;\n\tif (value === \"deny\" || value === \"block\") return \"deny\";\n\treturn undefined;\n}\n\nfunction copyText(\n\tvalue: unknown,\n\tfield: \"additionalContext\" | \"reason\" | \"stopReason\" | \"systemMessage\",\n\tstate: ParseState,\n): void {\n\tconst normalized = text(value);\n\tif (normalized !== undefined) state.output[field] = normalized;\n}\n\nfunction copyUnknown(value: unknown, field: \"updatedToolOutput\", state: ParseState): void {\n\tif (value !== undefined) state.output[field] = value;\n}\n\nfunction add(\n\tstate: ParseState,\n\tcode: \"invalid_event_config\" | \"invalid_root\" | \"unsupported_field\",\n\tpath: string,\n\tmessage: string,\n\tseverity?: \"error\" | \"warning\",\n): void {\n\tstate.diagnostics.push(\n\t\tdiagnostic(\n\t\t\t{ code, event: state.input.event, message, path, ...(severity === undefined ? {} : { severity }) },\n\t\t\tstate.input.source,\n\t\t),\n\t);\n}\n\nfunction text(value: unknown): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\tconst trimmed = value.trim();\n\treturn trimmed.length === 0 ? undefined : trimmed;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parsedOutput(state: ParseState): ParsedHookOutput {\n\treturn { output: state.output, diagnostics: state.diagnostics };\n}\n"]}
1
+ {"version":3,"file":"output-parser.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/output-parser.ts"],"names":[],"mappings":"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","sourcesContent":["import { diagnostic } from \"./diagnostics.ts\";\nimport type { HookDiagnostic, HookSourceMetadata, SupportedHookEvent } from \"./types.ts\";\n\nexport type HookOutputParseInput = {\n\treadonly event: SupportedHookEvent;\n\treadonly exitCode: number;\n\treadonly stdout: string;\n\treadonly stderr: string;\n\treadonly source: HookSourceMetadata;\n};\n\ntype HookDecision = \"allow\" | \"approve\" | \"ask\" | \"block\" | \"deny\";\ntype MutableHookOutput = {\n\tdecision?: HookDecision;\n\treason?: string;\n\tadditionalContext?: string;\n\tupdatedInput?: unknown;\n\tupdatedToolOutput?: unknown;\n\tcontinue?: boolean;\n\tstopReason?: string;\n\tsuppressOutput?: boolean;\n\tsystemMessage?: string;\n};\n\nexport type ParsedHookOutput = {\n\treadonly output: Readonly<MutableHookOutput>;\n\treadonly diagnostics: readonly HookDiagnostic[];\n};\n\ntype ParseState = {\n\treadonly input: HookOutputParseInput;\n\treadonly output: MutableHookOutput;\n\treadonly diagnostics: HookDiagnostic[];\n};\n\nconst SYSTEM_MESSAGE_EVENTS = new Set<SupportedHookEvent>([\n\t\"PreToolUse\",\n\t\"PostToolUse\",\n\t\"UserPromptSubmit\",\n\t\"SessionStart\",\n\t\"Stop\",\n]);\n\nexport function parseHookOutput(input: HookOutputParseInput): ParsedHookOutput {\n\tconst state: ParseState = { input, output: {}, diagnostics: [] };\n\tconst stderr = text(input.stderr);\n\tif (input.exitCode === 2) {\n\t\treturn { output: { decision: \"block\", ...(stderr === undefined ? {} : { reason: stderr }) }, diagnostics: [] };\n\t}\n\tconst stdout = input.stdout.trim();\n\tif (stdout.length === 0) return parsedOutput(state);\n\tconst parsed = parseStdoutJson(stdout, state);\n\tif (!isRecord(parsed)) return parsedOutput(state);\n\tparseUniversal(parsed, state);\n\tconst specific = parseSpecific(parsed.hookSpecificOutput, state);\n\tif (specific === \"mismatched\" || specific === \"invalid\") return parsedOutput(state);\n\tparseEvent(parsed, specific, state);\n\treturn parsedOutput(state);\n}\n\nfunction parseStdoutJson(stdout: string, state: ParseState): unknown {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(stdout);\n\t\tif (isRecord(parsed)) return parsed;\n\t\tadd(state, \"invalid_root\", \"stdout\", \"Hook stdout JSON must be an object.\");\n\t} catch (error) {\n\t\tif (!(error instanceof SyntaxError)) throw error;\n\t\tadd(state, \"invalid_root\", \"stdout\", \"Hook stdout must be valid JSON.\");\n\t}\n\treturn undefined;\n}\n\nfunction parseUniversal(parsed: Record<string, unknown>, state: ParseState): void {\n\tif (typeof parsed.continue === \"boolean\") {\n\t\tstate.output.continue = parsed.continue;\n\t\tif (state.input.event === \"Stop\" && parsed.continue === false) state.output.decision = \"block\";\n\t}\n\tcopyText(parsed.stopReason, \"stopReason\", state);\n\tif (typeof parsed.suppressOutput === \"boolean\") state.output.suppressOutput = parsed.suppressOutput;\n\tif (parsed.systemMessage === undefined) return;\n\tif (SYSTEM_MESSAGE_EVENTS.has(state.input.event)) {\n\t\tcopyText(parsed.systemMessage, \"systemMessage\", state);\n\t\treturn;\n\t}\n\tadd(\n\t\tstate,\n\t\t\"unsupported_field\",\n\t\t\"stdout.systemMessage\",\n\t\t\"Hook systemMessage is not supported for this event.\",\n\t\t\"warning\",\n\t);\n}\n\nfunction parseSpecific(\n\tvalue: unknown,\n\tstate: ParseState,\n): Record<string, unknown> | \"invalid\" | \"mismatched\" | undefined {\n\tif (value === undefined) return undefined;\n\tif (!isRecord(value)) {\n\t\tadd(\n\t\t\tstate,\n\t\t\t\"invalid_event_config\",\n\t\t\t\"stdout.hookSpecificOutput\",\n\t\t\t\"Hook hookSpecificOutput field must be an object.\",\n\t\t);\n\t\treturn \"invalid\";\n\t}\n\tconst eventName = value.hookEventName;\n\tif (eventName === undefined || eventName === state.input.event) return value;\n\tadd(\n\t\tstate,\n\t\t\"invalid_event_config\",\n\t\t\"stdout.hookSpecificOutput.hookEventName\",\n\t\t`Hook output event ${String(eventName)} does not match ${state.input.event}.`,\n\t);\n\treturn \"mismatched\";\n}\n\nfunction parseEvent(\n\tparsed: Record<string, unknown>,\n\tspecific: Record<string, unknown> | undefined,\n\tstate: ParseState,\n): void {\n\tswitch (state.input.event) {\n\t\tcase \"PreToolUse\":\n\t\t\tparsePreToolUse(parsed, specific, state);\n\t\t\treturn;\n\t\tcase \"PostToolUse\":\n\t\t\tblockOnlyDecision(parsed.decision, \"PostToolUse\", state);\n\t\t\tcopyText(parsed.reason, \"reason\", state);\n\t\t\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\t\t\tcopyUnknown(specific?.updatedToolOutput ?? parsed.updatedToolOutput, \"updatedToolOutput\", state);\n\t\t\treturn;\n\t\tcase \"UserPromptSubmit\":\n\t\t\tblockOnlyDecision(parsed.decision, \"UserPromptSubmit\", state);\n\t\t\tcopyText(parsed.reason, \"reason\", state);\n\t\t\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\t\t\trejectPromptReplacement(specific, state);\n\t\t\treturn;\n\t\tcase \"Stop\":\n\t\t\tif (parsed.decision === \"block\") state.output.decision = \"block\";\n\t\t\telse if (parsed.decision !== undefined && parsed.decision !== \"continue\") {\n\t\t\t\tadd(\n\t\t\t\t\tstate,\n\t\t\t\t\t\"unsupported_field\",\n\t\t\t\t\t\"stdout.decision\",\n\t\t\t\t\t\"Stop only supports decision block or continue.\",\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tcopyText(parsed.reason, \"reason\", state);\n\t\t\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\t\t\treturn;\n\t\tcase \"Notification\":\n\t\t\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\t\t\tif (parsed.decision !== undefined) {\n\t\t\t\tadd(state, \"unsupported_field\", \"stdout.decision\", \"Notification does not support decisions.\", \"warning\");\n\t\t\t}\n\t\t\treturn;\n\t\tcase \"SessionStart\":\n\t\t\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\t\t\tif (parsed.decision !== undefined) {\n\t\t\t\tadd(state, \"unsupported_field\", \"stdout.decision\", \"SessionStart does not support decisions.\", \"warning\");\n\t\t\t}\n\t\t\treturn;\n\t\tcase \"PreCompact\":\n\t\tcase \"PostCompact\":\n\t\t\treturn;\n\t}\n}\n\nfunction parsePreToolUse(\n\tparsed: Record<string, unknown>,\n\tspecific: Record<string, unknown> | undefined,\n\tstate: ParseState,\n): void {\n\tconst decision = preToolUseDecision(specific?.permissionDecision ?? parsed.decision);\n\tif (decision !== undefined) state.output.decision = decision;\n\tcopyText(specific?.permissionDecisionReason ?? parsed.reason, \"reason\", state);\n\tcopyText(specific?.additionalContext ?? parsed.additionalContext, \"additionalContext\", state);\n\tconst updatedInput = specific?.updatedInput ?? parsed.updatedInput;\n\tif (updatedInput === undefined) return;\n\tif (specific?.permissionDecision === \"allow\") {\n\t\tstate.output.updatedInput = updatedInput;\n\t\treturn;\n\t}\n\tadd(\n\t\tstate,\n\t\t\"unsupported_field\",\n\t\t\"stdout.hookSpecificOutput.updatedInput\",\n\t\t\"PreToolUse updatedInput is only applied when permissionDecision is allow.\",\n\t\t\"warning\",\n\t);\n}\n\nfunction blockOnlyDecision(value: unknown, event: string, state: ParseState): void {\n\tif (value === \"block\") state.output.decision = \"block\";\n\telse if (value !== undefined)\n\t\tadd(state, \"unsupported_field\", \"stdout.decision\", `${event} only supports decision block.`, \"warning\");\n}\n\nfunction rejectPromptReplacement(specific: Record<string, unknown> | undefined, state: ParseState): void {\n\tfor (const field of [\"prompt\", \"updatedPrompt\", \"replacementPrompt\"]) {\n\t\tif (specific !== undefined && Object.hasOwn(specific, field)) {\n\t\t\tadd(\n\t\t\t\tstate,\n\t\t\t\t\"unsupported_field\",\n\t\t\t\t`stdout.hookSpecificOutput.${field}`,\n\t\t\t\t\"UserPromptSubmit prompt replacement is not supported.\",\n\t\t\t\t\"warning\",\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction preToolUseDecision(value: unknown): HookDecision | undefined {\n\tif (value === \"allow\" || value === \"approve\" || value === \"ask\") return value;\n\tif (value === \"deny\" || value === \"block\") return \"deny\";\n\treturn undefined;\n}\n\nfunction copyText(\n\tvalue: unknown,\n\tfield: \"additionalContext\" | \"reason\" | \"stopReason\" | \"systemMessage\",\n\tstate: ParseState,\n): void {\n\tconst normalized = text(value);\n\tif (normalized !== undefined) state.output[field] = normalized;\n}\n\nfunction copyUnknown(value: unknown, field: \"updatedToolOutput\", state: ParseState): void {\n\tif (value !== undefined) state.output[field] = value;\n}\n\nfunction add(\n\tstate: ParseState,\n\tcode: \"invalid_event_config\" | \"invalid_root\" | \"unsupported_field\",\n\tpath: string,\n\tmessage: string,\n\tseverity?: \"error\" | \"warning\",\n): void {\n\tstate.diagnostics.push(\n\t\tdiagnostic(\n\t\t\t{ code, event: state.input.event, message, path, ...(severity === undefined ? {} : { severity }) },\n\t\t\tstate.input.source,\n\t\t),\n\t);\n}\n\nfunction text(value: unknown): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\tconst trimmed = value.trim();\n\treturn trimmed.length === 0 ? undefined : trimmed;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parsedOutput(state: ParseState): ParsedHookOutput {\n\treturn { output: state.output, diagnostics: state.diagnostics };\n}\n"]}
@@ -18,6 +18,8 @@ export declare class FileHookStateStorage implements HookStateStorage {
18
18
  private readonly globalStatePath;
19
19
  private readonly projectStatePath;
20
20
  constructor(options: FileHookStateStorageOptions);
21
+ /** Writers publish atomic snapshots. Missing or invalid snapshots authorize nothing. */
22
+ readAsync(scope: HookTrustStorageScope): Promise<HookTrustState>;
21
23
  read(scope: HookTrustStorageScope): HookTrustState;
22
24
  update(scope: HookTrustStorageScope, updater: (current: HookTrustState) => HookTrustState): HookTrustState;
23
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"trust-storage.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/trust-storage.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAChC,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAAC;IACnD,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,cAAc,GAAG,cAAc,CAAC;CAC3G;AAED,MAAM,MAAM,2BAA2B,GAAG;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,YAAY,OAAO,EAAE,2BAA2B,EAI/C;IAED,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAqBjD;IAED,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,cAAc,GAAG,cAAc,CAwBzG;CACD;AAED,qBAAa,wBAAyB,YAAW,gBAAgB;IAChE,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,YAAY,CAAyC;IAE7D,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAEjD;IAED,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,cAAc,GAAG,cAAc,CAQzG;CACD"}
1
+ {"version":3,"file":"trust-storage.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/hooks/trust-storage.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAChC,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAAC;IACnD,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,cAAc,GAAG,cAAc,CAAC;CAC3G;AAED,MAAM,MAAM,2BAA2B,GAAG;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,YAAY,OAAO,EAAE,2BAA2B,EAI/C;IAED,wFAAwF;IAClF,SAAS,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAQrE;IAED,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAqBjD;IAED,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,cAAc,GAAG,cAAc,CAwBzG;CACD;AAED,qBAAa,wBAAyB,YAAW,gBAAgB;IAChE,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,YAAY,CAAyC;IAE7D,IAAI,CAAC,KAAK,EAAE,qBAAqB,GAAG,cAAc,CAEjD;IAED,MAAM,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,cAAc,GAAG,cAAc,CAQzG;CACD"}
@@ -1,5 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
3
+ import { readFile } from "node:fs/promises";
3
4
  import { dirname, join } from "node:path";
4
5
  import lockfile from "proper-lockfile";
5
6
  import { CONFIG_DIR_NAME, getAgentDir } from "../../../../config.js";
@@ -16,6 +17,18 @@ export class FileHookStateStorage {
16
17
  this.globalStatePath = join(agentDir, "hooks-state.json");
17
18
  this.projectStatePath = join(options.cwd, CONFIG_DIR_NAME, "hooks-state.json");
18
19
  }
20
+ /** Writers publish atomic snapshots. Missing or invalid snapshots authorize nothing. */
21
+ async readAsync(scope) {
22
+ const path = statePathForScope(scope, this.globalStatePath, this.projectStatePath);
23
+ try {
24
+ return readHookTrustStateJson(await readFile(path, "utf8"));
25
+ }
26
+ catch (error) {
27
+ if (errorCode(error) === "ENOENT")
28
+ return emptyHookTrustState();
29
+ throw error;
30
+ }
31
+ }
19
32
  read(scope) {
20
33
  const path = statePathForScope(scope, this.globalStatePath, this.projectStatePath);
21
34
  const snapshot = parseHookTrustStateJson(existsSync(path) ? readFileSync(path, "utf-8") : undefined);