commandmate 0.22.1 → 0.23.0

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 (484) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +86 -86
  3. package/.next/app-path-routes-manifest.json +17 -17
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +9 -9
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/app/update-check/route.js +1 -1
  10. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/assistant/conversation/route.js +1 -1
  12. package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
  13. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/assistant/current-output/route.js +1 -1
  15. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  16. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/assistant/messages/route.js +1 -1
  18. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  19. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/assistant/session/route.js +1 -1
  21. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  22. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/assistant/start/route.js +1 -1
  24. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  25. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/assistant/terminal/route.js +3 -3
  27. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  28. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/assistant/tools/route.js +1 -1
  30. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  31. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/daily-summary/route.js +1 -1
  36. package/.next/server/app/api/daily-summary/route.js.nft.json +1 -1
  37. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/daily-summary/status/route.js +1 -1
  39. package/.next/server/app/api/daily-summary/status/route.js.nft.json +1 -1
  40. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/external-apps/[id]/health/route.js +1 -1
  42. package/.next/server/app/api/external-apps/[id]/health/route.js.nft.json +1 -1
  43. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/external-apps/[id]/route.js +1 -1
  45. package/.next/server/app/api/external-apps/[id]/route.js.nft.json +1 -1
  46. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/external-apps/route.js +1 -1
  48. package/.next/server/app/api/external-apps/route.js.nft.json +1 -1
  49. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/fs/browse/route.js +1 -1
  51. package/.next/server/app/api/fs/browse/route.js.nft.json +1 -1
  52. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/fs/recent-paths/route.js +1 -1
  54. package/.next/server/app/api/fs/recent-paths/route.js.nft.json +1 -1
  55. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  57. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  58. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/hooks/claude-done/route.js +1 -1
  60. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  61. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  63. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  64. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/metrics/vibe/route.js +1 -1
  66. package/.next/server/app/api/metrics/vibe/route.js.nft.json +1 -1
  67. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/push/subscriptions/route.js +1 -1
  70. package/.next/server/app/api/push/subscriptions/route.js.nft.json +1 -1
  71. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  72. package/.next/server/app/api/push/vapid/route.js +1 -1
  73. package/.next/server/app/api/push/vapid/route.js.nft.json +1 -1
  74. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/repositories/[id]/route.js +1 -1
  76. package/.next/server/app/api/repositories/[id]/route.js.nft.json +1 -1
  77. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js +1 -1
  79. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js.nft.json +1 -1
  80. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
  82. package/.next/server/app/api/repositories/[id]/todos/route.js.nft.json +1 -1
  83. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  85. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  86. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/repositories/clone/route.js +1 -1
  88. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  89. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/repositories/excluded/route.js +1 -1
  91. package/.next/server/app/api/repositories/excluded/route.js.nft.json +1 -1
  92. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/repositories/restore/route.js +1 -1
  94. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  95. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/repositories/route.js +1 -1
  97. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  98. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/repositories/scan/route.js +1 -1
  100. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  101. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/repositories/sync/route.js +1 -1
  103. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  104. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/repositories/validate-path/route.js +1 -1
  106. package/.next/server/app/api/repositories/validate-path/route.js.nft.json +1 -1
  107. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/sidebar/group-order/route.js +1 -1
  109. package/.next/server/app/api/sidebar/group-order/route.js.nft.json +1 -1
  110. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/skills/installations/route.js +1 -1
  113. package/.next/server/app/api/skills/installations/route.js.nft.json +1 -1
  114. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/skills/operations/route.js +1 -1
  116. package/.next/server/app/api/skills/operations/route.js.nft.json +1 -1
  117. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/skills/reindex/route.js +1 -1
  119. package/.next/server/app/api/skills/reindex/route.js.nft.json +1 -1
  120. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/tasks/[taskId]/cancel/route.js +1 -4
  124. package/.next/server/app/api/tasks/[taskId]/cancel/route.js.nft.json +1 -1
  125. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/tasks/[taskId]/route.js +1 -4
  127. package/.next/server/app/api/tasks/[taskId]/route.js.nft.json +1 -1
  128. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/templates/[id]/route.js +1 -1
  130. package/.next/server/app/api/templates/[id]/route.js.nft.json +1 -1
  131. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/templates/route.js +1 -1
  133. package/.next/server/app/api/templates/route.js.nft.json +1 -1
  134. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/todos/route.js +1 -1
  136. package/.next/server/app/api/todos/route.js.nft.json +1 -1
  137. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/verification/runs/[runId]/route.js +1 -1
  139. package/.next/server/app/api/verification/runs/[runId]/route.js.nft.json +1 -1
  140. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/verification/runs/route.js +1 -1
  142. package/.next/server/app/api/verification/runs/route.js.nft.json +1 -1
  143. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  146. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  149. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js.nft.json +1 -1
  152. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +2 -2
  154. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +1 -1
  155. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  158. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js.nft.json +1 -1
  161. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +2 -2
  163. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js.nft.json +1 -1
  164. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +1 -1
  167. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js.nft.json +1 -1
  170. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js.nft.json +1 -1
  173. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/git/branches/route.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/git/branches/route.js.nft.json +1 -1
  176. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/git/checkout/route.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/git/checkout/route.js.nft.json +1 -1
  179. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/git/commit/route.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/git/commit/route.js.nft.json +1 -1
  182. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/git/diff/route.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/git/diff/route.js.nft.json +1 -1
  185. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/git/fetch/route.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/git/fetch/route.js.nft.json +1 -1
  188. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/git/log/route.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/git/log/route.js.nft.json +1 -1
  191. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/git/pull/route.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/git/pull/route.js.nft.json +1 -1
  194. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/git/push/route.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/git/push/route.js.nft.json +1 -1
  197. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/git/reset/route.js +1 -1
  199. package/.next/server/app/api/worktrees/[id]/git/reset/route.js.nft.json +1 -1
  200. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/git/revert/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/git/revert/route.js.nft.json +1 -1
  203. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js.nft.json +1 -1
  206. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/api/worktrees/[id]/git/stage/route.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/git/stage/route.js.nft.json +1 -1
  209. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/api/worktrees/[id]/git/staged/route.js +1 -1
  211. package/.next/server/app/api/worktrees/[id]/git/staged/route.js.nft.json +1 -1
  212. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js +1 -1
  214. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js.nft.json +1 -1
  215. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js +1 -1
  217. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js.nft.json +1 -1
  218. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  219. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js +1 -1
  220. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js.nft.json +1 -1
  221. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  222. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js +1 -1
  223. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js.nft.json +1 -1
  224. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  225. package/.next/server/app/api/worktrees/[id]/git/stash/route.js +1 -1
  226. package/.next/server/app/api/worktrees/[id]/git/stash/route.js.nft.json +1 -1
  227. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/api/worktrees/[id]/git/status/route.js +1 -1
  229. package/.next/server/app/api/worktrees/[id]/git/status/route.js.nft.json +1 -1
  230. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  231. package/.next/server/app/api/worktrees/[id]/git/unstage/route.js +1 -1
  232. package/.next/server/app/api/worktrees/[id]/git/unstage/route.js.nft.json +1 -1
  233. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  234. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js +1 -1
  235. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js.nft.json +1 -1
  236. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  237. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  238. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  239. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  240. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  241. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  242. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  243. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
  244. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +1 -1
  245. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  246. package/.next/server/app/api/worktrees/[id]/logs/route.js +1 -1
  247. package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +1 -1
  248. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  249. package/.next/server/app/api/worktrees/[id]/marp-render/route.js +3 -3
  250. package/.next/server/app/api/worktrees/[id]/marp-render/route.js.nft.json +1 -1
  251. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  252. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -1
  253. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js.nft.json +1 -1
  254. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  255. package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -1
  256. package/.next/server/app/api/worktrees/[id]/memos/route.js.nft.json +1 -1
  257. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  258. package/.next/server/app/api/worktrees/[id]/messages/route.js +1 -1
  259. package/.next/server/app/api/worktrees/[id]/messages/route.js.nft.json +1 -1
  260. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  261. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  262. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  263. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  264. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  265. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  266. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  267. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  268. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  269. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  270. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +2 -2
  271. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js.nft.json +1 -1
  272. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  273. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
  274. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
  275. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  276. package/.next/server/app/api/worktrees/[id]/schedules/route.js +3 -3
  277. package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +1 -1
  278. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  279. package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
  280. package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +1 -1
  281. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  282. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  283. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  284. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  285. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +1 -1
  286. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  287. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  288. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js +1 -1
  289. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js.nft.json +1 -1
  290. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  291. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js +1 -1
  292. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js.nft.json +1 -1
  293. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  294. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js +1 -1
  295. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js.nft.json +1 -1
  296. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  297. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js +1 -1
  298. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js.nft.json +1 -1
  299. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  300. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route.js +1 -1
  301. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route.js.nft.json +1 -1
  302. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  303. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js +1 -1
  304. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js.nft.json +1 -1
  305. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  306. package/.next/server/app/api/worktrees/[id]/skills/route.js +1 -1
  307. package/.next/server/app/api/worktrees/[id]/skills/route.js.nft.json +1 -1
  308. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  309. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  310. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +1 -1
  311. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  312. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  313. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  314. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  315. package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -1
  316. package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
  317. package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
  318. package/.next/server/app/api/worktrees/[id]/tasks/route.js +2 -2
  319. package/.next/server/app/api/worktrees/[id]/tasks/route.js.nft.json +1 -1
  320. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  321. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  322. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  323. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  324. package/.next/server/app/api/worktrees/[id]/timers/history/route.js +1 -1
  325. package/.next/server/app/api/worktrees/[id]/timers/history/route.js.nft.json +1 -1
  326. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  327. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  328. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  329. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  330. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js +1 -1
  331. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js.nft.json +1 -1
  332. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  333. package/.next/server/app/api/worktrees/[id]/todos/route.js +1 -1
  334. package/.next/server/app/api/worktrees/[id]/todos/route.js.nft.json +1 -1
  335. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  336. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js +1 -1
  337. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +1 -1
  338. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  339. package/.next/server/app/api/worktrees/[id]/tree/route.js +1 -1
  340. package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +1 -1
  341. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  342. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js +1 -1
  343. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +1 -1
  344. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  345. package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -4
  346. package/.next/server/app/api/worktrees/[id]/verify/route.js.nft.json +1 -1
  347. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  348. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route.js +1 -1
  349. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route.js.nft.json +1 -1
  350. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  351. package/.next/server/app/api/worktrees/[id]/verify/runs/route.js +1 -1
  352. package/.next/server/app/api/worktrees/[id]/verify/runs/route.js.nft.json +1 -1
  353. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  354. package/.next/server/app/api/worktrees/[id]/viewed/route.js +1 -1
  355. package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +1 -1
  356. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  357. package/.next/server/app/api/worktrees/route.js +1 -1
  358. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  359. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  360. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  361. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  362. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  363. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  364. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  365. package/.next/server/app/page_client-reference-manifest.js +1 -1
  366. package/.next/server/app/proxy/[...path]/route.js +1 -1
  367. package/.next/server/app/proxy/[...path]/route.js.nft.json +1 -1
  368. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  369. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  370. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  371. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  372. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  373. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  374. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  375. package/.next/server/app/worktrees/[id]/files/[...path]/page.js +1 -1
  376. package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
  377. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  378. package/.next/server/app/worktrees/[id]/page.js +2 -2
  379. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  380. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  381. package/.next/server/app/worktrees/[id]/terminal/page.js +1 -1
  382. package/.next/server/app/worktrees/[id]/terminal/page.js.nft.json +1 -1
  383. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  384. package/.next/server/app-paths-manifest.json +17 -17
  385. package/.next/server/chunks/1029.js +1 -1
  386. package/.next/server/chunks/1068.js +1 -1
  387. package/.next/server/chunks/2119.js +1 -1
  388. package/.next/server/chunks/2404.js +1 -1
  389. package/.next/server/chunks/2445.js +1 -1
  390. package/.next/server/chunks/2546.js +1 -1
  391. package/.next/server/chunks/3241.js +1 -0
  392. package/.next/server/chunks/3417.js +1 -1
  393. package/.next/server/chunks/406.js +10 -6
  394. package/.next/server/chunks/4444.js +1 -1
  395. package/.next/server/chunks/5959.js +4 -5
  396. package/.next/server/chunks/5998.js +1 -12
  397. package/.next/server/chunks/6130.js +1 -1
  398. package/.next/server/chunks/6274.js +3 -3
  399. package/.next/server/chunks/6401.js +1 -1
  400. package/.next/server/chunks/6781.js +1 -0
  401. package/.next/server/chunks/7458.js +6 -0
  402. package/.next/server/chunks/{3753.js → 7970.js} +57 -32
  403. package/.next/server/chunks/8536.js +1 -1
  404. package/.next/server/chunks/8807.js +180 -127
  405. package/.next/server/chunks/9058.js +1 -1
  406. package/.next/server/chunks/9067.js +1 -1
  407. package/.next/server/chunks/9360.js +1 -1
  408. package/.next/server/chunks/9687.js +2 -2
  409. package/.next/server/middleware-manifest.json +5 -5
  410. package/.next/server/pages/500.html +1 -1
  411. package/.next/server/server-reference-manifest.json +1 -1
  412. package/.next/server/src/middleware.js.map +1 -1
  413. package/.next/static/chunks/{6488-63dacfbab082ca8d.js → 6488-95ba9d24a76f0cc5.js} +1 -1
  414. package/.next/static/chunks/app/worktrees/[id]/{page-c1be93f2595d0803.js → page-966a451ae7b0903a.js} +1 -1
  415. package/.next/trace +12 -12
  416. package/dist/cli/docs/agent-operations.d.ts +1 -1
  417. package/dist/cli/docs/agent-operations.d.ts.map +1 -1
  418. package/dist/cli/docs/agent-operations.js +5 -1
  419. package/dist/cli/utils/api-client.d.ts.map +1 -1
  420. package/dist/cli/utils/api-client.js +9 -2
  421. package/dist/cli/utils/server-url.d.ts +23 -0
  422. package/dist/cli/utils/server-url.d.ts.map +1 -1
  423. package/dist/cli/utils/server-url.js +33 -0
  424. package/dist/server/src/config/log-config.js +10 -1
  425. package/dist/server/src/config/safe-directory.js +103 -0
  426. package/dist/server/src/config/system-directories.js +74 -9
  427. package/dist/server/src/lib/cli-tools/antigravity.js +19 -2
  428. package/dist/server/src/lib/cli-tools/codex.js +95 -1
  429. package/dist/server/src/lib/cli-tools/copilot.js +30 -1
  430. package/dist/server/src/lib/cli-tools/gemini.js +28 -2
  431. package/dist/server/src/lib/cli-tools/opencode.js +51 -2
  432. package/dist/server/src/lib/git/git-default-branch.js +59 -0
  433. package/dist/server/src/lib/hooks/agent-event-service.js +205 -0
  434. package/dist/server/src/lib/hooks/agent-event-types.js +7 -86
  435. package/dist/server/src/lib/hooks/hook-settings-generator.js +26 -11
  436. package/dist/server/src/lib/hooks/permission-decision-service.js +269 -0
  437. package/dist/server/src/lib/hooks/sources/abstain.js +78 -0
  438. package/dist/server/src/lib/hooks/sources/antigravity/hooks-config.js +372 -0
  439. package/dist/server/src/lib/hooks/sources/antigravity/source.js +225 -0
  440. package/dist/server/src/lib/hooks/sources/antigravity/tool-id.js +16 -0
  441. package/dist/server/src/lib/hooks/sources/claude/source.js +143 -0
  442. package/dist/server/src/lib/hooks/sources/claude/tool-id.js +18 -0
  443. package/dist/server/src/lib/hooks/sources/codex/hooks-config.js +465 -0
  444. package/dist/server/src/lib/hooks/sources/codex/source.js +138 -0
  445. package/dist/server/src/lib/hooks/sources/codex/tool-id.js +15 -0
  446. package/dist/server/src/lib/hooks/sources/copilot/hook-settings.js +473 -0
  447. package/dist/server/src/lib/hooks/sources/copilot/source.js +210 -0
  448. package/dist/server/src/lib/hooks/sources/copilot/tool-id.js +15 -0
  449. package/dist/server/src/lib/hooks/sources/define-source.js +169 -0
  450. package/dist/server/src/lib/hooks/sources/event-mapper.js +157 -0
  451. package/dist/server/src/lib/hooks/sources/gemini/event-vocabulary.js +102 -0
  452. package/dist/server/src/lib/hooks/sources/gemini/settings-generator.js +315 -0
  453. package/dist/server/src/lib/hooks/sources/gemini/shared-config-tree.js +103 -0
  454. package/dist/server/src/lib/hooks/sources/gemini/source.js +151 -0
  455. package/dist/server/src/lib/hooks/sources/gemini/tool-id.js +17 -0
  456. package/dist/server/src/lib/hooks/sources/hook-event-vocabulary.js +111 -0
  457. package/dist/server/src/lib/hooks/sources/index.js +62 -0
  458. package/dist/server/src/lib/hooks/sources/legacy-relay.js +84 -0
  459. package/dist/server/src/lib/hooks/sources/opencode/client.js +299 -0
  460. package/dist/server/src/lib/hooks/sources/opencode/ingest.js +261 -0
  461. package/dist/server/src/lib/hooks/sources/opencode/mappers.js +154 -0
  462. package/dist/server/src/lib/hooks/sources/opencode/payloads.js +189 -0
  463. package/dist/server/src/lib/hooks/sources/opencode/ports.js +295 -0
  464. package/dist/server/src/lib/hooks/sources/opencode/runtime.js +159 -0
  465. package/dist/server/src/lib/hooks/sources/opencode/source.js +250 -0
  466. package/dist/server/src/lib/hooks/sources/opencode/subscription.js +422 -0
  467. package/dist/server/src/lib/hooks/sources/opencode/tool-id.js +14 -0
  468. package/dist/server/src/lib/hooks/sources/opencode/turn-gate.js +193 -0
  469. package/dist/server/src/lib/hooks/sources/pending-decisions.js +127 -0
  470. package/dist/server/src/lib/hooks/sources/registry.js +111 -0
  471. package/dist/server/src/lib/hooks/sources/types.js +46 -0
  472. package/dist/server/src/lib/session/agent-session-lifecycle.js +82 -0
  473. package/dist/server/src/lib/session/claude-session.js +10 -3
  474. package/dist/server/src/lib/tasks/contract-message.js +175 -0
  475. package/dist/server/src/lib/verification/env-clean-gate.js +320 -0
  476. package/dist/server/src/lib/verification/env-snapshot.js +474 -0
  477. package/dist/server/src/lib/verification/gate-runner.js +802 -0
  478. package/dist/server/src/lib/verification/scope-gate.js +402 -0
  479. package/dist/server/src/lib/verification/verify-config.js +281 -0
  480. package/package.json +1 -1
  481. package/scripts/hooks/cmate-agent-event.sh +73 -3
  482. package/.next/server/chunks/8856.js +0 -4
  483. /package/.next/static/{d4vh4O18WEhXs4WbdShIs → wH6K6QNPHSdATFkVoIcy3}/_buildManifest.js +0 -0
  484. /package/.next/static/{d4vh4O18WEhXs4WbdShIs → wH6K6QNPHSdATFkVoIcy3}/_ssgManifest.js +0 -0
@@ -5,12 +5,15 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.CodexTool = void 0;
8
+ exports.isCodexHooksReviewDialog = isCodexHooksReviewDialog;
8
9
  const base_1 = require("./base");
9
10
  const tmux_1 = require("../tmux/tmux");
10
11
  const submit_verified_sender_1 = require("./submit-verified-sender");
11
12
  const tmux_capture_cache_1 = require("../tmux/tmux-capture-cache");
12
13
  const cli_patterns_1 = require("../detection/cli-patterns");
13
14
  const logger_1 = require("../../lib/logger");
15
+ const sources_1 = require("../../lib/hooks/sources");
16
+ const agent_session_lifecycle_1 = require("../../lib/session/agent-session-lifecycle");
14
17
  const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
15
18
  const logger = (0, logger_1.createLogger)('cli-tools/codex');
16
19
  /**
@@ -28,6 +31,63 @@ const CODEX_POLL_INTERVAL_MS = 1000;
28
31
  const CODEX_INIT_MAX_ATTEMPTS = 30;
29
32
  /** Timeout for waiting for prompt before sending a message */
30
33
  const CODEX_PROMPT_WAIT_TIMEOUT_MS = 15000;
34
+ /**
35
+ * Anchors of codex's "Hooks need review" dialog (Issue #1760, measured on
36
+ * codex-cli 0.147.0):
37
+ *
38
+ * ```
39
+ * Hooks need review
40
+ * 5 hooks are new or changed.
41
+ * Hooks can run outside the sandbox after you trust them.
42
+ *
43
+ * > 1. Review hooks
44
+ * 2. Trust all and continue
45
+ * 3. Continue without trusting (hooks won't run)
46
+ * ```
47
+ *
48
+ * It has to be handled here rather than in `getCodexActiveDialog`, which
49
+ * classifies it as `null`: its wording matches none of that function's three
50
+ * anchors (`Skip until next version` / `Do you trust` / `Press enter to
51
+ * continue`). Measured consequence of leaving it alone, on a pane with the
52
+ * generated `hooks.json` present: `isCodexPromptReady` stays false for the full
53
+ * 30-attempt window and the session is then handed to `sendMessage` still
54
+ * sitting on the dialog. Every launch, because "continue without trusting" is
55
+ * not remembered — verified by relaunching and getting the same screen.
56
+ *
57
+ * Both strings are required so a "hooks" mention elsewhere cannot select an
58
+ * option on a live prompt.
59
+ */
60
+ const CODEX_HOOKS_REVIEW_ANCHORS = ['Hooks need review', 'Continue without trusting'];
61
+ /**
62
+ * Option 3, "Continue without trusting (hooks won't run)".
63
+ *
64
+ * Not option 2. Trusting writes `[hooks.state."<file>:<event>:0:0"]` entries
65
+ * into the operator's own `~/.codex/config.toml` — the file that carries, among
66
+ * other things, the `notify` command a Computer Use integration runs — and
67
+ * granting that on someone's behalf is not this server's call. So a session
68
+ * starts with the hooks inert and the screen scraper doing exactly what it did
69
+ * before Issue #1760; the human enables them once through codex's own review
70
+ * screen, or an operator sets `CM_CODEX_HOOK_TRUST=bypass`.
71
+ *
72
+ * Sent alone, like the other numbered dialogs (Issue #890): codex confirms a
73
+ * numbered selection instantly, and a trailing Enter would land on the next
74
+ * screen. Verified live — the prompt was ready on the following poll.
75
+ */
76
+ const CODEX_HOOKS_REVIEW_DECLINE_KEY = '3';
77
+ /**
78
+ * Whether the pane is sitting on the hooks review dialog.
79
+ *
80
+ * Position-independent on purpose, unlike `getCodexActiveDialog`: the only
81
+ * caller checks `isCodexPromptReady` first and returns when a genuine prompt
82
+ * exists, so residual dialog text above a live prompt is never reached, and a
83
+ * one-shot guard stops the key being sent twice.
84
+ *
85
+ * @param output - ANSI-stripped pane capture
86
+ * @returns True when both anchors of the dialog are present
87
+ */
88
+ function isCodexHooksReviewDialog(output) {
89
+ return CODEX_HOOKS_REVIEW_ANCHORS.every((anchor) => output.includes(anchor));
90
+ }
31
91
  /**
32
92
  * Codex CLI tool implementation
33
93
  * Manages Codex sessions using tmux
@@ -66,6 +126,18 @@ class CodexTool extends base_1.BaseCLITool {
66
126
  logger.info('codex-session-sessionname');
67
127
  return;
68
128
  }
129
+ // Issue #1760: everything the previous codex process reported through this
130
+ // (worktreeId, instanceId) belongs to a session that no longer exists, and
131
+ // the key is reused verbatim by the one about to be created. Without this
132
+ // fence the old process's last `user_prompt_submit` reads as the new one's
133
+ // and a brand-new session publishes `running` before anyone has typed into
134
+ // it (#1723).
135
+ //
136
+ // Creation path only — the reuse branch above has already returned — and
137
+ // before `createSession`, so no live pane is ever matched against a stale
138
+ // generation. Bumped even when the launch then fails: falling back to the
139
+ // scraper is always safe, trusting a dead session's events is not.
140
+ (0, agent_session_lifecycle_1.beginAgentSession)({ worktreeId, cliToolId: sources_1.CODEX_CLI_TOOL_ID, instanceId });
69
141
  try {
70
142
  // Create tmux session. Codex is inline-rendered, so its transcript lives in
71
143
  // the pane scrollback — depth comes from the shared TMUX_HISTORY_LIMIT
@@ -76,8 +148,18 @@ class CodexTool extends base_1.BaseCLITool {
76
148
  });
77
149
  // Wait a moment for the session to be created
78
150
  await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
151
+ // Issue #1760: hand this session its correlation keys, writing codex's
152
+ // hooks config first if it is not already there. codex has no
153
+ // `--settings`, so the keys ride in environment assignments on the launch
154
+ // line and the hook commands read them back — which is what tells `codex`
155
+ // from `codex-2` in one worktree, since `cwd` is identical for both.
156
+ //
157
+ // Falls back to the bare command on any failure and when
158
+ // `CM_AGENT_HOOKS_INJECT=0`; a session that starts without hooks is the
159
+ // pre-#1760 status quo, and a session that fails to start is not.
160
+ const launchCommand = (0, agent_session_lifecycle_1.prepareAgentLaunch)({ worktreeId, cliToolId: sources_1.CODEX_CLI_TOOL_ID, instanceId }, this.command).command;
79
161
  // Start Codex CLI in interactive mode
80
- await (0, tmux_1.sendKeys)(sessionName, 'codex', true);
162
+ await (0, tmux_1.sendKeys)(sessionName, launchCommand, true);
81
163
  // Wait for Codex to initialize
82
164
  await new Promise((resolve) => setTimeout(resolve, CODEX_INIT_WAIT_MS));
83
165
  // Poll until Codex interactive prompt is ready
@@ -102,6 +184,7 @@ class CodexTool extends base_1.BaseCLITool {
102
184
  // update branch re-sends "2" every poll and the live prompt gets "222...".
103
185
  let updateDialogHandled = false;
104
186
  let trustDialogHandled = false;
187
+ let hooksReviewHandled = false;
105
188
  for (let i = 0; i < CODEX_INIT_MAX_ATTEMPTS; i++) {
106
189
  try {
107
190
  const rawOutput = await (0, tmux_1.capturePane)(sessionName, 50);
@@ -114,6 +197,17 @@ class CodexTool extends base_1.BaseCLITool {
114
197
  logger.info('codex-prompt-detected');
115
198
  return;
116
199
  }
200
+ // Issue #1760: "Hooks need review". Reached only when no genuine prompt
201
+ // exists (the check above returned), so this cannot fire on a live
202
+ // prompt, and the one-shot guard stops a second key on a re-render.
203
+ // Declines: granting trust would write the operator's config.toml.
204
+ if (!hooksReviewHandled && isCodexHooksReviewDialog(output)) {
205
+ await (0, tmux_1.sendKeys)(sessionName, CODEX_HOOKS_REVIEW_DECLINE_KEY, false);
206
+ hooksReviewHandled = true;
207
+ logger.info('codex-hooks-review-declined');
208
+ await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.CODEX_DIALOG_SETTLE_MS));
209
+ continue;
210
+ }
117
211
  // Issue #892: classify the bottom-most ACTIVE dialog by position. A dialog
118
212
  // whose text is only residual scrollback above a genuine prompt returns
119
213
  // null here, so no stray key is sent after it has been dismissed.
@@ -17,6 +17,9 @@ const tmux_capture_cache_1 = require("../tmux/tmux-capture-cache");
17
17
  const cli_patterns_1 = require("../detection/cli-patterns");
18
18
  const copilot_constants_1 = require("../../config/copilot-constants");
19
19
  const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
20
+ const agent_session_lifecycle_1 = require("../../lib/session/agent-session-lifecycle");
21
+ const hook_settings_1 = require("../../lib/hooks/sources/copilot/hook-settings");
22
+ const tool_id_1 = require("../../lib/hooks/sources/copilot/tool-id");
20
23
  const errors_1 = require("../../lib/errors");
21
24
  const logger_1 = require("../../lib/logger");
22
25
  const logger = (0, logger_1.createLogger)('cli-tools/copilot');
@@ -112,6 +115,18 @@ class CopilotTool extends base_1.BaseCLITool {
112
115
  logger.info('copilot-session-exists');
113
116
  return;
114
117
  }
118
+ // Issue #1761: fence this session off from the previous copilot process's
119
+ // events. The state is keyed by (worktree, tool, instance), a key the new
120
+ // session reuses verbatim, so without this the old process's last
121
+ // `user_prompt_submit` reads as the new one's and a session publishes
122
+ // `running` before anybody has typed into it (#1723).
123
+ //
124
+ // Creation path only — the reuse branch above has already returned — and
125
+ // before the pane exists, so no live pane is ever judged against a stale
126
+ // generation. Outside the try, so a launch that then fails is still fenced:
127
+ // falling back to the scraper is always safe, trusting a dead session's
128
+ // events is not.
129
+ (0, agent_session_lifecycle_1.beginAgentSession)({ worktreeId, cliToolId: tool_id_1.COPILOT_CLI_TOOL_ID, instanceId });
115
130
  try {
116
131
  // Create tmux session. Scrollback depth comes from the shared
117
132
  // TMUX_HISTORY_LIMIT default (Issue #1624) — do not re-hardcode it here.
@@ -121,8 +136,22 @@ class CopilotTool extends base_1.BaseCLITool {
121
136
  });
122
137
  // Wait a moment for the session to be created
123
138
  await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
139
+ // Issue #1761: hand this session its hook configuration, so structured
140
+ // lifecycle events and Auto-Yes adjudication exist without the operator
141
+ // having edited ~/.copilot/settings.json by hand.
142
+ //
143
+ // The returned command is `gh copilot` with two environment assignments
144
+ // in front of it. Copilot's config is one file for the whole machine, so
145
+ // unlike Claude's `--settings` it cannot carry the correlation keys —
146
+ // they ride in the environment and the hook reads them when it fires.
147
+ // See `lib/hooks/sources/copilot/hook-settings`.
148
+ //
149
+ // Fails open in every branch: with `CM_AGENT_HOOKS_INJECT=0`, or with a
150
+ // settings file that cannot be read or written, this is byte-for-byte the
151
+ // `gh copilot` this line has always sent.
152
+ const launchCommand = (0, agent_session_lifecycle_1.prepareAgentLaunch)({ worktreeId, cliToolId: tool_id_1.COPILOT_CLI_TOOL_ID, instanceId }, hook_settings_1.COPILOT_LAUNCH_COMMAND).command;
124
153
  // Start Copilot CLI in interactive mode
125
- await (0, tmux_1.sendKeys)(sessionName, 'gh copilot', true);
154
+ await (0, tmux_1.sendKeys)(sessionName, launchCommand, true);
126
155
  // Wait for Copilot to initialize
127
156
  await new Promise((resolve) => setTimeout(resolve, COPILOT_INIT_WAIT_MS));
128
157
  // Poll until Copilot interactive prompt is ready
@@ -15,6 +15,9 @@ const tmux_1 = require("../tmux/tmux");
15
15
  const submit_verified_sender_1 = require("./submit-verified-sender");
16
16
  const tmux_capture_cache_1 = require("../tmux/tmux-capture-cache");
17
17
  const cli_patterns_1 = require("../detection/cli-patterns");
18
+ const sources_1 = require("../../lib/hooks/sources");
19
+ const source_1 = require("../../lib/hooks/sources/gemini/source");
20
+ const agent_session_lifecycle_1 = require("../../lib/session/agent-session-lifecycle");
18
21
  const logger_1 = require("../../lib/logger");
19
22
  const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
20
23
  const logger = (0, logger_1.createLogger)('cli-tools/gemini');
@@ -73,6 +76,13 @@ class GeminiTool extends base_1.BaseCLITool {
73
76
  logger.info('gemini-session-sessionname');
74
77
  return;
75
78
  }
79
+ // Issue #1762: fence this instance's structured events off from the process
80
+ // that used to hold the same (worktree, tool, instance) key. On the creation
81
+ // path only — the reuse branch above has already returned — and before the
82
+ // pane exists, so no live pane is ever judged against a stale generation.
83
+ // Bumped even if the launch below then fails: falling back to the screen
84
+ // scraper is always safe, trusting a dead session's events is not.
85
+ (0, agent_session_lifecycle_1.beginAgentSession)({ worktreeId, cliToolId: sources_1.GEMINI_CLI_TOOL_ID, instanceId });
76
86
  try {
77
87
  // Create tmux session. Scrollback depth comes from the shared
78
88
  // TMUX_HISTORY_LIMIT default (Issue #1624) — do not re-hardcode it here.
@@ -82,8 +92,24 @@ class GeminiTool extends base_1.BaseCLITool {
82
92
  });
83
93
  // Wait a moment for the session to be created
84
94
  await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
85
- // Start Gemini CLI in interactive mode (no flags = interactive REPL)
86
- await (0, tmux_1.sendKeys)(sessionName, 'gemini', true);
95
+ // Issue #1762: hand this worktree its own hooks config, merged into any
96
+ // `.gemini/settings.json` that is already there. Written from here rather
97
+ // than from the source's `prepareLaunch` because the worktree path is the
98
+ // one input `AgentInstanceRef` does not carry, and gemini is the only tool
99
+ // whose config is scoped to a worktree. Fail-open: a config that cannot be
100
+ // written costs the events and nothing else.
101
+ (0, source_1.injectGeminiHookSettings)(worktreePath, {
102
+ worktreeId,
103
+ cliToolId: sources_1.GEMINI_CLI_TOOL_ID,
104
+ instanceId,
105
+ });
106
+ // Start Gemini CLI in interactive mode (no flags = interactive REPL).
107
+ // `prepareAgentLaunch` prefixes `CM_HOOK_URL`, which is what tells the
108
+ // receiver which instance an event came from — `.gemini/settings.json` is
109
+ // per worktree and cannot. `CM_AGENT_HOOKS_INJECT=0` returns the bare
110
+ // command, unchanged from before this Issue.
111
+ const launchCommand = (0, agent_session_lifecycle_1.prepareAgentLaunch)({ worktreeId, cliToolId: sources_1.GEMINI_CLI_TOOL_ID, instanceId }, this.command).command;
112
+ await (0, tmux_1.sendKeys)(sessionName, launchCommand, true);
87
113
  // Wait for Gemini to initialize (minimum wait for banner/auth)
88
114
  await new Promise((resolve) => setTimeout(resolve, GEMINI_INIT_WAIT_MS));
89
115
  // Poll until Gemini interactive prompt is ready
@@ -8,6 +8,22 @@
8
8
  * - sendMessage: sends text via tmux send-keys + Enter
9
9
  * - killSession: sends `/exit` command then falls back to tmux kill-session
10
10
  * - interrupt(): inherits BaseCLITool default (Escape key) [D2-008]
11
+ *
12
+ * ## Structured events (Issue #1763, Epic #1720 Phase 4-5)
13
+ *
14
+ * opencode is the one supported agent that does not push lifecycle events at
15
+ * CommandMate: it is *subscribed to*. #1758 §5.1.2 measured that the plain TUI
16
+ * serves the same HTTP API `opencode serve` does once it is given `--port`, so
17
+ * the whole of the launch change is that flag — no second process, no pid to
18
+ * track, no orphan to reap, and `killSession`'s `/exit`, the init wait and
19
+ * `reconcileExistingSession` are all untouched.
20
+ *
21
+ * What is added around it is three calls into
22
+ * `@/lib/hooks/sources/opencode/runtime`: reserve a port before the launch
23
+ * command is built, attach the event stream once the TUI is up, and release
24
+ * both when the pane is killed. Every one of them is fail-open — a session that
25
+ * starts without structured events is the pre-#1763 status quo, and the screen
26
+ * scraper keeps deciding for it exactly as before.
11
27
  */
12
28
  Object.defineProperty(exports, "__esModule", { value: true });
13
29
  exports.OpenCodeTool = exports.OPENCODE_INIT_WAIT_MS = exports.OPENCODE_PANE_HEIGHT = exports.OPENCODE_EXIT_COMMAND = void 0;
@@ -19,6 +35,8 @@ const opencode_config_1 = require("./opencode-config");
19
35
  const child_process_1 = require("child_process");
20
36
  const util_1 = require("util");
21
37
  const logger_1 = require("../../lib/logger");
38
+ const agent_session_lifecycle_1 = require("../../lib/session/agent-session-lifecycle");
39
+ const runtime_1 = require("../../lib/hooks/sources/opencode/runtime");
22
40
  const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
23
41
  const logger = (0, logger_1.createLogger)('cli-tools/opencode');
24
42
  const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
@@ -77,15 +95,29 @@ class OpenCodeTool extends base_1.BaseCLITool {
77
95
  throw new Error('OpenCode is not installed or not in PATH');
78
96
  }
79
97
  const sessionName = this.getSessionName(worktreeId, instanceId);
98
+ const target = (0, runtime_1.opencodeTarget)(worktreeId, instanceId);
80
99
  const exists = await (0, tmux_1.hasSession)(sessionName);
81
100
  if (exists) {
82
101
  await this.reconcileExistingSession(sessionName, {
83
102
  windowWidth: 80,
84
103
  windowHeight: exports.OPENCODE_PANE_HEIGHT,
85
104
  });
105
+ // Issue #1763: the pane outlived this process (a CommandMate restart), so
106
+ // the subscription that used to watch it is gone while its server is
107
+ // still listening. Recovered from the recorded port, health-checked, and
108
+ // skipped silently when there is nothing there. NOT a new generation —
109
+ // the pane is the same one, and fencing here would discard a still-valid
110
+ // verdict on every reconnect.
111
+ await (0, runtime_1.resumeOpencodeEventStream)(target, worktreePath);
86
112
  logger.info('opencode-session-sessionname');
87
113
  return;
88
114
  }
115
+ // Issue #1759 (S8) / #1763: everything the previous opencode process
116
+ // reported through this (worktreeId, instanceId) belongs to a session that
117
+ // no longer exists, and the key is reused verbatim by the one about to be
118
+ // created. On the creation path only, before the pane exists, and even if
119
+ // the launch then fails — falling back to the scraper is always safe.
120
+ (0, agent_session_lifecycle_1.beginAgentSession)(target);
89
121
  try {
90
122
  // Generate opencode.json if not present (non-fatal on failure)
91
123
  await (0, opencode_config_1.ensureOpencodeConfig)(worktreePath);
@@ -109,10 +141,23 @@ class OpenCodeTool extends base_1.BaseCLITool {
109
141
  catch {
110
142
  // Non-fatal: resize may fail in some environments
111
143
  }
112
- // Start OpenCode TUI
113
- await (0, tmux_1.sendKeys)(sessionName, 'opencode', true);
144
+ // Issue #1763: pick the port before the command is built. The TUI is its
145
+ // own HTTP server once `--port` is passed (#1758 §5.1.2), and CommandMate
146
+ // assigns the number because opencode's `--port 0` is not an OS-assigned
147
+ // port — it tries 4096 first and only then falls back to an ephemeral one
148
+ // that nothing can read back (§5.9). Null means "no structured events",
149
+ // and the launch below is then the pre-#1763 bare command.
150
+ await (0, runtime_1.reserveOpencodeServerPort)(target, worktreePath);
151
+ // Start OpenCode TUI. `prepareAgentLaunch` asks the tool's own
152
+ // `AgentEventSource` for the command line (S3/S4/S5) and never throws.
153
+ const launchCommand = (0, agent_session_lifecycle_1.prepareAgentLaunch)(target, this.command).command;
154
+ await (0, tmux_1.sendKeys)(sessionName, launchCommand, true);
114
155
  // Wait for OpenCode to initialize (GPU model loading via Ollama)
115
156
  await new Promise((resolve) => setTimeout(resolve, exports.OPENCODE_INIT_WAIT_MS));
157
+ // Issue #1763: subscribe once the server has had the same time to come up
158
+ // that the TUI has. Health-checked first, so an opencode too old to know
159
+ // `--port` costs one probe and nothing else.
160
+ await (0, runtime_1.attachOpencodeEventStream)(target);
116
161
  logger.info('started-opencode-session:sessionname');
117
162
  }
118
163
  catch (error) {
@@ -164,6 +209,10 @@ class OpenCodeTool extends base_1.BaseCLITool {
164
209
  */
165
210
  async killSession(worktreeId, instanceId) {
166
211
  const sessionName = this.getSessionName(worktreeId, instanceId);
212
+ // Issue #1763: stop watching before the pane goes, so the stream is not
213
+ // reconnecting to a server that is being shut down. Also gives the port
214
+ // back — the pane is what held it. Never throws.
215
+ await (0, runtime_1.releaseOpencodeEventStream)((0, runtime_1.opencodeTarget)(worktreeId, instanceId));
167
216
  try {
168
217
  // Step 1: Check if the tmux session currently exists
169
218
  const exists = await (0, tmux_1.hasSession)(sessionName);
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ /**
3
+ * Repository default-branch resolution (origin/HEAD).
4
+ * Issue #921: extracted from git-utils.ts (god-module split, P1-a).
5
+ *
6
+ * Shared by reset / deleteBranch / push protection (Issue #783, DR1-001).
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.DEFAULT_BRANCH_UNRESOLVED = void 0;
10
+ exports.getDefaultBranch = getDefaultBranch;
11
+ exports.resolveDefaultBranchName = resolveDefaultBranchName;
12
+ const git_exec_1 = require("./git-exec");
13
+ /**
14
+ * Sentinel returned by getDefaultBranch when origin/HEAD is UNRESOLVED (the
15
+ * `symbolic-ref` read returned null). DISTINCT from `null` (which means
16
+ * symbolic-ref resolved to a value that is NOT an `origin/` ref). Issue #783,
17
+ * DR1-002: callers must distinguish "unresolved" from "resolved-but-non-origin/"
18
+ * so the reset fallback only fires on TRUE unresolution.
19
+ */
20
+ exports.DEFAULT_BRANCH_UNRESOLVED = Symbol('default-branch-unresolved');
21
+ /**
22
+ * Resolve the repository default branch name via origin/HEAD (Issue #783,
23
+ * shared by reset / deleteBranch / push protection — DR1-001).
24
+ *
25
+ * Returns THREE distinguishable outcomes (DR1-002 — required for reset's
26
+ * byte-invariance):
27
+ * - string : origin/<name> resolved; returns <name> (e.g. "main")
28
+ * - DEFAULT_BRANCH_UNRESOLVED : symbolic-ref returned null (origin/HEAD unresolved)
29
+ * - null : symbolic-ref returned a value that is NOT an
30
+ * `origin/` ref (unexpected value)
31
+ *
32
+ * Keeping "unresolved" and "resolved-but-non-origin/" separate lets
33
+ * isDefaultBranchForReset's main/master fallback fire ONLY when truly unresolved,
34
+ * preserving the original behavior (a naive `startsWith ? slice : null` would
35
+ * collapse the non-origin/ case into null and wrongly trigger the fallback).
36
+ */
37
+ async function getDefaultBranch(worktreePath) {
38
+ // DR2-006: execGitCommand returns an already-trimmed string on success / null
39
+ // on failure, so out is trimmed; the out.trim() below is an idempotent (harmless)
40
+ // double-trim. The "trimmed string / null" pair maps cleanly onto the 3 values:
41
+ // UNRESOLVED (out===null) / resolved name (startsWith 'origin/') / non-origin/ (else -> null).
42
+ // Empty-string edge: if symbolic-ref returned '' (non-null), v='' -> startsWith
43
+ // false -> null, matching the original isDefaultBranchForReset behavior.
44
+ const out = await (0, git_exec_1.execGitCommand)(['symbolic-ref', 'refs/remotes/origin/HEAD', '--short'], worktreePath);
45
+ if (out === null)
46
+ return exports.DEFAULT_BRANCH_UNRESOLVED;
47
+ const v = out.trim();
48
+ return v.startsWith('origin/') ? v.slice('origin/'.length) : null;
49
+ }
50
+ /**
51
+ * Thin wrapper for callers that only want "the resolved default name, or null
52
+ * when unknown" (Issue #783, DR1-001). Collapses both DEFAULT_BRANCH_UNRESOLVED
53
+ * and the non-origin/ `null` into `null` (= default name unknown). Used by
54
+ * deleteBranch (no fallback) and push protection (null = unprotected).
55
+ */
56
+ async function resolveDefaultBranchName(worktreePath) {
57
+ const r = await getDefaultBranch(worktreePath);
58
+ return typeof r === 'string' ? r : null;
59
+ }
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ /**
3
+ * Effects of a structured agent event (Issue #1549, Phase 3-2).
4
+ *
5
+ * The agent CLI is the only party that knows for certain that it finished a
6
+ * turn. Everything else in this codebase infers it by reading the terminal
7
+ * frame. This module is the first-class path: an event the agent itself sent,
8
+ * turned into a `task_events` row and — when the contract asks for it — a
9
+ * verification run.
10
+ *
11
+ * It does not replace the string analysis. `detectSessionStatus` keeps running
12
+ * and keeps deciding, because a hook only exists when a human wired one up and
13
+ * a completion mechanism that silently does nothing on an unconfigured machine
14
+ * is worse than one that is merely imprecise everywhere.
15
+ *
16
+ * Server-only: touches the filesystem (realpath) and the database.
17
+ *
18
+ * @module lib/hooks/agent-event-service
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.MAX_CWD_LENGTH = exports.isAgentEventType = exports.AGENT_EVENT_TYPES = void 0;
22
+ exports.validateHookCwd = validateHookCwd;
23
+ exports.resolveWorktreeByCwd = resolveWorktreeByCwd;
24
+ exports.applyAgentStopEvent = applyAgentStopEvent;
25
+ const fs_1 = require("fs");
26
+ const path_1 = require("path");
27
+ const db_1 = require("../../lib/db");
28
+ const tasks_db_1 = require("../../lib/db/tasks-db");
29
+ const path_validator_1 = require("../../lib/security/path-validator");
30
+ const task_transition_service_1 = require("../../lib/tasks/task-transition-service");
31
+ const gate_runner_1 = require("../../lib/verification/gate-runner");
32
+ const agent_event_state_1 = require("../../lib/session/agent-event-state");
33
+ const logger_1 = require("../../lib/logger");
34
+ const logger = (0, logger_1.createLogger)('lib/hooks/agent-event-service');
35
+ /**
36
+ * The event vocabulary lives in `agent-event-types` (Issue #1722) so the
37
+ * settings generator and the in-memory state can use it without importing this
38
+ * module's database and verification dependencies. Re-exported here because
39
+ * this is where callers have always found it.
40
+ *
41
+ * The Claude-specific mapping helpers that used to be re-exported alongside
42
+ * them are gone (Issue #1759): a tool's spellings now belong to that tool's
43
+ * `AgentEventSource`, and re-exporting one tool's from the generic service
44
+ * would have made this module the next place a Phase 4-x implementer reached
45
+ * for. Ask `getAgentEventSource(cliToolId).normalizeEvent()` instead.
46
+ *
47
+ * Every kind but `stop` is accepted, recorded and exposed without changing any
48
+ * state: the receiver has to exist before agents can be told to send them, and
49
+ * rejecting them would make every hook config a two-step rollout.
50
+ */
51
+ var agent_event_types_1 = require("../../lib/hooks/agent-event-types");
52
+ Object.defineProperty(exports, "AGENT_EVENT_TYPES", { enumerable: true, get: function () { return agent_event_types_1.AGENT_EVENT_TYPES; } });
53
+ Object.defineProperty(exports, "isAgentEventType", { enumerable: true, get: function () { return agent_event_types_1.isAgentEventType; } });
54
+ /** Bound on the accepted `cwd`, comfortably above PATH_MAX on every supported platform. */
55
+ exports.MAX_CWD_LENGTH = 4096;
56
+ /**
57
+ * Reject a `cwd` that cannot be a legitimate agent working directory.
58
+ *
59
+ * A hook posts the directory the agent is running in, so the only shapes worth
60
+ * accepting are absolute, traversal-free paths. `..` is refused rather than
61
+ * normalised away: `resolve()` would happily turn `/repos/a/../../etc` into a
62
+ * path that looks nothing like what the caller sent, and a value that changes
63
+ * meaning between validation and use is exactly how traversal checks get
64
+ * defeated. Percent-encoding is decoded first, so `%2e%2e%2f` cannot smuggle a
65
+ * `..` past a raw string scan.
66
+ */
67
+ function validateHookCwd(raw) {
68
+ if (typeof raw !== 'string' || raw.trim() === '') {
69
+ return { ok: false, reason: 'empty' };
70
+ }
71
+ if (raw.length > exports.MAX_CWD_LENGTH) {
72
+ return { ok: false, reason: 'too_long' };
73
+ }
74
+ let decoded = raw;
75
+ try {
76
+ decoded = decodeURIComponent(raw);
77
+ }
78
+ catch {
79
+ // Not valid percent-encoding; the raw string is the only interpretation.
80
+ decoded = raw;
81
+ }
82
+ if (raw.includes('\0') || decoded.includes('\0')) {
83
+ return { ok: false, reason: 'nul_byte' };
84
+ }
85
+ if (!(0, path_1.isAbsolute)(raw)) {
86
+ return { ok: false, reason: 'not_absolute' };
87
+ }
88
+ if (hasTraversalSegment(raw) || hasTraversalSegment(decoded)) {
89
+ return { ok: false, reason: 'traversal' };
90
+ }
91
+ return { ok: true, cwd: raw };
92
+ }
93
+ /** True when any path segment is `..`, under either separator convention. */
94
+ function hasTraversalSegment(value) {
95
+ return value
96
+ .split(path_1.sep === '\\' ? /[\\/]/ : '/')
97
+ .some((segment) => segment === '..');
98
+ }
99
+ /**
100
+ * The registered worktree an agent's `cwd` belongs to, or null.
101
+ *
102
+ * Both sides are resolved through `realpath` before comparison because the two
103
+ * ends disagree routinely and harmlessly: macOS hands agents `/var/...` for a
104
+ * worktree stored as `/private/var/...`, and worktree roots are often symlinked.
105
+ *
106
+ * A descendant matches its worktree — agents commonly run from a subdirectory —
107
+ * and the longest match wins, so a worktree nested inside another resolves to
108
+ * the inner one rather than to whichever row the database returned first.
109
+ *
110
+ * @param cwd - Already through {@link validateHookCwd}
111
+ * @returns null when the path does not exist or belongs to no worktree; the
112
+ * caller must not distinguish those two cases to the client
113
+ */
114
+ function resolveWorktreeByCwd(db, cwd) {
115
+ const resolvedCwd = safeRealpath(cwd);
116
+ if (resolvedCwd === null) {
117
+ return null;
118
+ }
119
+ let best = null;
120
+ let bestLength = -1;
121
+ for (const worktree of (0, db_1.getWorktrees)(db)) {
122
+ const resolvedWorktree = safeRealpath(worktree.path);
123
+ if (resolvedWorktree === null)
124
+ continue;
125
+ if (!(0, path_validator_1.isWithinRoot)(resolvedCwd, resolvedWorktree))
126
+ continue;
127
+ if (resolvedWorktree.length > bestLength) {
128
+ best = worktree;
129
+ bestLength = resolvedWorktree.length;
130
+ }
131
+ }
132
+ return best;
133
+ }
134
+ /** realpath, or null when the path does not exist / is unreadable. */
135
+ function safeRealpath(target) {
136
+ try {
137
+ return (0, fs_1.realpathSync)(target);
138
+ }
139
+ catch {
140
+ return null;
141
+ }
142
+ }
143
+ /**
144
+ * Apply a `stop` event to whatever the worktree is currently doing.
145
+ *
146
+ * The no-op is the load-bearing case. Sessions with no contract, and therefore
147
+ * no task, are the overwhelming majority; for them this records the timestamp
148
+ * and returns. Nothing about the existing completion path changes.
149
+ *
150
+ * Never throws. A hook is fire-and-forget from a CLI's stop handler, and a
151
+ * failure here must not become the agent's problem.
152
+ */
153
+ async function applyAgentStopEvent(db, worktree, cliToolId, instanceId) {
154
+ (0, agent_event_state_1.recordAgentStopEvent)(worktree.id, cliToolId, instanceId);
155
+ let task;
156
+ try {
157
+ task = (0, tasks_db_1.getActiveTaskForInstance)(db, worktree.id, cliToolId, instanceId);
158
+ }
159
+ catch (error) {
160
+ logger.warn('agent-stop-task-lookup-failed', {
161
+ worktreeId: worktree.id,
162
+ error: error instanceof Error ? error.message : String(error),
163
+ });
164
+ return { taskId: null, taskEventApplied: false, verificationRunId: null };
165
+ }
166
+ if (!task) {
167
+ return { taskId: null, taskEventApplied: false, verificationRunId: null };
168
+ }
169
+ let taskEventApplied = false;
170
+ try {
171
+ const result = (0, task_transition_service_1.applyTaskEvent)(db, task.id, 'agent_idle', { source: 'hook' });
172
+ taskEventApplied = result !== null && result.toStatus !== null;
173
+ }
174
+ catch (error) {
175
+ logger.warn('agent-stop-event-failed', {
176
+ taskId: task.id,
177
+ error: error instanceof Error ? error.message : String(error),
178
+ });
179
+ }
180
+ if (!task.contract.success.autoVerifyOnStop) {
181
+ return { taskId: task.id, taskEventApplied, verificationRunId: null };
182
+ }
183
+ let verificationRunId = null;
184
+ try {
185
+ const { runId } = await (0, gate_runner_1.startVerification)({
186
+ worktreeId: worktree.id,
187
+ worktreePath: worktree.path,
188
+ instanceId,
189
+ taskId: task.id,
190
+ trigger: 'task',
191
+ });
192
+ verificationRunId = runId;
193
+ }
194
+ catch (error) {
195
+ // A run already in flight is the expected collision, not a fault: the agent
196
+ // stopping twice while gates execute is ordinary.
197
+ if (!(error instanceof gate_runner_1.VerificationConflictError)) {
198
+ logger.error('agent-stop-auto-verify-failed', {
199
+ taskId: task.id,
200
+ error: error instanceof Error ? error.message : String(error),
201
+ });
202
+ }
203
+ }
204
+ return { taskId: task.id, taskEventApplied, verificationRunId };
205
+ }