commandmate 0.30.1 → 0.31.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 (442) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +164 -164
  3. package/.next/app-path-routes-manifest.json +28 -28
  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/agents/update/route_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update-check/route.js +1 -1
  12. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/assistant/conversation/route.js +1 -1
  14. package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
  15. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/assistant/current-output/route.js +1 -1
  17. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  18. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/assistant/messages/route.js +1 -1
  20. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  21. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/assistant/session/route.js +1 -1
  23. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  24. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/assistant/start/route.js +3 -3
  26. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  27. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/assistant/terminal/route.js +4 -4
  29. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  30. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/assistant/tools/route.js +1 -1
  32. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  33. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/capabilities/route.js +1 -1
  38. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  47. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  48. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/hooks/claude-done/route.js +1 -1
  50. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  51. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  53. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  54. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  55. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  65. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  66. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/repositories/clone/route.js +1 -1
  68. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  69. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/repositories/restore/route.js +1 -1
  72. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  73. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/repositories/route.js +1 -1
  75. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  76. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/repositories/scan/route.js +1 -1
  78. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  79. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/repositories/sync/route.js +1 -1
  81. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  82. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/settings/default-agents/route.js +1 -1
  85. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  86. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/skills/[id]/route.js +1 -1
  90. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/skills/route.js +1 -1
  95. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/slash-commands/route.js +1 -1
  97. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  107. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  110. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  113. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  119. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  150. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  153. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  156. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  168. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  172. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  175. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +4 -3
  177. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  179. package/.next/server/app/api/worktrees/[id]/schedules/route.js +4 -3
  180. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  182. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  184. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +2 -2
  186. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  187. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  191. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  199. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  203. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  206. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  207. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  209. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  211. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  212. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  214. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  215. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  217. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  218. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  219. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  220. package/.next/server/app/api/worktrees/route.js +1 -1
  221. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  222. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  223. package/.next/server/app/chat/page.js +2 -2
  224. package/.next/server/app/chat/page.js.nft.json +1 -1
  225. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  226. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  227. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/more/page.js +2 -2
  229. package/.next/server/app/more/page.js.nft.json +1 -1
  230. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  231. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  232. package/.next/server/app/page.js +1 -1
  233. package/.next/server/app/page.js.nft.json +1 -1
  234. package/.next/server/app/page_client-reference-manifest.js +1 -1
  235. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  236. package/.next/server/app/repositories/page.js +2 -2
  237. package/.next/server/app/repositories/page.js.nft.json +1 -1
  238. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  239. package/.next/server/app/review/page.js +1 -1
  240. package/.next/server/app/review/page.js.nft.json +1 -1
  241. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  242. package/.next/server/app/sessions/page.js +1 -1
  243. package/.next/server/app/sessions/page.js.nft.json +1 -1
  244. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  245. package/.next/server/app/skills/[skillId]/page.js +2 -2
  246. package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
  247. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  248. package/.next/server/app/skills/installed/page.js +2 -2
  249. package/.next/server/app/skills/installed/page.js.nft.json +1 -1
  250. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  251. package/.next/server/app/skills/page.js +1 -1
  252. package/.next/server/app/skills/page.js.nft.json +1 -1
  253. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  254. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  255. package/.next/server/app/worktrees/[id]/page.js +10 -10
  256. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  257. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  258. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  259. package/.next/server/app-paths-manifest.json +28 -28
  260. package/.next/server/chunks/1058.js +1 -1
  261. package/.next/server/chunks/1068.js +1 -1
  262. package/.next/server/chunks/1262.js +1 -1
  263. package/.next/server/chunks/1886.js +3 -3
  264. package/.next/server/chunks/1990.js +103 -0
  265. package/.next/server/chunks/2119.js +1 -1
  266. package/.next/server/chunks/2328.js +1 -1
  267. package/.next/server/chunks/2404.js +1 -1
  268. package/.next/server/chunks/2445.js +1 -1
  269. package/.next/server/chunks/261.js +1 -1
  270. package/.next/server/chunks/3123.js +1 -1
  271. package/.next/server/chunks/3241.js +1 -1
  272. package/.next/server/chunks/3480.js +5 -4
  273. package/.next/server/chunks/4299.js +1 -1
  274. package/.next/server/chunks/4393.js +1 -1
  275. package/.next/server/chunks/4443.js +1 -5
  276. package/.next/server/chunks/5017.js +1 -1
  277. package/.next/server/chunks/5043.js +1 -1
  278. package/.next/server/chunks/5164.js +1 -1
  279. package/.next/server/chunks/552.js +2 -2
  280. package/.next/server/chunks/6072.js +1 -1
  281. package/.next/server/chunks/6130.js +1 -1
  282. package/.next/server/chunks/663.js +4 -3
  283. package/.next/server/chunks/6894.js +2 -2
  284. package/.next/server/chunks/7187.js +1 -0
  285. package/.next/server/chunks/7472.js +1 -1
  286. package/.next/server/chunks/{880.js → 7859.js} +6 -6
  287. package/.next/server/chunks/7905.js +1 -1
  288. package/.next/server/chunks/8800.js +2 -2
  289. package/.next/server/chunks/8918.js +7 -0
  290. package/.next/server/chunks/9123.js +2 -2
  291. package/.next/server/chunks/9130.js +4 -4
  292. package/.next/server/chunks/9627.js +1 -1
  293. package/.next/server/chunks/9696.js +2 -2
  294. package/.next/server/chunks/9798.js +1 -1
  295. package/.next/server/middleware-manifest.json +5 -5
  296. package/.next/server/pages/500.html +1 -1
  297. package/.next/server/server-reference-manifest.json +1 -1
  298. package/.next/static/chunks/1783-11c9b4d8a52ebd91.js +1 -0
  299. package/.next/static/chunks/4718-de1224c9e8a6e7fc.js +1 -0
  300. package/.next/static/chunks/6022-2fa0b5a82d4ce7b6.js +1 -0
  301. package/.next/static/chunks/{5229-6c89475b61bd2c8b.js → 6170-951b9f5fe6b4b3b5.js} +1 -1
  302. package/.next/static/chunks/app/chat/{page-9aa2011410895b0d.js → page-37d7615d17d7e2a0.js} +1 -1
  303. package/.next/static/chunks/app/layout-4c2f21e3f653ee4c.js +1 -0
  304. package/.next/static/chunks/app/more/{page-333bba1c8bbc9c11.js → page-353a3924e6d7968e.js} +1 -1
  305. package/.next/static/chunks/app/{page-214f7ffa13a0cf10.js → page-c2bf871d953a1d6f.js} +1 -1
  306. package/.next/static/chunks/app/repositories/{page-4951cac905e50224.js → page-7d0f26df0537254c.js} +1 -1
  307. package/.next/static/chunks/app/review/{page-a0899b2d285318c3.js → page-e3f141b2829973e9.js} +1 -1
  308. package/.next/static/chunks/app/sessions/{page-fb36145ec732092a.js → page-53f188ed9ca49e5f.js} +1 -1
  309. package/.next/static/chunks/app/skills/[skillId]/{page-9099e26b60442873.js → page-80569b720aea59cc.js} +1 -1
  310. package/.next/static/chunks/app/skills/installed/{page-182e32368696d824.js → page-dbd2690ad72da95b.js} +1 -1
  311. package/.next/static/chunks/app/skills/{page-d3fdc88239ebe0ab.js → page-dacd36f9c11aa7da.js} +1 -1
  312. package/.next/static/chunks/app/worktrees/[id]/page-97205088520255a5.js +1 -0
  313. package/.next/static/css/5c13ea243dfdcb66.css +1 -0
  314. package/.next/trace +13 -13
  315. package/README.md +37 -11
  316. package/dist/cli/commands/attach.d.ts +50 -0
  317. package/dist/cli/commands/attach.d.ts.map +1 -0
  318. package/dist/cli/commands/attach.js +204 -0
  319. package/dist/cli/commands/capture.d.ts.map +1 -1
  320. package/dist/cli/commands/capture.js +114 -0
  321. package/dist/cli/commands/instances.d.ts.map +1 -1
  322. package/dist/cli/commands/instances.js +23 -2
  323. package/dist/cli/commands/ls.d.ts.map +1 -1
  324. package/dist/cli/commands/ls.js +41 -1
  325. package/dist/cli/config/cli-dependencies.d.ts.map +1 -1
  326. package/dist/cli/config/cli-dependencies.js +34 -0
  327. package/dist/cli/program.d.ts.map +1 -1
  328. package/dist/cli/program.js +5 -0
  329. package/dist/cli/types/index.d.ts +36 -0
  330. package/dist/cli/types/index.d.ts.map +1 -1
  331. package/dist/config/tmux-pane-config.d.ts +153 -0
  332. package/dist/config/tmux-pane-config.d.ts.map +1 -0
  333. package/dist/config/tmux-pane-config.js +172 -0
  334. package/dist/lib/cli-tools/session-name.d.ts +44 -0
  335. package/dist/lib/cli-tools/session-name.d.ts.map +1 -0
  336. package/dist/lib/cli-tools/session-name.js +57 -0
  337. package/dist/lib/cli-tools/types.d.ts +1 -1
  338. package/dist/lib/cli-tools/types.d.ts.map +1 -1
  339. package/dist/lib/cli-tools/types.js +6 -1
  340. package/dist/lib/cli-tools/validation.d.ts +34 -0
  341. package/dist/lib/cli-tools/validation.d.ts.map +1 -0
  342. package/dist/lib/cli-tools/validation.js +41 -0
  343. package/dist/lib/detection/status-reason.d.ts +18 -0
  344. package/dist/lib/detection/status-reason.d.ts.map +1 -1
  345. package/dist/lib/detection/status-reason.js +18 -0
  346. package/dist/lib/detection/tools/verified-against.d.ts +57 -7
  347. package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
  348. package/dist/lib/detection/tools/verified-against.js +59 -8
  349. package/dist/lib/detection/version-probes.d.ts +26 -5
  350. package/dist/lib/detection/version-probes.d.ts.map +1 -1
  351. package/dist/lib/detection/version-probes.js +28 -6
  352. package/dist/lib/session/tmux-session-surface.d.ts +369 -0
  353. package/dist/lib/session/tmux-session-surface.d.ts.map +1 -0
  354. package/dist/lib/session/tmux-session-surface.js +525 -0
  355. package/dist/server/src/config/cli-tool-timing-config.js +12 -1
  356. package/dist/server/src/config/detection-evidence-config.js +5 -0
  357. package/dist/server/src/config/schedule-config.js +28 -1
  358. package/dist/server/src/lib/cli-tools/antigravity.js +2 -2
  359. package/dist/server/src/lib/cli-tools/base.js +13 -8
  360. package/dist/server/src/lib/cli-tools/claude.js +20 -0
  361. package/dist/server/src/lib/cli-tools/codex.js +205 -61
  362. package/dist/server/src/lib/cli-tools/command-code.js +349 -0
  363. package/dist/server/src/lib/cli-tools/composer-spec.js +6 -0
  364. package/dist/server/src/lib/cli-tools/copilot.js +2 -2
  365. package/dist/server/src/lib/cli-tools/gemini.js +2 -2
  366. package/dist/server/src/lib/cli-tools/graceful-exit.js +16 -1
  367. package/dist/server/src/lib/cli-tools/index.js +4 -1
  368. package/dist/server/src/lib/cli-tools/install-hints.js +131 -0
  369. package/dist/server/src/lib/cli-tools/liveness-spec.js +18 -0
  370. package/dist/server/src/lib/cli-tools/manager.js +2 -0
  371. package/dist/server/src/lib/cli-tools/opencode.js +2 -2
  372. package/dist/server/src/lib/cli-tools/start-availability.js +18 -11
  373. package/dist/server/src/lib/cli-tools/types.js +6 -1
  374. package/dist/server/src/lib/cli-tools/vibe-local.js +2 -2
  375. package/dist/server/src/lib/cmate-parser.js +6 -0
  376. package/dist/server/src/lib/detection/cli-patterns.js +441 -8
  377. package/dist/server/src/lib/detection/opencode-modal-overlay.js +66 -100
  378. package/dist/server/src/lib/detection/selection-shape.js +341 -0
  379. package/dist/server/src/lib/detection/sgr-background.js +210 -0
  380. package/dist/server/src/lib/detection/status-detector.js +6 -0
  381. package/dist/server/src/lib/detection/status-reason.js +18 -0
  382. package/dist/server/src/lib/detection/tools/antigravity/detect.js +38 -15
  383. package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +392 -0
  384. package/dist/server/src/lib/detection/tools/codex/detect.js +83 -2
  385. package/dist/server/src/lib/detection/tools/command-code/detect.js +159 -0
  386. package/dist/server/src/lib/detection/tools/registry.js +6 -4
  387. package/dist/server/src/lib/detection/tools/verified-against.js +59 -8
  388. package/dist/server/src/lib/detection/version-probes.js +28 -6
  389. package/dist/server/src/lib/hooks/sources/antigravity/history.js +101 -21
  390. package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +39 -0
  391. package/dist/server/src/lib/hooks/sources/claude/history.js +245 -21
  392. package/dist/server/src/lib/hooks/sources/claude/transcript.js +175 -13
  393. package/dist/server/src/lib/hooks/sources/codex/history.js +84 -15
  394. package/dist/server/src/lib/hooks/sources/codex/hooks-config.js +130 -17
  395. package/dist/server/src/lib/hooks/sources/codex/relay-install.js +145 -0
  396. package/dist/server/src/lib/hooks/sources/command-code/history.js +865 -0
  397. package/dist/server/src/lib/hooks/sources/command-code/hooks-config.js +390 -0
  398. package/dist/server/src/lib/hooks/sources/command-code/source.js +290 -0
  399. package/dist/server/src/lib/hooks/sources/command-code/tool-id.js +18 -0
  400. package/dist/server/src/lib/hooks/sources/command-code/transcript.js +604 -0
  401. package/dist/server/src/lib/hooks/sources/index.js +3 -1
  402. package/dist/server/src/lib/hooks/sources/opencode/history.js +57 -3
  403. package/dist/server/src/lib/hooks/sources/opencode/transcript.js +24 -28
  404. package/dist/server/src/lib/hooks/sources/registry.js +4 -0
  405. package/dist/server/src/lib/hooks/sources/turn-body.js +77 -19
  406. package/dist/server/src/lib/hooks/stop-history-capture.js +58 -25
  407. package/dist/server/src/lib/job-executor.js +12 -0
  408. package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +6 -0
  409. package/dist/server/src/lib/polling/response-checker.js +112 -7
  410. package/dist/server/src/lib/polling/structured-history-gate.js +15 -8
  411. package/dist/server/src/lib/realtime/types.js +15 -5
  412. package/dist/server/src/lib/response-cleaner.js +24 -1
  413. package/dist/server/src/lib/response-extractor.js +11 -0
  414. package/dist/server/src/lib/session/claude-executor.js +223 -4
  415. package/dist/server/src/lib/session/cli-session.js +52 -0
  416. package/dist/server/src/lib/session/tmux-session-surface.js +525 -0
  417. package/dist/server/src/lib/skills/compatibility-matrix.js +117 -1
  418. package/dist/server/src/lib/tmux/geometry-delegation.js +143 -0
  419. package/dist/server/src/lib/tmux/read-mode-pager.js +76 -10
  420. package/dist/server/src/lib/tmux/read-mode.js +44 -2
  421. package/dist/server/src/lib/tmux/session-hook-scripts.js +249 -0
  422. package/dist/server/src/lib/tmux/session-hooks.js +122 -0
  423. package/dist/server/src/lib/tmux/session-status-options.js +213 -0
  424. package/dist/server/src/lib/tmux/tmux.js +79 -2
  425. package/dist/server/src/lib/version-checker.js +110 -0
  426. package/dist/server/src/lib/ws-server.js +16 -10
  427. package/dist/server/src/types/agent-transcript.js +73 -1
  428. package/dist/server/src/types/terminal-keys.js +131 -3
  429. package/dist/types/terminal-keys.d.ts +100 -3
  430. package/dist/types/terminal-keys.d.ts.map +1 -1
  431. package/dist/types/terminal-keys.js +131 -3
  432. package/package.json +1 -1
  433. package/.next/server/chunks/3099.js +0 -5
  434. package/.next/server/chunks/7824.js +0 -1
  435. package/.next/static/chunks/3916-0e929d089282dc5d.js +0 -1
  436. package/.next/static/chunks/6022-7a7d1760fc9814c7.js +0 -1
  437. package/.next/static/chunks/6381-dbf04a99647f6018.js +0 -1
  438. package/.next/static/chunks/app/layout-6a26ea22d5cf03dc.js +0 -1
  439. package/.next/static/chunks/app/worktrees/[id]/page-aac399392ec8c273.js +0 -1
  440. package/.next/static/css/23f9c40ecc458c77.css +0 -1
  441. /package/.next/static/{pcpB4K6KreMzu2qbhvuRY → nXW4dPkpE_9xUf_9ySRff}/_buildManifest.js +0 -0
  442. /package/.next/static/{pcpB4K6KreMzu2qbhvuRY → nXW4dPkpE_9xUf_9ySRff}/_ssgManifest.js +0 -0
@@ -6,6 +6,7 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.ClaudeTool = void 0;
8
8
  const base_1 = require("./base");
9
+ const terminal_keys_1 = require("../../types/terminal-keys");
9
10
  const claude_session_1 = require("../session/claude-session");
10
11
  /**
11
12
  * Claude Code CLI tool implementation
@@ -15,6 +16,25 @@ class ClaudeTool extends base_1.BaseCLITool {
15
16
  id = 'claude';
16
17
  name = 'Claude Code';
17
18
  command = 'claude';
19
+ /**
20
+ * Declare the base pad plus `s` (Issue #2297).
21
+ *
22
+ * The one screen that needs it is `/model`, whose footer reads
23
+ * `Enter to set as default · s to use this session only · Esc to cancel`
24
+ * (measured on 2.1.259 and 2.1.260 at the production 200x1000 geometry). On
25
+ * that overlay `Enter` rewrites `model` in `~/.claude/settings.json`
26
+ * (Issue #1495), so before this Issue the chat surface's dialog card could
27
+ * send the key that changes the user's global default and had no way at all to
28
+ * send the key that does not.
29
+ *
30
+ * The rest of the declaration is `NAVIGATION_KEY_VALUES`, untouched — see
31
+ * {@link CLAUDE_NAVIGATION_KEY_VALUES} for why `s` is not simply added to the
32
+ * shared pad (it is a live binding on copilot's session picker, and a bare
33
+ * letter in opencode's composer).
34
+ */
35
+ navigationKeys() {
36
+ return { keys: terminal_keys_1.CLAUDE_NAVIGATION_KEY_VALUES, leaderKey: null };
37
+ }
18
38
  /**
19
39
  * Check if Claude CLI is installed
20
40
  * Uses existing isClaudeInstalled function for compatibility
@@ -16,9 +16,10 @@ const codex_update_dialog_config_1 = require("../../config/codex-update-dialog-c
16
16
  const updates_1 = require("../../lib/updates");
17
17
  const logger_1 = require("../../lib/logger");
18
18
  const sources_1 = require("../../lib/hooks/sources");
19
+ const hooks_config_1 = require("../../lib/hooks/sources/codex/hooks-config");
19
20
  const agent_session_lifecycle_1 = require("../../lib/session/agent-session-lifecycle");
20
21
  const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
21
- const session_start_error_1 = require("../session/session-start-error");
22
+ const install_hints_1 = require("./install-hints");
22
23
  const logger = (0, logger_1.createLogger)('cli-tools/codex');
23
24
  /**
24
25
  * Extract error message from unknown error type (DRY)
@@ -59,15 +60,12 @@ const CODEX_UPDATE_LOCK_TOOL = 'codex';
59
60
  /** Timeout for waiting for prompt before sending a message */
60
61
  const CODEX_PROMPT_WAIT_TIMEOUT_MS = 15000;
61
62
  /**
62
- * Option 3, "Continue without trusting (hooks won't run)".
63
+ * Screen 1, option 3: "Continue without trusting (hooks won't run)".
63
64
  *
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`.
65
+ * The `CM_CODEX_HOOK_TRUST=never` answer since Issue #2315, and the default
66
+ * answer before it. It leaves the hooks inert and the screen scraper doing what
67
+ * it did before Issue #1760 and, crucially, codex does not remember it: there
68
+ * is no "asked and refused" state, only a grant, so this key buys one launch.
71
69
  *
72
70
  * Sent alone, like the other numbered dialogs (Issue #890): codex confirms a
73
71
  * numbered selection instantly, and a trailing Enter would land on the next
@@ -85,23 +83,71 @@ const CODEX_PROMPT_WAIT_TIMEOUT_MS = 15000;
85
83
  */
86
84
  const CODEX_HOOKS_REVIEW_DECLINE_KEY = '3';
87
85
  /**
88
- * How many times `waitForReady` may press `esc` to climb out of codex's hooks
89
- * review screens (Issue #1829).
86
+ * Screen 1, option 2: "Trust all and continue" (Issue #2315).
90
87
  *
91
- * Two is the depth of the UI detail -> list -> closed and the cap exists
92
- * because the alternative is one press per poll: 30 keystrokes into whatever is
93
- * really on screen if the classifier is ever wrong about a frame. Two spare
94
- * presses cover a redraw landing between capture and send.
88
+ * The default answer now, gated on {@link shouldTrustCodexHooks}which
89
+ * withholds it from any worktree carrying its own `.codex/hooks.json`, the one
90
+ * case where "all" could mean a repository's hooks rather than the operator's.
91
+ * That function carries the whole of the argument for reversing #1760 here.
92
+ *
93
+ * This is the half of the fix that makes the dialog stop coming back: codex
94
+ * records the grant as `[hooks.state."…:<event>:0:0"] trusted_hash`, so the
95
+ * screen appears once rather than every launch. It only holds because the other
96
+ * half — `hooks/sources/codex/relay-install` — stopped the generated file's
97
+ * bytes moving between checkouts and invalidating that very hash.
98
+ */
99
+ const CODEX_HOOKS_REVIEW_TRUST_KEY = '2';
100
+ /**
101
+ * Screen 1, option 1: "Review hooks", which opens the list (Issue #2315).
102
+ *
103
+ * The second attempt on screen 1, never the first. A numbered option is a
104
+ * position in a menu codex is free to renumber between versions, and this method
105
+ * has already been re-pinned twice for exactly that kind of drift (#890, #1829).
106
+ * The two screens *below* this one announce their own keys in a footer that
107
+ * `getCodexLifecycleDialog` matches — `Press t to trust all;` and
108
+ * `Press t to trust;` — so descending into the list turns a guess about
109
+ * numbering into a key the screen itself named.
110
+ */
111
+ const CODEX_HOOKS_REVIEW_LIST_KEY = '1';
112
+ /**
113
+ * `t` — "trust", the key screens 2 and 3 print in their own footers.
114
+ *
115
+ * Sent literally: `sendKeys` hands a bare string to `tmux send-keys`, which
116
+ * resolves key NAMES before characters, and a single letter that happens to
117
+ * match one would be sent as something else entirely.
118
+ */
119
+ const CODEX_HOOKS_TRUST_KEY = 't';
120
+ /**
121
+ * How many keys `waitForReady` may spend on ONE hooks screen before it stops
122
+ * pressing (Issue #1829, reworked for #2315).
123
+ *
124
+ * The number that matters is per screen, and the counter resets whenever the
125
+ * classification changes — which is the fix. #1829 spent a fixed budget of 4
126
+ * across the whole launch, so a pane that legitimately walked screen 1 -> 2 -> 3
127
+ * could exhaust it on the way down and park on the last one for good; that is
128
+ * one of the two ways the reported session ended up stuck. Progress now buys
129
+ * more attempts, and only a screen that will not respond at all runs out.
130
+ *
131
+ * Three per screen, because each screen has at most two keys worth trying
132
+ * (`2` then `1` on the review dialog; `t` or `esc` below it) plus one spare for
133
+ * a redraw landing between the capture and the send.
95
134
  */
96
- const CODEX_HOOKS_SCREEN_MAX_ESCAPES = 4;
135
+ const CODEX_HOOKS_SCREEN_MAX_ATTEMPTS = 3;
136
+ /** A fresh {@link CodexHooksScreenState}. */
137
+ function newHooksScreenState() {
138
+ return { screen: null, attempts: 0 };
139
+ }
97
140
  /**
98
141
  * Whether the pane is sitting on the hooks review dialog.
99
142
  *
100
- * Position-independent on purpose, unlike `getCodexActiveDialog`: the only
101
- * caller checks `isCodexPromptReady` first and returns when a genuine prompt
102
- * exists, so residual dialog text above a live prompt is never reached, and a
103
- * one-shot guard stops the key being sent twice. Callers OUTSIDE this launch
104
- * sequence must use `getCodexLifecycleDialog` instead, which is position-based.
143
+ * Position-independent, which is why Issue #2315 stopped branching on it.
144
+ * `waitForReady` now classifies with `getCodexLifecycleDialog`, and the reason
145
+ * is the shape the reported session was found in: screen 1's text stays in
146
+ * scrollback while the pane sits on screen 3, so this predicate answers `true`
147
+ * for a frame whose active screen is a different one, and the key it selected
148
+ * was the key for the screen that had already been left. Kept as the
149
+ * position-INDEPENDENT question ("has this pane ever shown the dialog?"), which
150
+ * is a different question from "what is on it now".
105
151
  *
106
152
  * The dialog has to be handled here rather than in `getCodexActiveDialog`, which
107
153
  * classifies it as `null`: its wording matches none of that function's three
@@ -152,7 +198,7 @@ class CodexTool extends base_1.BaseCLITool {
152
198
  // Check if Codex is installed
153
199
  const codexAvailable = await this.isInstalled();
154
200
  if (!codexAvailable) {
155
- throw new session_start_error_1.SessionStartUnavailableError(this.name, 'Codex CLI is not installed or not in PATH');
201
+ throw (0, install_hints_1.missingToolError)(this);
156
202
  }
157
203
  const sessionName = this.getSessionName(worktreeId, instanceId);
158
204
  // Check if session already exists
@@ -231,7 +277,14 @@ class CodexTool extends base_1.BaseCLITool {
231
277
  await new Promise((resolve) => setTimeout(resolve, CODEX_INIT_WAIT_MS));
232
278
  // Poll until Codex interactive prompt is ready
233
279
  // Handles trust dialog and update notification automatically
234
- await this.waitForReady(sessionName, { relaunch: relaunchIntoSamePane });
280
+ // Issue #2315: the provenance check happens here, where the worktree path
281
+ // is, and not inside the polling loop — a repository that ships its own
282
+ // `.codex/hooks.json` is one whose review dialog this server must not
283
+ // answer with "trust all".
284
+ await this.waitForReady(sessionName, {
285
+ relaunch: relaunchIntoSamePane,
286
+ trustHooks: (0, hooks_config_1.shouldTrustCodexHooks)(worktreePath),
287
+ });
235
288
  logger.info('started-codex-session:sessionname');
236
289
  }
237
290
  catch (error) {
@@ -250,15 +303,21 @@ class CodexTool extends base_1.BaseCLITool {
250
303
  * Supplied by {@link launchSession} and used only after the update dialog
251
304
  * has been answered with `1` — by this method under the `update` policy of
252
305
  * `config/codex-update-dialog-config`, or by a human under `ask`.
306
+ * @param options.trustHooks - Whether the hook review may be answered with
307
+ * *trust* (Issue #2315). Decided by {@link shouldTrustCodexHooks} from the
308
+ * worktree path, which this method does not have; passing it in keeps the
309
+ * provenance check next to the directory it is a check about.
253
310
  */
254
311
  async waitForReady(sessionName, options) {
312
+ const trustHooks = options?.trustHooks ?? false;
255
313
  // Issue #892: one-shot guards. capturePane(50) keeps a dismissed dialog in
256
314
  // scrollback, so a key must be sent at most once per dialog -- otherwise the
257
315
  // update branch re-sends "2" every poll and the live prompt gets "222...".
258
316
  let updateDialogHandled = false;
259
317
  let trustDialogHandled = false;
260
- let hooksReviewHandled = false;
261
- let hooksScreenEscapes = 0;
318
+ // Issue #2315: one budget per hooks screen, reset whenever the screen
319
+ // changes, in place of #1829's single launch-wide escape count.
320
+ const hooksScreenState = newHooksScreenState();
262
321
  // Issue #2068. Resolved once per launch rather than per poll: the operator
263
322
  // does not get to change their mind halfway through one session start, and
264
323
  // one reading is one fewer thing that can differ between the frame that saw
@@ -295,6 +354,26 @@ class CodexTool extends base_1.BaseCLITool {
295
354
  try {
296
355
  const rawOutput = await (0, tmux_1.capturePane)(sessionName, 50);
297
356
  const output = (0, cli_patterns_1.stripAnsi)(rawOutput);
357
+ // Issue #2315: the hooks screens are judged BEFORE readiness, and the
358
+ // order is load-bearing. `isCodexPromptReady` answers true for
359
+ // `CODEX_HOOKS_STUCK_PANE` — the shape both #1829 sessions were found
360
+ // in — because a genuine composer line IS in the frame; it is simply
361
+ // buried under two review screens that codex painted after it. Ready
362
+ // first would return on that frame and hand `sendMessage` a pane whose
363
+ // keystrokes go to the review UI. `getCodexLifecycleDialog` cannot make
364
+ // the opposite mistake: its window starts BELOW the bottom-most prompt
365
+ // line, so it names a hooks screen only when that screen is what the
366
+ // pane is actually showing.
367
+ const lifecycleScreen = (0, cli_patterns_1.getCodexLifecycleDialog)(output);
368
+ if (lifecycleScreen === 'hooks-review' ||
369
+ lifecycleScreen === 'hooks-list' ||
370
+ lifecycleScreen === 'hooks-detail') {
371
+ const sent = await this.answerCodexHooksScreen(sessionName, lifecycleScreen, hooksScreenState, trustHooks);
372
+ if (sent) {
373
+ await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.CODEX_DIALOG_SETTLE_MS));
374
+ continue;
375
+ }
376
+ }
298
377
  // Check if the genuine interactive input prompt is ready.
299
378
  // Issue #892: isCodexPromptReady() is position-based -- a genuine "› " line
300
379
  // below stale dialog scrollback IS ready, while an active dialog (option
@@ -353,8 +432,8 @@ class CodexTool extends base_1.BaseCLITool {
353
432
  // Left alone, the dialog simply stays on the pane where `detectPrompt`
354
433
  // reports it and the human can answer it.
355
434
  trustDialogHandled = false;
356
- hooksReviewHandled = false;
357
- hooksScreenEscapes = 0;
435
+ hooksScreenState.screen = null;
436
+ hooksScreenState.attempts = 0;
358
437
  // Issue #2068 x #2069: the shell prompt IS the completion signal for
359
438
  // an install this process cannot await, so release here rather than
360
439
  // holding #2069's lock for the rest of the (up to two-minute) window
@@ -368,36 +447,6 @@ class CodexTool extends base_1.BaseCLITool {
368
447
  await options.relaunch();
369
448
  continue;
370
449
  }
371
- // Issue #1760: "Hooks need review". Reached only when no genuine prompt
372
- // exists (the check above returned), so this cannot fire on a live
373
- // prompt, and the one-shot guard stops a second key on a re-render.
374
- // Declines: granting trust would write the operator's config.toml.
375
- if (!hooksReviewHandled && isCodexHooksReviewDialog(output)) {
376
- await (0, tmux_1.sendKeys)(sessionName, CODEX_HOOKS_REVIEW_DECLINE_KEY, false);
377
- hooksReviewHandled = true;
378
- logger.info('codex-hooks-review-declined');
379
- await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.CODEX_DIALOG_SETTLE_MS));
380
- continue;
381
- }
382
- // Issue #1829: back out of the two screens the hooks dialog leads to.
383
- // Confirming its option 1 -- which the Auto-Yes poller did on two live
384
- // sessions, and which a human can do too -- opens a review UI whose only
385
- // exits are `t` and `esc`. `t` is out: it writes `[hooks.state…]` into
386
- // the operator's own ~/.codex/config.toml, the grant Issue #1760
387
- // declined on their behalf. So `esc`, once per poll until the screens
388
- // are gone. Before this, nothing sent either key: the whole 30-attempt
389
- // window elapsed, waitForReady returned as if ready, and the session was
390
- // left parked there -- reported as `running`, because neither screen
391
- // carries an option, a confirm footer or a thinking indicator.
392
- const hooksScreen = (0, cli_patterns_1.getCodexLifecycleDialog)(output);
393
- if ((hooksScreen === 'hooks-list' || hooksScreen === 'hooks-detail') &&
394
- hooksScreenEscapes < CODEX_HOOKS_SCREEN_MAX_ESCAPES) {
395
- await (0, tmux_1.sendSpecialKey)(sessionName, 'Escape');
396
- hooksScreenEscapes++;
397
- logger.info('codex-hooks-screen-escaped');
398
- await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.CODEX_DIALOG_SETTLE_MS));
399
- continue;
400
- }
401
450
  // Issue #892: classify the bottom-most ACTIVE dialog by position. A dialog
402
451
  // whose text is only residual scrollback above a genuine prompt returns
403
452
  // null here, so no stray key is sent after it has been dismissed.
@@ -532,6 +581,77 @@ class CodexTool extends base_1.BaseCLITool {
532
581
  }
533
582
  }
534
583
  }
584
+ /**
585
+ * Send the one key that gets this pane off the hooks screen it is on
586
+ * (Issue #2315).
587
+ *
588
+ * ## Why a state machine and not a budget
589
+ *
590
+ * codex's hook review is three screens deep, and #1829's recovery counted its
591
+ * `esc` presses across the whole launch. A pane that walked all three could
592
+ * therefore run out on the way down and park on the last one — which is one
593
+ * half of what the reported session was doing. The count here is per screen
594
+ * and resets the moment the classification changes, so descending costs
595
+ * nothing and only a screen that ignores its own documented key runs out.
596
+ *
597
+ * ## Which key
598
+ *
599
+ * When `trust` is granted the answer is the one that ends the review for good:
600
+ * `2` on the launch dialog, `t` on either screen below it. codex records that
601
+ * as a `trusted_hash` in the operator's `~/.codex/config.toml`, so the dialog
602
+ * appears once instead of on every launch — the decline it replaces was never
603
+ * remembered, which is why "度々" was the Issue's word for this.
604
+ *
605
+ * When it is withheld — `CM_CODEX_HOOK_TRUST=never`, or a worktree carrying
606
+ * its own `.codex/hooks.json` — it is the pre-#2315 path: `3`, then `esc`.
607
+ *
608
+ * The launch dialog gets a second, different key on its second attempt.
609
+ * Numbered options are a menu position codex is free to renumber (this method
610
+ * has been re-pinned for that twice already), so if `2`/`3` did not move the
611
+ * screen, `1` descends into the list, whose footer NAMES the key that closes
612
+ * it and which `getCodexLifecycleDialog` matched to get here.
613
+ *
614
+ * @param sessionName - tmux session name
615
+ * @param screen - The bottom-most active hooks screen, from `getCodexLifecycleDialog`
616
+ * @param state - Per-screen budget, carried across polls by the caller
617
+ * @param trust - Whether trust may be granted, from {@link shouldTrustCodexHooks}
618
+ * @returns True when a key was sent, false when this screen's budget is spent
619
+ */
620
+ async answerCodexHooksScreen(sessionName, screen, state, trust) {
621
+ if (state.screen !== screen) {
622
+ // Progress. The pane moved, so the previous screen's spent attempts say
623
+ // nothing about this one.
624
+ state.screen = screen;
625
+ state.attempts = 0;
626
+ }
627
+ if (state.attempts >= CODEX_HOOKS_SCREEN_MAX_ATTEMPTS) {
628
+ logger.warn('codex-hooks-screen-unresponsive', { sessionName, screen, trust });
629
+ return false;
630
+ }
631
+ const attempt = ++state.attempts;
632
+ if (screen === 'hooks-review') {
633
+ const key = attempt === 1
634
+ ? trust
635
+ ? CODEX_HOOKS_REVIEW_TRUST_KEY
636
+ : CODEX_HOOKS_REVIEW_DECLINE_KEY
637
+ : CODEX_HOOKS_REVIEW_LIST_KEY;
638
+ // Issue #890: the number selects AND confirms. A trailing Enter would land
639
+ // on the screen this key just opened.
640
+ await (0, tmux_1.sendKeys)(sessionName, key, false);
641
+ logger.info('codex-hooks-review-answered', { sessionName, key, attempt, trust });
642
+ return true;
643
+ }
644
+ if (trust) {
645
+ // `t`, the key screens 2 and 3 print in their own footers. Literal, so
646
+ // tmux sends the character rather than resolving it as a key name.
647
+ await (0, tmux_1.sendKeys)(sessionName, CODEX_HOOKS_TRUST_KEY, false, { literal: true });
648
+ logger.info('codex-hooks-screen-trusted', { sessionName, screen, attempt });
649
+ return true;
650
+ }
651
+ await (0, tmux_1.sendSpecialKey)(sessionName, 'Escape');
652
+ logger.info('codex-hooks-screen-escaped', { sessionName, screen, attempt });
653
+ return true;
654
+ }
535
655
  /**
536
656
  * Wait for Codex prompt before sending a message.
537
657
  * Used by sendMessage to ensure Codex is ready to accept input.
@@ -546,14 +666,38 @@ class CodexTool extends base_1.BaseCLITool {
546
666
  async waitForPrompt(sessionName) {
547
667
  const startTime = Date.now();
548
668
  const pollInterval = 500;
669
+ // Issue #2315: the hooks review can come back AFTER the launch is over --
670
+ // `waitForReady` runs once and is long gone by then. Issue #1829's two live
671
+ // sessions were found in exactly that shape (`CODEX_HOOKS_STUCK_PANE`: a
672
+ // ready prompt in scrollback with the review screens below it), and until
673
+ // now nothing owned it: every send timed out here and threw, session after
674
+ // session, with `kill-session` by hand as the only way out. The same state
675
+ // machine the launch uses gets the pane back.
676
+ const hooksScreenState = newHooksScreenState();
677
+ /** Resolved lazily — one tmux call, and only if a hooks screen shows up. */
678
+ let trustHooks = null;
549
679
  while (Date.now() - startTime < CODEX_PROMPT_WAIT_TIMEOUT_MS) {
550
680
  try {
551
681
  const rawOutput = await (0, tmux_1.capturePane)(sessionName, 50);
552
682
  const output = (0, cli_patterns_1.stripAnsi)(rawOutput);
553
- // Issue #890/#892: position-based guard so a residual update/trust dialog
554
- // ("› 1. ...") is never mistaken for a ready prompt -- yet a genuine "› "
555
- // prompt below stale dialog scrollback IS accepted.
556
- if ((0, cli_patterns_1.isCodexPromptReady)(output)) {
683
+ // Before readiness, for the reason `waitForReady` gives: a review screen
684
+ // painted OVER a live composer leaves `isCodexPromptReady` true, and
685
+ // returning there types the user's message into the review UI.
686
+ const screen = (0, cli_patterns_1.getCodexLifecycleDialog)(output);
687
+ if (screen === 'hooks-review' || screen === 'hooks-list' || screen === 'hooks-detail') {
688
+ if (trustHooks === null) {
689
+ // The pane's own directory, for the same reason `relaunchIfToolExited`
690
+ // asks tmux for it: `sendMessage` is handed a worktree id, not a path,
691
+ // and the pane knows where it is actually running.
692
+ const worktreePath = await (0, tmux_1.getSessionWorkingDirectory)(sessionName);
693
+ trustHooks = worktreePath !== null && (0, hooks_config_1.shouldTrustCodexHooks)(worktreePath);
694
+ }
695
+ await this.answerCodexHooksScreen(sessionName, screen, hooksScreenState, trustHooks);
696
+ }
697
+ else if ((0, cli_patterns_1.isCodexPromptReady)(output)) {
698
+ // Issue #890/#892: position-based guard so a residual update/trust dialog
699
+ // ("› 1. ...") is never mistaken for a ready prompt -- yet a genuine "› "
700
+ // prompt below stale dialog scrollback IS accepted.
557
701
  return;
558
702
  }
559
703
  }