commandmate 0.44.1 → 0.44.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 (313) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +159 -159
  3. package/.next/app-path-routes-manifest.json +32 -32
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +12 -12
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/capabilities/route.js +1 -1
  17. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  18. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/hooks/agent-event/route.js +2 -2
  26. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  27. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/hooks/claude-done/route.js +2 -2
  29. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  30. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  32. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  33. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
  40. package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
  41. package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/relays/route.js +1 -1
  43. package/.next/server/app/api/relays/route.js.nft.json +1 -1
  44. package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  48. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  49. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/repositories/clone/route.js +1 -1
  51. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  52. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/repositories/restore/route.js +1 -1
  55. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  56. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/repositories/route.js +1 -1
  58. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  59. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/repositories/scan/route.js +1 -1
  61. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  62. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/repositories/sync/route.js +1 -1
  64. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  65. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/settings/default-agents/route.js +1 -1
  68. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  69. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  72. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  76. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  85. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  86. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  88. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  89. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  91. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  92. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  97. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  98. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
  100. package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
  101. package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  113. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  132. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  135. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  138. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -2
  147. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -1
  148. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -2
  150. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -1
  151. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  154. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  158. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  161. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  168. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +3 -3
  170. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  171. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  179. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  182. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/tasks/route.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/terminal/route.js +2 -2
  186. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  187. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  191. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/verify/config/route.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  199. package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  203. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  206. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/api/worktrees/route.js +1 -1
  208. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  209. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  211. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  212. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  213. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  214. package/.next/server/app/page_client-reference-manifest.js +1 -1
  215. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  217. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  218. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  219. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  220. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  221. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  222. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  223. package/.next/server/app/worktrees/[id]/page.js +9 -9
  224. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  225. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  226. package/.next/server/app-paths-manifest.json +32 -32
  227. package/.next/server/chunks/1068.js +1 -1
  228. package/.next/server/chunks/1210.js +1 -1
  229. package/.next/server/chunks/2460.js +1 -0
  230. package/.next/server/chunks/2908.js +1 -0
  231. package/.next/server/chunks/4372.js +5 -0
  232. package/.next/server/chunks/5595.js +1 -0
  233. package/.next/server/chunks/5845.js +1 -0
  234. package/.next/server/chunks/6130.js +1 -1
  235. package/.next/server/chunks/6401.js +1 -1
  236. package/.next/server/chunks/6474.js +2 -2
  237. package/.next/server/chunks/850.js +1 -0
  238. package/.next/server/chunks/8543.js +1 -1
  239. package/.next/server/chunks/8728.js +2 -2
  240. package/.next/server/chunks/9130.js +1 -5
  241. package/.next/server/chunks/9390.js +1 -2
  242. package/.next/server/chunks/9627.js +1 -1
  243. package/.next/server/chunks/967.js +1 -1
  244. package/.next/server/chunks/9731.js +2 -2
  245. package/.next/server/chunks/9798.js +2 -0
  246. package/.next/server/chunks/9882.js +3 -3
  247. package/.next/server/middleware-manifest.json +5 -5
  248. package/.next/server/pages/500.html +1 -1
  249. package/.next/server/server-reference-manifest.json +1 -1
  250. package/.next/static/chunks/{2407-f1f258d4a1d92620.js → 2407-051f6f84226a9f2c.js} +1 -1
  251. package/.next/static/chunks/591-539fec878c9dec5e.js +1 -0
  252. package/.next/static/chunks/app/{layout-da66300cc20244ed.js → layout-9da1ab602bcb3051.js} +1 -1
  253. package/.next/static/chunks/app/worktrees/[id]/page-2a81397e60f17e63.js +1 -0
  254. package/.next/trace +13 -13
  255. package/dist/cli/commands/capture.d.ts.map +1 -1
  256. package/dist/cli/commands/capture.js +7 -8
  257. package/dist/cli/commands/wait.d.ts.map +1 -1
  258. package/dist/cli/commands/wait.js +36 -2
  259. package/dist/cli/types/api-responses.d.ts +15 -0
  260. package/dist/cli/types/api-responses.d.ts.map +1 -1
  261. package/dist/lib/session/prompt-view.d.ts +205 -0
  262. package/dist/lib/session/prompt-view.d.ts.map +1 -0
  263. package/dist/lib/session/prompt-view.js +267 -0
  264. package/dist/server/server.js +5 -3
  265. package/dist/server/src/lib/auto-yes-lifecycle.js +133 -0
  266. package/dist/server/src/lib/auto-yes-poller.js +19 -4
  267. package/dist/server/src/lib/cli-tools/antigravity.js +1 -1
  268. package/dist/server/src/lib/detection/cli-patterns.js +38 -20
  269. package/dist/server/src/lib/detection/status-detector.js +1 -1
  270. package/dist/server/src/lib/detection/tools/antigravity/detect.js +7 -31
  271. package/dist/server/src/lib/detection/tools/antigravity/live-region.js +39 -0
  272. package/dist/server/src/lib/detection/tools/claude/detect.js +8 -3
  273. package/dist/server/src/lib/detection/tools/claude/live-region.js +26 -0
  274. package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +1 -1
  275. package/dist/server/src/lib/detection/tools/codex/detect.js +26 -46
  276. package/dist/server/src/lib/detection/tools/codex/live-region.js +73 -0
  277. package/dist/server/src/lib/detection/tools/command-code/detect.js +11 -0
  278. package/dist/server/src/lib/detection/tools/command-code/live-region.js +36 -0
  279. package/dist/server/src/lib/detection/tools/copilot/detect.js +3 -0
  280. package/dist/server/src/lib/detection/tools/copilot/live-region.js +52 -0
  281. package/dist/server/src/lib/detection/tools/frame.js +36 -2
  282. package/dist/server/src/lib/detection/tools/live-region-specs.js +31 -0
  283. package/dist/server/src/lib/detection/tools/live-region.js +204 -0
  284. package/dist/server/src/lib/detection/tools/opencode/detect.js +3 -0
  285. package/dist/server/src/lib/detection/tools/opencode/live-region.js +24 -0
  286. package/dist/server/src/lib/detection/tools/opencode-gutter-live-region.js +72 -0
  287. package/dist/server/src/lib/detection/tools/opencode-v2/detect.js +3 -0
  288. package/dist/server/src/lib/detection/tools/opencode-v2/live-region.js +24 -0
  289. package/dist/server/src/lib/detection/tools/run-detection.js +25 -3
  290. package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +16 -4
  291. package/dist/server/src/lib/polling/response-checker.js +25 -20
  292. package/dist/server/src/lib/prompt-answer-sender.js +1 -1
  293. package/dist/server/src/lib/realtime/terminal-broadcast.js +3 -0
  294. package/dist/server/src/lib/relay/relay-delivery.js +3 -0
  295. package/dist/server/src/lib/relay/relay-triggers.js +9 -0
  296. package/dist/server/src/lib/resource-cleanup.js +6 -4
  297. package/dist/server/src/lib/session/current-output-builder.js +4 -0
  298. package/dist/server/src/lib/session/prompt-view.js +267 -0
  299. package/dist/server/src/lib/session/prompt-waiting-composition.js +34 -0
  300. package/dist/server/src/lib/session/waiting-kind.js +3 -0
  301. package/dist/server/src/lib/session-cleanup.js +5 -3
  302. package/package.json +1 -1
  303. package/release-notes/0.44.2.json +33 -0
  304. package/.next/server/chunks/434.js +0 -1
  305. package/.next/server/chunks/5775.js +0 -1
  306. package/.next/server/chunks/650.js +0 -1
  307. package/.next/server/chunks/6661.js +0 -1
  308. package/.next/server/chunks/8583.js +0 -1
  309. package/.next/server/chunks/964.js +0 -1
  310. package/.next/static/chunks/591-308072f285c34787.js +0 -1
  311. package/.next/static/chunks/app/worktrees/[id]/page-040c5f0f585e6812.js +0 -1
  312. /package/.next/static/{57lOiz8zSEHdw97XIm0af → QlCqLjorauDDBXPa-C7TK}/_buildManifest.js +0 -0
  313. /package/.next/static/{57lOiz8zSEHdw97XIm0af → QlCqLjorauDDBXPa-C7TK}/_ssgManifest.js +0 -0
@@ -0,0 +1,267 @@
1
+ "use strict";
2
+ /**
3
+ * How a waiting prompt is shown and answered, decided once (Issue #3184).
4
+ *
5
+ * Before this module every reader of a prompt payload re-derived the same three
6
+ * facts for itself — "can it be answered?", "where are the choices?", "is the
7
+ * answer a keystroke or an API call?" — from `type`, `options`,
8
+ * `decisionOptions`, `decisionId` and `askUserQuestion`. The panel, the phone
9
+ * sheet, the chat surface, Auto-Yes and `wait` each combined them a little
10
+ * differently, and a fix to one surface kept missing the others (#2775 →
11
+ * #2810 → #2822, #3181). {@link derivePromptView} is the one combination; a
12
+ * reader takes its {@link PromptView} and does not look at the raw fields to
13
+ * decide what to show.
14
+ *
15
+ * ## No imports, on purpose
16
+ *
17
+ * The CLI (`tsconfig.cli.json`) compiles with `"paths": {}`, so it can reach a
18
+ * module under `src/lib` by a relative path only when nothing in that module's
19
+ * graph uses the `@/` alias. `types/models` and `session/structured-prompt` both
20
+ * do. The input is therefore a structural type ({@link PromptViewSource}) that
21
+ * every existing prompt shape — `LivePromptData`, `StoredPromptData`, the CLI's
22
+ * own `PromptData` mirror — satisfies without a cast, and this file stays
23
+ * importable from a client component, the server and the CLI alike.
24
+ *
25
+ * ## What it does not replace
26
+ *
27
+ * `isAnswerablePromptData()` (`types/models`) stays: it narrows to the closed
28
+ * `PromptData` union (#1725) for the code that builds an answer body. The two
29
+ * agree by construction — `derivePromptView(x)?.kind === 'screen-choices'`
30
+ * exactly when `isAnswerablePromptData(x)` — and
31
+ * `tests/unit/session/prompt-view-3184.test.ts` holds that over every fixture.
32
+ *
33
+ * @module lib/session/prompt-view
34
+ */
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.TYPED_TEXT_FIELD_LABEL_PATTERNS = exports.UNCLASSIFIED_PROMPT_VIEW_TYPE = void 0;
37
+ exports.promptHeadingMessage = promptHeadingMessage;
38
+ exports.optionTakesTypedText = optionTakesTypedText;
39
+ exports.readDecisionId = readDecisionId;
40
+ exports.readQuestionChoices = readQuestionChoices;
41
+ exports.readDecisionHeading = readDecisionHeading;
42
+ exports.derivePromptView = derivePromptView;
43
+ exports.readPromptView = readPromptView;
44
+ /**
45
+ * `promptData.type` for a frame nothing could classify. Same value as
46
+ * `UNCLASSIFIED_PROMPT_TYPE` in `types/models`, restated because this module may
47
+ * not import it (see the module note); the test asserts the two are equal.
48
+ */
49
+ exports.UNCLASSIFIED_PROMPT_VIEW_TYPE = 'unclassified';
50
+ function promptHeadingMessage(heading) {
51
+ switch (heading.kind) {
52
+ case 'question':
53
+ return { text: heading.text };
54
+ case 'approval':
55
+ return heading.toolName
56
+ ? { key: 'structuredApprovalTitle', values: { toolName: heading.toolName } }
57
+ : { key: 'structuredApprovalTitleNoTool' };
58
+ case 'agent-question':
59
+ return { key: 'structuredQuestionTitle' };
60
+ case 'unreadable':
61
+ return { key: 'unclassifiedTitle' };
62
+ }
63
+ }
64
+ // =============================================================================
65
+ // Field readers (moved from components/worktree/prompt-decision-id, #1932/#2039/#3181)
66
+ // =============================================================================
67
+ /**
68
+ * The option labels measured to be a text field on screen (Issue #2573).
69
+ * Restated from `TYPED_TEXT_FIELD_LABEL_PATTERNS` in
70
+ * `lib/detection/prompt-detect-multiple-choice`, whose graph reaches `fs`.
71
+ */
72
+ exports.TYPED_TEXT_FIELD_LABEL_PATTERNS = [
73
+ /^[^\S\n]*type\s+something\b/i,
74
+ ];
75
+ /**
76
+ * Whether an option is a text field on screen, so its answer is the typed TEXT
77
+ * rather than its number (Issue #2573). `requiresTextInput` alone is also true
78
+ * for a menu row such as `No, tell Command Code what to do differently`.
79
+ */
80
+ function optionTakesTypedText(option) {
81
+ return option.requiresTextInput === true
82
+ && exports.TYPED_TEXT_FIELD_LABEL_PATTERNS.some((pattern) => pattern.test(option.label));
83
+ }
84
+ /**
85
+ * The decision id a payload names, or null (Issue #1932). A validating read:
86
+ * absent, empty or not a string is "no addressable decision".
87
+ */
88
+ function readDecisionId(source) {
89
+ if (!source)
90
+ return null;
91
+ const candidate = source.decisionId;
92
+ return typeof candidate === 'string' && candidate !== '' ? candidate : null;
93
+ }
94
+ function hasDecisionOptions(source) {
95
+ return Array.isArray(source.decisionOptions) && source.decisionOptions.length > 0;
96
+ }
97
+ /**
98
+ * The choices a question offers when it may be answered over the API, or null
99
+ * (Issue #2039). All three must hold: a decision id, exactly one question with
100
+ * a complete label list, and NO approval verdicts on the same payload.
101
+ */
102
+ function readQuestionChoices(source) {
103
+ if (!source || readDecisionId(source) === null)
104
+ return null;
105
+ if (hasDecisionOptions(source))
106
+ return null;
107
+ const asked = source.askUserQuestion;
108
+ if (!asked || typeof asked.question !== 'string' || asked.question === '')
109
+ return null;
110
+ if (!Array.isArray(asked.labels) || asked.labels.length === 0)
111
+ return null;
112
+ const labels = asked.labels.filter((label) => typeof label === 'string' && label !== '');
113
+ // Partial is worse than none: the numbers are positions in this list.
114
+ if (labels.length !== asked.labels.length)
115
+ return null;
116
+ const questionCount = typeof asked.questionCount === 'number' ? asked.questionCount : 1;
117
+ if (questionCount !== 1)
118
+ return null;
119
+ return {
120
+ question: asked.question,
121
+ labels,
122
+ questionCount,
123
+ ...(asked.custom === true ? { custom: true } : {}),
124
+ };
125
+ }
126
+ /** The heading for addressable choices, or null when there is nothing to click (#3181). */
127
+ function readDecisionHeading(source) {
128
+ if (!source || readDecisionId(source) === null)
129
+ return null;
130
+ if (hasDecisionOptions(source)) {
131
+ return {
132
+ kind: 'approval',
133
+ toolName: typeof source.toolName === 'string' && source.toolName ? source.toolName : null,
134
+ };
135
+ }
136
+ return readQuestionChoices(source) ? { kind: 'question' } : null;
137
+ }
138
+ // =============================================================================
139
+ // The view
140
+ // =============================================================================
141
+ function screenChoices(source) {
142
+ const options = Array.isArray(source.options) ? source.options : [];
143
+ const choices = [];
144
+ for (const option of options) {
145
+ if (typeof option === 'string') {
146
+ // yes_no: `['yes', 'no']`, answered by the word itself.
147
+ choices.push({
148
+ answer: option,
149
+ label: option,
150
+ isDefault: source.defaultOption === option,
151
+ takesText: false,
152
+ });
153
+ continue;
154
+ }
155
+ if (!option || typeof option !== 'object')
156
+ continue;
157
+ const o = option;
158
+ if (typeof o.number !== 'number' || typeof o.label !== 'string')
159
+ continue;
160
+ choices.push({
161
+ answer: String(o.number),
162
+ label: o.label,
163
+ isDefault: o.isDefault === true,
164
+ takesText: optionTakesTypedText({ label: o.label, requiresTextInput: o.requiresTextInput === true }),
165
+ ...(typeof o.description === 'string' ? { description: o.description } : {}),
166
+ });
167
+ }
168
+ return choices;
169
+ }
170
+ function decisionChoices(decisionOptions) {
171
+ if (!Array.isArray(decisionOptions))
172
+ return [];
173
+ const choices = [];
174
+ for (const option of decisionOptions) {
175
+ const o = option;
176
+ if (!o || typeof o.number !== 'number' || typeof o.label !== 'string')
177
+ continue;
178
+ choices.push({ answer: String(o.number), label: o.label, isDefault: false, takesText: false });
179
+ }
180
+ return choices;
181
+ }
182
+ const UNREADABLE_VIEW = {
183
+ kind: 'unreadable',
184
+ heading: { kind: 'unreadable' },
185
+ choices: [],
186
+ multiSelect: false,
187
+ freeText: null,
188
+ decisionId: null,
189
+ apiTarget: null,
190
+ };
191
+ /**
192
+ * Decide how a prompt payload is shown and answered (Issue #3184).
193
+ *
194
+ * Evaluated in this order (design §2.3):
195
+ * 1. any `type` but the unclassified sentinel → `screen-choices`;
196
+ * 2. unclassified + decision id + approval verdicts → `api-choices` (approval);
197
+ * 3. unclassified + decision id + one complete question → `api-choices` (question);
198
+ * 4. every other unclassified payload — no id, #1932's options-without-id half
199
+ * state, and both stored history records — → `unreadable`.
200
+ *
201
+ * @param source - A live or stored prompt payload, or null
202
+ * @returns The view, or null when there is no prompt
203
+ */
204
+ function derivePromptView(source) {
205
+ if (source == null)
206
+ return null;
207
+ if (source.type !== exports.UNCLASSIFIED_PROMPT_VIEW_TYPE) {
208
+ const choices = screenChoices(source);
209
+ return {
210
+ kind: 'screen-choices',
211
+ heading: { kind: 'question', text: typeof source.question === 'string' ? source.question : '' },
212
+ choices,
213
+ multiSelect: source.multiSelect === true,
214
+ freeText: choices.some((choice) => choice.takesText) ? { via: 'screen' } : null,
215
+ decisionId: null,
216
+ apiTarget: null,
217
+ };
218
+ }
219
+ const decisionId = readDecisionId(source);
220
+ if (decisionId !== null && hasDecisionOptions(source)) {
221
+ const choices = decisionChoices(source.decisionOptions);
222
+ if (choices.length > 0) {
223
+ return {
224
+ kind: 'api-choices',
225
+ heading: {
226
+ kind: 'approval',
227
+ toolName: typeof source.toolName === 'string' && source.toolName ? source.toolName : null,
228
+ },
229
+ choices,
230
+ multiSelect: false,
231
+ freeText: null,
232
+ decisionId,
233
+ apiTarget: 'approval',
234
+ };
235
+ }
236
+ }
237
+ const question = readQuestionChoices(source);
238
+ if (decisionId !== null && question !== null) {
239
+ return {
240
+ kind: 'api-choices',
241
+ heading: { kind: 'agent-question', text: question.question },
242
+ choices: question.labels.map((label, index) => ({
243
+ answer: String(index + 1),
244
+ label,
245
+ isDefault: false,
246
+ takesText: false,
247
+ })),
248
+ multiSelect: false,
249
+ freeText: question.custom === true ? { via: 'api' } : null,
250
+ decisionId,
251
+ apiTarget: 'question',
252
+ };
253
+ }
254
+ return UNREADABLE_VIEW;
255
+ }
256
+ /**
257
+ * The view a `current-output` payload carries, falling back to deriving it.
258
+ *
259
+ * `??`, not `||`: a server from before #3184 sends no `promptView`, and its
260
+ * absence means "this daemon does not publish the field" — the same function
261
+ * then decides from `promptData`, so old and new servers reach the same answer.
262
+ */
263
+ function readPromptView(payload) {
264
+ if (!payload)
265
+ return null;
266
+ return payload.promptView ?? derivePromptView(payload.promptData);
267
+ }
@@ -71,7 +71,7 @@ const ws_server_1 = require("./src/lib/ws-server");
71
71
  const worktrees_1 = require("./src/lib/git/worktrees");
72
72
  const db_instance_1 = require("./src/lib/db/db-instance");
73
73
  const response_poller_1 = require("./src/lib/polling/response-poller");
74
- const auto_yes_manager_1 = require("./src/lib/polling/auto-yes-manager");
74
+ const auto_yes_lifecycle_1 = require("./src/lib/auto-yes-lifecycle");
75
75
  const schedule_manager_1 = require("./src/lib/schedule-manager");
76
76
  const timer_manager_1 = require("./src/lib/timer-manager");
77
77
  const resource_cleanup_1 = require("./src/lib/resource-cleanup");
@@ -825,8 +825,10 @@ app.prepare().then(() => {
825
825
  }
826
826
  // Stop polling first
827
827
  (0, response_poller_1.stopAllPolling)();
828
- // Issue #138: Stop all auto-yes pollers
829
- (0, auto_yes_manager_1.stopAllAutoYesPolling)();
828
+ // Issue #138: Stop all auto-yes pollers. Issue #3184: the `server-shutdown`
829
+ // row of the Auto-Yes lifecycle table — the state itself is in memory and
830
+ // goes with the process; nothing is persisted for the next start.
831
+ (0, auto_yes_lifecycle_1.releaseAutoYes)('server-shutdown', { scope: 'all' });
830
832
  // Issue #294: Stop all scheduled executions (SIGKILL fire-and-forget)
831
833
  (0, schedule_manager_1.stopAllSchedules)();
832
834
  // Issue #534: Stop all timer-based delayed messages
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ /**
3
+ * When Auto-Yes state is released, decided in one table (Issue #3184).
4
+ *
5
+ * Auto-Yes lives per worktree x instance with its own expiry, independent of
6
+ * the session it answers for. Every path that ends that relationship — a killed
7
+ * session (#3182), a removed instance, a deleted worktree, the orphan sweep,
8
+ * a poller giving up on errors, server shutdown — used to decide for itself
9
+ * what to do with the state, and one of them (instance removal) decided
10
+ * nothing at all, leaving a grant that silently approved the next session to
11
+ * claim the id. {@link AUTO_YES_LIFECYCLE} is the decision; each path calls
12
+ * {@link releaseAutoYes} (or its two halves) with the event it is.
13
+ *
14
+ * ## disable vs delete
15
+ *
16
+ * - `disable` keeps the entry with `enabled: false` (and the `stopReason`), for
17
+ * an instance that still exists — the UI can say why Auto-Yes went off.
18
+ * - `delete` drops the entry, for an instance or worktree that no longer
19
+ * exists. Kept, it would never be swept: the orphan sweep works per worktree.
20
+ *
21
+ * ## Not in the table
22
+ *
23
+ * Manual disable, expiry and the stop pattern are Auto-Yes's own conditions,
24
+ * not lifecycle events, and stay in `auto-yes-state` / the auto-yes route. A
25
+ * worktree ID rename MOVES the state (`worktree-session-reconcile`) rather than
26
+ * releasing it. The "starting" record (#3179) is cleared by kill-session beside
27
+ * this call, not by it: it has its own token rules (#3195).
28
+ *
29
+ * ## Imports go through the auto-yes-manager barrel
30
+ *
31
+ * The cleanup modules' tests mock `@/lib/polling/auto-yes-manager`, and so must
32
+ * this module's imports resolve to it. That barrel re-exports the poller, so
33
+ * `auto-yes-poller` must NOT import this module (it would be a cycle); its
34
+ * consecutive-errors path applies the same row directly, and
35
+ * `tests/unit/lib/auto-yes-lifecycle-3184.test.ts` holds the two equal.
36
+ *
37
+ * @module lib/auto-yes-lifecycle
38
+ */
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.AUTO_YES_LIFECYCLE = void 0;
41
+ exports.stopAutoYesPollersFor = stopAutoYesPollersFor;
42
+ exports.applyAutoYesStateRule = applyAutoYesStateRule;
43
+ exports.releaseAutoYes = releaseAutoYes;
44
+ const auto_yes_manager_1 = require("./polling/auto-yes-manager");
45
+ /**
46
+ * The table (design §8.2).
47
+ *
48
+ * `session-killed` is #3182's decision as #3188 shipped it: disable with no
49
+ * reason (no new reason was added), for the instance only. `server-shutdown`
50
+ * deliberately does not persist anything: the state lives in memory, and a
51
+ * restarted server starting with every grant off is the safe side.
52
+ */
53
+ exports.AUTO_YES_LIFECYCLE = {
54
+ 'session-killed': { state: 'disable', poller: 'stop' },
55
+ 'instance-removed': { state: 'delete', poller: 'stop' },
56
+ 'worktree-deleted': { state: 'delete', poller: 'stop' },
57
+ 'orphan-swept': { state: 'delete', poller: 'stop' },
58
+ 'consecutive-errors': { state: 'disable', stopReason: 'consecutive_errors', poller: 'stop' },
59
+ 'server-shutdown': { state: 'none', poller: 'stop' },
60
+ };
61
+ /**
62
+ * Stop the pollers the event's target names (the poller half of the table).
63
+ * Separate from {@link applyAutoYesStateRule} so a caller that reports the two
64
+ * failures apart (`session-cleanup`) can keep doing so.
65
+ */
66
+ function stopAutoYesPollersFor(event, target) {
67
+ if (exports.AUTO_YES_LIFECYCLE[event].poller !== 'stop')
68
+ return;
69
+ switch (target.scope) {
70
+ case 'instance':
71
+ (0, auto_yes_manager_1.stopAutoYesPolling)((0, auto_yes_manager_1.buildCompositeKey)(target.worktreeId, target.cliToolId, target.instanceId));
72
+ return;
73
+ case 'worktree':
74
+ (0, auto_yes_manager_1.stopAutoYesPollingByWorktree)(target.worktreeId);
75
+ return;
76
+ case 'key':
77
+ (0, auto_yes_manager_1.stopAutoYesPolling)(target.compositeKey);
78
+ return;
79
+ case 'all':
80
+ (0, auto_yes_manager_1.stopAllAutoYesPolling)();
81
+ return;
82
+ }
83
+ }
84
+ function disableKey(compositeKey, stopReason) {
85
+ const cliToolId = (0, auto_yes_manager_1.extractCliToolId)(compositeKey);
86
+ if (!cliToolId)
87
+ return;
88
+ (0, auto_yes_manager_1.disableAutoYes)((0, auto_yes_manager_1.extractWorktreeId)(compositeKey), cliToolId, stopReason, (0, auto_yes_manager_1.extractInstanceId)(compositeKey) ?? undefined);
89
+ }
90
+ /** Apply the event's state rule to its target (the state half of the table). */
91
+ function applyAutoYesStateRule(event, target) {
92
+ const rule = exports.AUTO_YES_LIFECYCLE[event];
93
+ if (rule.state === 'none')
94
+ return;
95
+ switch (target.scope) {
96
+ case 'instance':
97
+ if (rule.state === 'disable') {
98
+ (0, auto_yes_manager_1.disableAutoYes)(target.worktreeId, target.cliToolId, rule.stopReason, target.instanceId);
99
+ }
100
+ else {
101
+ (0, auto_yes_manager_1.deleteAutoYesState)((0, auto_yes_manager_1.buildCompositeKey)(target.worktreeId, target.cliToolId, target.instanceId));
102
+ }
103
+ return;
104
+ case 'worktree':
105
+ if (rule.state === 'disable') {
106
+ (0, auto_yes_manager_1.getCompositeKeysByWorktree)(target.worktreeId).forEach((key) => disableKey(key, rule.stopReason));
107
+ }
108
+ else {
109
+ (0, auto_yes_manager_1.deleteAutoYesStateByWorktree)(target.worktreeId);
110
+ }
111
+ return;
112
+ case 'key':
113
+ if (rule.state === 'disable') {
114
+ disableKey(target.compositeKey, rule.stopReason);
115
+ }
116
+ else {
117
+ (0, auto_yes_manager_1.deleteAutoYesState)(target.compositeKey);
118
+ }
119
+ return;
120
+ case 'all':
121
+ (0, auto_yes_manager_1.getAutoYesStateCompositeKeys)().forEach((key) => rule.state === 'disable' ? disableKey(key, rule.stopReason) : (0, auto_yes_manager_1.deleteAutoYesState)(key));
122
+ return;
123
+ }
124
+ }
125
+ /**
126
+ * Release Auto-Yes for an event: stop the pollers first, then apply the state
127
+ * rule — the order `session-cleanup` has kept since #404. Both halves are
128
+ * synchronous, so no poll can run between them.
129
+ */
130
+ function releaseAutoYes(event, target) {
131
+ stopAutoYesPollersFor(event, target);
132
+ applyAutoYesStateRule(event, target);
133
+ }
@@ -65,6 +65,7 @@ const antigravity_permission_receipts_1 = require("./polling/antigravity-permiss
65
65
  const auto_yes_resolver_1 = require("./polling/auto-yes-resolver");
66
66
  const auto_yes_policy_1 = require("./polling/auto-yes-policy");
67
67
  const detect_1 = require("./detection/tools/codex/detect");
68
+ const frame_1 = require("./detection/tools/frame");
68
69
  const auto_yes_suppression_state_1 = require("./polling/auto-yes-suppression-state");
69
70
  const auto_yes_dialog_gate_1 = require("./polling/auto-yes-dialog-gate");
70
71
  const task_transition_service_1 = require("./tasks/task-transition-service");
@@ -182,6 +183,13 @@ function incrementErrorCount(compositeKey) {
182
183
  pollerState.consecutiveErrors++;
183
184
  pollerState.currentInterval = (0, auto_yes_state_1.calculateBackoffInterval)(pollerState.consecutiveErrors);
184
185
  // Issue #499 Item 5: Auto-stop after consecutive error threshold.
186
+ //
187
+ // Issue #3184: this is the `consecutive-errors` row of AUTO_YES_LIFECYCLE
188
+ // (`lib/auto-yes-lifecycle`) — disable with `consecutive_errors`, stop the
189
+ // poller — applied here directly rather than through `releaseAutoYes`:
190
+ // that module reaches this one through the auto-yes-manager barrel, so
191
+ // importing it back would be a cycle. `auto-yes-lifecycle-3184.test.ts`
192
+ // holds this call and the table row equal.
185
193
  if (pollerState.consecutiveErrors >= auto_yes_config_1.AUTO_STOP_ERROR_THRESHOLD) {
186
194
  const worktreeId = (0, auto_yes_state_1.extractWorktreeId)(compositeKey);
187
195
  const cliToolId = (0, auto_yes_state_1.extractCliToolId)(compositeKey);
@@ -439,7 +447,14 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
439
447
  // such a machine's dialogs alone, which is why `logIfWithheldForWantOfReceipt`
440
448
  // says so.
441
449
  const receiptScope = { worktreeId, instanceId };
442
- const promptDetection = (0, response_checker_1.detectPromptOnCleanFrame)(cleanOutput, cliToolId, precomputedLines, rawOutput, receiptScope);
450
+ // Issue #3183: the ONE frame every judgement below reads — normalised once,
451
+ // from the capture as captured (the input-box markers are rule rows the
452
+ // cleaned spelling has blanked), and handed as the same object to the
453
+ // prompt reading, the codex launch guards and the dialog gate. That is what
454
+ // makes "the status chain and Auto-Yes read the same live region" a fact
455
+ // rather than a hope: there is no second normalisation to disagree with.
456
+ const frame = (0, frame_1.normalizeFrame)(rawOutput ?? cleanOutput, cliToolId);
457
+ const promptDetection = (0, response_checker_1.detectPromptOnCleanFrame)(cleanOutput, cliToolId, precomputedLines, rawOutput, receiptScope, frame);
443
458
  if (!promptDetection.isPrompt || !promptDetection.promptData) {
444
459
  pollerState.lastAnsweredPromptKey = null;
445
460
  pollerState.lastAnsweredAt = null;
@@ -473,7 +488,7 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
473
488
  // to the tool. Auto-answer layer only: the detection above still reports the
474
489
  // prompt, so the human keeps seeing the screen and the response poller
475
490
  // still notifies them about it.
476
- const launchDialog = cliToolId === 'codex' ? (0, cli_patterns_1.getCodexLifecycleDialog)(cleanOutput) : null;
491
+ const launchDialog = cliToolId === 'codex' ? (0, cli_patterns_1.getCodexLifecycleDialog)(frame) : null;
477
492
  if (launchDialog) {
478
493
  // Recorded through the #1684 channel so `capture --json` and `cmate wait`
479
494
  // can name the reason instead of showing a worker that went quiet.
@@ -498,7 +513,7 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
498
513
  // The tool's `detectPrompt` still reports the prompt, so `/prompt-response`
499
514
  // (the human's answer) is unaffected. Reuses `unclassified-frame`: the tool
500
515
  // recognised the frame and deliberately declined it.
501
- if (cliToolId === 'codex' && (0, detect_1.isCodexModelPickerFrame)(cleanOutput)) {
516
+ if (cliToolId === 'codex' && (0, detect_1.isCodexModelPickerFrame)(frame)) {
502
517
  (0, auto_yes_suppression_state_1.recordPolicySuppression)(worktreeId, cliToolId, instanceId, {
503
518
  reason: 'unclassified-frame',
504
519
  mode: null,
@@ -529,7 +544,7 @@ async function detectAndRespondToPrompt(worktreeId, pollerState, cliToolId, clea
529
544
  // Recorded through the #1684 channel with the reason code #1924 landed for
530
545
  // exactly this position, so `capture --json` and `cmate wait` can name the
531
546
  // gap instead of showing a worker that silently went quiet.
532
- const dialogGate = (0, auto_yes_dialog_gate_1.evaluateAutoYesDialogGate)(cliToolId, promptDetection.promptData.type, cleanOutput);
547
+ const dialogGate = (0, auto_yes_dialog_gate_1.evaluateAutoYesDialogGate)(cliToolId, promptDetection.promptData.type, frame);
533
548
  if (!dialogGate.allowed) {
534
549
  (0, auto_yes_suppression_state_1.recordPolicySuppression)(worktreeId, cliToolId, instanceId, {
535
550
  reason: 'unclassified-frame',
@@ -150,7 +150,7 @@ function readInputBoxStatusRow(contentLines) {
150
150
  * @returns True when the input box is live and agy is idle
151
151
  */
152
152
  function isAntigravityReady(output) {
153
- const frame = (0, frame_1.normalizeFrame)(output);
153
+ const frame = (0, frame_1.normalizeFrame)(output, 'antigravity');
154
154
  if (cli_patterns_1.ANTIGRAVITY_SELECTION_LIST_PATTERN.test(frame.lastLines))
155
155
  return false;
156
156
  if (ANTIGRAVITY_TRUST_DIALOG_PATTERN.test(frame.lastLines))
@@ -4,14 +4,15 @@
4
4
  * Shared between response-poller.ts and API routes
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.findOpencodeV2DialogTitle = exports.OPENCODE_V2_DIALOG_TITLE_PATTERN = exports.OPENCODE_V2_THINKING_PATTERN = exports.OPENCODE_V2_FOOTER_PATTERN = exports.OPENCODE_V2_IDLE_COMPOSER_PATTERN = exports.OPENCODE_SKIP_PATTERNS = exports.OPENCODE_SEPARATOR_PATTERN = exports.CLAUDE_SELECTION_LIST_FOOTER = exports.CLAUDE_MODEL_OVERLAY_FOOTER_PATTERN = exports.OPENCODE_SELECTION_LIST_PATTERN = exports.OPENCODE_FOOTER_STATUS_PATTERN = exports.OPENCODE_USER_ECHO_PATTERN = exports.OPENCODE_GUTTER_ROW_PATTERN = exports.OPENCODE_COMPOSER_BOTTOM_BORDER = exports.OPENCODE_PROCESSING_INDICATOR = exports.OPENCODE_PERMISSION_PATTERN = exports.OPENCODE_TURN_COMPLETE_PATTERN = exports.OPENCODE_RESPONSE_COMPLETE = exports.OPENCODE_LOADING_PATTERN = exports.OPENCODE_THINKING_PATTERN = exports.OPENCODE_PROMPT_AFTER_RESPONSE = exports.OPENCODE_IDLE_COMPOSER_PATTERN = exports.OPENCODE_PROMPT_PATTERN = exports.GEMINI_THINKING_PATTERN = exports.GEMINI_PROMPT_PATTERN = exports.MAX_PASTED_TEXT_RETRIES = exports.PASTED_TEXT_DETECT_DELAY = exports.PASTED_TEXT_PATTERN = exports.CODEX_USER_ECHO_PATTERN = exports.CODEX_TRAILED_STATUS_BAR_PATTERN = exports.CODEX_STATUS_BAR_PATTERN = exports.CODEX_PAGER_FOOTER_PATTERN = exports.CODEX_EFFORT_PICKER_FOOTER_PATTERN = exports.CODEX_PICKER_FOOTER_PATTERN = exports.CODEX_FORM_SUBMIT_FOOTER_PATTERN = exports.CODEX_APPROVAL_FOOTER_PATTERN = exports.CODEX_SELECTION_LIST_PATTERN = exports.CODEX_SEPARATOR_PATTERN = exports.CODEX_HOOKS_REVIEW_ANCHORS = exports.CODEX_DIALOG_PATTERN = exports.CODEX_TRUST_QUESTION_PATTERN = exports.CODEX_PROMPT_PATTERN = exports.CLAUDE_TRUST_DIALOG_PATTERN = exports.CLAUDE_SEPARATOR_PATTERN = exports.CLAUDE_PROMPT_PATTERN = exports.CODEX_INTERRUPT_HINT_PATTERN = exports.CODEX_THINKING_PATTERN = exports.CLAUDE_INTERRUPT_HINT_PATTERN = exports.CLAUDE_THINKING_PATTERN = exports.CLAUDE_SPINNER_CHARS = void 0;
8
- exports.CLAUDE_SESSION_ERROR_REGEX_PATTERNS = exports.CLAUDE_SESSION_ERROR_PATTERNS = exports.extractAnsiSequences = exports.stripAnsi = exports.COMMAND_CODE_SKIP_PATTERNS = exports.COMMAND_CODE_HOOK_NOTICE_PATTERN = exports.COMMAND_CODE_BANNER_PATTERNS = exports.COMMAND_CODE_MODE_INDICATOR_PATTERN = exports.COMMAND_CODE_COMPLETION_PATTERN = exports.COMMAND_CODE_RESPONSE_MARKER_PATTERN = exports.COMMAND_CODE_THINKING_PATTERN = exports.COMMAND_CODE_INTERRUPT_HINT_PATTERN = exports.COMMAND_CODE_SEPARATOR_PATTERN = exports.COMMAND_CODE_PROMPT_PATTERN = exports.COMMAND_CODE_SPINNER_CHARS = exports.ANTIGRAVITY_SKIP_PATTERNS = exports.ANTIGRAVITY_SURVEY_PATTERN = exports.ANTIGRAVITY_DIALOG_MAX_ROWS = exports.ANTIGRAVITY_DIALOG_BOUNDARY_PATTERN = exports.ANTIGRAVITY_SWITCH_MODEL_HEADER_PATTERN = exports.ANTIGRAVITY_NUMBERED_OPTION_PATTERN = exports.ANTIGRAVITY_NAVIGATE_FOOTER_PATTERN = exports.ANTIGRAVITY_SELECTION_LIST_PATTERN = exports.ANTIGRAVITY_SEPARATOR_PATTERN = exports.ANTIGRAVITY_THINKING_PATTERN = exports.ANTIGRAVITY_PROMPT_PATTERN = exports.ANTIGRAVITY_COMPOSER_MODE_BANNER_PATTERN = exports.ANTIGRAVITY_COMPOSER_MODE_BANNER_SOURCE = exports.VIBE_LOCAL_THINKING_PATTERN = exports.VIBE_LOCAL_PROMPT_PATTERN = exports.COPILOT_SKIP_PATTERNS = exports.COPILOT_FOLDER_TRUST_ANSWER_KEY = exports.COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN = exports.COPILOT_FOLDER_TRUST_ANCHORS = exports.COPILOT_SELECTION_FOOTER_PATTERN = exports.COPILOT_BOOT_BANNER_ANCHORS = exports.COPILOT_TRANSCRIPT_CONTINUATION_PATTERN = exports.COPILOT_TOOL_ROW_PATTERN = exports.COPILOT_TOOL_VERBS = exports.COPILOT_TRANSCRIPT_DIVIDER_PATTERN = exports.COPILOT_USER_ECHO_PATTERN = exports.COPILOT_REASONING_HEADER_PATTERN = exports.COPILOT_BOX_ROW_PATTERN = exports.COPILOT_SEPARATOR_PATTERN = exports.COPILOT_IDLE_STATUS_PATTERN = exports.COPILOT_WORKING_STATUS_PATTERN = exports.COPILOT_THINKING_PATTERN = exports.COPILOT_PROMPT_PATTERN = exports.OPENCODE_V2_SKIP_PATTERNS = void 0;
7
+ exports.OPENCODE_V2_DIALOG_TITLE_PATTERN = exports.OPENCODE_V2_THINKING_PATTERN = exports.OPENCODE_V2_FOOTER_PATTERN = exports.OPENCODE_V2_IDLE_COMPOSER_PATTERN = exports.OPENCODE_SKIP_PATTERNS = exports.OPENCODE_SEPARATOR_PATTERN = exports.CLAUDE_SELECTION_LIST_FOOTER = exports.CLAUDE_MODEL_OVERLAY_FOOTER_PATTERN = exports.OPENCODE_SELECTION_LIST_PATTERN = exports.OPENCODE_FOOTER_STATUS_PATTERN = exports.OPENCODE_USER_ECHO_PATTERN = exports.OPENCODE_GUTTER_ROW_PATTERN = exports.OPENCODE_COMPOSER_BOTTOM_BORDER = exports.OPENCODE_PROCESSING_INDICATOR = exports.OPENCODE_PERMISSION_PATTERN = exports.OPENCODE_TURN_COMPLETE_PATTERN = exports.OPENCODE_RESPONSE_COMPLETE = exports.OPENCODE_LOADING_PATTERN = exports.OPENCODE_THINKING_PATTERN = exports.OPENCODE_PROMPT_AFTER_RESPONSE = exports.OPENCODE_IDLE_COMPOSER_PATTERN = exports.OPENCODE_PROMPT_PATTERN = exports.GEMINI_THINKING_PATTERN = exports.GEMINI_PROMPT_PATTERN = exports.MAX_PASTED_TEXT_RETRIES = exports.PASTED_TEXT_DETECT_DELAY = exports.PASTED_TEXT_PATTERN = exports.CODEX_USER_ECHO_PATTERN = exports.CODEX_TRAILED_STATUS_BAR_PATTERN = exports.CODEX_STATUS_BAR_PATTERN = exports.CODEX_PAGER_FOOTER_PATTERN = exports.CODEX_EFFORT_PICKER_FOOTER_PATTERN = exports.CODEX_PICKER_FOOTER_PATTERN = exports.CODEX_FORM_SUBMIT_FOOTER_PATTERN = exports.CODEX_APPROVAL_FOOTER_PATTERN = exports.CODEX_SELECTION_LIST_PATTERN = exports.CODEX_SEPARATOR_PATTERN = exports.CODEX_HOOKS_REVIEW_ANCHORS = exports.CODEX_GENUINE_PROMPT_LINE = exports.CODEX_DIALOG_PATTERN = exports.CODEX_TRUST_QUESTION_PATTERN = exports.CODEX_PROMPT_PATTERN = exports.CLAUDE_TRUST_DIALOG_PATTERN = exports.CLAUDE_SEPARATOR_PATTERN = exports.CLAUDE_PROMPT_PATTERN = exports.CODEX_INTERRUPT_HINT_PATTERN = exports.CODEX_THINKING_PATTERN = exports.CLAUDE_INTERRUPT_HINT_PATTERN = exports.CLAUDE_THINKING_PATTERN = exports.CLAUDE_SPINNER_CHARS = void 0;
8
+ exports.CLAUDE_SESSION_ERROR_REGEX_PATTERNS = exports.CLAUDE_SESSION_ERROR_PATTERNS = exports.extractAnsiSequences = exports.stripAnsi = exports.COMMAND_CODE_SKIP_PATTERNS = exports.COMMAND_CODE_HOOK_NOTICE_PATTERN = exports.COMMAND_CODE_BANNER_PATTERNS = exports.COMMAND_CODE_MODE_INDICATOR_PATTERN = exports.COMMAND_CODE_COMPLETION_PATTERN = exports.COMMAND_CODE_RESPONSE_MARKER_PATTERN = exports.COMMAND_CODE_THINKING_PATTERN = exports.COMMAND_CODE_INTERRUPT_HINT_PATTERN = exports.COMMAND_CODE_SEPARATOR_PATTERN = exports.COMMAND_CODE_PROMPT_PATTERN = exports.COMMAND_CODE_SPINNER_CHARS = exports.ANTIGRAVITY_SKIP_PATTERNS = exports.ANTIGRAVITY_SURVEY_PATTERN = exports.ANTIGRAVITY_DIALOG_MAX_ROWS = exports.ANTIGRAVITY_DIALOG_BOUNDARY_PATTERN = exports.ANTIGRAVITY_SWITCH_MODEL_HEADER_PATTERN = exports.ANTIGRAVITY_NUMBERED_OPTION_PATTERN = exports.ANTIGRAVITY_NAVIGATE_FOOTER_PATTERN = exports.ANTIGRAVITY_SELECTION_LIST_PATTERN = exports.ANTIGRAVITY_SEPARATOR_PATTERN = exports.ANTIGRAVITY_THINKING_PATTERN = exports.ANTIGRAVITY_PROMPT_PATTERN = exports.ANTIGRAVITY_COMPOSER_MODE_BANNER_PATTERN = exports.ANTIGRAVITY_COMPOSER_MODE_BANNER_SOURCE = exports.VIBE_LOCAL_THINKING_PATTERN = exports.VIBE_LOCAL_PROMPT_PATTERN = exports.COPILOT_SKIP_PATTERNS = exports.COPILOT_FOLDER_TRUST_ANSWER_KEY = exports.COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN = exports.COPILOT_FOLDER_TRUST_ANCHORS = exports.COPILOT_SELECTION_FOOTER_PATTERN = exports.COPILOT_BOOT_BANNER_ANCHORS = exports.COPILOT_TRANSCRIPT_CONTINUATION_PATTERN = exports.COPILOT_TOOL_ROW_PATTERN = exports.COPILOT_TOOL_VERBS = exports.COPILOT_TRANSCRIPT_DIVIDER_PATTERN = exports.COPILOT_USER_ECHO_PATTERN = exports.COPILOT_REASONING_HEADER_PATTERN = exports.COPILOT_BOX_ROW_PATTERN = exports.COPILOT_SEPARATOR_PATTERN = exports.COPILOT_IDLE_STATUS_PATTERN = exports.COPILOT_WORKING_STATUS_PATTERN = exports.COPILOT_THINKING_PATTERN = exports.COPILOT_PROMPT_PATTERN = exports.OPENCODE_V2_SKIP_PATTERNS = exports.findOpencodeV2DialogTitle = void 0;
9
9
  exports.isCodexTurnActive = isCodexTurnActive;
10
10
  exports.findClaudeChromeStart = findClaudeChromeStart;
11
11
  exports.resolveClaudeTrustDialogKeys = resolveClaudeTrustDialogKeys;
12
12
  exports.isClaudeTrustDialogOpen = isClaudeTrustDialogOpen;
13
13
  exports.isShellPaneCommand = isShellPaneCommand;
14
14
  exports.isCodexPromptReady = isCodexPromptReady;
15
+ exports.findCodexComposerRow = findCodexComposerRow;
15
16
  exports.getCodexActiveDialog = getCodexActiveDialog;
16
17
  exports.getCodexLifecycleDialog = getCodexLifecycleDialog;
17
18
  exports.findCodexChromeStart = findCodexChromeStart;
@@ -364,7 +365,7 @@ exports.CODEX_DIALOG_PATTERN = new RegExp(`Skip until next version|${exports.COD
364
365
  * distinguishes the genuine input line from a dialog option line. Single-line
365
366
  * (no /m, no /g) -- callers test it per line to locate the prompt's position.
366
367
  */
367
- const CODEX_GENUINE_PROMPT_LINE = /^\s*›(?!\s*\d+\.)/;
368
+ exports.CODEX_GENUINE_PROMPT_LINE = /^\s*›(?!\s*\d+\.)/;
368
369
  /**
369
370
  * Decide whether Codex output shows a genuine interactive input prompt rather than
370
371
  * a startup dialog (Issue #890, reworked in Issue #892).
@@ -395,7 +396,7 @@ function isCodexPromptReady(output) {
395
396
  lastDialogMarkerIdx = i;
396
397
  continue;
397
398
  }
398
- if (CODEX_GENUINE_PROMPT_LINE.test(line)) {
399
+ if (exports.CODEX_GENUINE_PROMPT_LINE.test(line)) {
399
400
  lastPromptIdx = i;
400
401
  }
401
402
  }
@@ -415,32 +416,49 @@ function isCodexPromptReady(output) {
415
416
  * on the update dialog could confirm the default "1. Update now" (npm install).
416
417
  */
417
418
  /**
418
- * The lines of Codex's ACTIVE region: everything strictly below the bottom-most
419
- * genuine input-prompt line, or the whole frame when there is no prompt line
420
- * (Issue #892).
419
+ * Index of codex's bottom-most genuine input-prompt row, or -1 (Issue #892).
420
+ *
421
+ * This is codex's live-region composer marker (Issue #3183): the declaration in
422
+ * `tools/codex/live-region.ts` is built on it, so `NormalizedFrame.liveRegion`
423
+ * starts at this row, and the string entries below — which keep a caller that
424
+ * has no `NormalizedFrame` (codex's own launch loop) — read the same row.
421
425
  *
422
- * This is the one rule that keeps every Codex dialog classifier honest.
423
426
  * capturePane returns scrollback, so a dialog that was answered minutes ago is
424
427
  * still in the frame; only what sits BELOW the live prompt is still awaiting a
425
428
  * key. Shared by getCodexActiveDialog and getCodexLifecycleDialog so the two
426
429
  * cannot drift into disagreeing about what "active" means.
427
430
  */
428
- function codexActiveRegionLines(output) {
429
- const lines = output.split('\n');
430
- // Index of the bottom-most genuine input-prompt line (-1 if none).
431
- let promptIdx = -1;
431
+ function findCodexComposerRow(lines) {
432
432
  for (let i = lines.length - 1; i >= 0; i--) {
433
- if (CODEX_GENUINE_PROMPT_LINE.test(lines[i])) {
434
- promptIdx = i;
435
- break;
433
+ if (exports.CODEX_GENUINE_PROMPT_LINE.test(lines[i]))
434
+ return i;
435
+ }
436
+ return -1;
437
+ }
438
+ /**
439
+ * The rows of codex's ACTIVE region: everything strictly below the composer
440
+ * row, or the whole frame when there is none (Issue #892).
441
+ *
442
+ * A {@link NormalizedFrame} carries that answer already (Issue #3183); a string
443
+ * is read with the same marker, {@link findCodexComposerRow}.
444
+ */
445
+ function codexActiveRows(input) {
446
+ if (typeof input !== 'string') {
447
+ const region = input.liveRegion;
448
+ if (region.tool === 'codex') {
449
+ return region.anchor === 'composer'
450
+ ? input.contentLines.slice((region.composerEndRow ?? region.startRow) + 1)
451
+ : input.contentLines;
436
452
  }
453
+ return codexActiveRows(input.clean);
437
454
  }
438
- return lines.slice(promptIdx + 1);
455
+ const lines = input.split('\n');
456
+ return lines.slice(findCodexComposerRow(lines) + 1);
439
457
  }
440
458
  function getCodexActiveDialog(output) {
441
459
  // Residual dialog text above a live prompt is excluded, so a dialog lingering
442
460
  // in scrollback is never treated as active.
443
- const active = codexActiveRegionLines(output).join('\n');
461
+ const active = codexActiveRows(output).join('\n');
444
462
  if (active === '') {
445
463
  return null;
446
464
  }
@@ -525,7 +543,7 @@ const CODEX_UPDATE_DIALOG_ANCHORS = [
525
543
  /**
526
544
  * Classify the bottom-most ACTIVE codex lifecycle screen (Issue #1829).
527
545
  *
528
- * Position-based, via {@link codexActiveRegionLines}: a dialog left in
546
+ * Position-based, via {@link codexActiveRows}: a dialog left in
529
547
  * scrollback above a live prompt is not active and returns `null`. That is not
530
548
  * a detail — the auto-answer guard in the Auto-Yes poller is built on this
531
549
  * function, and a whole-frame version of it would switch Auto-Yes off for the
@@ -540,11 +558,11 @@ const CODEX_UPDATE_DIALOG_ANCHORS = [
540
558
  * reports these screens, so a human still sees them; what this function gates is
541
559
  * only whether a machine may answer on their behalf.
542
560
  *
543
- * @param output - ANSI-stripped pane capture
561
+ * @param output - ANSI-stripped pane capture, or a frame `normalizeFrame(…, 'codex')` built
544
562
  * @returns The active lifecycle screen, or null when none is
545
563
  */
546
564
  function getCodexLifecycleDialog(output) {
547
- const activeLines = codexActiveRegionLines(output);
565
+ const activeLines = codexActiveRows(output);
548
566
  const window = [];
549
567
  for (let i = activeLines.length - 1; i >= 0 && window.length < CODEX_LIFECYCLE_TAIL_LINES; i--) {
550
568
  if (activeLines[i].trim() === '')
@@ -139,7 +139,7 @@ Object.defineProperty(exports, "STATUS_CHECK_LINE_COUNT", { enumerable: true, ge
139
139
  * @returns Detection result with status, confidence, reason, hasActivePrompt, evidence and promptDetection
140
140
  */
141
141
  function detectSessionStatus(output, cliToolId, lastOutputTimestamp) {
142
- const frame = (0, frame_1.normalizeFrame)(output);
142
+ const frame = (0, frame_1.normalizeFrame)(output, cliToolId);
143
143
  const verdict = (0, registry_1.getToolStatusDetector)(cliToolId).detect(frame, {
144
144
  lastOutputTimestamp,
145
145
  // Issue #2991: the same presence reading Auto-Yes and History use, so an