commandmate 0.49.0 → 0.49.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (806) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +251 -248
  3. package/.next/app-path-routes-manifest.json +22 -21
  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/routes-manifest.json +8 -0
  8. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/capabilities/route.js +1 -1
  18. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/hooks/agent-event/route.js +2 -2
  27. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  28. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/hooks/claude-done/route.js +2 -2
  30. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  31. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  33. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  34. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/push/subscriptions/route.js +1 -1
  39. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
  42. package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
  43. package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/relays/[relayId]/route.js +1 -0
  45. package/.next/server/app/api/relays/[relayId]/route.js.nft.json +1 -0
  46. package/.next/server/app/api/relays/[relayId]/route_client-reference-manifest.js +1 -0
  47. package/.next/server/app/api/relays/route.js +1 -1
  48. package/.next/server/app/api/relays/route.js.nft.json +1 -1
  49. package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  51. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  53. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  54. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  55. package/.next/server/app/api/repositories/clone/route.js +1 -1
  56. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  57. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/repositories/restore/route.js +1 -1
  60. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  61. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/repositories/route.js +1 -1
  63. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  64. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/repositories/scan/route.js +1 -1
  66. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  67. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/repositories/sync/route.js +1 -1
  69. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  70. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  72. package/.next/server/app/api/settings/default-agents/route.js +1 -1
  73. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  74. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  76. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/tasks/[taskId]/route.js +1 -1
  85. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/verification/runs/[runId]/route.js +1 -1
  89. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/verification/runs/route.js +1 -1
  91. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  93. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  94. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  96. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  97. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  99. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  100. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/worktrees/[id]/cli-reference/route.js +1 -1
  102. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
  104. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  109. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
  112. package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
  113. package/.next/server/app/api/worktrees/[id]/env/route.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/git/branches/route.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/checkout/route.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/commit/route.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/diff/route.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.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/log/route.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/git/pull/route.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/git/push/route.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/git/reset/route.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/git/revert/route.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/git/stage/route.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/git/staged/route.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/git/stash/route.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/git/status/route.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/git/unstage/route.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/instances/notes/route.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  170. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  173. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +2 -1
  175. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  176. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +1 -1
  179. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/logs/route.js +2 -2
  181. package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +1 -1
  182. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/marp-render/route.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/messages/route.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  191. package/.next/server/app/api/worktrees/[id]/opencode/diff/route.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/opencode/diff/route.js.nft.json +1 -1
  193. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -1
  196. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -1
  199. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  202. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  203. package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js.nft.json +1 -1
  205. package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route_client-reference-manifest.js +1 -1
  206. package/.next/server/app/api/worktrees/[id]/resolve-target/route.js +1 -1
  207. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  209. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  210. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  211. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  212. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  213. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  214. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +1 -1
  215. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
  217. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  218. package/.next/server/app/api/worktrees/[id]/schedules/route.js +1 -1
  219. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  220. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  221. package/.next/server/app/api/worktrees/[id]/send/route.js +144 -1
  222. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  223. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  224. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +2 -2
  225. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  226. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  227. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  229. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  230. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  231. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  232. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  233. package/.next/server/app/api/worktrees/[id]/skills/route.js +1 -1
  234. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  235. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  236. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  237. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  238. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  239. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  240. package/.next/server/app/api/worktrees/[id]/tasks/route.js +1 -1
  241. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  242. package/.next/server/app/api/worktrees/[id]/terminal/route.js +103 -1
  243. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  244. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  245. package/.next/server/app/api/worktrees/[id]/timers/history/route.js +1 -1
  246. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  247. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  248. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  249. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  250. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js +1 -1
  251. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js.nft.json +1 -1
  252. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  253. package/.next/server/app/api/worktrees/[id]/todos/route.js +1 -1
  254. package/.next/server/app/api/worktrees/[id]/todos/route.js.nft.json +1 -1
  255. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  256. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  257. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  258. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  259. package/.next/server/app/api/worktrees/[id]/verify/config/route.js +1 -1
  260. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  261. package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
  262. package/.next/server/app/api/worktrees/[id]/verify/route.js.nft.json +1 -1
  263. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  264. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
  265. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js.nft.json +1 -1
  266. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  267. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route.js +1 -1
  268. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  269. package/.next/server/app/api/worktrees/[id]/verify/runs/route.js +1 -1
  270. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  271. package/.next/server/app/api/worktrees/[id]/viewed/route.js +1 -1
  272. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  273. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  274. package/.next/server/app/api/worktrees/route.js +1 -1
  275. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  276. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  277. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  278. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  279. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  280. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  281. package/.next/server/app/page_client-reference-manifest.js +1 -1
  282. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  283. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  284. package/.next/server/app/review/page.js +1 -1
  285. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  286. package/.next/server/app/sessions/page.js +1 -1
  287. package/.next/server/app/sessions/page.js.nft.json +1 -1
  288. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  289. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  290. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  291. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  292. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  293. package/.next/server/app/worktrees/[id]/page.js +11 -11
  294. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  295. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  296. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  297. package/.next/server/app-paths-manifest.json +22 -21
  298. package/.next/server/chunks/1062.js +1 -0
  299. package/.next/server/chunks/{936.js → 110.js} +1 -1
  300. package/.next/server/chunks/1501.js +5 -4
  301. package/.next/server/chunks/1656.js +2 -2
  302. package/.next/server/chunks/1957.js +2 -0
  303. package/.next/server/chunks/2119.js +1 -1
  304. package/.next/server/chunks/2404.js +1 -1
  305. package/.next/server/chunks/2445.js +1 -1
  306. package/.next/server/chunks/2897.js +1 -0
  307. package/.next/server/chunks/3417.js +1 -0
  308. package/.next/server/chunks/3505.js +1 -1
  309. package/.next/server/chunks/{4280.js → 3756.js} +1 -1
  310. package/.next/server/chunks/3801.js +31 -0
  311. package/.next/server/chunks/4911.js +1 -0
  312. package/.next/server/chunks/4936.js +1 -0
  313. package/.next/server/chunks/5209.js +2 -1
  314. package/.next/server/chunks/5354.js +1 -1
  315. package/.next/server/chunks/{9130.js → 5630.js} +1 -1
  316. package/.next/server/chunks/610.js +1 -0
  317. package/.next/server/chunks/6119.js +1 -1
  318. package/.next/server/chunks/6130.js +1 -1
  319. package/.next/server/chunks/6401.js +1 -1
  320. package/.next/server/chunks/6486.js +1 -1
  321. package/.next/server/chunks/6781.js +1 -1
  322. package/.next/server/chunks/6808.js +4 -0
  323. package/.next/server/chunks/7023.js +14 -0
  324. package/.next/server/chunks/7905.js +1 -1
  325. package/.next/server/chunks/8581.js +8 -8
  326. package/.next/server/chunks/8728.js +2 -2
  327. package/.next/server/chunks/8782.js +1 -1
  328. package/.next/server/chunks/8807.js +63 -53
  329. package/.next/server/chunks/8918.js +103 -1
  330. package/.next/server/chunks/9198.js +144 -0
  331. package/.next/server/chunks/9390.js +1 -1
  332. package/.next/server/chunks/9584.js +1 -1
  333. package/.next/server/chunks/9627.js +1 -1
  334. package/.next/server/chunks/9731.js +3 -3
  335. package/.next/server/middleware-manifest.json +5 -5
  336. package/.next/server/pages/500.html +1 -1
  337. package/.next/server/server-reference-manifest.json +1 -1
  338. package/.next/static/chunks/{2407-ab92ae9837c39dce.js → 2407-07a237575e1ceb9e.js} +1 -1
  339. package/.next/static/chunks/3931-61ad1a4fc0208d0e.js +1 -0
  340. package/.next/static/chunks/5794-7975b8e51e731b19.js +1 -0
  341. package/.next/static/chunks/6966-d8dc6032410ffaba.js +1 -0
  342. package/.next/static/chunks/7197-ed3b3d99ac3bd450.js +1 -0
  343. package/.next/static/chunks/7636-a48cf0f7110250c5.js +1 -0
  344. package/.next/static/chunks/app/api/agents/update/route-a4f129c451de7859.js +1 -0
  345. package/.next/static/chunks/app/api/agents/versions/route-a4f129c451de7859.js +1 -0
  346. package/.next/static/chunks/app/api/app/release-notes/route-a4f129c451de7859.js +1 -0
  347. package/.next/static/chunks/app/api/app/update/route-a4f129c451de7859.js +1 -0
  348. package/.next/static/chunks/app/api/app/update-check/route-a4f129c451de7859.js +1 -0
  349. package/.next/static/chunks/app/api/auth/login/route-a4f129c451de7859.js +1 -0
  350. package/.next/static/chunks/app/api/auth/logout/route-a4f129c451de7859.js +1 -0
  351. package/.next/static/chunks/app/api/auth/status/route-a4f129c451de7859.js +1 -0
  352. package/.next/static/chunks/app/api/capabilities/route-a4f129c451de7859.js +1 -0
  353. package/.next/static/chunks/app/api/daily-summary/route-a4f129c451de7859.js +1 -0
  354. package/.next/static/chunks/app/api/daily-summary/status/route-a4f129c451de7859.js +1 -0
  355. package/.next/static/chunks/app/api/external-apps/[id]/health/route-a4f129c451de7859.js +1 -0
  356. package/.next/static/chunks/app/api/external-apps/[id]/route-a4f129c451de7859.js +1 -0
  357. package/.next/static/chunks/app/api/external-apps/route-a4f129c451de7859.js +1 -0
  358. package/.next/static/chunks/app/api/fs/browse/route-a4f129c451de7859.js +1 -0
  359. package/.next/static/chunks/app/api/fs/recent-paths/route-a4f129c451de7859.js +1 -0
  360. package/.next/static/chunks/app/api/hooks/agent-event/route-a4f129c451de7859.js +1 -0
  361. package/.next/static/chunks/app/api/hooks/claude-done/route-a4f129c451de7859.js +1 -0
  362. package/.next/static/chunks/app/api/hooks/permission-request/route-a4f129c451de7859.js +1 -0
  363. package/.next/static/chunks/app/api/metrics/vibe/route-a4f129c451de7859.js +1 -0
  364. package/.next/static/chunks/app/api/ollama/models/route-a4f129c451de7859.js +1 -0
  365. package/.next/static/chunks/app/api/push/escalation/route-a4f129c451de7859.js +1 -0
  366. package/.next/static/chunks/app/api/push/subscriptions/route-a4f129c451de7859.js +1 -0
  367. package/.next/static/chunks/app/api/push/vapid/route-a4f129c451de7859.js +1 -0
  368. package/.next/static/chunks/app/api/relays/[relayId]/cancel/route-a4f129c451de7859.js +1 -0
  369. package/.next/static/chunks/app/api/relays/[relayId]/route-a4f129c451de7859.js +1 -0
  370. package/.next/static/chunks/app/api/relays/route-a4f129c451de7859.js +1 -0
  371. package/.next/static/chunks/app/api/remote/pair/route-a4f129c451de7859.js +1 -0
  372. package/.next/static/chunks/app/api/repositories/[id]/route-a4f129c451de7859.js +1 -0
  373. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-a4f129c451de7859.js +1 -0
  374. package/.next/static/chunks/app/api/repositories/clone/route-a4f129c451de7859.js +1 -0
  375. package/.next/static/chunks/app/api/repositories/excluded/route-a4f129c451de7859.js +1 -0
  376. package/.next/static/chunks/app/api/repositories/restore/route-a4f129c451de7859.js +1 -0
  377. package/.next/static/chunks/app/api/repositories/route-a4f129c451de7859.js +1 -0
  378. package/.next/static/chunks/app/api/repositories/scan/route-a4f129c451de7859.js +1 -0
  379. package/.next/static/chunks/app/api/repositories/sync/route-a4f129c451de7859.js +1 -0
  380. package/.next/static/chunks/app/api/repositories/validate-path/route-a4f129c451de7859.js +1 -0
  381. package/.next/static/chunks/app/api/settings/default-agents/route-a4f129c451de7859.js +1 -0
  382. package/.next/static/chunks/app/api/settings/default-surface-mode/route-a4f129c451de7859.js +1 -0
  383. package/.next/static/chunks/app/api/sidebar/group-order/route-a4f129c451de7859.js +1 -0
  384. package/.next/static/chunks/app/api/skills/[id]/route-a4f129c451de7859.js +1 -0
  385. package/.next/static/chunks/app/api/skills/installations/route-a4f129c451de7859.js +1 -0
  386. package/.next/static/chunks/app/api/skills/operations/route-a4f129c451de7859.js +1 -0
  387. package/.next/static/chunks/app/api/skills/reindex/route-a4f129c451de7859.js +1 -0
  388. package/.next/static/chunks/app/api/skills/route-a4f129c451de7859.js +1 -0
  389. package/.next/static/chunks/app/api/slash-commands/route-a4f129c451de7859.js +1 -0
  390. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-a4f129c451de7859.js +1 -0
  391. package/.next/static/chunks/app/api/tasks/[taskId]/route-a4f129c451de7859.js +1 -0
  392. package/.next/static/chunks/app/api/templates/[id]/route-a4f129c451de7859.js +1 -0
  393. package/.next/static/chunks/app/api/templates/route-a4f129c451de7859.js +1 -0
  394. package/.next/static/chunks/app/api/verification/runs/[runId]/route-a4f129c451de7859.js +1 -0
  395. package/.next/static/chunks/app/api/verification/runs/route-a4f129c451de7859.js +1 -0
  396. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-a4f129c451de7859.js +1 -0
  397. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-a4f129c451de7859.js +1 -0
  398. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-a4f129c451de7859.js +1 -0
  399. package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-a4f129c451de7859.js +1 -0
  400. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-a4f129c451de7859.js +1 -0
  401. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-a4f129c451de7859.js +1 -0
  402. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-a4f129c451de7859.js +1 -0
  403. package/.next/static/chunks/app/api/worktrees/[id]/direct-input/route-a4f129c451de7859.js +1 -0
  404. package/.next/static/chunks/app/api/worktrees/[id]/env/route-a4f129c451de7859.js +1 -0
  405. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-a4f129c451de7859.js +1 -0
  406. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-a4f129c451de7859.js +1 -0
  407. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-a4f129c451de7859.js +1 -0
  408. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-a4f129c451de7859.js +1 -0
  409. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-a4f129c451de7859.js +1 -0
  410. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-a4f129c451de7859.js +1 -0
  411. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-a4f129c451de7859.js +1 -0
  412. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-a4f129c451de7859.js +1 -0
  413. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-a4f129c451de7859.js +1 -0
  414. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-a4f129c451de7859.js +1 -0
  415. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-a4f129c451de7859.js +1 -0
  416. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-a4f129c451de7859.js +1 -0
  417. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-a4f129c451de7859.js +1 -0
  418. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-a4f129c451de7859.js +1 -0
  419. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-a4f129c451de7859.js +1 -0
  420. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-a4f129c451de7859.js +1 -0
  421. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-a4f129c451de7859.js +1 -0
  422. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-a4f129c451de7859.js +1 -0
  423. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-a4f129c451de7859.js +1 -0
  424. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-a4f129c451de7859.js +1 -0
  425. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-a4f129c451de7859.js +1 -0
  426. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-a4f129c451de7859.js +1 -0
  427. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-a4f129c451de7859.js +1 -0
  428. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-a4f129c451de7859.js +1 -0
  429. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-a4f129c451de7859.js +1 -0
  430. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-a4f129c451de7859.js +1 -0
  431. package/.next/static/chunks/app/api/worktrees/[id]/instances/notes/route-a4f129c451de7859.js +1 -0
  432. package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-a4f129c451de7859.js +1 -0
  433. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-a4f129c451de7859.js +1 -0
  434. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-a4f129c451de7859.js +1 -0
  435. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-a4f129c451de7859.js +1 -0
  436. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-a4f129c451de7859.js +1 -0
  437. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-a4f129c451de7859.js +1 -0
  438. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-a4f129c451de7859.js +1 -0
  439. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-a4f129c451de7859.js +1 -0
  440. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-a4f129c451de7859.js +1 -0
  441. package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-a4f129c451de7859.js +1 -0
  442. package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-a4f129c451de7859.js +1 -0
  443. package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-a4f129c451de7859.js +1 -0
  444. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-a4f129c451de7859.js +1 -0
  445. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/strict/route-a4f129c451de7859.js +1 -0
  446. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-a4f129c451de7859.js +1 -0
  447. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-a4f129c451de7859.js +1 -0
  448. package/.next/static/chunks/app/api/worktrees/[id]/route-a4f129c451de7859.js +1 -0
  449. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-a4f129c451de7859.js +1 -0
  450. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-a4f129c451de7859.js +1 -0
  451. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-a4f129c451de7859.js +1 -0
  452. package/.next/static/chunks/app/api/worktrees/[id]/search/route-a4f129c451de7859.js +1 -0
  453. package/.next/static/chunks/app/api/worktrees/[id]/send/route-a4f129c451de7859.js +1 -0
  454. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-a4f129c451de7859.js +1 -0
  455. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-a4f129c451de7859.js +1 -0
  456. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-a4f129c451de7859.js +1 -0
  457. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-a4f129c451de7859.js +1 -0
  458. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-a4f129c451de7859.js +1 -0
  459. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-a4f129c451de7859.js +1 -0
  460. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-a4f129c451de7859.js +1 -0
  461. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-a4f129c451de7859.js +1 -0
  462. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-a4f129c451de7859.js +1 -0
  463. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-a4f129c451de7859.js +1 -0
  464. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-a4f129c451de7859.js +1 -0
  465. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-a4f129c451de7859.js +1 -0
  466. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-a4f129c451de7859.js +1 -0
  467. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-a4f129c451de7859.js +1 -0
  468. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-a4f129c451de7859.js +1 -0
  469. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-a4f129c451de7859.js +1 -0
  470. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-a4f129c451de7859.js +1 -0
  471. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-a4f129c451de7859.js +1 -0
  472. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-a4f129c451de7859.js +1 -0
  473. package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-a4f129c451de7859.js +1 -0
  474. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-a4f129c451de7859.js +1 -0
  475. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-a4f129c451de7859.js +1 -0
  476. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-a4f129c451de7859.js +1 -0
  477. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-a4f129c451de7859.js +1 -0
  478. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-a4f129c451de7859.js +1 -0
  479. package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-a4f129c451de7859.js +1 -0
  480. package/.next/static/chunks/app/api/worktrees/route-a4f129c451de7859.js +1 -0
  481. package/.next/static/chunks/app/layout-4f64316957b0a8e5.js +1 -0
  482. package/.next/static/chunks/app/manifest.webmanifest/route-a4f129c451de7859.js +1 -0
  483. package/.next/static/chunks/app/more/page-ff5af5ca48774c89.js +1 -0
  484. package/.next/static/chunks/app/page-b4863bfe0452e09d.js +1 -0
  485. package/.next/static/chunks/app/proxy/[...path]/route-a4f129c451de7859.js +1 -0
  486. package/.next/static/chunks/app/review/page-ff3efb96fdf9bb4b.js +1 -0
  487. package/.next/static/chunks/app/sessions/page-c6eb7c02db2f4c80.js +1 -0
  488. package/.next/static/chunks/app/worktrees/[id]/layout-a4f129c451de7859.js +1 -0
  489. package/.next/static/chunks/app/worktrees/[id]/page-33afc6aa96289fb0.js +1 -0
  490. package/.next/static/css/c1e307d05daf93b6.css +1 -0
  491. package/.next/trace +13 -13
  492. package/.next/types/app/api/relays/[relayId]/route.ts +347 -0
  493. package/.next/types/routes.d.ts +2 -1
  494. package/.next/types/validator.ts +9 -0
  495. package/dist/cli/commands/ask.d.ts.map +1 -1
  496. package/dist/cli/commands/ask.js +233 -17
  497. package/dist/cli/commands/attach.d.ts +4 -1
  498. package/dist/cli/commands/attach.d.ts.map +1 -1
  499. package/dist/cli/commands/attach.js +19 -7
  500. package/dist/cli/commands/command-target.d.ts +7 -0
  501. package/dist/cli/commands/command-target.d.ts.map +1 -1
  502. package/dist/cli/commands/command-target.js +10 -0
  503. package/dist/cli/commands/instances.d.ts.map +1 -1
  504. package/dist/cli/commands/instances.js +38 -2
  505. package/dist/cli/commands/message-dispatch.d.ts +39 -5
  506. package/dist/cli/commands/message-dispatch.d.ts.map +1 -1
  507. package/dist/cli/commands/message-dispatch.js +100 -8
  508. package/dist/cli/commands/relays.d.ts +26 -2
  509. package/dist/cli/commands/relays.d.ts.map +1 -1
  510. package/dist/cli/commands/relays.js +70 -5
  511. package/dist/cli/commands/respond-strict.d.ts.map +1 -1
  512. package/dist/cli/commands/respond-strict.js +22 -5
  513. package/dist/cli/commands/respond.d.ts +12 -0
  514. package/dist/cli/commands/respond.d.ts.map +1 -1
  515. package/dist/cli/commands/respond.js +83 -18
  516. package/dist/cli/commands/send.d.ts.map +1 -1
  517. package/dist/cli/commands/send.js +14 -8
  518. package/dist/cli/commands/wait-hook-stop-settle.d.ts +66 -0
  519. package/dist/cli/commands/wait-hook-stop-settle.d.ts.map +1 -0
  520. package/dist/cli/commands/wait-hook-stop-settle.js +150 -0
  521. package/dist/cli/commands/wait-instance.d.ts +29 -0
  522. package/dist/cli/commands/wait-instance.d.ts.map +1 -0
  523. package/dist/cli/commands/wait-instance.js +56 -0
  524. package/dist/cli/commands/wait-notices.d.ts +87 -0
  525. package/dist/cli/commands/wait-notices.d.ts.map +1 -0
  526. package/dist/cli/commands/wait-notices.js +301 -0
  527. package/dist/cli/commands/wait-poll-bookkeeping.d.ts +15 -0
  528. package/dist/cli/commands/wait-poll-bookkeeping.d.ts.map +1 -0
  529. package/dist/cli/commands/wait-poll-bookkeeping.js +57 -0
  530. package/dist/cli/commands/wait-poll-state.d.ts +136 -0
  531. package/dist/cli/commands/wait-poll-state.d.ts.map +1 -0
  532. package/dist/cli/commands/wait-poll-state.js +6 -0
  533. package/dist/cli/commands/wait-timing.d.ts +46 -0
  534. package/dist/cli/commands/wait-timing.d.ts.map +1 -0
  535. package/dist/cli/commands/wait-timing.js +99 -0
  536. package/dist/cli/commands/wait-turn-boundary.d.ts +284 -0
  537. package/dist/cli/commands/wait-turn-boundary.d.ts.map +1 -0
  538. package/dist/cli/commands/wait-turn-boundary.js +427 -0
  539. package/dist/cli/commands/wait-verify.d.ts +51 -0
  540. package/dist/cli/commands/wait-verify.d.ts.map +1 -0
  541. package/dist/cli/commands/wait-verify.js +128 -0
  542. package/dist/cli/commands/wait.d.ts +6 -105
  543. package/dist/cli/commands/wait.d.ts.map +1 -1
  544. package/dist/cli/commands/wait.js +240 -968
  545. package/dist/cli/commands/whoami.d.ts.map +1 -1
  546. package/dist/cli/commands/whoami.js +3 -1
  547. package/dist/cli/docs/agent-operations.d.ts +2 -2
  548. package/dist/cli/docs/agent-operations.d.ts.map +1 -1
  549. package/dist/cli/docs/agent-operations.js +24 -1
  550. package/dist/cli/types/api-responses.d.ts +49 -3
  551. package/dist/cli/types/api-responses.d.ts.map +1 -1
  552. package/dist/cli/utils/api-client.d.ts +69 -1
  553. package/dist/cli/utils/api-client.d.ts.map +1 -1
  554. package/dist/cli/utils/api-client.js +226 -18
  555. package/dist/cli/utils/follow-up-command.d.ts +38 -0
  556. package/dist/cli/utils/follow-up-command.d.ts.map +1 -0
  557. package/dist/cli/utils/follow-up-command.js +57 -0
  558. package/dist/cli/utils/reply-ledger.d.ts +80 -1
  559. package/dist/cli/utils/reply-ledger.d.ts.map +1 -1
  560. package/dist/cli/utils/reply-ledger.js +147 -2
  561. package/dist/cli/utils/server-capabilities.d.ts +18 -0
  562. package/dist/cli/utils/server-capabilities.d.ts.map +1 -1
  563. package/dist/cli/utils/server-capabilities.js +36 -3
  564. package/dist/cli/utils/session-target.d.ts +1 -1
  565. package/dist/cli/utils/session-target.d.ts.map +1 -1
  566. package/dist/cli/utils/session-target.js +3 -0
  567. package/dist/cli/utils/verify-runner.d.ts +7 -0
  568. package/dist/cli/utils/verify-runner.d.ts.map +1 -1
  569. package/dist/cli/utils/verify-runner.js +51 -15
  570. package/dist/lib/cli-tools/session-name.d.ts.map +1 -1
  571. package/dist/lib/cli-tools/session-name.js +11 -3
  572. package/dist/lib/session/send-attempt-types.d.ts +48 -1
  573. package/dist/lib/session/send-attempt-types.d.ts.map +1 -1
  574. package/dist/lib/session/send-attempt-types.js +18 -1
  575. package/dist/lib/verification/session-kill-ledger.d.ts +110 -0
  576. package/dist/lib/verification/session-kill-ledger.d.ts.map +1 -0
  577. package/dist/lib/verification/session-kill-ledger.js +174 -0
  578. package/dist/server/locales/en/worktree.json +20 -3
  579. package/dist/server/locales/ja/worktree.json +20 -3
  580. package/dist/server/src/config/cli-tool-timing-config.js +1 -7
  581. package/dist/server/src/lib/auto-yes-poller.js +54 -11
  582. package/dist/server/src/lib/cli-tools/antigravity.js +45 -9
  583. package/dist/server/src/lib/cli-tools/base.js +39 -0
  584. package/dist/server/src/lib/cli-tools/codex.js +67 -15
  585. package/dist/server/src/lib/cli-tools/command-code-plan-review.js +24 -2
  586. package/dist/server/src/lib/cli-tools/command-code.js +7 -3
  587. package/dist/server/src/lib/cli-tools/copilot.js +125 -33
  588. package/dist/server/src/lib/cli-tools/gemini.js +37 -10
  589. package/dist/server/src/lib/cli-tools/launch-keys.js +39 -0
  590. package/dist/server/src/lib/cli-tools/opencode-v2.js +6 -2
  591. package/dist/server/src/lib/cli-tools/opencode.js +60 -15
  592. package/dist/server/src/lib/cli-tools/session-name.js +11 -3
  593. package/dist/server/src/lib/cli-tools/submit-composer-read.js +590 -0
  594. package/dist/server/src/lib/cli-tools/submit-verified-sender.js +512 -620
  595. package/dist/server/src/lib/cli-tools/vibe-local.js +4 -2
  596. package/dist/server/src/lib/db/db-migration-path.js +63 -2
  597. package/dist/server/src/lib/db/migrations/index.js +2 -0
  598. package/dist/server/src/lib/db/migrations/pre-migration-backup.js +266 -0
  599. package/dist/server/src/lib/db/migrations/runner.js +37 -4
  600. package/dist/server/src/lib/db/migrations/v62-session-relays-bind.js +102 -0
  601. package/dist/server/src/lib/db/relay-bind-db.js +437 -0
  602. package/dist/server/src/lib/db/relay-db.js +59 -96
  603. package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +5 -4
  604. package/dist/server/src/lib/detection/upstream-faults.js +40 -6
  605. package/dist/server/src/lib/hooks/sources/copilot/hook-settings.js +2 -3
  606. package/dist/server/src/lib/hooks/sources/opencode/client.js +12 -6
  607. package/dist/server/src/lib/polling/response-checker.js +7 -5
  608. package/dist/server/src/lib/prompt-answer-errors.js +362 -0
  609. package/dist/server/src/lib/prompt-answer-sender.js +264 -288
  610. package/dist/server/src/lib/push/failure-episode-state.js +4 -1
  611. package/dist/server/src/lib/realtime/terminal-broadcast.js +1 -4
  612. package/dist/server/src/lib/realtime-snippet.js +54 -0
  613. package/dist/server/src/lib/relay/relay-bind.js +294 -0
  614. package/dist/server/src/lib/relay/relay-boot.js +51 -0
  615. package/dist/server/src/lib/relay/relay-bound-reply.js +519 -0
  616. package/dist/server/src/lib/relay/relay-delivery.js +134 -220
  617. package/dist/server/src/lib/relay/relay-messages.js +39 -4
  618. package/dist/server/src/lib/relay/relay-overlap.js +92 -0
  619. package/dist/server/src/lib/relay/relay-system-line.js +3 -2
  620. package/dist/server/src/lib/relay/types.js +12 -1
  621. package/dist/server/src/lib/session/agent-event-state.js +4 -0
  622. package/dist/server/src/lib/session/agent-session-lifecycle.js +23 -0
  623. package/dist/server/src/lib/session/claude-session.js +59 -8
  624. package/dist/server/src/lib/session/composer-clear.js +54 -1
  625. package/dist/server/src/lib/session/current-output-builder.js +26 -8
  626. package/dist/server/src/lib/session/current-output-history-writers.js +1 -1
  627. package/dist/server/src/lib/session/instance-input-lock.js +664 -0
  628. package/dist/server/src/lib/session/prompt-submit-receipt.js +155 -0
  629. package/dist/server/src/lib/session/prompt-waiting-guard.js +10 -3
  630. package/dist/server/src/lib/session/send-attempt-state.js +65 -0
  631. package/dist/server/src/lib/session/send-attempt-types.js +18 -1
  632. package/dist/server/src/lib/session/send-user-message.js +84 -14
  633. package/dist/server/src/lib/session/session-launch-flight.js +243 -0
  634. package/dist/server/src/lib/session/session-starting-state.js +40 -4
  635. package/dist/server/src/lib/session/structured-prompt.js +12 -9
  636. package/dist/server/src/lib/session/waiting-episode-binding.js +4 -2
  637. package/dist/server/src/lib/session-cleanup.js +32 -0
  638. package/dist/server/src/lib/session-key-sender.js +0 -27
  639. package/dist/server/src/lib/verification/env-clean-gate.js +129 -0
  640. package/dist/server/src/lib/verification/env-snapshot.js +11 -2
  641. package/dist/server/src/lib/verification/session-kill-ledger.js +174 -0
  642. package/package.json +5 -1
  643. package/release-notes/0.49.1.json +66 -0
  644. package/release-notes/0.49.2.json +49 -0
  645. package/.next/server/chunks/1210.js +0 -1
  646. package/.next/server/chunks/1945.js +0 -14
  647. package/.next/server/chunks/1990.js +0 -103
  648. package/.next/server/chunks/4194.js +0 -67
  649. package/.next/server/chunks/5845.js +0 -1
  650. package/.next/server/chunks/720.js +0 -103
  651. package/.next/server/chunks/7604.js +0 -2
  652. package/.next/server/chunks/9540.js +0 -1
  653. package/.next/static/chunks/4768-ad6f82f034f21eae.js +0 -1
  654. package/.next/static/chunks/5794-80ac3f06f098ea29.js +0 -1
  655. package/.next/static/chunks/6654-f3534f35f16644bc.js +0 -1
  656. package/.next/static/chunks/7665-e9ef6e0a85b9fa49.js +0 -1
  657. package/.next/static/chunks/8606-cf6bdbff44a764cf.js +0 -1
  658. package/.next/static/chunks/9079-987939d231704218.js +0 -1
  659. package/.next/static/chunks/app/api/agents/update/route-c81284a9d8b35304.js +0 -1
  660. package/.next/static/chunks/app/api/agents/versions/route-c81284a9d8b35304.js +0 -1
  661. package/.next/static/chunks/app/api/app/release-notes/route-c81284a9d8b35304.js +0 -1
  662. package/.next/static/chunks/app/api/app/update/route-c81284a9d8b35304.js +0 -1
  663. package/.next/static/chunks/app/api/app/update-check/route-c81284a9d8b35304.js +0 -1
  664. package/.next/static/chunks/app/api/auth/login/route-c81284a9d8b35304.js +0 -1
  665. package/.next/static/chunks/app/api/auth/logout/route-c81284a9d8b35304.js +0 -1
  666. package/.next/static/chunks/app/api/auth/status/route-c81284a9d8b35304.js +0 -1
  667. package/.next/static/chunks/app/api/capabilities/route-c81284a9d8b35304.js +0 -1
  668. package/.next/static/chunks/app/api/daily-summary/route-c81284a9d8b35304.js +0 -1
  669. package/.next/static/chunks/app/api/daily-summary/status/route-c81284a9d8b35304.js +0 -1
  670. package/.next/static/chunks/app/api/external-apps/[id]/health/route-c81284a9d8b35304.js +0 -1
  671. package/.next/static/chunks/app/api/external-apps/[id]/route-c81284a9d8b35304.js +0 -1
  672. package/.next/static/chunks/app/api/external-apps/route-c81284a9d8b35304.js +0 -1
  673. package/.next/static/chunks/app/api/fs/browse/route-c81284a9d8b35304.js +0 -1
  674. package/.next/static/chunks/app/api/fs/recent-paths/route-c81284a9d8b35304.js +0 -1
  675. package/.next/static/chunks/app/api/hooks/agent-event/route-c81284a9d8b35304.js +0 -1
  676. package/.next/static/chunks/app/api/hooks/claude-done/route-c81284a9d8b35304.js +0 -1
  677. package/.next/static/chunks/app/api/hooks/permission-request/route-c81284a9d8b35304.js +0 -1
  678. package/.next/static/chunks/app/api/metrics/vibe/route-c81284a9d8b35304.js +0 -1
  679. package/.next/static/chunks/app/api/ollama/models/route-c81284a9d8b35304.js +0 -1
  680. package/.next/static/chunks/app/api/push/escalation/route-c81284a9d8b35304.js +0 -1
  681. package/.next/static/chunks/app/api/push/subscriptions/route-c81284a9d8b35304.js +0 -1
  682. package/.next/static/chunks/app/api/push/vapid/route-c81284a9d8b35304.js +0 -1
  683. package/.next/static/chunks/app/api/relays/[relayId]/cancel/route-c81284a9d8b35304.js +0 -1
  684. package/.next/static/chunks/app/api/relays/route-c81284a9d8b35304.js +0 -1
  685. package/.next/static/chunks/app/api/remote/pair/route-c81284a9d8b35304.js +0 -1
  686. package/.next/static/chunks/app/api/repositories/[id]/route-c81284a9d8b35304.js +0 -1
  687. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-c81284a9d8b35304.js +0 -1
  688. package/.next/static/chunks/app/api/repositories/clone/route-c81284a9d8b35304.js +0 -1
  689. package/.next/static/chunks/app/api/repositories/excluded/route-c81284a9d8b35304.js +0 -1
  690. package/.next/static/chunks/app/api/repositories/restore/route-c81284a9d8b35304.js +0 -1
  691. package/.next/static/chunks/app/api/repositories/route-c81284a9d8b35304.js +0 -1
  692. package/.next/static/chunks/app/api/repositories/scan/route-c81284a9d8b35304.js +0 -1
  693. package/.next/static/chunks/app/api/repositories/sync/route-c81284a9d8b35304.js +0 -1
  694. package/.next/static/chunks/app/api/repositories/validate-path/route-c81284a9d8b35304.js +0 -1
  695. package/.next/static/chunks/app/api/settings/default-agents/route-c81284a9d8b35304.js +0 -1
  696. package/.next/static/chunks/app/api/settings/default-surface-mode/route-c81284a9d8b35304.js +0 -1
  697. package/.next/static/chunks/app/api/sidebar/group-order/route-c81284a9d8b35304.js +0 -1
  698. package/.next/static/chunks/app/api/skills/[id]/route-c81284a9d8b35304.js +0 -1
  699. package/.next/static/chunks/app/api/skills/installations/route-c81284a9d8b35304.js +0 -1
  700. package/.next/static/chunks/app/api/skills/operations/route-c81284a9d8b35304.js +0 -1
  701. package/.next/static/chunks/app/api/skills/reindex/route-c81284a9d8b35304.js +0 -1
  702. package/.next/static/chunks/app/api/skills/route-c81284a9d8b35304.js +0 -1
  703. package/.next/static/chunks/app/api/slash-commands/route-c81284a9d8b35304.js +0 -1
  704. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-c81284a9d8b35304.js +0 -1
  705. package/.next/static/chunks/app/api/tasks/[taskId]/route-c81284a9d8b35304.js +0 -1
  706. package/.next/static/chunks/app/api/templates/[id]/route-c81284a9d8b35304.js +0 -1
  707. package/.next/static/chunks/app/api/templates/route-c81284a9d8b35304.js +0 -1
  708. package/.next/static/chunks/app/api/verification/runs/[runId]/route-c81284a9d8b35304.js +0 -1
  709. package/.next/static/chunks/app/api/verification/runs/route-c81284a9d8b35304.js +0 -1
  710. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-c81284a9d8b35304.js +0 -1
  711. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-c81284a9d8b35304.js +0 -1
  712. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-c81284a9d8b35304.js +0 -1
  713. package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-c81284a9d8b35304.js +0 -1
  714. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-c81284a9d8b35304.js +0 -1
  715. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-c81284a9d8b35304.js +0 -1
  716. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-c81284a9d8b35304.js +0 -1
  717. package/.next/static/chunks/app/api/worktrees/[id]/direct-input/route-c81284a9d8b35304.js +0 -1
  718. package/.next/static/chunks/app/api/worktrees/[id]/env/route-c81284a9d8b35304.js +0 -1
  719. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-c81284a9d8b35304.js +0 -1
  720. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-c81284a9d8b35304.js +0 -1
  721. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-c81284a9d8b35304.js +0 -1
  722. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-c81284a9d8b35304.js +0 -1
  723. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-c81284a9d8b35304.js +0 -1
  724. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-c81284a9d8b35304.js +0 -1
  725. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-c81284a9d8b35304.js +0 -1
  726. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-c81284a9d8b35304.js +0 -1
  727. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-c81284a9d8b35304.js +0 -1
  728. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-c81284a9d8b35304.js +0 -1
  729. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-c81284a9d8b35304.js +0 -1
  730. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-c81284a9d8b35304.js +0 -1
  731. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-c81284a9d8b35304.js +0 -1
  732. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-c81284a9d8b35304.js +0 -1
  733. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-c81284a9d8b35304.js +0 -1
  734. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-c81284a9d8b35304.js +0 -1
  735. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-c81284a9d8b35304.js +0 -1
  736. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-c81284a9d8b35304.js +0 -1
  737. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-c81284a9d8b35304.js +0 -1
  738. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-c81284a9d8b35304.js +0 -1
  739. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-c81284a9d8b35304.js +0 -1
  740. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-c81284a9d8b35304.js +0 -1
  741. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-c81284a9d8b35304.js +0 -1
  742. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-c81284a9d8b35304.js +0 -1
  743. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-c81284a9d8b35304.js +0 -1
  744. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-c81284a9d8b35304.js +0 -1
  745. package/.next/static/chunks/app/api/worktrees/[id]/instances/notes/route-c81284a9d8b35304.js +0 -1
  746. package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-c81284a9d8b35304.js +0 -1
  747. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-c81284a9d8b35304.js +0 -1
  748. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-c81284a9d8b35304.js +0 -1
  749. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-c81284a9d8b35304.js +0 -1
  750. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-c81284a9d8b35304.js +0 -1
  751. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-c81284a9d8b35304.js +0 -1
  752. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-c81284a9d8b35304.js +0 -1
  753. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-c81284a9d8b35304.js +0 -1
  754. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-c81284a9d8b35304.js +0 -1
  755. package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-c81284a9d8b35304.js +0 -1
  756. package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-c81284a9d8b35304.js +0 -1
  757. package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-c81284a9d8b35304.js +0 -1
  758. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-c81284a9d8b35304.js +0 -1
  759. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/strict/route-c81284a9d8b35304.js +0 -1
  760. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-c81284a9d8b35304.js +0 -1
  761. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-c81284a9d8b35304.js +0 -1
  762. package/.next/static/chunks/app/api/worktrees/[id]/route-c81284a9d8b35304.js +0 -1
  763. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-c81284a9d8b35304.js +0 -1
  764. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-c81284a9d8b35304.js +0 -1
  765. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-c81284a9d8b35304.js +0 -1
  766. package/.next/static/chunks/app/api/worktrees/[id]/search/route-c81284a9d8b35304.js +0 -1
  767. package/.next/static/chunks/app/api/worktrees/[id]/send/route-c81284a9d8b35304.js +0 -1
  768. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-c81284a9d8b35304.js +0 -1
  769. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-c81284a9d8b35304.js +0 -1
  770. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-c81284a9d8b35304.js +0 -1
  771. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-c81284a9d8b35304.js +0 -1
  772. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-c81284a9d8b35304.js +0 -1
  773. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-c81284a9d8b35304.js +0 -1
  774. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-c81284a9d8b35304.js +0 -1
  775. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-c81284a9d8b35304.js +0 -1
  776. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-c81284a9d8b35304.js +0 -1
  777. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-c81284a9d8b35304.js +0 -1
  778. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-c81284a9d8b35304.js +0 -1
  779. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-c81284a9d8b35304.js +0 -1
  780. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-c81284a9d8b35304.js +0 -1
  781. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-c81284a9d8b35304.js +0 -1
  782. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-c81284a9d8b35304.js +0 -1
  783. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-c81284a9d8b35304.js +0 -1
  784. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-c81284a9d8b35304.js +0 -1
  785. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-c81284a9d8b35304.js +0 -1
  786. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-c81284a9d8b35304.js +0 -1
  787. package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-c81284a9d8b35304.js +0 -1
  788. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-c81284a9d8b35304.js +0 -1
  789. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-c81284a9d8b35304.js +0 -1
  790. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-c81284a9d8b35304.js +0 -1
  791. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-c81284a9d8b35304.js +0 -1
  792. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-c81284a9d8b35304.js +0 -1
  793. package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-c81284a9d8b35304.js +0 -1
  794. package/.next/static/chunks/app/api/worktrees/route-c81284a9d8b35304.js +0 -1
  795. package/.next/static/chunks/app/layout-aa8e66164a4367af.js +0 -1
  796. package/.next/static/chunks/app/manifest.webmanifest/route-c81284a9d8b35304.js +0 -1
  797. package/.next/static/chunks/app/more/page-87c84987b2765213.js +0 -1
  798. package/.next/static/chunks/app/page-1b820c421db48c2c.js +0 -1
  799. package/.next/static/chunks/app/proxy/[...path]/route-c81284a9d8b35304.js +0 -1
  800. package/.next/static/chunks/app/review/page-e2fd4a590646a2d8.js +0 -1
  801. package/.next/static/chunks/app/sessions/page-cfd645305e25fd33.js +0 -1
  802. package/.next/static/chunks/app/worktrees/[id]/layout-c81284a9d8b35304.js +0 -1
  803. package/.next/static/chunks/app/worktrees/[id]/page-a8d7886703ffc7b4.js +0 -1
  804. package/.next/static/css/db8959555c3d9c96.css +0 -1
  805. /package/.next/static/{3_JtAZaKMJEDFIIfkHv4n → yGatWDsS532awSs51kXyd}/_buildManifest.js +0 -0
  806. /package/.next/static/{3_JtAZaKMJEDFIIfkHv4n → yGatWDsS532awSs51kXyd}/_ssgManifest.js +0 -0
@@ -22,21 +22,38 @@
22
22
  * Infrastructure errors use ExitCode (1, 2, 99)
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.SELF_RESUME_HOLD_MS = exports.SELF_RESUME_CAPABILITY = exports.SELF_RESUME_PENDING_DETAIL = exports.TURN_OPENING_EVENT_TYPES = void 0;
26
- exports.formatRestartReleaseNotice = formatRestartReleaseNotice;
25
+ exports.settleCurrentOutputPath = exports.HOOK_STOP_SETTLE_MAX_MS = exports.HOOK_STOP_SETTLE_INTERVAL_MS = exports.TURN_OPENING_EVENT_TYPES = exports.SELF_RESUME_PENDING_DETAIL = exports.SELF_RESUME_HOLD_MS = exports.SELF_RESUME_CAPABILITY = exports.formatRestartReleaseNotice = void 0;
27
26
  exports.pollWorktree = pollWorktree;
28
27
  exports.createWaitCommand = createWaitCommand;
29
28
  const commander_1 = require("commander");
30
29
  const types_1 = require("../types");
31
30
  const api_client_1 = require("../utils/api-client");
32
31
  const command_helpers_1 = require("../utils/command-helpers");
33
- const verify_runner_1 = require("../utils/verify-runner");
34
32
  const agent_target_options_1 = require("../config/agent-target-options");
35
33
  const prompt_1 = require("./prompt");
36
34
  const prompt_view_1 = require("../../lib/session/prompt-view");
37
35
  const instances_1 = require("./instances");
38
- /** [IA3-02] Polling interval 5 seconds (matches tmux-capture-cache TTL=2s) */
39
- const POLL_INTERVAL_MS = 5000;
36
+ const wait_timing_1 = require("./wait-timing");
37
+ const wait_notices_1 = require("./wait-notices");
38
+ const wait_turn_boundary_1 = require("./wait-turn-boundary");
39
+ const wait_hook_stop_settle_1 = require("./wait-hook-stop-settle");
40
+ const wait_verify_1 = require("./wait-verify");
41
+ const wait_instance_1 = require("./wait-instance");
42
+ const follow_up_command_1 = require("../utils/follow-up-command");
43
+ const wait_poll_bookkeeping_1 = require("./wait-poll-bookkeeping");
44
+ // Issue #3964: the split-out modules' exports, re-exported so every import of
45
+ // `./wait` keeps working.
46
+ var wait_notices_2 = require("./wait-notices");
47
+ Object.defineProperty(exports, "formatRestartReleaseNotice", { enumerable: true, get: function () { return wait_notices_2.formatRestartReleaseNotice; } });
48
+ var wait_turn_boundary_2 = require("./wait-turn-boundary");
49
+ Object.defineProperty(exports, "SELF_RESUME_CAPABILITY", { enumerable: true, get: function () { return wait_turn_boundary_2.SELF_RESUME_CAPABILITY; } });
50
+ Object.defineProperty(exports, "SELF_RESUME_HOLD_MS", { enumerable: true, get: function () { return wait_turn_boundary_2.SELF_RESUME_HOLD_MS; } });
51
+ Object.defineProperty(exports, "SELF_RESUME_PENDING_DETAIL", { enumerable: true, get: function () { return wait_turn_boundary_2.SELF_RESUME_PENDING_DETAIL; } });
52
+ Object.defineProperty(exports, "TURN_OPENING_EVENT_TYPES", { enumerable: true, get: function () { return wait_turn_boundary_2.TURN_OPENING_EVENT_TYPES; } });
53
+ var wait_hook_stop_settle_2 = require("./wait-hook-stop-settle");
54
+ Object.defineProperty(exports, "HOOK_STOP_SETTLE_INTERVAL_MS", { enumerable: true, get: function () { return wait_hook_stop_settle_2.HOOK_STOP_SETTLE_INTERVAL_MS; } });
55
+ Object.defineProperty(exports, "HOOK_STOP_SETTLE_MAX_MS", { enumerable: true, get: function () { return wait_hook_stop_settle_2.HOOK_STOP_SETTLE_MAX_MS; } });
56
+ Object.defineProperty(exports, "settleCurrentOutputPath", { enumerable: true, get: function () { return wait_hook_stop_settle_2.settleCurrentOutputPath; } });
40
57
  /**
41
58
  * `type` reported for a blocked-on-a-human frame that carries no parsable prompt
42
59
  * (Issue #1628). Arrow-key menus — Codex's pager and `/model`, antigravity's
@@ -74,76 +91,6 @@ function waitAnswerVia(view) {
74
91
  return 'api';
75
92
  return 'terminal';
76
93
  }
77
- /**
78
- * Why `wait` decided the agent was done, printed on the completion line
79
- * (Issue #1839).
80
- *
81
- * `Completed: <id>` used to be the whole story, which made two very different
82
- * situations indistinguishable in a log: the agent's own `Stop` hook arrived, or
83
- * nothing but the screen said so. The measurement behind this Issue is exactly
84
- * that difference — a 529 storm returns Claude to its composer in ~3 s with the
85
- * scraper reporting `ready`/`input_prompt` and no `Stop` ever sent — so the
86
- * basis belongs next to the verdict rather than in a triage session afterwards.
87
- */
88
- const COMPLETION_BASIS = {
89
- /** The agent reported the turn ended, and the report postdates this wait's turn. */
90
- HOOK_STOP: 'hook_stop',
91
- /** The tmux session went away after we had seen it alive. */
92
- SESSION_GONE: 'session_gone',
93
- /** The terminal frame says the agent is back at its composer. Nothing corroborated it. */
94
- SCRAPER_READY: 'scraper_ready',
95
- };
96
- /**
97
- * Structured event types that mean "a turn is under way" (Issue #1839).
98
- *
99
- * Mirrors AGENT_EVENT_TYPES in src/lib/hooks/agent-event-types.ts; duplicated
100
- * rather than imported because the CLI bundle keeps its own copy of the API
101
- * shapes (see api-responses.ts).
102
- *
103
- * `notification` is deliberately absent, and that is the one measured deviation
104
- * from the design sketched in Issue #1839. The Issue proposed accepting
105
- * `stop` **or** `idle_prompt` as the end of a turn; the live capture of
106
- * 2026-08-20 (see docs/design/upstream-fault-turn-boundary-1839.md) shows
107
- * Claude 2.1.236 emitting `Notification(idle_prompt)` 62 s into a turn that
108
- * ran nothing at all, because the composer had been idle for a minute. Reading
109
- * it as a turn boundary would have re-created the false completion this gate
110
- * exists to stop, one minute later. Only `Stop` ends a turn.
111
- *
112
- * Exported for the cross-layer pin in
113
- * `tests/unit/session/status-contract-1926.test.ts`. The server opens a turn on
114
- * the same three events (`src/lib/session/provisional-turn.ts`
115
- * TURN_ACTIVITY_EVENTS), and since Issue #1930 `adoptTurnStart` reads that
116
- * turn's `openedAt` rather than this set — so a set that drifted would change
117
- * this gate silently. The set is still read here for the pre-#1930 fallback
118
- * path, and the CLI cannot import the server module (`tsconfig.cli.json` sets
119
- * `"paths": {}`), so the test is the only thing holding the two together.
120
- */
121
- exports.TURN_OPENING_EVENT_TYPES = new Set([
122
- 'user_prompt_submit',
123
- 'pre_tool_use',
124
- 'post_tool_use',
125
- ]);
126
- /**
127
- * How far *before* this wait started a turn-opening event may sit and still be
128
- * read as the turn this wait is about (Issue #1839).
129
- *
130
- * `wait` does not know when `send` ran, and the honest proxy is its own start:
131
- * an orchestrator sends and then waits, so the turn's `UserPromptSubmit` lands
132
- * after `wait` is already polling (measured at +0.6 s from the send). One poll
133
- * interval of slack covers a `wait` that starts a moment late.
134
- *
135
- * The bound is what keeps this from being a new way to hang, and Issue #1930
136
- * narrowed what it has to defend against. It was written when structured events
137
- * were NOT fenced by generation on the way into `structuredEvents`, so a stale
138
- * `user_prompt_submit` from a previous agent process could still be the last
139
- * event on the wire and this window was the only thing stopping it from gating
140
- * a wait for ever. The server fences the turn now and publishes null when it
141
- * does, so the window's remaining job is narrower and sharper: a turn that has
142
- * already CLOSED must have closed inside this wait to count, or `wait` on a
143
- * session that finished an hour ago would inherit that turn's gate. An open
144
- * turn is adopted whatever its age — see {@link adoptTurnStart}.
145
- */
146
- const TURN_ADOPTION_GRACE_MS = POLL_INTERVAL_MS;
147
94
  /**
148
95
  * How long `isUnclassifiedActive` must hold before `wait` treats it as a stop
149
96
  * reason (Issue #1708).
@@ -163,625 +110,6 @@ const TURN_ADOPTION_GRACE_MS = POLL_INTERVAL_MS;
163
110
  * for working around a detector bug, and the bug is the thing to fix.
164
111
  */
165
112
  const UNCLASSIFIED_DWELL_MS = 60_000;
166
- /**
167
- * The keystroke that closes opencode's sidebar, in opencode's own notation
168
- * (Issue #2095).
169
- *
170
- * A local copy of `OPENCODE_SIDEBAR_RECOVERY_CHORD` from
171
- * `src/lib/detection/opencode-pane-obstruction.ts` and not an import: the CLI
172
- * builds with `"paths": {}` (tsconfig.cli.json) and cannot reach `@/lib` at all,
173
- * which is why `api-responses.ts` mirrors payload shapes rather than importing
174
- * them. Taken from opencode's own keybind table, which its `ctrl+p` palette
175
- * prints as `Show sidebar ctrl+x b`.
176
- */
177
- const OPENCODE_SIDEBAR_RECOVERY_CHORD = 'ctrl+x b';
178
- /**
179
- * The cause sentence to append when the frame carries a pane obstruction, or ''
180
- * (Issue #2095).
181
- *
182
- * Appended rather than substituted, and no exit code moves: the frame is
183
- * genuinely unclassified and `wait` was already right to stop on it. What it
184
- * could not say before is WHY, which left an operator with `capture --pane` and
185
- * a screenful of box drawing to work it out from.
186
- *
187
- * Empty for a server too old to publish the field, which is the same output
188
- * `wait` produced before this Issue.
189
- */
190
- function describePaneObstruction(data) {
191
- const obstruction = data.paneObstruction;
192
- if (!obstruction)
193
- return '';
194
- return (` Cause: paneObstruction=${obstruction.id} — a second column is sharing rows with the ` +
195
- `transcript (it reads ${JSON.stringify(obstruction.matchedText)}), which covers the marker ` +
196
- `that ends a turn. Press \`${OPENCODE_SIDEBAR_RECOVERY_CHORD}\` in the pane to close ` +
197
- `opencode's sidebar.`);
198
- }
199
- /**
200
- * How recent `autoYes.lastSuppression` must be to be reported as the reason this
201
- * wait is blocked (Issue #1699).
202
- *
203
- * The record is refreshed on every poll for as long as the suppressed prompt is
204
- * on screen, so a fresh timestamp means "this is happening now" while an old one
205
- * is a historical suppression of some earlier prompt. The window is generous
206
- * against the server's own poll interval — being a few seconds late with a true
207
- * report beats staying silent, which is the failure this exists to fix.
208
- *
209
- * Issue #2463 reads the same window as "the policy withheld THIS prompt", which
210
- * is what ends the Auto-Yes hold at once. `current-output` publishes no start
211
- * time for a scraped prompt, so the push gate's `suppression.at >= waitingSince`
212
- * (`src/lib/push/prompt-push-gate.ts`) cannot be computed here; a record that is
213
- * still being re-stamped is the CLI's reading of it. Using one window for both
214
- * keeps the hold and the payload in agreement: an exit 10 carries
215
- * `autoYesSuppression` exactly when the hold judged the answer withheld. The
216
- * error runs towards reporting — a withheld answer to an earlier prompt, under a
217
- * minute old, still ends the hold, which is the pre-#2463 exit rather than a
218
- * new failure.
219
- *
220
- * Issue #3798: a server that names the waiting episodes does what the push gate
221
- * does — the record's `episodeId` against the payload's
222
- * `autoYes.waitingEpisodeId`, which decide when both are present: another id
223
- * (or no wait open) is a record of an earlier wait, however recent; the same
224
- * id is this wait's. Either one missing (an older server, a record written
225
- * before any wait was open), this window decides as before. Whichever
226
- * decides, a record the server marks `lastSuppressionAnswered` — Auto-Yes
227
- * answered the open wait after it was written — is history, not this wait's
228
- * reason, as the push gate reads it: the hold goes on.
229
- */
230
- const SUPPRESSION_FRESH_MS = 60_000;
231
- /**
232
- * The suppression currently blocking this session, or null.
233
- *
234
- * Issue #3863: with the Auto-Yes answer mode in effect (`autoYesAnswerMode`)
235
- * when the server publishes one — what `question-left-to-human` and
236
- * `recommended-option-unidentified` depend on.
237
- */
238
- function activeSuppression(data, now) {
239
- // No `autoYes` at all (a session that is not running, Issue #3300) reads as
240
- // "nothing was withheld", the same as a null record.
241
- const suppression = data.autoYes?.lastSuppression;
242
- if (!suppression)
243
- return null;
244
- const ageMs = now - suppression.at;
245
- const waitId = data.autoYes?.waitingEpisodeId;
246
- if (suppression.episodeId !== undefined && waitId !== undefined) {
247
- if (suppression.episodeId !== waitId)
248
- return null;
249
- }
250
- else if (ageMs > SUPPRESSION_FRESH_MS) {
251
- // A negative age is clock skew between the CLI and the server, not staleness.
252
- return null;
253
- }
254
- if (data.autoYes?.lastSuppressionAnswered === true)
255
- return null;
256
- const answerMode = data.autoYesAnswerMode;
257
- return {
258
- suppression,
259
- ageSeconds: Math.max(0, Math.round(ageMs / 1000)),
260
- ...(answerMode !== undefined ? { answerMode } : {}),
261
- };
262
- }
263
- /** The wording for the four reasons a contract's `autoYes` block really authors. */
264
- const CONTRACT_POLICY_CAUSE = 'by contract policy';
265
- /**
266
- * What withheld the answer, in the words `wait` puts on stderr (Issue #1843).
267
- *
268
- * A Record over the whole reason union rather than one fixed phrase: adding a
269
- * reason to {@link AutoYesSuppressionReason} without deciding what `wait` should
270
- * say about it is a compile error here, which is the point. Until #1843 the
271
- * notice hard-coded "by contract policy" for every reason, so #1829's
272
- * `agent-launch-dialog` — a product-side decision the poller makes with no
273
- * contract in sight (`suppressIfNotOursToAnswer` in
274
- * `src/lib/polling/auto-yes-prompt-suppression.ts`: codex's lifecycle dialogs,
275
- * gemini's folder trust since #3776 and copilot's since #3790) — sent operators
276
- * of contract-less worktrees hunting for a `denyPatterns` entry that did not
277
- * exist.
278
- *
279
- * The three sites that record a suppression are covered: the poller's launch-dialog
280
- * branch (`agent-launch-dialog`), the poller's policy branch and
281
- * `lib/hooks/permission-decision-service.ts` (both the four `evaluatePolicyAgainstTexts`
282
- * verdicts, which is why those four keep the pre-#1843 wording exactly), and
283
- * the poller's stopped-answer branch (`partial-answer`, Issue #3706 / #3713),
284
- * and the poller's agy trust-screen branch (`startup-trust-unhandled`, Issue #3757),
285
- * and the poller's question confirm-page branch (`question-confirm-page`, Issue #3748),
286
- * and the poller's question branch (`question-left-to-human`, Issue #3822),
287
- * and the resolver's permission-row reading (`allow-once-unidentified`, Issue #3822),
288
- * and the resolver's choice of a question's recommended option
289
- * (`recommended-option-unidentified`, Issue #3863),
290
- * and the poller's agy receipt-gate branch (`no-hook-receipt`, Issue #3767),
291
- * and a contract lookup that failed on either of the policy paths
292
- * (`policy-lookup-failed`, Issue #3822).
293
- */
294
- const SUPPRESSION_CAUSE = {
295
- 'mode-off': CONTRACT_POLICY_CAUSE,
296
- 'deny-pattern': CONTRACT_POLICY_CAUSE,
297
- 'deny-pattern-unusable': CONTRACT_POLICY_CAUSE,
298
- 'type-not-allowed': CONTRACT_POLICY_CAUSE,
299
- // Issue #3822. Not "by contract policy": the contract could not be read at
300
- // all, so nothing it says was applied. Withheld rather than answered, since
301
- // the contract may state `off`; it clears once the server reads it again.
302
- 'policy-lookup-failed': 'because the server could not read the execution contract (the database lookup failed), so Auto-Yes does not answer until it can; check the server log for policy-lookup-failed',
303
- // Issue #3790: after the launch window the poller still leaves copilot's and
304
- // gemini's trust dialogs alone when the cursor is not on the safe row, and
305
- // nobody else answers them then.
306
- 'agent-launch-dialog': "while the agent's launch dialog was on screen; if it stays after the launch (copilot's cursor on 2. or 3., gemini's not on 1. Trust folder), answer it at the pane",
307
- // Issue #1924. Deliberately not "by contract policy": no contract was
308
- // consulted. The frame looked like a numbered list to the generic estimator
309
- // and like prose to the tool's own detector, and an operator who reads this
310
- // should go and look at the pane rather than at `denyPatterns`.
311
- 'unclassified-frame': 'because no tool-specific dialog detector recognised the frame',
312
- // Issue #3713 (#3706's reason). Not "by contract policy" either: an earlier
313
- // Auto-Yes answer was stopped with some of its keys already in the input, and
314
- // typing it again would append to them, so the prompt waits for a human.
315
- // Issue #3880: or a send of it (Auto-Yes's, or a person's that failed) ended
316
- // without tmux confirming it, and no key may be known to be there. The #3713
317
- // sentence is kept as it was and the other case follows it.
318
- 'partial-answer': "because an earlier answer left partial input; Auto-Yes is waiting for a human (or that answer's send could not be confirmed, so the input may hold it: check the pane, then answer; an answer that goes through releases the hold)",
319
- // Issue #3757. agy's startup folder-trust screen: the launch's to confirm, not
320
- // Auto-Yes's, and agy drew it after the launch window had ended.
321
- 'startup-trust-unhandled': "because agy's startup folder-trust confirmation is the launch's to answer, not Auto-Yes's; the next send confirms it once, or answer it at the pane",
322
- // Issue #3748. The AskUserQuestion confirm page (`Submit` / `Cancel`): the
323
- // tool's own reader recognised it, and `Submit` commits whatever stands as the
324
- // answers, so it waits for a human. Was recorded as `unclassified-frame`,
325
- // whose wording above says the opposite (nothing recognised the frame).
326
- 'question-confirm-page': "because the question's Submit/Cancel confirmation commits the answers as they stand, so Auto-Yes leaves it to a human",
327
- // Issue #3822. A question the agent asks the operator (an AskUserQuestion
328
- // picker, OpenCode V2's question form): Auto-Yes answers permissions only,
329
- // and no contract setting delegates the question. Issue #3863: since the
330
- // answer modes, that is the `careful` mode's rule (and OpenCode V2's form
331
- // under either mode); `answerMode=` on the line says which mode was on.
332
- 'question-left-to-human': 'because the agent is asking a question, and Auto-Yes answers permissions only (the careful answer mode, or a question form no mode answers); answer it at the pane (prompt --json, respond), or turn Auto-Yes on with --answer-mode recommended to have it pick the recommended option',
333
- // Issue #3822. A permission dialog none of whose rows allows this call only
334
- // (each saves a rule, changes the mode or denies), or two of which read so.
335
- // Auto-Yes never picks a row that outlives this call, so it waits for a human.
336
- 'allow-once-unidentified': 'because no single option of the permission dialog allows this call only (the others save a rule, change the permission mode, or deny); Auto-Yes does not pick those, so answer it at the pane (prompt --json, respond)',
337
- // Issue #3863. The recommended answer mode answers a question with its one
338
- // recommended option (else its default), and could not tell which that is.
339
- 'recommended-option-unidentified': "because the question's recommended option could not be told (two or more marked recommended, a title it could not tell from its description, a typed-text or multi-select answer); answer it at the pane (prompt --json, respond)",
340
- // Issue #3767. agy's approval dialog has no matching hook question (none, too
341
- // late, already on screen, or the hook stopped arriving). Not a contract verdict.
342
- // Issue #3789: nor one left unused — the last was spent on keys Auto-Yes sent,
343
- // and a dialog is still up past the grace — so "no unused question" covers both.
344
- 'no-hook-receipt': "because there is no unused agy hook permission question for this dialog (none arrived in time, or the last one was spent on keys that did not clear it); answer it yourself (auto-yes --disable, prompt --json, respond --expect-screen) or check hooks.json",
345
- };
346
- /**
347
- * {@link SUPPRESSION_CAUSE} for a reason that arrived over the wire.
348
- *
349
- * `reason` is a server-supplied string, so a server newer than this CLI can name
350
- * a reason the union does not have. Naming it verbatim is the only honest answer:
351
- * quietly folding an unknown reason into "by contract policy" is the same
352
- * misattribution #1843 exists to remove, just for a future reason instead of
353
- * `agent-launch-dialog`.
354
- */
355
- function suppressionCause(reason) {
356
- return Object.prototype.hasOwnProperty.call(SUPPRESSION_CAUSE, reason)
357
- ? SUPPRESSION_CAUSE[reason]
358
- : `for a reason this CLI does not recognise (${reason})`;
359
- }
360
- /**
361
- * One stderr line naming what is holding this prompt (Issue #1699).
362
- *
363
- * `wait` used to print only "Waiting for human response...", which reads the
364
- * same whether a human was always going to answer or whether Auto-Yes silently
365
- * refused to. That ambiguity is what let a deny pattern matching a finished turn
366
- * stall two workers unnoticed; the pattern and the reason code belong on screen.
367
- *
368
- * Issue #1843: the cause is chosen per reason rather than asserted. `reason=` is
369
- * in the payload either way, so the prefix is the only part that can lie — and it
370
- * did, for every non-contract suppression.
371
- */
372
- function formatSuppressionNotice(suppression, ageSeconds, answerMode) {
373
- const parts = [
374
- `reason=${suppression.reason}`,
375
- `mode=${suppression.mode ?? 'none'}`,
376
- `promptType=${suppression.promptType}`,
377
- ];
378
- if (suppression.pattern !== undefined) {
379
- parts.push(`pattern=${JSON.stringify(suppression.pattern)}`);
380
- }
381
- // Issue #3863: the Auto-Yes answer mode in effect, when the server says.
382
- if (answerMode !== undefined) {
383
- parts.push(`answerMode=${answerMode}`);
384
- }
385
- const cause = suppressionCause(suppression.reason);
386
- return ` auto-yes suppressed this prompt ${cause}: ${parts.join(' ')} (${ageSeconds}s ago)`;
387
- }
388
- /**
389
- * One stderr line saying Auto-Yes is off on this instance because the server
390
- * restarted (Issue #3730), or null.
391
- *
392
- * Only words: the prompt was going to be reported either way — an instance
393
- * whose grant the restart released is an instance with Auto-Yes off, and exit
394
- * 10 for it is exactly the hand-back it always was. What this adds is the WHY,
395
- * so a delegating agent re-enables Auto-Yes instead of guessing. A server
396
- * older than the reason sends none, and nothing is printed.
397
- *
398
- * The command it suggests names the instance this wait is about: without
399
- * `--instance`, `auto-yes --enable` arms the worktree's default primary, which
400
- * for an alias (or a non-default tool) is another instance — the waited-on one
401
- * would stay off while a grant went somewhere nobody asked for. The instance is
402
- * the resolved `--instance` when one was given, else the CLI tool the server
403
- * answered for (a primary's instance ID is its tool ID).
404
- *
405
- * @param instanceId - The resolved `--instance` of this wait, if any
406
- */
407
- function formatRestartReleaseNotice(worktreeId, data, instanceId) {
408
- if (data.autoYes?.enabled !== false || data.autoYes.stopReason !== 'server-restart')
409
- return null;
410
- const target = instanceId ?? data.cliToolId;
411
- const command = `commandmate auto-yes ${worktreeId} --enable${target ? ` --instance ${target}` : ''}`;
412
- return ` auto-yes was released by a server restart on ${worktreeId} (it is not turned back on ` +
413
- `automatically); re-enable it with \`${command}\` if this session should keep answering.`;
414
- }
415
- /**
416
- * One stderr line saying Auto-Yes pressed Enter on THIS prompt (Issue #3397), or
417
- * null when the record is absent or about another screen.
418
- *
419
- * The prompt is one CommandMate could not read (the window offers direct input
420
- * for it). `sent` — Auto-Yes confirmed whatever was selected; `no-effect` — the
421
- * same screen outlived the Enter, no second one was sent, and it is a human's
422
- * again. An outcome this CLI does not know is named verbatim (#1843's rule).
423
- * `currentPrompt` is the server's judgement that the record is about the
424
- * `promptData` of the same response, so an Enter sent to an earlier screen is
425
- * never reported against this one.
426
- */
427
- function formatEnterFallbackNotice(data, now) {
428
- const record = data.autoYes?.lastEnterFallback;
429
- if (!record || record.currentPrompt !== true)
430
- return null;
431
- const detail = `refusal=${record.refusalReason} promptType=${record.promptType}`;
432
- const ago = `(${Math.max(0, Math.round((now - record.at) / 1000))}s ago)`;
433
- if (record.outcome === 'sent') {
434
- return ` auto-yes sent Enter to this prompt (CommandMate could not read it): ${detail} ${ago}`;
435
- }
436
- if (record.outcome === 'no-effect') {
437
- return ` auto-yes sent Enter to this prompt, but the same screen is still up (no-effect); ` +
438
- `answer it in the terminal: ${detail} ${ago}`;
439
- }
440
- return ` auto-yes Enter record for this prompt: outcome=${record.outcome} ${detail} ${ago}`;
441
- }
442
- /**
443
- * Issue #3821: the server's own word that Auto-Yes left this prompt to a human
444
- * (`autoYesDecision.state === 'withheld'`) — `server-poller-inactive` when no
445
- * poller runs for the instance, or a stop the suppression record does not
446
- * carry. Read only when the server publishes the field; an older one leaves
447
- * `wait` holding as before.
448
- */
449
- function decisionWithheldReason(data) {
450
- const decision = data.autoYesDecision;
451
- if (decision?.state !== 'withheld')
452
- return null;
453
- return decision.reason ?? 'unknown';
454
- }
455
- /**
456
- * Whether this server publishes a real turn record (Issue #1930).
457
- *
458
- * `dialogPendingMaxMs` landed with the turn model and is set on every payload a
459
- * server of that vintage produces, so its presence is the version probe. A
460
- * *value* rather than a version string, for the reason #1924 gives for the
461
- * capability block: a payload that has to be interpreted by its sender's
462
- * version number is a payload nobody can read forward.
463
- *
464
- * The probe is needed because the two readings below disagree in exactly the
465
- * case that matters. On a #1930 server, `openedAt` being null while
466
- * `lastEventType` is `user_prompt_submit` means the turn was fenced off by a
467
- * generation or aged out — the server has *decided* it is not this instance's
468
- * turn. Falling back to the event on such a payload would put back the stale
469
- * adoption the turn record exists to remove.
470
- */
471
- function publishesTurnRecord(data) {
472
- return data.structuredEvents?.dialogPendingMaxMs != null;
473
- }
474
- /**
475
- * Adopt the turn this wait is about, if this poll shows one (Issue #1839,
476
- * moved onto the turn record in #1930).
477
- *
478
- * ## What changed, and why the grace window is no longer the whole guard
479
- *
480
- * Before #1930 this read `lastEventType` / `lastEventAt` — the newest event of
481
- * any kind — and refused anything older than {@link TURN_ADOPTION_GRACE_MS},
482
- * because (in the words of that constant) structured events "are NOT fenced by
483
- * generation on the way into `structuredEvents`", so a stale
484
- * `user_prompt_submit` from a previous agent process could still be the last
485
- * event on the wire. The bound was the only thing keeping such a record from
486
- * gating a wait for ever.
487
- *
488
- * The server fences the turn now, and publishes null when it does. So an **open**
489
- * turn is adopted whatever its age — which closes a hole the old reading had:
490
- * a turn that opened ten minutes before this `wait` started, and is still
491
- * running, used to be adopted only because its *newest* event was fresh. An
492
- * agent that goes quiet mid-turn (thinking, a long tool call) has no fresh
493
- * event, so the #1839 gate came down at exactly the moment a 529 storm would
494
- * exploit it.
495
- *
496
- * A **closed** turn still has to have opened inside this wait's window, and the
497
- * reason is the one the grace constant gives: `wait` does not know when `send`
498
- * ran, so the last turn of a session that finished an hour ago must not gate a
499
- * wait that has only just started. `commandmate wait` on an already-idle
500
- * session therefore adopts nothing and completes on its first poll, exactly as
501
- * it did before — #1975 measured that at 234/242/259 ms and it is the
502
- * orchestrator's normal path.
503
- *
504
- * @param previous - the turn start adopted so far, or null
505
- * @returns the newest adopted turn start, or `previous` when nothing qualified
506
- */
507
- function adoptTurnStart(data, waitStartedAt, previous) {
508
- const events = data.structuredEvents;
509
- if (!events)
510
- return previous;
511
- if (!publishesTurnRecord(data)) {
512
- // A server older than #1930. Same reading this function has had since
513
- // #1839, kept so a newer CLI pointed at an older server does not silently
514
- // lose the gate.
515
- if (events.lastEventAt == null || events.lastEventType == null)
516
- return previous;
517
- if (!exports.TURN_OPENING_EVENT_TYPES.has(events.lastEventType))
518
- return previous;
519
- if (events.lastEventAt < waitStartedAt - TURN_ADOPTION_GRACE_MS)
520
- return previous;
521
- return previous === null || events.lastEventAt > previous ? events.lastEventAt : previous;
522
- }
523
- const openedAt = events.openedAt;
524
- // Null covers every "there is no turn to adopt" case the server knows about:
525
- // nothing reported, a previous generation, aged out, or a `stop` whose
526
- // opening was never observed.
527
- if (openedAt == null)
528
- return previous;
529
- if (events.closedAt != null && openedAt < waitStartedAt - TURN_ADOPTION_GRACE_MS) {
530
- return previous;
531
- }
532
- return previous === null || openedAt > previous ? openedAt : previous;
533
- }
534
- /**
535
- * `structuredEvents.closedBy`, phrased for a diagnostic line (Issue #1930).
536
- *
537
- * The server's close-reason vocabulary and {@link COMPLETION_BASIS} answer two
538
- * different questions — "why did the turn end" and "what did `wait` decide on"
539
- * — and are deliberately printed side by side rather than folded together.
540
- * `hook_stop` is the only place they meet: it is `closedBy: 'stop'` seen from
541
- * the CLI's end. Everything else (`stale`, `scraper_evidence`, `session_end`,
542
- * `generation`, `resync_idle`) is a reason the turn stopped being trusted, which
543
- * is precisely what `wait` must NOT read as completion.
544
- */
545
- function describeTurnClose(data) {
546
- const events = data.structuredEvents;
547
- if (!events)
548
- return 'turn=unknown';
549
- const id = events.turnId ?? 'none';
550
- const closedBy = events.closedBy ?? (events.openedAt != null ? 'open' : 'none');
551
- return `turn=${id} closedBy=${closedBy}`;
552
- }
553
- /**
554
- * Whether the agent has reported the end of the turn this wait adopted
555
- * (Issue #1839).
556
- *
557
- * True when no turn was adopted at all, which is the whole of the unchanged
558
- * path: a session whose agent posts no hooks never adopts one, so every caller
559
- * on a machine without hook injection sees precisely the pre-#1839 behaviour.
560
- */
561
- function turnSettled(data, turnStartedAt) {
562
- if (turnStartedAt === null)
563
- return true;
564
- const stoppedAt = data.lastStopEventAt;
565
- return stoppedAt != null && stoppedAt >= turnStartedAt;
566
- }
567
- /**
568
- * The structured event that ends a turn (Issue #1975).
569
- *
570
- * The counterpart of {@link TURN_OPENING_EVENT_TYPES}, kept as a bare constant
571
- * because the vocabulary a source declares in `capabilities.supportedEvents` is
572
- * the wire's, not this build's: a tool that cannot say `stop` cannot release the
573
- * hold below, so asking for the word by name is the whole of the check.
574
- */
575
- const TURN_CLOSING_EVENT_TYPE = 'stop';
576
- /**
577
- * How long `wait` will hold a composer frame open for an agent that has been
578
- * handed a prompt it has not reported the end of (Issue #1975).
579
- *
580
- * The hold's *reason* is exact — see {@link outstandingPrompt} — so this is not
581
- * a settling window standing in for evidence. It is the bound the contract of
582
- * this Issue asks for: hooks are fail-open on every path, so a `Stop` that is
583
- * simply lost (the receiver was restarted, the machine-wide
584
- * `~/.copilot/settings.json` was rewritten by another server mid-session, the
585
- * 4-second curl in the hook timed out) must not turn `wait` into a command that
586
- * never returns. After this it completes on the frame alone, exactly as it did
587
- * before this Issue, and says so.
588
- *
589
- * 60s is the same dwell {@link UNCLASSIFIED_DWELL_MS} uses for the same job, and
590
- * it is ~55x the widest send-to-turn-open window measured for this Issue
591
- * (2026-08-22, copilot 1.0.80 against an isolated server: 0.04s / 0.75s / 0.88s
592
- * / 1.10s over four sends, the last of them a cold session start). `--timeout`
593
- * and `--stall-timeout` below 60s still win, as they do for the unclassified
594
- * dwell: this pre-empts long waits, it does not extend short ones.
595
- */
596
- const PENDING_PROMPT_HOLD_MS = 60_000;
597
- /**
598
- * Whether this tool's event source claims it can report both ends of a turn
599
- * (Issue #1975).
600
- *
601
- * The gate that keeps the hold below off every path it has no evidence for.
602
- * `structuredEvents.source.capabilities` is #1924's declaration, published to
603
- * the CLI already, and the compatibility source a tool with no implementation
604
- * gets (`src/lib/hooks/sources/legacy-relay.ts`) declares `supportedEvents: []`
605
- * — so a tool that posts no hooks answers `false` here and takes precisely the
606
- * pre-#1975 path. So does a server older than #1924, which sends no `source` at
607
- * all.
608
- *
609
- * Both words are required. Without a turn-opening word nothing would ever open
610
- * the turn this waits for; without `stop` nothing could ever close it, and the
611
- * hold would only ever end at its own bound.
612
- */
613
- function reportsTurnBoundaries(data) {
614
- const declared = data.structuredEvents?.source?.capabilities?.supportedEvents;
615
- if (!Array.isArray(declared))
616
- return false;
617
- return (declared.includes(TURN_CLOSING_EVENT_TYPE) &&
618
- declared.some(event => exports.TURN_OPENING_EVENT_TYPES.has(event)));
619
- }
620
- /**
621
- * The `stop` detail meaning "the agent ended its turn with its own background
622
- * work still running, and resumes by itself when that work finishes"
623
- * (Issue #2614).
624
- *
625
- * A copy of `SELF_RESUME_PENDING_DETAIL` in `src/lib/hooks/agent-event-types.ts`
626
- * for the reason {@link TURN_OPENING_EVENT_TYPES} is a copy: the CLI builds with
627
- * `"paths": {}`. `tests/unit/cli/commands/wait-self-resume-2614.test.ts` pins the
628
- * two together.
629
- */
630
- exports.SELF_RESUME_PENDING_DETAIL = 'self_resume_pending';
631
- /**
632
- * The capability a source declares when its `stop` can carry
633
- * {@link SELF_RESUME_PENDING_DETAIL} (Issue #2614).
634
- *
635
- * Read by name rather than through the mirrored type in `api-responses.ts`,
636
- * which predates it: `structuredEvents.source.capabilities` is published as the
637
- * source's whole declaration, so a newer server sends the key and an older one
638
- * simply does not.
639
- */
640
- exports.SELF_RESUME_CAPABILITY = 'stopReportsSelfResume';
641
- /**
642
- * How long `wait` holds a `stop` whose agent said it would resume by itself
643
- * (Issue #2614).
644
- *
645
- * Measured 2026-09-17 against antigravity 1.2.4: a `schedule` of 60 s closed the
646
- * turn, the agent woke 58 s after its `Stop` and did it again three more times,
647
- * and the real end came five minutes after the first `Stop` — which is where
648
- * `wait` had already reported `Completed (basis=hook_stop)` and started a
649
- * verification against a half-finished worktree. The wake is not something to
650
- * time: it is a `post_tool_use` that opens a new turn, and #1839's gate takes
651
- * over from there. What needs a bound is only the case where it never comes.
652
- *
653
- * A timer's own length is not on the wire (the `schedule` arguments reach the
654
- * permission receiver and stop there), and a command sent to the background has
655
- * no length at all, so the bound is the one the server already uses for the
656
- * same question the other way round: how long an open turn is trusted with
657
- * nothing heard (`TURN_STALE_AFTER_MS` in `src/lib/session/provisional-turn.ts`,
658
- * pinned equal by `wait-self-resume-2614.test.ts`). Every wake starts a new
659
- * `stop` and a new hold, so an agent that keeps rescheduling never reaches it.
660
- *
661
- * A constant, like {@link PENDING_PROMPT_HOLD_MS}: `--timeout` and
662
- * `--stall-timeout` below it still win.
663
- */
664
- exports.SELF_RESUME_HOLD_MS = 30 * 60 * 1000;
665
- /**
666
- * Whether this tool's event source can say, on its `stop`, that the agent will
667
- * resume by itself (Issue #2614).
668
- *
669
- * The same kind of gate as {@link reportsTurnBoundaries}, and it requires that
670
- * one too: the hold below is released by a turn-opening event, and a source
671
- * that cannot send one could only ever end the hold at its bound. A server that
672
- * predates the declaration answers `false`, and so does every source but the one
673
- * that writes the detail.
674
- */
675
- function reportsSelfResume(data) {
676
- const declared = data.structuredEvents?.source?.capabilities;
677
- return declared?.[exports.SELF_RESUME_CAPABILITY] === true && reportsTurnBoundaries(data);
678
- }
679
- /**
680
- * The instant of the `stop` this agent said it would resume from, or null
681
- * (Issue #2614).
682
- *
683
- * Non-null only while that `stop` is still the newest thing the agent has said.
684
- * The wake is a `post_tool_use` (antigravity reports the timer's own tool call
685
- * finishing when it fires), which replaces the displayed event and opens a new
686
- * turn, so this answers null from the first poll after it — and a later `stop`
687
- * is a different instant, which is how a hold knows it is about a new one.
688
- *
689
- * On a server that publishes a turn record the `stop` must also be what closed
690
- * that turn: a turn ended by `generation` or `session_end` belongs to a process
691
- * that is gone, and nothing it scheduled is going to wake anything.
692
- */
693
- function pendingSelfResumeStop(data) {
694
- if (!reportsSelfResume(data))
695
- return null;
696
- const events = data.structuredEvents;
697
- if (!events || events.lastEventType !== TURN_CLOSING_EVENT_TYPE)
698
- return null;
699
- if (events.lastEventDetail !== exports.SELF_RESUME_PENDING_DETAIL)
700
- return null;
701
- // `closedBy` is the server's close-reason vocabulary; `'stop'` there is the
702
- // agent's own `Stop`, the only close this hold is about.
703
- if (publishesTurnRecord(data) && events.closedBy !== 'stop')
704
- return null;
705
- return events.lastEventAt ?? null;
706
- }
707
- /**
708
- * When this (worktree, instance) was last handed a prompt (Issue #1975).
709
- *
710
- * `limit=1&unit=pairs` is "every row at or after the newest user message"
711
- * (src/lib/db/chat-db.ts), which is the smallest query that is *guaranteed* to
712
- * contain that message: plain `limit=1` returns the newest row of either role,
713
- * and for a turn the agent has already answered that row is the assistant's.
714
- *
715
- * Scoped the same way the poll above is: `--instance` when the caller named one,
716
- * otherwise the `cliToolId` the server resolved for that same poll. Asking
717
- * unscoped would let a message sent to claude decide a wait on codex.
718
- *
719
- * Never throws. An unreadable ledger is not evidence that nothing was sent, so
720
- * it is reported as such rather than as "nothing was sent" — the call site
721
- * degrades to the pre-#1975 behaviour instead of holding on a guess.
722
- */
723
- async function readNewestPromptAt(client, worktreeId, options, data) {
724
- const query = new URLSearchParams({ limit: '1', unit: 'pairs' });
725
- if (options.instance)
726
- query.set('instance', options.instance);
727
- else if (data.cliToolId)
728
- query.set('cliTool', data.cliToolId);
729
- try {
730
- const rows = await client.get(`/api/worktrees/${worktreeId}/messages?${query.toString()}`);
731
- let newest = null;
732
- for (const row of rows ?? []) {
733
- if (row.role !== 'user')
734
- continue;
735
- // ISO string on the wire (a JSON-serialized Date), so this is the only
736
- // place the two clocks meet — and both sides of the comparison below are
737
- // stamped by the server, so no CLI/server skew enters the verdict.
738
- const at = Date.parse(row.timestamp);
739
- if (Number.isNaN(at))
740
- continue;
741
- if (newest === null || at > newest)
742
- newest = at;
743
- }
744
- return { readable: true, submittedAt: newest };
745
- }
746
- catch (error) {
747
- console.error(`Note: could not read the message ledger for ${worktreeId} ` +
748
- `(${error instanceof Error ? error.message : String(error)}); ` +
749
- 'completion will be judged from the frame alone.');
750
- return { readable: false };
751
- }
752
- }
753
- /**
754
- * Whether the newest prompt this instance was handed is still unanswered
755
- * (Issue #1975).
756
- *
757
- * This is the distinction the whole Issue turns on, and it is a comparison of
758
- * two server-stamped facts rather than a timer:
759
- *
760
- * - **idle before this wait began** — the agent's `Stop` postdates the newest
761
- * prompt. Nothing is outstanding; `wait` completes on the first poll exactly
762
- * as it always has. An orchestrator waiting on a session that finished long
763
- * ago pays nothing.
764
- * - **`send` a moment ago** — the newest prompt postdates the last `Stop`
765
- * (or there has never been one). The agent has been given work and has not
766
- * reported finishing it, so a composer frame is "it has not started yet",
767
- * not "it is done".
768
- *
769
- * `wait` could not tell these apart before, because from `current-output` alone
770
- * they are the same payload: in both, the last thing the agent said was the
771
- * previous turn's `stop`, and `adoptTurnStart` adopts nothing. Measured against
772
- * copilot 1.0.80 on 2026-08-22, the window in which that is true after a send is
773
- * ~1s wide, and `wait`'s first poll is immediate — which is why the false
774
- * completions came back in 0.3s with `basis=scraper_ready`, 3 times in 5.
775
- *
776
- * The fast-turn case falls out of the same comparison rather than needing a rule
777
- * of its own: a turn that opens and closes between two polls leaves
778
- * `lastEventType: 'stop'` (so no turn is adopted) but a `stop` that postdates
779
- * the prompt — answered, and completed on the spot.
780
- */
781
- function outstandingPrompt(data, submittedAt) {
782
- const stoppedAt = data.lastStopEventAt;
783
- return stoppedAt == null || stoppedAt < submittedAt;
784
- }
785
113
  /**
786
114
  * How long `--on-prompt agent` holds a prompt the target's own Auto-Yes is
787
115
  * answering before reporting it anyway, in seconds (Issue #2463).
@@ -815,25 +143,6 @@ function parseGraceSeconds(raw) {
815
143
  const trimmed = raw.trim();
816
144
  return /^\d+$/.test(trimmed) ? Number(trimmed) : Number.NaN;
817
145
  }
818
- /**
819
- * Whether one more poll interval still lands inside `--timeout` and
820
- * `--stall-timeout` (Issue #2463).
821
- *
822
- * The Auto-Yes hold asks before it sleeps. Otherwise a caller whose deadline
823
- * lapses during the hold would hear 124 about a prompt it used to hear 10 about:
824
- * the hold is there to give Auto-Yes a chance to answer, not to turn an open
825
- * prompt into a timeout. The same two checks the top of {@link pollWorktree}'s
826
- * loop makes, one interval ahead.
827
- */
828
- function nextPollWithinDeadlines(options, startTime, lastActivityTime, now) {
829
- const nextPollAt = now + POLL_INTERVAL_MS;
830
- if (options.timeout && nextPollAt - startTime >= options.timeout * 1000)
831
- return false;
832
- if (options.stallTimeout && nextPollAt - lastActivityTime >= options.stallTimeout * 1000) {
833
- return false;
834
- }
835
- return true;
836
- }
837
146
  /**
838
147
  * The exit-10 payload for a prompt the detection layer parsed. `suppressed` is
839
148
  * {@link activeSuppression}'s reading of the same poll.
@@ -912,17 +221,18 @@ function buildSelectionListOutput(worktreeId, data) {
912
221
  * What `wait` says about a frame that stayed unclassified for the whole dwell
913
222
  * (Issue #1708): the stderr line, and the `question` of its exit-10 payload.
914
223
  */
915
- function describeUnclassifiedFrame(worktreeId, data, dwellMs) {
224
+ function describeUnclassifiedFrame(worktreeId, data, dwellMs, options) {
916
225
  const dwellSeconds = Math.round(dwellMs / 1000);
917
226
  return (`Unclassified interactive frame on ${worktreeId} for ${dwellSeconds}s ` +
918
227
  `(status=${data.sessionStatus ?? 'unknown'}/${data.sessionStatusReason ?? 'unknown'}). ` +
919
228
  `The detection layer could not parse it; inspect the raw pane with ` +
920
- `\`commandmate capture ${worktreeId} --pane\`.` +
229
+ // Issue #3982: the instance waited on, and enough of its pane for a dialog.
230
+ `\`${(0, follow_up_command_1.dialogCaptureCommand)(worktreeId, (0, wait_instance_1.waitCommandTarget)(options))}\`.` +
921
231
  // Issue #2095: the sidebar is exactly this frame's reason, and the
922
232
  // one recovery is a keystroke in the pane. Riding the message keeps
923
233
  // the exit-code table (10, `type: unclassified`) unchanged for every
924
234
  // caller that already branches on it.
925
- describePaneObstruction(data));
235
+ (0, wait_notices_1.describePaneObstruction)(data));
926
236
  }
927
237
  /** The exit-10 payload for a persistently unclassified frame (Issue #1708). */
928
238
  function buildUnclassifiedOutput(worktreeId, data, question) {
@@ -1004,9 +314,9 @@ function promptStage(poll, state, data) {
1004
314
  // Issue #1699: report a policy suppression on both exits — the human one
1005
315
  // keeps polling and would otherwise say nothing about why nobody
1006
316
  // answered, and the agent one is read by pipelines that never see stderr.
1007
- const suppressed = activeSuppression(data, Date.now());
317
+ const suppressed = (0, wait_notices_1.activeSuppression)(data, Date.now());
1008
318
  // Issue #3821: withheld by the server's decision, with no suppression to say so.
1009
- const decisionWithheld = suppressed ? null : decisionWithheldReason(data);
319
+ const decisionWithheld = suppressed ? null : (0, wait_notices_1.decisionWithheldReason)(data);
1010
320
  const decisionNotice = decisionWithheld === null
1011
321
  ? null
1012
322
  : ` auto-yes is not answering this prompt (reason=${decisionWithheld}); it is a human's to answer.`;
@@ -1015,16 +325,16 @@ function promptStage(poll, state, data) {
1015
325
  // Block and continue polling - user handles prompt manually
1016
326
  console.error(`Prompt detected on ${worktreeId}. Waiting for human response...`);
1017
327
  if (suppressed) {
1018
- console.error(formatSuppressionNotice(suppressed.suppression, suppressed.ageSeconds, suppressed.answerMode));
328
+ console.error((0, wait_notices_1.formatSuppressionNotice)(suppressed.suppression, suppressed.ageSeconds, suppressed.answerMode));
1019
329
  }
1020
330
  if (decisionNotice)
1021
331
  console.error(decisionNotice);
1022
332
  // Issue #3397: and whether Auto-Yes already pressed Enter on it.
1023
- const enterNotice = formatEnterFallbackNotice(data, Date.now());
333
+ const enterNotice = (0, wait_notices_1.formatEnterFallbackNotice)(data, Date.now());
1024
334
  if (enterNotice)
1025
335
  console.error(enterNotice);
1026
336
  // Issue #3730: and whether a restart is why nothing is answering it.
1027
- const restartNotice = formatRestartReleaseNotice(worktreeId, data, poll.options.instance);
337
+ const restartNotice = (0, wait_notices_1.formatRestartReleaseNotice)(worktreeId, data, poll.options.instance);
1028
338
  if (restartNotice)
1029
339
  console.error(restartNotice);
1030
340
  return { kind: 'wait' };
@@ -1047,7 +357,7 @@ function promptStage(poll, state, data) {
1047
357
  }
1048
358
  const heldMs = now - state.autoYesAnsweringSince;
1049
359
  if (heldMs < autoYesGraceMs &&
1050
- nextPollWithinDeadlines(options, startTime, state.lastActivityTime, now)) {
360
+ (0, wait_timing_1.nextPollWithinDeadlines)(options, startTime, state.lastActivityTime, now)) {
1051
361
  return { kind: 'wait' };
1052
362
  }
1053
363
  console.error(heldMs < autoYesGraceMs
@@ -1062,16 +372,16 @@ function promptStage(poll, state, data) {
1062
372
  // Default (agent mode): output prompt info and exit 10
1063
373
  const promptOutput = buildPromptOutput(worktreeId, data, data.promptData, suppressed);
1064
374
  if (suppressed) {
1065
- console.error(formatSuppressionNotice(suppressed.suppression, suppressed.ageSeconds, suppressed.answerMode));
375
+ console.error((0, wait_notices_1.formatSuppressionNotice)(suppressed.suppression, suppressed.ageSeconds, suppressed.answerMode));
1066
376
  }
1067
377
  if (decisionNotice)
1068
378
  console.error(decisionNotice);
1069
379
  // Issue #3397: stderr only, like the notice above; the exit-10 payload is unchanged.
1070
- const enterNotice = formatEnterFallbackNotice(data, Date.now());
380
+ const enterNotice = (0, wait_notices_1.formatEnterFallbackNotice)(data, Date.now());
1071
381
  if (enterNotice)
1072
382
  console.error(enterNotice);
1073
383
  // Issue #3730: stderr only as well.
1074
- const restartNotice = formatRestartReleaseNotice(worktreeId, data, poll.options.instance);
384
+ const restartNotice = (0, wait_notices_1.formatRestartReleaseNotice)(worktreeId, data, poll.options.instance);
1075
385
  if (restartNotice)
1076
386
  console.error(restartNotice);
1077
387
  return exitWith({ exitCode: types_1.WaitExitCode.PROMPT_DETECTED, output: promptOutput });
@@ -1091,18 +401,18 @@ function selectionListStage(poll, data) {
1091
401
  'Waiting for human response...');
1092
402
  // Issue #1699: the poller parses frames status-detector publishes as
1093
403
  // selection lists, so a policy can be the reason this one is stuck too.
1094
- const suppressed = activeSuppression(data, Date.now());
404
+ const suppressed = (0, wait_notices_1.activeSuppression)(data, Date.now());
1095
405
  if (suppressed) {
1096
- console.error(formatSuppressionNotice(suppressed.suppression, suppressed.ageSeconds, suppressed.answerMode));
406
+ console.error((0, wait_notices_1.formatSuppressionNotice)(suppressed.suppression, suppressed.ageSeconds, suppressed.answerMode));
1097
407
  }
1098
408
  // Issue #3730
1099
- const restartNotice = formatRestartReleaseNotice(worktreeId, data, poll.options.instance);
409
+ const restartNotice = (0, wait_notices_1.formatRestartReleaseNotice)(worktreeId, data, poll.options.instance);
1100
410
  if (restartNotice)
1101
411
  console.error(restartNotice);
1102
412
  return { kind: 'wait' };
1103
413
  }
1104
414
  // Issue #3730: stderr only; the exit-10 payload is unchanged.
1105
- const restartNotice = formatRestartReleaseNotice(worktreeId, data, poll.options.instance);
415
+ const restartNotice = (0, wait_notices_1.formatRestartReleaseNotice)(worktreeId, data, poll.options.instance);
1106
416
  if (restartNotice)
1107
417
  console.error(restartNotice);
1108
418
  return exitWith({
@@ -1159,9 +469,9 @@ function unclassifiedStage(poll, state, data) {
1159
469
  state.unclassifiedSince = Date.now();
1160
470
  const dwellMs = Date.now() - state.unclassifiedSince;
1161
471
  if (dwellMs >= UNCLASSIFIED_DWELL_MS) {
1162
- const question = describeUnclassifiedFrame(worktreeId, data, dwellMs);
472
+ const question = describeUnclassifiedFrame(worktreeId, data, dwellMs, poll.options);
1163
473
  // Issue #3730: why Auto-Yes is not there to answer it, if a restart is why.
1164
- const restartNotice = formatRestartReleaseNotice(worktreeId, data, poll.options.instance);
474
+ const restartNotice = (0, wait_notices_1.formatRestartReleaseNotice)(worktreeId, data, poll.options.instance);
1165
475
  if (options.onPrompt === 'human') {
1166
476
  console.error(question);
1167
477
  if (restartNotice)
@@ -1203,14 +513,25 @@ function notRunningStage(poll, state, data, selfResumeSuffix) {
1203
513
  return exitWith({ exitCode: types_1.VerifyExitCode.NOT_STARTED });
1204
514
  }
1205
515
  if (!data.isRunning) {
1206
- console.error(`Completed: ${worktreeId} (basis=${COMPLETION_BASIS.SESSION_GONE}${selfResumeSuffix()})`);
516
+ console.error(`Completed: ${worktreeId} (basis=${wait_turn_boundary_1.COMPLETION_BASIS.SESSION_GONE}${selfResumeSuffix()})`);
1207
517
  return exitWith({ exitCode: types_1.WaitExitCode.SUCCESS });
1208
518
  }
1209
519
  return { kind: 'next' };
1210
520
  }
521
+ /**
522
+ * The upstream fault on the frame that `--fail-on-upstream-fault` reports, or
523
+ * null (Issue #1839). Prints nothing, so a caller can decide which frame the
524
+ * verdict is on before {@link upstreamFaultStage} reports it (Issue #3956).
525
+ */
526
+ function reportableUpstreamFault(poll, data) {
527
+ if (!poll.options.failOnUpstreamFault)
528
+ return null;
529
+ return data.upstreamFault ?? null;
530
+ }
1211
531
  /**
1212
532
  * Stage of a `ready` frame: an upstream fault on the frame, under
1213
- * `--fail-on-upstream-fault` (Issue #1839). Exit 11.
533
+ * `--fail-on-upstream-fault` (Issue #1839). Exit 11, with its diagnosis on
534
+ * stderr.
1214
535
  */
1215
536
  function upstreamFaultStage(poll, data) {
1216
537
  const { worktreeId, options } = poll;
@@ -1219,8 +540,8 @@ function upstreamFaultStage(poll, data) {
1219
540
  // because it is the answer to the question that gate can only ask: the
1220
541
  // turn did not end, and this is why. Without it the same session runs
1221
542
  // to --timeout and reports 124, which says nothing about the cause.
1222
- const fault = data.upstreamFault ?? null;
1223
- if (options.failOnUpstreamFault && fault) {
543
+ const fault = reportableUpstreamFault(poll, data);
544
+ if (fault) {
1224
545
  console.error(`Upstream fault on ${worktreeId}: id=${fault.id} — the agent is back at its ` +
1225
546
  'composer with an upstream API failure on screen, so this turn did not run. ' +
1226
547
  `Matched: ${JSON.stringify(fault.matchedText)}`);
@@ -1237,6 +558,32 @@ function upstreamFaultStage(poll, data) {
1237
558
  }
1238
559
  return { kind: 'next' };
1239
560
  }
561
+ /**
562
+ * The chat-ledger read of a poll, bounded by `--timeout` / `--stall-timeout`
563
+ * (Issue #3974).
564
+ *
565
+ * On an ordinary poll, a ledger that does not answer in time ends the wait
566
+ * ({@link DeadlineReached} back to {@link deadlineStage}, exit 124), not
567
+ * "unreadable". On the frame a settle returned (`judgingSettledFrame`) it does
568
+ * not: that frame was read inside the deadlines and is judged even after them
569
+ * (#3956), so the ledger is reported unreadable and the frame decides alone —
570
+ * as {@link faultFrameHasStop} treats a ledger cut by the same deadlines.
571
+ */
572
+ async function readLedgerWithinDeadlines(poll, state, data, judgingSettledFrame) {
573
+ const { client, worktreeId, options, startTime } = poll;
574
+ try {
575
+ // Quiet when aborted: what the deadline leads to is said here (settled
576
+ // frame) or by deadlineStage (124), not "judged from the frame alone".
577
+ return await (0, wait_timing_1.readWithinDeadlines)(options, startTime, state.lastActivityTime, signal => (0, wait_turn_boundary_1.readNewestPromptAt)(client, worktreeId, options, data, signal, true));
578
+ }
579
+ catch (error) {
580
+ if (!judgingSettledFrame || !(error instanceof wait_timing_1.DeadlineReached))
581
+ throw error;
582
+ console.error(`Note: the message ledger for ${worktreeId} could not be read within --timeout/--stall-timeout; ` +
583
+ 'judging the settled frame alone.');
584
+ return { readable: false };
585
+ }
586
+ }
1240
587
  /**
1241
588
  * How long `wait` holds an orphan turn — see {@link releaseOrphanTurn} — before
1242
589
  * completing on the `Stop` that answered the newest prompt (Issue #3429).
@@ -1247,7 +594,7 @@ function upstreamFaultStage(poll, data) {
1247
594
  * is restarted by any change to the frame, so a pane that is still drawing is
1248
595
  * never released. `--timeout` and `--stall-timeout` below it still win.
1249
596
  */
1250
- const ORPHAN_TURN_HOLD_MS = PENDING_PROMPT_HOLD_MS;
597
+ const ORPHAN_TURN_HOLD_MS = wait_turn_boundary_1.PENDING_PROMPT_HOLD_MS;
1251
598
  /**
1252
599
  * Whether the unsettled turn this wait adopted is an orphan the agent will never
1253
600
  * send a `Stop` for, held for {@link ORPHAN_TURN_HOLD_MS} (Issue #3429).
@@ -1268,13 +615,13 @@ const ORPHAN_TURN_HOLD_MS = PENDING_PROMPT_HOLD_MS;
1268
615
  * prompt has no `Stop` after it — that one keeps holding to `--timeout`;
1269
616
  * - the frame has not changed for {@link ORPHAN_TURN_HOLD_MS}.
1270
617
  */
1271
- async function releaseOrphanTurn(poll, state, data) {
1272
- const { client, worktreeId, options } = poll;
618
+ async function releaseOrphanTurn(poll, state, data, judgingSettledFrame) {
619
+ const { worktreeId } = poll;
1273
620
  const events = data.structuredEvents;
1274
621
  const closedByScreen = events?.closedBy === 'scraper_evidence' || events?.closedBy === 'stale';
1275
622
  if (!events ||
1276
- !publishesTurnRecord(data) ||
1277
- !reportsTurnBoundaries(data) ||
623
+ !(0, wait_turn_boundary_1.publishesTurnRecord)(data) ||
624
+ !(0, wait_turn_boundary_1.reportsTurnBoundaries)(data) ||
1278
625
  events.closedAt == null ||
1279
626
  events.openedAt == null ||
1280
627
  !closedByScreen ||
@@ -1283,9 +630,10 @@ async function releaseOrphanTurn(poll, state, data) {
1283
630
  state.orphanTurnHold = null;
1284
631
  return false;
1285
632
  }
1286
- const ledger = await readNewestPromptAt(client, worktreeId, options, data);
633
+ // Issue #3974: bounded by --timeout / --stall-timeout.
634
+ const ledger = await readLedgerWithinDeadlines(poll, state, data, judgingSettledFrame);
1287
635
  state.promptLedgerReadable = ledger.readable;
1288
- if (!ledger.readable || ledger.submittedAt === null || outstandingPrompt(data, ledger.submittedAt)) {
636
+ if (!ledger.readable || ledger.submittedAt === null || (0, wait_turn_boundary_1.outstandingPrompt)(data, ledger.submittedAt)) {
1289
637
  state.orphanTurnHold = null;
1290
638
  return false;
1291
639
  }
@@ -1298,7 +646,7 @@ async function releaseOrphanTurn(poll, state, data) {
1298
646
  return false;
1299
647
  console.error(`Note: ${worktreeId} answered its newest prompt with a stop ` +
1300
648
  `(lastStopEventAt=${data.lastStopEventAt}), and the turn opened after it ` +
1301
- `(turnStartedAt=${state.turnStartedAt}, ${describeTurnClose(data)}) has had no prompt, ` +
649
+ `(turnStartedAt=${state.turnStartedAt}, ${(0, wait_turn_boundary_1.describeTurnClose)(data)}) has had no prompt, ` +
1302
650
  `no stop and no new output for ${Math.round(quietMs / 1000)}s; completing on that stop.`);
1303
651
  return true;
1304
652
  }
@@ -1306,7 +654,7 @@ async function releaseOrphanTurn(poll, state, data) {
1306
654
  * Stage of a `ready` frame: the agent has not reported the end of the turn this
1307
655
  * wait adopted (Issue #1839). Held, except for an orphan turn (Issue #3429).
1308
656
  */
1309
- async function unsettledTurnStage(poll, state, data) {
657
+ async function unsettledTurnStage(poll, state, data, judgingSettledFrame) {
1310
658
  const { worktreeId } = poll;
1311
659
  // Issue #1839: `ready` off the terminal frame is the agent's composer,
1312
660
  // not the agent's verdict. Measured 2026-08-20 against a stub upstream
@@ -1315,14 +663,14 @@ async function unsettledTurnStage(poll, state, data) {
1315
663
  // hooks ARE reporting — the only case in which `turnStartedAt` is
1316
664
  // non-null — that missing `Stop` is the difference between "finished"
1317
665
  // and "never ran", and it is the only signal that carries it.
1318
- if (!turnSettled(data, state.turnStartedAt)) {
1319
- if (await releaseOrphanTurn(poll, state, data))
666
+ if (!(0, wait_turn_boundary_1.turnSettled)(data, state.turnStartedAt)) {
667
+ if (await releaseOrphanTurn(poll, state, data, judgingSettledFrame))
1320
668
  return { kind: 'next' };
1321
669
  console.error(`Waiting: ${worktreeId} is back at its composer, but its agent has not reported ` +
1322
670
  `the end of this turn (turnStartedAt=${state.turnStartedAt}, ` +
1323
- `lastStopEventAt=${data.lastStopEventAt ?? 'none'}, ${describeTurnClose(data)}). ` +
671
+ `lastStopEventAt=${data.lastStopEventAt ?? 'none'}, ${(0, wait_turn_boundary_1.describeTurnClose)(data)}). ` +
1324
672
  'Not reporting completion; inspect with ' +
1325
- `\`commandmate capture ${worktreeId} --json\`.`);
673
+ `\`${(0, follow_up_command_1.followUpCommand)('capture', worktreeId, (0, wait_instance_1.waitCommandTarget)(poll.options), undefined, '--json')}\`.`);
1326
674
  return { kind: 'wait' };
1327
675
  }
1328
676
  return { kind: 'next' };
@@ -1352,13 +700,13 @@ function selfResumeHoldStage(poll, state, data, selfResumeStopAt) {
1352
700
  state.selfResumeHold = { stopAt: selfResumeStopAt, since: now };
1353
701
  const heldMs = now - state.selfResumeHold.since;
1354
702
  const elapsedMs = Math.max(heldMs, now - selfResumeStopAt);
1355
- if (elapsedMs < exports.SELF_RESUME_HOLD_MS) {
703
+ if (elapsedMs < wait_turn_boundary_1.SELF_RESUME_HOLD_MS) {
1356
704
  state.selfResumeHeld = true;
1357
705
  console.error(`Waiting: ${worktreeId} ended its turn with background work still running ` +
1358
706
  `(stoppedAt=${new Date(selfResumeStopAt).toISOString()}, ` +
1359
- `lastEventDetail=${exports.SELF_RESUME_PENDING_DETAIL}, ${describeTurnClose(data)}); ` +
707
+ `lastEventDetail=${wait_turn_boundary_1.SELF_RESUME_PENDING_DETAIL}, ${(0, wait_turn_boundary_1.describeTurnClose)(data)}); ` +
1360
708
  'it resumes by itself when that work finishes. Not reporting completion ' +
1361
- `(held ${Math.round(heldMs / 1000)}s, at most ${exports.SELF_RESUME_HOLD_MS / 1000}s ` +
709
+ `(held ${Math.round(heldMs / 1000)}s, at most ${wait_turn_boundary_1.SELF_RESUME_HOLD_MS / 1000}s ` +
1362
710
  'after the stop).');
1363
711
  return { kind: 'wait' };
1364
712
  }
@@ -1374,8 +722,8 @@ function selfResumeHoldStage(poll, state, data, selfResumeStopAt) {
1374
722
  * `next` carries whether the newest prompt was answered, which
1375
723
  * {@link completionStage} needs for its basis.
1376
724
  */
1377
- async function promptLedgerStage(poll, state, data) {
1378
- const { client, worktreeId, options, startTime } = poll;
725
+ async function promptLedgerStage(poll, state, data, judgingSettledFrame) {
726
+ const { worktreeId, pollStartedAt } = poll;
1379
727
  // Issue #1975: the same frame, one question further back. #1839's gate
1380
728
  // above can only fire once a turn has been ADOPTED, and `send` leaves a
1381
729
  // window ~1s wide in which nothing has been: the newest structured event
@@ -1393,18 +741,19 @@ async function promptLedgerStage(poll, state, data) {
1393
741
  // {@link reportsTurnBoundaries} for why a tool that posts no hooks never
1394
742
  // reaches it.
1395
743
  let answeredNewestPrompt = false;
1396
- if (state.turnStartedAt === null && state.promptLedgerReadable && reportsTurnBoundaries(data)) {
1397
- const ledger = await readNewestPromptAt(client, worktreeId, options, data);
744
+ if (state.turnStartedAt === null && state.promptLedgerReadable && (0, wait_turn_boundary_1.reportsTurnBoundaries)(data)) {
745
+ // Issue #3974: bounded by --timeout / --stall-timeout.
746
+ const ledger = await readLedgerWithinDeadlines(poll, state, data, judgingSettledFrame);
1398
747
  // One notice, then stop asking: a ledger that failed once will fail
1399
748
  // every poll, and the point of degrading is to stop paying for it.
1400
749
  state.promptLedgerReadable = ledger.readable;
1401
750
  if (ledger.readable && ledger.submittedAt !== null) {
1402
- if (outstandingPrompt(data, ledger.submittedAt)) {
1403
- const heldMs = Date.now() - startTime;
1404
- if (heldMs < PENDING_PROMPT_HOLD_MS) {
751
+ if ((0, wait_turn_boundary_1.outstandingPrompt)(data, ledger.submittedAt)) {
752
+ const heldMs = Date.now() - pollStartedAt;
753
+ if (heldMs < wait_turn_boundary_1.PENDING_PROMPT_HOLD_MS) {
1405
754
  console.error(`Waiting: ${worktreeId} is at its composer, but the newest prompt sent to it ` +
1406
755
  `has no reported end (sentAt=${new Date(ledger.submittedAt).toISOString()}, ` +
1407
- `lastStopEventAt=${data.lastStopEventAt ?? 'none'}, ${describeTurnClose(data)}). ` +
756
+ `lastStopEventAt=${data.lastStopEventAt ?? 'none'}, ${(0, wait_turn_boundary_1.describeTurnClose)(data)}). ` +
1408
757
  'Not reporting completion: the agent has not started this turn yet.');
1409
758
  return { kind: 'wait' };
1410
759
  }
@@ -1419,25 +768,34 @@ async function promptLedgerStage(poll, state, data) {
1419
768
  }
1420
769
  return { kind: 'next', answeredNewestPrompt };
1421
770
  }
771
+ /**
772
+ * The basis of a completion on a `ready` frame (Issue #1839).
773
+ *
774
+ * `hook_stop` on both branches that have one, and they are the same statement
775
+ * made from two records: the agent reported the end of the turn this wait is
776
+ * about. `scraper_ready` keeps its documented meaning — "the screen said so and
777
+ * nothing corroborated it" — which is now exactly the set of cases that reach it.
778
+ */
779
+ function readyCompletionBasis(state, answeredNewestPrompt) {
780
+ return state.turnStartedAt !== null || answeredNewestPrompt
781
+ ? wait_turn_boundary_1.COMPLETION_BASIS.HOOK_STOP
782
+ : wait_turn_boundary_1.COMPLETION_BASIS.SCRAPER_READY;
783
+ }
1422
784
  /** Last stage of a `ready` frame: the completion line with its basis. Exit 0. */
1423
785
  function completionStage(poll, state, answeredNewestPrompt, selfResumeSuffix) {
1424
786
  const { worktreeId } = poll;
1425
- // `hook_stop` on both branches that have one, and they are the same
1426
- // statement made from two records: the agent reported the end of the
1427
- // turn this wait is about. `scraper_ready` keeps its documented meaning
1428
- // — "the screen said so and nothing corroborated it" — which is now
1429
- // exactly the set of cases that reach it.
1430
- const basis = state.turnStartedAt !== null || answeredNewestPrompt
1431
- ? COMPLETION_BASIS.HOOK_STOP
1432
- : COMPLETION_BASIS.SCRAPER_READY;
787
+ const basis = readyCompletionBasis(state, answeredNewestPrompt);
1433
788
  console.error(`Completed: ${worktreeId} (basis=${basis}${selfResumeSuffix()})`);
1434
789
  return exitWith({ exitCode: types_1.WaitExitCode.SUCCESS });
1435
790
  }
1436
791
  /**
1437
792
  * Stage: the agent is back at its composer on a frame that was understood. Asks
1438
793
  * the stages of a `ready` frame in order; the first that applies decides.
794
+ *
795
+ * `judgingSettledFrame` is true when `data` is the frame a settle returned
796
+ * (Issue #3956): it is judged as it stands and never settled again.
1439
797
  */
1440
- async function readyStage(poll, state, data, selfResumeStopAt, selfResumeSuffix) {
798
+ async function readyStage(poll, state, data, selfResumeStopAt, selfResumeSuffix, judgingSettledFrame) {
1441
799
  // Issue #1708 narrowed Path B: `ready` is only a completion when the frame
1442
800
  // was actually understood. A structured `hook_stop` over an unreadable
1443
801
  // pane is the degraded form of an overlay nobody could parse (see the note
@@ -1445,18 +803,41 @@ async function readyStage(poll, state, data, selfResumeStopAt, selfResumeSuffix)
1445
803
  // merged. Path A is untouched — a session that went away really is
1446
804
  // finished, and carries no flag anyway.
1447
805
  if (data.sessionStatus === 'ready' && data.isUnclassifiedActive !== true) {
1448
- const faultOutcome = upstreamFaultStage(poll, data);
1449
- if (faultOutcome.kind !== 'next')
1450
- return faultOutcome;
1451
- const turnOutcome = await unsettledTurnStage(poll, state, data);
806
+ // Issue #3956: one bound for everything a `Stop` poll's settle waits on —
807
+ // the ledger read that confirms the `Stop` and the re-reads — measured
808
+ // from this poll, so the verdict comes at most HOOK_STOP_SETTLE_MAX_MS
809
+ // after it (`--timeout` is applied on top, where each wait is bounded).
810
+ const settleDeadline = Date.now() + wait_hook_stop_settle_1.HOOK_STOP_SETTLE_MAX_MS;
811
+ if (reportableUpstreamFault(poll, data) !== null) {
812
+ // Issue #3956: a fault on the frame of a `Stop` poll is on a pane that
813
+ // may still be drawing, as much as a clean one is; it is judged on the
814
+ // settled frame too. Without a `Stop` it is #1839's case, reported now.
815
+ // Nothing is printed before that is decided: the diagnosis is for the
816
+ // frame the verdict is on.
817
+ if (!judgingSettledFrame && (await (0, wait_hook_stop_settle_1.faultFrameHasStop)(poll, state, data, settleDeadline))) {
818
+ return { kind: 'settled', data: await (0, wait_hook_stop_settle_1.settleAfterHookStop)(poll, state, data, settleDeadline) };
819
+ }
820
+ return upstreamFaultStage(poll, data);
821
+ }
822
+ const turnOutcome = await unsettledTurnStage(poll, state, data, judgingSettledFrame);
1452
823
  if (turnOutcome.kind !== 'next')
1453
824
  return turnOutcome;
1454
825
  const holdOutcome = selfResumeHoldStage(poll, state, data, selfResumeStopAt);
1455
826
  if (holdOutcome.kind !== 'next')
1456
827
  return holdOutcome;
1457
- const ledgerOutcome = await promptLedgerStage(poll, state, data);
828
+ const ledgerOutcome = await promptLedgerStage(poll, state, data, judgingSettledFrame);
1458
829
  if (ledgerOutcome.kind !== 'next')
1459
830
  return ledgerOutcome;
831
+ // Issue #3956: the `Stop` can land before the end of the reply is on the
832
+ // pane, so a `hook_stop` completion is judged again on the settled frame —
833
+ // as a poll of its own, so a prompt or a new turn drawn meanwhile is not
834
+ // read as this completion. Only under the flag: a plain `wait` reads no
835
+ // fault and waits no longer.
836
+ if (!judgingSettledFrame &&
837
+ poll.options.failOnUpstreamFault &&
838
+ readyCompletionBasis(state, ledgerOutcome.answeredNewestPrompt) === wait_turn_boundary_1.COMPLETION_BASIS.HOOK_STOP) {
839
+ return { kind: 'settled', data: await (0, wait_hook_stop_settle_1.settleAfterHookStop)(poll, state, data, settleDeadline) };
840
+ }
1460
841
  return completionStage(poll, state, ledgerOutcome.answeredNewestPrompt, selfResumeSuffix);
1461
842
  }
1462
843
  return { kind: 'next' };
@@ -1476,7 +857,10 @@ async function readyStage(poll, state, data, selfResumeStopAt, selfResumeSuffix)
1476
857
  * {@link resolveWaitInstance}.
1477
858
  */
1478
859
  async function pollWorktree(client, worktreeId, options) {
1479
- const startTime = Date.now();
860
+ const pollStartedAt = Date.now();
861
+ // Issue #3983: `--timeout` counts from the command's start when the caller
862
+ // passed it, so the reads before this poll are inside the deadline.
863
+ const startTime = options.timeoutStartedAt ?? pollStartedAt;
1480
864
  const state = {
1481
865
  lastActivityTime: Date.now(),
1482
866
  lastContent: '',
@@ -1492,7 +876,15 @@ async function pollWorktree(client, worktreeId, options) {
1492
876
  };
1493
877
  const autoYesGraceSeconds = options.autoYesGrace ?? AUTO_YES_GRACE_DEFAULT_SECONDS;
1494
878
  const autoYesGraceMs = autoYesGraceSeconds * 1000;
1495
- const poll = { client, worktreeId, options, startTime, autoYesGraceSeconds, autoYesGraceMs };
879
+ const poll = {
880
+ client,
881
+ worktreeId,
882
+ options,
883
+ startTime,
884
+ pollStartedAt,
885
+ autoYesGraceSeconds,
886
+ autoYesGraceMs,
887
+ };
1496
888
  /**
1497
889
  * What the completion line adds when this wait held for a self-resume, or ''
1498
890
  * (Issue #2614). `basis=` keeps its word: the verdict is still the agent's own
@@ -1504,23 +896,34 @@ async function pollWorktree(client, worktreeId, options) {
1504
896
  const total = state.selfResumeHeldMs + (state.selfResumeHold ? Date.now() - state.selfResumeHold.since : 0);
1505
897
  return `, heldForSelfResume=${Math.round(total / 1000)}s`;
1506
898
  };
899
+ /**
900
+ * The frame a settle returned, judged as the next poll (Issue #3956). It was
901
+ * read inside the deadlines the settle kept to, so that poll does not ask
902
+ * {@link deadlineStage} again: a turn that completed in time is not a 124.
903
+ */
904
+ let settledFrame = null;
1507
905
  while (true) {
1508
- const deadlineOutcome = deadlineStage(poll, state);
1509
- if (deadlineOutcome.kind === 'exit')
1510
- return deadlineOutcome.result;
906
+ const judgingSettledFrame = settledFrame !== null;
907
+ if (!judgingSettledFrame) {
908
+ const deadlineOutcome = deadlineStage(poll, state);
909
+ if (deadlineOutcome.kind === 'exit')
910
+ return deadlineOutcome.result;
911
+ }
1511
912
  try {
1512
913
  // Issue #868: scope polling to a specific agent instance when provided.
1513
914
  // Issue #3755: `observe=1` so an exit 10 carries the observation of the
1514
915
  // very capture it was decided on (see {@link withObservation}).
1515
- const data = await client.get((0, prompt_1.observedCurrentOutputPath)(worktreeId, options.instance));
1516
- // Track content changes for stall detection
1517
- if (data.content !== state.lastContent) {
1518
- state.lastContent = data.content;
1519
- state.lastActivityTime = Date.now();
1520
- }
1521
- if (data.isRunning) {
1522
- state.everRunning = true;
1523
- }
916
+ const data = settledFrame ??
917
+ // Issue #3974: bounded by --timeout / --stall-timeout, so a server that
918
+ // does not answer cannot hold the wait past them.
919
+ (await (0, wait_timing_1.readWithinDeadlines)(options, startTime, state.lastActivityTime, signal => {
920
+ const path = (0, prompt_1.observedCurrentOutputPath)(worktreeId, options.instance);
921
+ return signal
922
+ ? client.get(path, { signal })
923
+ : client.get(path);
924
+ }));
925
+ settledFrame = null;
926
+ (0, wait_poll_bookkeeping_1.trackPollActivity)(state, data);
1524
927
  // Issue #3179: the agent is still launching. Work in progress, so keep
1525
928
  // polling: no prompt or selection list is read off the launch's frame,
1526
929
  // the unclassified dwell does not run, and a pane that does not exist yet
@@ -1529,220 +932,78 @@ async function pollWorktree(client, worktreeId, options) {
1529
932
  // completion. The server bounds the launch, so this cannot hold forever.
1530
933
  if (typeof data.startingSince === 'number') {
1531
934
  state.unclassifiedSince = null;
1532
- await sleep(POLL_INTERVAL_MS);
935
+ await (0, wait_timing_1.sleep)(wait_timing_1.POLL_INTERVAL_MS);
1533
936
  continue;
1534
937
  }
1535
- // Issue #1839: done before any exit path so the turn is adopted even on a
1536
- // poll that ends in a prompt — the same turn is still open when the human
1537
- // answers and `--on-prompt human` resumes polling.
1538
- state.turnStartedAt = adoptTurnStart(data, startTime, state.turnStartedAt);
938
+ (0, wait_poll_bookkeeping_1.adoptAndPublishTurn)(state, data, pollStartedAt, options);
1539
939
  // Issue #2614: a self-resume hold is about one `stop`, and ends the first
1540
940
  // time that `stop` is no longer the newest word — the agent woke (a
1541
941
  // turn-opening event) or stopped again. Checked on every poll, ahead of
1542
942
  // every exit, because the wake usually lands on a `running` frame that
1543
943
  // never reaches the hold itself.
1544
- const selfResumeStopAt = pendingSelfResumeStop(data);
1545
- if (state.selfResumeHold !== null && state.selfResumeHold.stopAt !== selfResumeStopAt) {
1546
- const heldMs = Date.now() - state.selfResumeHold.since;
1547
- state.selfResumeHeldMs += heldMs;
1548
- state.selfResumeHold = null;
1549
- console.error(`Note: ${worktreeId} has moved past the stop it said it would resume from ` +
1550
- `(held ${Math.round(heldMs / 1000)}s); judging its current state.`);
1551
- }
944
+ const selfResumeStopAt = (0, wait_turn_boundary_1.pendingSelfResumeStop)(data);
945
+ (0, wait_poll_bookkeeping_1.releaseMovedSelfResumeHold)(worktreeId, state, selfResumeStopAt);
1552
946
  const promptOutcome = promptStage(poll, state, data);
1553
947
  if (promptOutcome.kind === 'exit')
1554
948
  return withObservation(promptOutcome.result, data);
1555
949
  if (promptOutcome.kind === 'wait') {
1556
- await sleep(POLL_INTERVAL_MS);
950
+ await (0, wait_timing_1.sleep)(wait_timing_1.POLL_INTERVAL_MS);
1557
951
  continue;
1558
952
  }
1559
953
  // Issue #2463: the prompt the hold was waiting on has gone. Who answered it
1560
954
  // is not on the wire — Auto-Yes, or a human at the pane — so the line says
1561
955
  // only that it cleared; what the agent does next is for the checks below.
1562
- if (state.autoYesAnsweringSince !== null) {
1563
- console.error(`Prompt on ${worktreeId} cleared after ` +
1564
- `${Math.round((Date.now() - state.autoYesAnsweringSince) / 1000)}s; judging completion as usual.`);
1565
- state.autoYesAnsweringSince = null;
1566
- }
956
+ (0, wait_poll_bookkeeping_1.noteAutoYesPromptCleared)(worktreeId, state);
1567
957
  const selectionListOutcome = selectionListStage(poll, data);
1568
958
  if (selectionListOutcome.kind === 'exit')
1569
959
  return withObservation(selectionListOutcome.result, data);
1570
960
  if (selectionListOutcome.kind === 'wait') {
1571
- await sleep(POLL_INTERVAL_MS);
961
+ await (0, wait_timing_1.sleep)(wait_timing_1.POLL_INTERVAL_MS);
1572
962
  continue;
1573
963
  }
1574
964
  const unclassifiedOutcome = unclassifiedStage(poll, state, data);
1575
965
  if (unclassifiedOutcome.kind === 'exit')
1576
966
  return withObservation(unclassifiedOutcome.result, data);
1577
967
  if (unclassifiedOutcome.kind === 'wait') {
1578
- await sleep(POLL_INTERVAL_MS);
968
+ await (0, wait_timing_1.sleep)(wait_timing_1.POLL_INTERVAL_MS);
1579
969
  continue;
1580
970
  }
1581
971
  const notRunningOutcome = notRunningStage(poll, state, data, selfResumeSuffix);
1582
972
  if (notRunningOutcome.kind === 'exit')
1583
973
  return notRunningOutcome.result;
1584
- const readyOutcome = await readyStage(poll, state, data, selfResumeStopAt, selfResumeSuffix);
974
+ const readyOutcome = await readyStage(poll, state, data, selfResumeStopAt, selfResumeSuffix, judgingSettledFrame);
1585
975
  if (readyOutcome.kind === 'exit')
1586
976
  return readyOutcome.result;
977
+ if (readyOutcome.kind === 'settled') {
978
+ settledFrame = readyOutcome.data;
979
+ continue;
980
+ }
1587
981
  if (readyOutcome.kind === 'wait') {
1588
- await sleep(POLL_INTERVAL_MS);
982
+ // Issue #3974: the settled frame skipped deadlineStage, and its ledger
983
+ // read may have been cut by the deadline; ask it now rather than one
984
+ // interval late. With time left, the next poll comes as before.
985
+ if (judgingSettledFrame) {
986
+ const deadlineOutcome = deadlineStage(poll, state);
987
+ if (deadlineOutcome.kind === 'exit')
988
+ return deadlineOutcome.result;
989
+ }
990
+ await (0, wait_timing_1.sleep)(wait_timing_1.POLL_INTERVAL_MS);
1589
991
  continue;
1590
992
  }
1591
993
  // Progress indicator on stderr [DR1-05]
1592
994
  console.error(`Waiting: ${worktreeId} (status=${data.sessionStatus}, running=${data.isRunning}, prompt=${data.isPromptWaiting})`);
1593
995
  }
1594
996
  catch (error) {
997
+ // Issue #3974: a read ended by --timeout / --stall-timeout. Not a failed
998
+ // poll: straight back to deadlineStage, which exits 124.
999
+ if (error instanceof wait_timing_1.DeadlineReached)
1000
+ continue;
1595
1001
  if (error instanceof api_client_1.ApiError) {
1596
1002
  throw error;
1597
1003
  }
1598
1004
  console.error(`Poll error for ${worktreeId}: ${error instanceof Error ? error.message : String(error)}`);
1599
1005
  }
1600
- await sleep(POLL_INTERVAL_MS);
1601
- }
1602
- }
1603
- function sleep(ms) {
1604
- return new Promise(resolve => setTimeout(resolve, ms));
1605
- }
1606
- /** True when the caller asked for a verdict rather than "the agent stopped". */
1607
- function verifyRequested(options) {
1608
- return Boolean(options.verify || options.requireWork);
1609
- }
1610
- /**
1611
- * Whether this poll outcome should still be handed to the verification gates.
1612
- *
1613
- * A completion is the obvious case. NOT_STARTED joins it (Issue #1628) so the
1614
- * operator gets the gate results instead of a bare "no session": work committed
1615
- * by an agent whose session has since gone away is still worth reporting. The
1616
- * verdict is merged rather than substituted — mergeExitCode never lets a passing
1617
- * run overwrite NOT_STARTED, so "wait never saw this agent" survives to the exit
1618
- * code even when the gates are green.
1619
- */
1620
- function shouldVerify(exitCode, options) {
1621
- if (!verifyRequested(options))
1622
- return false;
1623
- return exitCode === types_1.WaitExitCode.SUCCESS || exitCode === types_1.VerifyExitCode.NOT_STARTED;
1624
- }
1625
- /**
1626
- * Task statuses that mean "this wait is about that task".
1627
- *
1628
- * Mirrors ACTIVE_TASK_STATUSES in src/lib/db/tasks-db.ts. Deliberately narrower
1629
- * than the set the server will attach a run to: this is a guess made from a
1630
- * worktree id alone, and a task that had already finished before the wait began
1631
- * is a different delegation, not this one.
1632
- */
1633
- const IN_FLIGHT_TASK_STATUSES = new Set([
1634
- 'running',
1635
- 'waiting_input',
1636
- 'verifying',
1637
- ]);
1638
- /**
1639
- * Read the task this wait is about, before waiting for it (Issue #1620).
1640
- *
1641
- * Timing is the whole point. Agents are asked to run the gates themselves
1642
- * before reporting completion, and doing so moves their task to a terminal
1643
- * status — after which a verification run started with only a worktree id has
1644
- * no contract to resolve, judges no scope, and still reports `passed`. Read
1645
- * while the task is still in flight, the id survives that transition and the
1646
- * run that follows is judged against the contract it was supposed to judge.
1647
- *
1648
- * Never throws: an unreadable ledger costs the attribution, and refusing to
1649
- * verify over it would cost every gate.
1650
- *
1651
- * @returns the task id, or undefined to leave resolution to the server
1652
- */
1653
- async function resolveWaitedTaskId(client, worktreeId) {
1654
- try {
1655
- const data = await client.get(`/api/worktrees/${worktreeId}/tasks?limit=1`);
1656
- const task = data?.tasks?.[0];
1657
- if (!task || !IN_FLIGHT_TASK_STATUSES.has(task.status))
1658
- return undefined;
1659
- return task.id;
1660
- }
1661
- catch (error) {
1662
- console.error(`Note: could not read the task ledger for ${worktreeId} ` +
1663
- `(${error instanceof Error ? error.message : String(error)}); ` +
1664
- 'verification will resolve its own task.');
1665
- return undefined;
1666
- }
1667
- }
1668
- /**
1669
- * Run verification for one worktree after its completion was detected.
1670
- *
1671
- * Swallows ApiError into an exit code: with several worktrees in flight, one
1672
- * unreachable run must not abort the verdicts of the others.
1673
- */
1674
- async function verifyAfterWait(client, worktreeId, options, taskId) {
1675
- // --verify runs every gate, and work-evidence is always part of "every gate",
1676
- // so combining it with --require-work is a superset rather than a conflict.
1677
- const gateIds = options.verify ? undefined : [verify_runner_1.WORK_EVIDENCE_GATE_ID];
1678
- try {
1679
- const outcome = await (0, verify_runner_1.runVerification)(client, {
1680
- worktreeId,
1681
- trigger: 'wait',
1682
- instanceId: options.instance,
1683
- taskId,
1684
- gateIds,
1685
- // stdout stays reserved for the prompt JSON contract.
1686
- resultStream: 'stderr',
1687
- });
1688
- return outcome.exitCode;
1689
- }
1690
- catch (error) {
1691
- if (error instanceof api_client_1.ApiError) {
1692
- console.error(`Error: ${error.message}`);
1693
- return error.exitCode;
1694
- }
1695
- console.error(`Error: verification of ${worktreeId} failed: ${error instanceof Error ? error.message : String(error)}`);
1696
- return types_1.ExitCode.UNEXPECTED_ERROR;
1697
- }
1698
- }
1699
- /**
1700
- * Fold one worktree's exit code into the aggregate.
1701
- *
1702
- * Ranked codes (see WAIT_EXIT_CODE_PRIORITY) beat unranked infrastructure
1703
- * codes, and among equals the first one observed stands.
1704
- */
1705
- function mergeExitCode(current, candidate) {
1706
- if (candidate === types_1.WaitExitCode.SUCCESS)
1707
- return current;
1708
- if (current === types_1.WaitExitCode.SUCCESS)
1709
- return candidate;
1710
- const rank = (code) => {
1711
- const index = types_1.WAIT_EXIT_CODE_PRIORITY.indexOf(code);
1712
- return index === -1 ? Number.MAX_SAFE_INTEGER : index;
1713
- };
1714
- return rank(candidate) < rank(current) ? candidate : current;
1715
- }
1716
- /**
1717
- * `options` with `--instance` resolved from a selector to an instance ID
1718
- * (Issue #2376).
1719
- *
1720
- * `wait` polls `/current-output?instance=`, which matches instance IDs and
1721
- * nothing else, so an alias that reached it would filter to no session and the
1722
- * wait would report on the worktree default instead — the exact silent
1723
- * wrong-session failure Issue #1638 catalogued for `--agent`.
1724
- *
1725
- * @param client - API client
1726
- * @param worktreeId - Worktree the selector is resolved against
1727
- * @param options - The options as given
1728
- */
1729
- async function resolveWaitInstance(client, worktreeId, options) {
1730
- if (!options.instance)
1731
- return options;
1732
- try {
1733
- const target = await (0, instances_1.resolveInstanceTarget)(client, worktreeId, options.instance, undefined);
1734
- return { ...options, instance: target.instanceId ?? options.instance };
1735
- }
1736
- catch (error) {
1737
- // Degrade to the pre-#2376 behaviour rather than failing the wait. An
1738
- // instance ID needs no resolution to reach `/current-output?instance=` —
1739
- // resolution exists here so that an ALIAS can — so a resolver that cannot
1740
- // be reached costs alias support for this call and nothing else. Failing
1741
- // instead would turn a reachable session into a non-zero exit for an
1742
- // orchestrator that has been waiting on it correctly for two years.
1743
- console.error(`Warning: could not resolve --instance '${options.instance}' `
1744
- + `(${(0, types_1.getErrorMessage)(error)}); using it as an instance id.`);
1745
- return options;
1006
+ await (0, wait_timing_1.sleep)(wait_timing_1.POLL_INTERVAL_MS);
1746
1007
  }
1747
1008
  }
1748
1009
  function createWaitCommand() {
@@ -1838,6 +1099,9 @@ The observation on exit 10 (Issue #3755):
1838
1099
  a missing record does not mean Auto-Yes can answer.
1839
1100
  `)
1840
1101
  .action(async (worktreeIds, options) => {
1102
+ // Issue #3983: `--timeout` is the deadline of the whole command, counted
1103
+ // from here — the reads before the poll included.
1104
+ const commandStartedAt = Date.now();
1841
1105
  try {
1842
1106
  // [SEC4-04] Validate all worktree IDs
1843
1107
  for (const id of worktreeIds) {
@@ -1860,34 +1124,42 @@ The observation on exit 10 (Issue #3755):
1860
1124
  return;
1861
1125
  }
1862
1126
  const client = new api_client_1.ApiClient({ token: options.token });
1127
+ // Issue #3983: the reads before the poll go through a client bounded by
1128
+ // `--timeout`; one that runs out ends the command with 124 before any
1129
+ // poll or verification. The poll bounds its own reads by the same
1130
+ // clock (`timeoutStartedAt`), and verification — after the wait, and
1131
+ // not part of it — keeps the unbounded `client`.
1132
+ const timeoutStartedAt = options.timeout ? commandStartedAt : undefined;
1133
+ const preflightClient = client.withDeadline(options.timeout ? commandStartedAt + options.timeout * 1000 : undefined);
1134
+ const pollOptions = (resolved) => timeoutStartedAt === undefined ? resolved : { ...resolved, timeoutStartedAt };
1863
1135
  // Issue #2376: resolve the selector PER worktree. `wait a b --instance
1864
1136
  // "Codex 2"` is one alias against two rosters, and the id behind it can
1865
1137
  // legitimately differ — resolving once and reusing the answer would poll
1866
1138
  // the wrong session on the second worktree.
1867
- const perWorktreeOptions = await Promise.all(worktreeIds.map(id => resolveWaitInstance(client, id, options)));
1139
+ const perWorktreeOptions = await Promise.all(worktreeIds.map(id => (0, wait_instance_1.resolveWaitInstance)(preflightClient, id, options)));
1868
1140
  // Issue #1620: resolved before any polling starts. Once the agent stops
1869
1141
  // there is no reliable way left to tell which contract this wait was
1870
1142
  // about — the agent's own verification may have closed it by then.
1871
- const boundTaskIds = verifyRequested(options)
1872
- ? await Promise.all(worktreeIds.map(id => resolveWaitedTaskId(client, id)))
1143
+ const boundTaskIds = (0, wait_verify_1.verifyRequested)(options)
1144
+ ? await Promise.all(worktreeIds.map(id => (0, wait_verify_1.resolveWaitedTaskId)(preflightClient, id)))
1873
1145
  : worktreeIds.map(() => undefined);
1874
1146
  if (worktreeIds.length === 1) {
1875
1147
  // Single worktree
1876
- const result = await pollWorktree(client, worktreeIds[0], perWorktreeOptions[0]);
1148
+ const result = await pollWorktree(client, worktreeIds[0], pollOptions(perWorktreeOptions[0]));
1877
1149
  if (result.output) {
1878
1150
  // stdout for result (JSON output)
1879
1151
  console.log(JSON.stringify(result.output));
1880
1152
  }
1881
1153
  // Issue #1544: only a detected completion is worth verifying — a
1882
1154
  // prompt or a timeout means the agent never claimed to be done.
1883
- const exitCode = shouldVerify(result.exitCode, options)
1884
- ? mergeExitCode(result.exitCode, await verifyAfterWait(client, worktreeIds[0], options, boundTaskIds[0]))
1155
+ const exitCode = (0, wait_verify_1.shouldVerify)(result.exitCode, options)
1156
+ ? (0, wait_verify_1.mergeExitCode)(result.exitCode, await (0, wait_verify_1.verifyAfterWait)(client, worktreeIds[0], options, boundTaskIds[0]))
1885
1157
  : result.exitCode;
1886
1158
  process.exit(exitCode);
1887
1159
  return;
1888
1160
  }
1889
1161
  // [DR1-07] Multiple worktrees: Promise.allSettled for error isolation
1890
- const results = await Promise.allSettled(worktreeIds.map((id, index) => pollWorktree(client, id, perWorktreeOptions[index])));
1162
+ const results = await Promise.allSettled(worktreeIds.map((id, index) => pollWorktree(client, id, pollOptions(perWorktreeOptions[index]))));
1891
1163
  // Collect results
1892
1164
  const outputs = [];
1893
1165
  let finalExitCode = types_1.WaitExitCode.SUCCESS;
@@ -1897,25 +1169,25 @@ The observation on exit 10 (Issue #3755):
1897
1169
  if (result.value.output) {
1898
1170
  outputs.push(result.value.output);
1899
1171
  }
1900
- if (shouldVerify(result.value.exitCode, options)) {
1172
+ if ((0, wait_verify_1.shouldVerify)(result.value.exitCode, options)) {
1901
1173
  verifyTargets.push({ id: worktreeIds[index], taskId: boundTaskIds[index] });
1902
1174
  // Issue #1628: fold NOT_STARTED in before verification so a green
1903
1175
  // gate run cannot promote "no session was ever running" to success.
1904
- finalExitCode = mergeExitCode(finalExitCode, result.value.exitCode);
1176
+ finalExitCode = (0, wait_verify_1.mergeExitCode)(finalExitCode, result.value.exitCode);
1905
1177
  return;
1906
1178
  }
1907
- finalExitCode = mergeExitCode(finalExitCode, result.value.exitCode);
1179
+ finalExitCode = (0, wait_verify_1.mergeExitCode)(finalExitCode, result.value.exitCode);
1908
1180
  }
1909
1181
  else {
1910
1182
  const err = result.reason;
1911
- finalExitCode = mergeExitCode(finalExitCode, err instanceof api_client_1.ApiError ? err.exitCode : types_1.ExitCode.UNEXPECTED_ERROR);
1183
+ finalExitCode = (0, wait_verify_1.mergeExitCode)(finalExitCode, err instanceof api_client_1.ApiError ? err.exitCode : types_1.ExitCode.UNEXPECTED_ERROR);
1912
1184
  }
1913
1185
  });
1914
1186
  // Issue #1544: serial on purpose. The server caps concurrent runs
1915
1187
  // process-wide, so firing them together only queues them behind each
1916
1188
  // other while every gate competes for the same machine.
1917
1189
  for (const target of verifyTargets) {
1918
- finalExitCode = mergeExitCode(finalExitCode, await verifyAfterWait(client, target.id, options, target.taskId));
1190
+ finalExitCode = (0, wait_verify_1.mergeExitCode)(finalExitCode, await (0, wait_verify_1.verifyAfterWait)(client, target.id, options, target.taskId));
1919
1191
  }
1920
1192
  if (outputs.length > 0) {
1921
1193
  console.log(JSON.stringify(outputs));