commandmate 0.26.1 → 0.27.1

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 (840) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +430 -402
  3. package/.next/app-path-routes-manifest.json +32 -28
  4. package/.next/build-manifest.json +5 -5
  5. package/.next/prerender-manifest.json +12 -12
  6. package/.next/react-loadable-manifest.json +6 -6
  7. package/.next/required-server-files.json +1 -1
  8. package/.next/routes-manifest.json +24 -0
  9. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update-check/route.js +1 -1
  12. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/assistant/conversation/route.js +1 -1
  14. package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
  15. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/assistant/current-output/route.js +1 -1
  17. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  18. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/assistant/messages/route.js +1 -1
  20. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  21. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/assistant/session/route.js +1 -1
  23. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  24. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/assistant/start/route.js +1 -1
  26. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  27. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/assistant/terminal/route.js +2 -2
  29. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  30. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/assistant/tools/route.js +1 -1
  32. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  33. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/capabilities/route.js +1 -0
  38. package/.next/server/app/api/capabilities/route.js.nft.json +1 -0
  39. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -0
  40. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/fs/browse/route.js +2 -2
  46. package/.next/server/app/api/fs/browse/route.js.nft.json +1 -1
  47. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/fs/recent-paths/route.js +2 -2
  49. package/.next/server/app/api/fs/recent-paths/route.js.nft.json +1 -1
  50. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  51. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  52. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  53. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/hooks/claude-done/route.js +19 -1
  55. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  56. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  58. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  59. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/push/escalation/route.js +1 -1
  63. package/.next/server/app/api/push/escalation/route.js.nft.json +1 -1
  64. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/push/subscriptions/route.js +1 -1
  66. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/push/vapid/route.js +1 -1
  68. package/.next/server/app/api/push/vapid/route.js.nft.json +1 -1
  69. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js +1 -1
  72. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
  74. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  76. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  77. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/repositories/clone/route.js +1 -1
  79. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  80. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/repositories/restore/route.js +1 -1
  83. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  84. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/repositories/route.js +1 -1
  86. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  87. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/repositories/scan/route.js +1 -1
  89. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  90. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/repositories/sync/route.js +1 -1
  92. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  93. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/repositories/validate-path/route.js +1 -1
  95. package/.next/server/app/api/repositories/validate-path/route.js.nft.json +1 -1
  96. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/slash-commands/route.js.nft.json +1 -1
  104. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/tasks/[taskId]/route.js +1 -1
  107. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  109. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/todos/route.js +1 -1
  111. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/verification/runs/[runId]/route.js +1 -1
  113. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/verification/runs/route.js +1 -1
  115. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  118. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  121. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -0
  123. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -0
  124. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -0
  125. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +1 -1
  129. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/current-output/route.js +2 -1
  131. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  132. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/env/route.js +2 -0
  134. package/.next/server/app/api/worktrees/[id]/env/route.js.nft.json +1 -0
  135. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -0
  136. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +1 -1
  142. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/git/branches/route.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/git/commit/route.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/git/log/route.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/git/staged/route.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/git/stash/route.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/git/status/route.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  176. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  179. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +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]/prompt-response/route.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  193. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/resolve-target/route.js +1 -0
  195. package/.next/server/app/api/worktrees/[id]/resolve-target/route.js.nft.json +1 -0
  196. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -0
  197. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  199. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  202. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  203. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +1 -5
  204. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js.nft.json +1 -1
  205. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  206. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
  207. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
  208. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  209. package/.next/server/app/api/worktrees/[id]/schedules/route.js +2 -6
  210. package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +1 -1
  211. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  212. package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
  213. package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +1 -1
  214. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  215. package/.next/server/app/api/worktrees/[id]/send/route.js +3 -1
  216. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  217. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  218. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +1 -1
  219. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  220. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  221. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  222. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  223. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  224. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  225. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  226. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  227. package/.next/server/app/api/worktrees/[id]/skills/route.js +1 -1
  228. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  229. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  230. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +1 -1
  231. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  232. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  233. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  234. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  235. package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -1
  236. package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
  237. package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
  238. package/.next/server/app/api/worktrees/[id]/tasks/route.js +1 -1
  239. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  240. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  241. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  242. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  243. package/.next/server/app/api/worktrees/[id]/timers/history/route.js +1 -1
  244. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  245. package/.next/server/app/api/worktrees/[id]/timers/route.js +3 -1
  246. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  247. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  248. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js +1 -1
  249. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  250. package/.next/server/app/api/worktrees/[id]/todos/route.js +1 -1
  251. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  252. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js +1 -1
  253. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +1 -1
  254. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  255. package/.next/server/app/api/worktrees/[id]/tree/route.js +1 -1
  256. package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +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.js +1 -1
  259. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +1 -1
  260. package/.next/server/app/api/worktrees/[id]/upload/[...path]/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]/route.js +1 -1
  265. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  266. package/.next/server/app/api/worktrees/[id]/verify/runs/route.js +1 -1
  267. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  268. package/.next/server/app/api/worktrees/[id]/viewed/route.js +1 -1
  269. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  270. package/.next/server/app/api/worktrees/route.js +1 -1
  271. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  272. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  273. package/.next/server/app/chat/page.js +2 -2
  274. package/.next/server/app/chat/page.js.nft.json +1 -1
  275. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  276. package/.next/server/app/login/page.js +2 -2
  277. package/.next/server/app/login/page.js.nft.json +1 -1
  278. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  279. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  280. package/.next/server/app/more/page.js +2 -2
  281. package/.next/server/app/more/page.js.nft.json +1 -1
  282. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  283. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  284. package/.next/server/app/page.js +1 -1
  285. package/.next/server/app/page.js.nft.json +1 -1
  286. package/.next/server/app/page_client-reference-manifest.js +1 -1
  287. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  288. package/.next/server/app/repositories/page.js +2 -2
  289. package/.next/server/app/repositories/page.js.nft.json +1 -1
  290. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  291. package/.next/server/app/review/page.js +1 -1
  292. package/.next/server/app/review/page.js.nft.json +1 -1
  293. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  294. package/.next/server/app/sessions/page.js +1 -1
  295. package/.next/server/app/sessions/page.js.nft.json +1 -1
  296. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  297. package/.next/server/app/skills/[skillId]/page.js +2 -2
  298. package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
  299. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  300. package/.next/server/app/skills/installed/page.js +2 -2
  301. package/.next/server/app/skills/installed/page.js.nft.json +1 -1
  302. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  303. package/.next/server/app/skills/page.js +2 -2
  304. package/.next/server/app/skills/page.js.nft.json +1 -1
  305. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  306. package/.next/server/app/worktrees/[id]/files/[...path]/page.js +2 -2
  307. package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
  308. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  309. package/.next/server/app/worktrees/[id]/page.js +9 -7
  310. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  311. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  312. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  313. package/.next/server/app-paths-manifest.json +32 -28
  314. package/.next/server/chunks/1029.js +1 -1
  315. package/.next/server/chunks/1068.js +3 -1
  316. package/.next/server/chunks/1296.js +1 -1
  317. package/.next/server/chunks/1538.js +7 -0
  318. package/.next/server/chunks/1601.js +2 -2
  319. package/.next/server/chunks/2119.js +1 -1
  320. package/.next/server/chunks/2404.js +3 -2
  321. package/.next/server/chunks/2445.js +1 -1
  322. package/.next/server/chunks/2546.js +1 -1
  323. package/.next/server/chunks/2689.js +13 -0
  324. package/.next/server/chunks/2759.js +8 -0
  325. package/.next/server/chunks/2839.js +1 -0
  326. package/.next/server/chunks/3241.js +1 -1
  327. package/.next/server/chunks/3292.js +1 -0
  328. package/.next/server/chunks/3417.js +1 -1
  329. package/.next/server/chunks/3480.js +1 -17
  330. package/.next/server/chunks/4393.js +1 -1
  331. package/.next/server/chunks/4423.js +1 -0
  332. package/.next/server/chunks/4444.js +22 -8
  333. package/.next/server/chunks/4565.js +3 -0
  334. package/.next/server/chunks/467.js +1 -0
  335. package/.next/server/chunks/4905.js +5 -0
  336. package/.next/server/chunks/5017.js +1 -0
  337. package/.next/server/chunks/5089.js +1 -0
  338. package/.next/server/chunks/5164.js +1 -1
  339. package/.next/server/chunks/5220.js +1 -0
  340. package/.next/server/chunks/5354.js +1 -0
  341. package/.next/server/chunks/552.js +19 -0
  342. package/.next/server/chunks/5571.js +1 -1
  343. package/.next/server/chunks/5998.js +3 -3
  344. package/.next/server/chunks/6130.js +1 -1
  345. package/.next/server/chunks/6274.js +11 -11
  346. package/.next/server/chunks/6285.js +1 -1
  347. package/.next/server/chunks/6401.js +1 -1
  348. package/.next/server/chunks/6781.js +1 -1
  349. package/.next/server/chunks/7472.js +1 -0
  350. package/.next/server/chunks/7506.js +1 -0
  351. package/.next/server/chunks/848.js +1 -1
  352. package/.next/server/chunks/8536.js +1 -1
  353. package/.next/server/chunks/880.js +1 -1
  354. package/.next/server/chunks/8807.js +5 -5
  355. package/.next/server/chunks/9067.js +1 -1
  356. package/.next/server/chunks/9284.js +1 -0
  357. package/.next/server/chunks/9358.js +1 -1
  358. package/.next/server/chunks/9508.js +1 -0
  359. package/.next/server/chunks/9938.js +1 -0
  360. package/.next/server/middleware-build-manifest.js +1 -1
  361. package/.next/server/middleware-manifest.json +5 -5
  362. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  363. package/.next/server/pages/500.html +1 -1
  364. package/.next/server/server-reference-manifest.json +1 -1
  365. package/.next/static/9IXgWfBUtnEnRqnbmErTp/_buildManifest.js +1 -0
  366. package/.next/static/chunks/{2053-dfac2d49227cc942.js → 2053-c0e931eb4391baa1.js} +1 -1
  367. package/.next/static/chunks/3361-5d6e93fba8a92bc1.js +1 -0
  368. package/.next/static/chunks/3922.0d2e64daf9f187da.js +1 -0
  369. package/.next/static/chunks/{5229-35f9acab97a553c5.js → 5229-1f5f19740a8d6c11.js} +1 -1
  370. package/.next/static/chunks/{6381-0e097c0286155883.js → 6381-8cfe50a5ca5425b1.js} +1 -1
  371. package/.next/static/chunks/{8649-f551b0010dba4986.js → 8521-c43994fb58501d13.js} +1 -1
  372. package/.next/static/chunks/app/api/app/update/route-6add0d88e2828c23.js +1 -0
  373. package/.next/static/chunks/app/api/app/update-check/route-6add0d88e2828c23.js +1 -0
  374. package/.next/static/chunks/app/api/assistant/conversation/route-6add0d88e2828c23.js +1 -0
  375. package/.next/static/chunks/app/api/assistant/current-output/route-6add0d88e2828c23.js +1 -0
  376. package/.next/static/chunks/app/api/assistant/messages/route-6add0d88e2828c23.js +1 -0
  377. package/.next/static/chunks/app/api/assistant/session/route-6add0d88e2828c23.js +1 -0
  378. package/.next/static/chunks/app/api/assistant/start/route-6add0d88e2828c23.js +1 -0
  379. package/.next/static/chunks/app/api/assistant/terminal/route-6add0d88e2828c23.js +1 -0
  380. package/.next/static/chunks/app/api/assistant/tools/route-6add0d88e2828c23.js +1 -0
  381. package/.next/static/chunks/app/api/auth/login/route-6add0d88e2828c23.js +1 -0
  382. package/.next/static/chunks/app/api/auth/logout/route-6add0d88e2828c23.js +1 -0
  383. package/.next/static/chunks/app/api/auth/status/route-6add0d88e2828c23.js +1 -0
  384. package/.next/static/chunks/app/api/capabilities/route-6add0d88e2828c23.js +1 -0
  385. package/.next/static/chunks/app/api/daily-summary/route-6add0d88e2828c23.js +1 -0
  386. package/.next/static/chunks/app/api/daily-summary/status/route-6add0d88e2828c23.js +1 -0
  387. package/.next/static/chunks/app/api/external-apps/[id]/health/route-6add0d88e2828c23.js +1 -0
  388. package/.next/static/chunks/app/api/external-apps/[id]/route-6add0d88e2828c23.js +1 -0
  389. package/.next/static/chunks/app/api/external-apps/route-6add0d88e2828c23.js +1 -0
  390. package/.next/static/chunks/app/api/fs/browse/route-6add0d88e2828c23.js +1 -0
  391. package/.next/static/chunks/app/api/fs/recent-paths/route-6add0d88e2828c23.js +1 -0
  392. package/.next/static/chunks/app/api/hooks/agent-event/route-6add0d88e2828c23.js +1 -0
  393. package/.next/static/chunks/app/api/hooks/claude-done/route-6add0d88e2828c23.js +1 -0
  394. package/.next/static/chunks/app/api/hooks/permission-request/route-6add0d88e2828c23.js +1 -0
  395. package/.next/static/chunks/app/api/metrics/vibe/route-6add0d88e2828c23.js +1 -0
  396. package/.next/static/chunks/app/api/ollama/models/route-6add0d88e2828c23.js +1 -0
  397. package/.next/static/chunks/app/api/push/escalation/route-6add0d88e2828c23.js +1 -0
  398. package/.next/static/chunks/app/api/push/subscriptions/route-6add0d88e2828c23.js +1 -0
  399. package/.next/static/chunks/app/api/push/vapid/route-6add0d88e2828c23.js +1 -0
  400. package/.next/static/chunks/app/api/repositories/[id]/route-6add0d88e2828c23.js +1 -0
  401. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-6add0d88e2828c23.js +1 -0
  402. package/.next/static/chunks/app/api/repositories/[id]/todos/route-6add0d88e2828c23.js +1 -0
  403. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-6add0d88e2828c23.js +1 -0
  404. package/.next/static/chunks/app/api/repositories/clone/route-6add0d88e2828c23.js +1 -0
  405. package/.next/static/chunks/app/api/repositories/excluded/route-6add0d88e2828c23.js +1 -0
  406. package/.next/static/chunks/app/api/repositories/restore/route-6add0d88e2828c23.js +1 -0
  407. package/.next/static/chunks/app/api/repositories/route-6add0d88e2828c23.js +1 -0
  408. package/.next/static/chunks/app/api/repositories/scan/route-6add0d88e2828c23.js +1 -0
  409. package/.next/static/chunks/app/api/repositories/sync/route-6add0d88e2828c23.js +1 -0
  410. package/.next/static/chunks/app/api/repositories/validate-path/route-6add0d88e2828c23.js +1 -0
  411. package/.next/static/chunks/app/api/sidebar/group-order/route-6add0d88e2828c23.js +1 -0
  412. package/.next/static/chunks/app/api/skills/[id]/route-6add0d88e2828c23.js +1 -0
  413. package/.next/static/chunks/app/api/skills/installations/route-6add0d88e2828c23.js +1 -0
  414. package/.next/static/chunks/app/api/skills/operations/route-6add0d88e2828c23.js +1 -0
  415. package/.next/static/chunks/app/api/skills/reindex/route-6add0d88e2828c23.js +1 -0
  416. package/.next/static/chunks/app/api/skills/route-6add0d88e2828c23.js +1 -0
  417. package/.next/static/chunks/app/api/slash-commands/route-6add0d88e2828c23.js +1 -0
  418. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-6add0d88e2828c23.js +1 -0
  419. package/.next/static/chunks/app/api/tasks/[taskId]/route-6add0d88e2828c23.js +1 -0
  420. package/.next/static/chunks/app/api/templates/[id]/route-6add0d88e2828c23.js +1 -0
  421. package/.next/static/chunks/app/api/templates/route-6add0d88e2828c23.js +1 -0
  422. package/.next/static/chunks/app/api/todos/route-6add0d88e2828c23.js +1 -0
  423. package/.next/static/chunks/app/api/verification/runs/[runId]/route-6add0d88e2828c23.js +1 -0
  424. package/.next/static/chunks/app/api/verification/runs/route-6add0d88e2828c23.js +1 -0
  425. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-6add0d88e2828c23.js +1 -0
  426. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-6add0d88e2828c23.js +1 -0
  427. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-6add0d88e2828c23.js +1 -0
  428. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-6add0d88e2828c23.js +1 -0
  429. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-6add0d88e2828c23.js +1 -0
  430. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-6add0d88e2828c23.js +1 -0
  431. package/.next/static/chunks/app/api/worktrees/[id]/env/route-6add0d88e2828c23.js +1 -0
  432. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-6add0d88e2828c23.js +1 -0
  433. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-6add0d88e2828c23.js +1 -0
  434. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-6add0d88e2828c23.js +1 -0
  435. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-6add0d88e2828c23.js +1 -0
  436. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-6add0d88e2828c23.js +1 -0
  437. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-6add0d88e2828c23.js +1 -0
  438. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-6add0d88e2828c23.js +1 -0
  439. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-6add0d88e2828c23.js +1 -0
  440. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-6add0d88e2828c23.js +1 -0
  441. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-6add0d88e2828c23.js +1 -0
  442. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-6add0d88e2828c23.js +1 -0
  443. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-6add0d88e2828c23.js +1 -0
  444. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-6add0d88e2828c23.js +1 -0
  445. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-6add0d88e2828c23.js +1 -0
  446. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-6add0d88e2828c23.js +1 -0
  447. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-6add0d88e2828c23.js +1 -0
  448. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-6add0d88e2828c23.js +1 -0
  449. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-6add0d88e2828c23.js +1 -0
  450. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-6add0d88e2828c23.js +1 -0
  451. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-6add0d88e2828c23.js +1 -0
  452. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-6add0d88e2828c23.js +1 -0
  453. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-6add0d88e2828c23.js +1 -0
  454. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-6add0d88e2828c23.js +1 -0
  455. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-6add0d88e2828c23.js +1 -0
  456. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-6add0d88e2828c23.js +1 -0
  457. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-6add0d88e2828c23.js +1 -0
  458. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-6add0d88e2828c23.js +1 -0
  459. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-6add0d88e2828c23.js +1 -0
  460. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-6add0d88e2828c23.js +1 -0
  461. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-6add0d88e2828c23.js +1 -0
  462. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-6add0d88e2828c23.js +1 -0
  463. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-6add0d88e2828c23.js +1 -0
  464. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-6add0d88e2828c23.js +1 -0
  465. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-6add0d88e2828c23.js +1 -0
  466. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-6add0d88e2828c23.js +1 -0
  467. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-6add0d88e2828c23.js +1 -0
  468. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-6add0d88e2828c23.js +1 -0
  469. package/.next/static/chunks/app/api/worktrees/[id]/route-6add0d88e2828c23.js +1 -0
  470. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-6add0d88e2828c23.js +1 -0
  471. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-6add0d88e2828c23.js +1 -0
  472. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-6add0d88e2828c23.js +1 -0
  473. package/.next/static/chunks/app/api/worktrees/[id]/search/route-6add0d88e2828c23.js +1 -0
  474. package/.next/static/chunks/app/api/worktrees/[id]/send/route-6add0d88e2828c23.js +1 -0
  475. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-6add0d88e2828c23.js +1 -0
  476. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-6add0d88e2828c23.js +1 -0
  477. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-6add0d88e2828c23.js +1 -0
  478. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-6add0d88e2828c23.js +1 -0
  479. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-6add0d88e2828c23.js +1 -0
  480. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-6add0d88e2828c23.js +1 -0
  481. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-6add0d88e2828c23.js +1 -0
  482. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-6add0d88e2828c23.js +1 -0
  483. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-6add0d88e2828c23.js +1 -0
  484. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-6add0d88e2828c23.js +1 -0
  485. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-6add0d88e2828c23.js +1 -0
  486. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-6add0d88e2828c23.js +1 -0
  487. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-6add0d88e2828c23.js +1 -0
  488. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-6add0d88e2828c23.js +1 -0
  489. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-6add0d88e2828c23.js +1 -0
  490. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-6add0d88e2828c23.js +1 -0
  491. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-6add0d88e2828c23.js +1 -0
  492. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-6add0d88e2828c23.js +1 -0
  493. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-6add0d88e2828c23.js +1 -0
  494. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-6add0d88e2828c23.js +1 -0
  495. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-6add0d88e2828c23.js +1 -0
  496. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-6add0d88e2828c23.js +1 -0
  497. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-6add0d88e2828c23.js +1 -0
  498. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-6add0d88e2828c23.js +1 -0
  499. package/.next/static/chunks/app/api/worktrees/route-6add0d88e2828c23.js +1 -0
  500. package/.next/static/chunks/app/chat/{page-439b35c9cb90dbe0.js → page-231df45127e876c2.js} +1 -1
  501. package/.next/static/chunks/app/login/{page-eefd515d8c37e5ee.js → page-adc51f0f7cbb7ac6.js} +1 -1
  502. package/.next/static/chunks/app/manifest.webmanifest/route-6add0d88e2828c23.js +1 -0
  503. package/.next/static/chunks/app/more/{page-889b7546a8a553dc.js → page-3266dfa945972649.js} +1 -1
  504. package/.next/static/chunks/app/{page-a8d04ac0e3e4c9fc.js → page-0305431f43195431.js} +1 -1
  505. package/.next/static/chunks/app/proxy/[...path]/route-6add0d88e2828c23.js +1 -0
  506. package/.next/static/chunks/app/repositories/{page-f3c4d8839b1ca203.js → page-ae8fa55749976f79.js} +1 -1
  507. package/.next/static/chunks/app/review/{page-6dc88649fe88ac16.js → page-8f63aff862fee421.js} +1 -1
  508. package/.next/static/chunks/app/sessions/{page-2c9ed9e969097688.js → page-4d5382b257077c14.js} +1 -1
  509. package/.next/static/chunks/app/skills/[skillId]/{page-19beef6121c4c982.js → page-aaf0bcb1dfb558b9.js} +1 -1
  510. package/.next/static/chunks/app/skills/installed/{page-d5b9cef6d21fabda.js → page-dafc486410e839b7.js} +1 -1
  511. package/.next/static/chunks/app/skills/{page-06ef637e07dd9377.js → page-9e3c91da31514893.js} +1 -1
  512. package/.next/static/chunks/app/worktrees/[id]/files/[...path]/{page-5fed3984fafcd910.js → page-90f96977c741bbf8.js} +1 -1
  513. package/.next/static/chunks/app/worktrees/[id]/layout-6add0d88e2828c23.js +1 -0
  514. package/.next/static/chunks/app/worktrees/[id]/page-f7b3dfbe757dc6b8.js +1 -0
  515. package/.next/static/chunks/{webpack-9d892a9ff07c289d.js → webpack-6a9668cf54a26eba.js} +1 -1
  516. package/.next/static/css/928e5a8830fbf997.css +1 -0
  517. package/.next/trace +13 -12
  518. package/.next/types/app/api/capabilities/route.ts +347 -0
  519. package/.next/types/app/api/worktrees/[id]/clear-composer/route.ts +347 -0
  520. package/.next/types/app/api/worktrees/[id]/env/route.ts +347 -0
  521. package/.next/types/app/api/worktrees/[id]/resolve-target/route.ts +347 -0
  522. package/.next/types/routes.d.ts +5 -1
  523. package/.next/types/validator.ts +36 -0
  524. package/dist/cli/commands/auto-yes.d.ts.map +1 -1
  525. package/dist/cli/commands/auto-yes.js +40 -2
  526. package/dist/cli/commands/capture.d.ts.map +1 -1
  527. package/dist/cli/commands/capture.js +28 -13
  528. package/dist/cli/commands/instances.d.ts +30 -18
  529. package/dist/cli/commands/instances.d.ts.map +1 -1
  530. package/dist/cli/commands/instances.js +32 -36
  531. package/dist/cli/commands/ls.d.ts.map +1 -1
  532. package/dist/cli/commands/ls.js +73 -1
  533. package/dist/cli/commands/respond.d.ts.map +1 -1
  534. package/dist/cli/commands/respond.js +18 -1
  535. package/dist/cli/commands/send.d.ts.map +1 -1
  536. package/dist/cli/commands/send.js +21 -15
  537. package/dist/cli/commands/status.d.ts.map +1 -1
  538. package/dist/cli/commands/status.js +38 -0
  539. package/dist/cli/commands/wait.d.ts +26 -0
  540. package/dist/cli/commands/wait.d.ts.map +1 -1
  541. package/dist/cli/commands/wait.js +390 -43
  542. package/dist/cli/config/cli-dependencies.d.ts.map +1 -1
  543. package/dist/cli/config/cli-dependencies.js +16 -0
  544. package/dist/cli/config/cli-tool-ids.d.ts +11 -0
  545. package/dist/cli/config/cli-tool-ids.d.ts.map +1 -1
  546. package/dist/cli/config/cli-tool-ids.js +12 -1
  547. package/dist/cli/types/api-responses.d.ts +443 -2
  548. package/dist/cli/types/api-responses.d.ts.map +1 -1
  549. package/dist/cli/utils/api-client.d.ts +18 -0
  550. package/dist/cli/utils/api-client.d.ts.map +1 -1
  551. package/dist/cli/utils/api-client.js +22 -0
  552. package/dist/cli/utils/server-capabilities.d.ts +56 -0
  553. package/dist/cli/utils/server-capabilities.d.ts.map +1 -0
  554. package/dist/cli/utils/server-capabilities.js +166 -0
  555. package/dist/cli/utils/session-target.d.ts +70 -0
  556. package/dist/cli/utils/session-target.d.ts.map +1 -0
  557. package/dist/cli/utils/session-target.js +118 -0
  558. package/dist/lib/cli-tools/copilot-executable.d.ts +79 -0
  559. package/dist/lib/cli-tools/copilot-executable.d.ts.map +1 -0
  560. package/dist/lib/cli-tools/copilot-executable.js +155 -0
  561. package/dist/lib/cli-tools/types.d.ts +61 -0
  562. package/dist/lib/cli-tools/types.d.ts.map +1 -1
  563. package/dist/lib/cli-tools/types.js +41 -0
  564. package/dist/lib/detection/ansi.d.ts +2 -1
  565. package/dist/lib/detection/ansi.d.ts.map +1 -1
  566. package/dist/lib/detection/ansi.js +3 -2
  567. package/dist/lib/detection/tools/verified-against.d.ts +84 -0
  568. package/dist/lib/detection/tools/verified-against.d.ts.map +1 -0
  569. package/dist/lib/detection/tools/verified-against.js +88 -0
  570. package/dist/lib/detection/version-probes.d.ts +207 -0
  571. package/dist/lib/detection/version-probes.d.ts.map +1 -0
  572. package/dist/lib/detection/version-probes.js +290 -0
  573. package/dist/lib/security/env-sanitizer.d.ts +198 -0
  574. package/dist/lib/security/env-sanitizer.d.ts.map +1 -0
  575. package/dist/lib/security/env-sanitizer.js +232 -0
  576. package/dist/server/locales/en/notifications.json +17 -6
  577. package/dist/server/locales/ja/notifications.json +17 -6
  578. package/dist/server/src/config/activity-bar-config.js +4 -0
  579. package/dist/server/src/config/cli-tool-timing-config.js +59 -2
  580. package/dist/server/src/config/copilot-constants.js +11 -1
  581. package/dist/server/src/config/detection-evidence-config.js +129 -0
  582. package/dist/server/src/config/schedule-config.js +56 -7
  583. package/dist/server/src/config/tmux-pane-config.js +18 -1
  584. package/dist/server/src/lib/auto-yes-poller.js +36 -0
  585. package/dist/server/src/lib/cli-tools/antigravity.js +4 -2
  586. package/dist/server/src/lib/cli-tools/base.js +131 -10
  587. package/dist/server/src/lib/cli-tools/capture-spec.js +56 -0
  588. package/dist/server/src/lib/cli-tools/claude.js +1 -1
  589. package/dist/server/src/lib/cli-tools/codex.js +6 -2
  590. package/dist/server/src/lib/cli-tools/composer-spec.js +96 -0
  591. package/dist/server/src/lib/cli-tools/copilot-executable.js +155 -0
  592. package/dist/server/src/lib/cli-tools/copilot.js +307 -81
  593. package/dist/server/src/lib/cli-tools/gemini.js +8 -6
  594. package/dist/server/src/lib/cli-tools/graceful-exit.js +181 -0
  595. package/dist/server/src/lib/cli-tools/index.js +11 -1
  596. package/dist/server/src/lib/cli-tools/manager.js +56 -4
  597. package/dist/server/src/lib/cli-tools/opencode-config.js +195 -24
  598. package/dist/server/src/lib/cli-tools/opencode.js +233 -30
  599. package/dist/server/src/lib/cli-tools/session-name.js +57 -0
  600. package/dist/server/src/lib/cli-tools/submit-verified-sender.js +213 -30
  601. package/dist/server/src/lib/cli-tools/types.js +41 -0
  602. package/dist/server/src/lib/cli-tools/vibe-local.js +7 -3
  603. package/dist/server/src/lib/cmate-cli-tool-parser.js +29 -1
  604. package/dist/server/src/lib/cmate-parser.js +12 -4
  605. package/dist/server/src/lib/db/db.js +5 -1
  606. package/dist/server/src/lib/db/migrations/v41-push-subscriptions.js +11 -0
  607. package/dist/server/src/lib/db/push-subscriptions-db.js +60 -3
  608. package/dist/server/src/lib/detection/ansi.js +3 -2
  609. package/dist/server/src/lib/detection/cli-patterns.js +901 -67
  610. package/dist/server/src/lib/detection/composer-text.js +455 -0
  611. package/dist/server/src/lib/detection/idle-evidence-observation.js +51 -0
  612. package/dist/server/src/lib/detection/model-info-extractor.js +195 -4
  613. package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +19 -0
  614. package/dist/server/src/lib/detection/status-detector.js +76 -675
  615. package/dist/server/src/lib/detection/status-reason.js +57 -0
  616. package/dist/server/src/lib/detection/tools/antigravity/detect.js +75 -0
  617. package/dist/server/src/lib/detection/tools/claude/detect.js +144 -0
  618. package/dist/server/src/lib/detection/tools/claude/patterns.js +98 -0
  619. package/dist/server/src/lib/detection/tools/claude/prompt.js +124 -0
  620. package/dist/server/src/lib/detection/tools/codex/detect.js +343 -0
  621. package/dist/server/src/lib/detection/tools/codex/prompt.js +104 -0
  622. package/dist/server/src/lib/detection/tools/copilot/detect.js +185 -0
  623. package/dist/server/src/lib/detection/tools/copilot/prompt.js +89 -0
  624. package/dist/server/src/lib/detection/tools/dialog-block.js +159 -0
  625. package/dist/server/src/lib/detection/tools/frame.js +47 -0
  626. package/dist/server/src/lib/detection/tools/opencode/detect.js +242 -0
  627. package/dist/server/src/lib/detection/tools/opencode/prompt.js +85 -0
  628. package/dist/server/src/lib/detection/tools/registry.js +58 -0
  629. package/dist/server/src/lib/detection/tools/run-detection.js +202 -0
  630. package/dist/server/src/lib/detection/tools/types.js +34 -0
  631. package/dist/server/src/lib/detection/tools/verified-against.js +88 -0
  632. package/dist/server/src/lib/hooks/agent-event-types.js +19 -1
  633. package/dist/server/src/lib/hooks/permission-adjudication.js +160 -0
  634. package/dist/server/src/lib/hooks/permission-decision-service.js +81 -14
  635. package/dist/server/src/lib/hooks/permission-decision-state.js +62 -0
  636. package/dist/server/src/lib/hooks/permission-request-payload.js +18 -1
  637. package/dist/server/src/lib/hooks/sources/antigravity/source.js +10 -0
  638. package/dist/server/src/lib/hooks/sources/claude/source.js +20 -0
  639. package/dist/server/src/lib/hooks/sources/codex/source.js +10 -0
  640. package/dist/server/src/lib/hooks/sources/copilot/hook-settings.js +403 -50
  641. package/dist/server/src/lib/hooks/sources/copilot/source.js +40 -4
  642. package/dist/server/src/lib/hooks/sources/define-source.js +23 -1
  643. package/dist/server/src/lib/hooks/sources/event-mapper.js +29 -1
  644. package/dist/server/src/lib/hooks/sources/gemini/source.js +10 -0
  645. package/dist/server/src/lib/hooks/sources/index.js +3 -1
  646. package/dist/server/src/lib/hooks/sources/launch-command.js +96 -1
  647. package/dist/server/src/lib/hooks/sources/legacy-relay.js +12 -0
  648. package/dist/server/src/lib/hooks/sources/opencode/client.js +295 -32
  649. package/dist/server/src/lib/hooks/sources/opencode/ingest.js +120 -42
  650. package/dist/server/src/lib/hooks/sources/opencode/mappers.js +95 -3
  651. package/dist/server/src/lib/hooks/sources/opencode/ports.js +70 -9
  652. package/dist/server/src/lib/hooks/sources/opencode/runtime.js +62 -4
  653. package/dist/server/src/lib/hooks/sources/opencode/source.js +54 -3
  654. package/dist/server/src/lib/hooks/sources/opencode/subscription.js +254 -26
  655. package/dist/server/src/lib/hooks/sources/opencode/turn-gate.js +119 -4
  656. package/dist/server/src/lib/hooks/sources/pending-decisions.js +40 -2
  657. package/dist/server/src/lib/hooks/tool-input-normalization-state.js +67 -0
  658. package/dist/server/src/lib/hooks/tool-input-normalization.js +157 -0
  659. package/dist/server/src/lib/job-executor.js +16 -4
  660. package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +184 -0
  661. package/dist/server/src/lib/polling/response-checker.js +243 -26
  662. package/dist/server/src/lib/push/failure-episode-state.js +127 -0
  663. package/dist/server/src/lib/push/failure-push-notifier.js +344 -0
  664. package/dist/server/src/lib/push/index.js +35 -1
  665. package/dist/server/src/lib/push/prompt-card-state.js +93 -0
  666. package/dist/server/src/lib/push/prompt-push-gate.js +130 -0
  667. package/dist/server/src/lib/push/push-sender.js +82 -7
  668. package/dist/server/src/lib/push/resolution-push-notifier.js +193 -0
  669. package/dist/server/src/lib/push/waiting-push-notifier.js +42 -0
  670. package/dist/server/src/lib/response-cleaner.js +93 -20
  671. package/dist/server/src/lib/response-extractor.js +98 -5
  672. package/dist/server/src/lib/security/env-sanitizer.js +179 -5
  673. package/dist/server/src/lib/session/agent-event-state.js +1038 -189
  674. package/dist/server/src/lib/session/agent-session-lifecycle.js +8 -0
  675. package/dist/server/src/lib/session/claude-executor.js +23 -3
  676. package/dist/server/src/lib/session/claude-session.js +11 -1
  677. package/dist/server/src/lib/session/composer-clear.js +95 -0
  678. package/dist/server/src/lib/session/current-output-builder.js +267 -25
  679. package/dist/server/src/lib/session/provisional-turn.js +310 -0
  680. package/dist/server/src/lib/session/resolve-session-target.js +156 -0
  681. package/dist/server/src/lib/session/send-user-message.js +14 -18
  682. package/dist/server/src/lib/session/session-start-error.js +53 -1
  683. package/dist/server/src/lib/session/status-evidence.js +217 -0
  684. package/dist/server/src/lib/session/structured-prompt.js +46 -4
  685. package/dist/server/src/lib/session/waiting-episode-state.js +24 -0
  686. package/dist/server/src/lib/tmux/key-sequence.js +120 -0
  687. package/dist/server/src/lib/tmux/tmux.js +91 -19
  688. package/dist/server/src/lib/tui-accumulator.js +68 -1
  689. package/dist/server/src/lib/verification/gate-runner.js +84 -1
  690. package/dist/server/src/lib/ws-server.js +8 -5
  691. package/dist/server/src/types/cli-tool-contracts.js +75 -0
  692. package/dist/server/src/types/terminal-keys.js +37 -0
  693. package/dist/types/cli-tool-contracts.d.ts +235 -0
  694. package/dist/types/cli-tool-contracts.d.ts.map +1 -0
  695. package/dist/types/cli-tool-contracts.js +75 -0
  696. package/package.json +3 -2
  697. package/public/sw.js +65 -2
  698. package/.next/server/chunks/1841.js +0 -1
  699. package/.next/server/chunks/233.js +0 -1
  700. package/.next/server/chunks/3022.js +0 -1
  701. package/.next/server/chunks/3270.js +0 -1
  702. package/.next/server/chunks/4455.js +0 -1
  703. package/.next/server/chunks/5959.js +0 -27
  704. package/.next/server/chunks/7458.js +0 -6
  705. package/.next/server/chunks/8730.js +0 -1
  706. package/.next/server/chunks/9058.js +0 -1
  707. package/.next/server/chunks/9687.js +0 -3
  708. package/.next/static/chunks/3898-ef488bfa804507d9.js +0 -1
  709. package/.next/static/chunks/9263.f2034ec525abcf72.js +0 -1
  710. package/.next/static/chunks/app/api/app/update/route-fae89f8d4cc3ff97.js +0 -1
  711. package/.next/static/chunks/app/api/app/update-check/route-fae89f8d4cc3ff97.js +0 -1
  712. package/.next/static/chunks/app/api/assistant/conversation/route-fae89f8d4cc3ff97.js +0 -1
  713. package/.next/static/chunks/app/api/assistant/current-output/route-fae89f8d4cc3ff97.js +0 -1
  714. package/.next/static/chunks/app/api/assistant/messages/route-fae89f8d4cc3ff97.js +0 -1
  715. package/.next/static/chunks/app/api/assistant/session/route-fae89f8d4cc3ff97.js +0 -1
  716. package/.next/static/chunks/app/api/assistant/start/route-fae89f8d4cc3ff97.js +0 -1
  717. package/.next/static/chunks/app/api/assistant/terminal/route-fae89f8d4cc3ff97.js +0 -1
  718. package/.next/static/chunks/app/api/assistant/tools/route-fae89f8d4cc3ff97.js +0 -1
  719. package/.next/static/chunks/app/api/auth/login/route-fae89f8d4cc3ff97.js +0 -1
  720. package/.next/static/chunks/app/api/auth/logout/route-fae89f8d4cc3ff97.js +0 -1
  721. package/.next/static/chunks/app/api/auth/status/route-fae89f8d4cc3ff97.js +0 -1
  722. package/.next/static/chunks/app/api/daily-summary/route-fae89f8d4cc3ff97.js +0 -1
  723. package/.next/static/chunks/app/api/daily-summary/status/route-fae89f8d4cc3ff97.js +0 -1
  724. package/.next/static/chunks/app/api/external-apps/[id]/health/route-fae89f8d4cc3ff97.js +0 -1
  725. package/.next/static/chunks/app/api/external-apps/[id]/route-fae89f8d4cc3ff97.js +0 -1
  726. package/.next/static/chunks/app/api/external-apps/route-fae89f8d4cc3ff97.js +0 -1
  727. package/.next/static/chunks/app/api/fs/browse/route-fae89f8d4cc3ff97.js +0 -1
  728. package/.next/static/chunks/app/api/fs/recent-paths/route-fae89f8d4cc3ff97.js +0 -1
  729. package/.next/static/chunks/app/api/hooks/agent-event/route-fae89f8d4cc3ff97.js +0 -1
  730. package/.next/static/chunks/app/api/hooks/claude-done/route-fae89f8d4cc3ff97.js +0 -1
  731. package/.next/static/chunks/app/api/hooks/permission-request/route-fae89f8d4cc3ff97.js +0 -1
  732. package/.next/static/chunks/app/api/metrics/vibe/route-fae89f8d4cc3ff97.js +0 -1
  733. package/.next/static/chunks/app/api/ollama/models/route-fae89f8d4cc3ff97.js +0 -1
  734. package/.next/static/chunks/app/api/push/escalation/route-fae89f8d4cc3ff97.js +0 -1
  735. package/.next/static/chunks/app/api/push/subscriptions/route-fae89f8d4cc3ff97.js +0 -1
  736. package/.next/static/chunks/app/api/push/vapid/route-fae89f8d4cc3ff97.js +0 -1
  737. package/.next/static/chunks/app/api/repositories/[id]/route-fae89f8d4cc3ff97.js +0 -1
  738. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-fae89f8d4cc3ff97.js +0 -1
  739. package/.next/static/chunks/app/api/repositories/[id]/todos/route-fae89f8d4cc3ff97.js +0 -1
  740. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-fae89f8d4cc3ff97.js +0 -1
  741. package/.next/static/chunks/app/api/repositories/clone/route-fae89f8d4cc3ff97.js +0 -1
  742. package/.next/static/chunks/app/api/repositories/excluded/route-fae89f8d4cc3ff97.js +0 -1
  743. package/.next/static/chunks/app/api/repositories/restore/route-fae89f8d4cc3ff97.js +0 -1
  744. package/.next/static/chunks/app/api/repositories/route-fae89f8d4cc3ff97.js +0 -1
  745. package/.next/static/chunks/app/api/repositories/scan/route-fae89f8d4cc3ff97.js +0 -1
  746. package/.next/static/chunks/app/api/repositories/sync/route-fae89f8d4cc3ff97.js +0 -1
  747. package/.next/static/chunks/app/api/repositories/validate-path/route-fae89f8d4cc3ff97.js +0 -1
  748. package/.next/static/chunks/app/api/sidebar/group-order/route-fae89f8d4cc3ff97.js +0 -1
  749. package/.next/static/chunks/app/api/skills/[id]/route-fae89f8d4cc3ff97.js +0 -1
  750. package/.next/static/chunks/app/api/skills/installations/route-fae89f8d4cc3ff97.js +0 -1
  751. package/.next/static/chunks/app/api/skills/operations/route-fae89f8d4cc3ff97.js +0 -1
  752. package/.next/static/chunks/app/api/skills/reindex/route-fae89f8d4cc3ff97.js +0 -1
  753. package/.next/static/chunks/app/api/skills/route-fae89f8d4cc3ff97.js +0 -1
  754. package/.next/static/chunks/app/api/slash-commands/route-fae89f8d4cc3ff97.js +0 -1
  755. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-fae89f8d4cc3ff97.js +0 -1
  756. package/.next/static/chunks/app/api/tasks/[taskId]/route-fae89f8d4cc3ff97.js +0 -1
  757. package/.next/static/chunks/app/api/templates/[id]/route-fae89f8d4cc3ff97.js +0 -1
  758. package/.next/static/chunks/app/api/templates/route-fae89f8d4cc3ff97.js +0 -1
  759. package/.next/static/chunks/app/api/todos/route-fae89f8d4cc3ff97.js +0 -1
  760. package/.next/static/chunks/app/api/verification/runs/[runId]/route-fae89f8d4cc3ff97.js +0 -1
  761. package/.next/static/chunks/app/api/verification/runs/route-fae89f8d4cc3ff97.js +0 -1
  762. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-fae89f8d4cc3ff97.js +0 -1
  763. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-fae89f8d4cc3ff97.js +0 -1
  764. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-fae89f8d4cc3ff97.js +0 -1
  765. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-fae89f8d4cc3ff97.js +0 -1
  766. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-fae89f8d4cc3ff97.js +0 -1
  767. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-fae89f8d4cc3ff97.js +0 -1
  768. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-fae89f8d4cc3ff97.js +0 -1
  769. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-fae89f8d4cc3ff97.js +0 -1
  770. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-fae89f8d4cc3ff97.js +0 -1
  771. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-fae89f8d4cc3ff97.js +0 -1
  772. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-fae89f8d4cc3ff97.js +0 -1
  773. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-fae89f8d4cc3ff97.js +0 -1
  774. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-fae89f8d4cc3ff97.js +0 -1
  775. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-fae89f8d4cc3ff97.js +0 -1
  776. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-fae89f8d4cc3ff97.js +0 -1
  777. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-fae89f8d4cc3ff97.js +0 -1
  778. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-fae89f8d4cc3ff97.js +0 -1
  779. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-fae89f8d4cc3ff97.js +0 -1
  780. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-fae89f8d4cc3ff97.js +0 -1
  781. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-fae89f8d4cc3ff97.js +0 -1
  782. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-fae89f8d4cc3ff97.js +0 -1
  783. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-fae89f8d4cc3ff97.js +0 -1
  784. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-fae89f8d4cc3ff97.js +0 -1
  785. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-fae89f8d4cc3ff97.js +0 -1
  786. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-fae89f8d4cc3ff97.js +0 -1
  787. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-fae89f8d4cc3ff97.js +0 -1
  788. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-fae89f8d4cc3ff97.js +0 -1
  789. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-fae89f8d4cc3ff97.js +0 -1
  790. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-fae89f8d4cc3ff97.js +0 -1
  791. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-fae89f8d4cc3ff97.js +0 -1
  792. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-fae89f8d4cc3ff97.js +0 -1
  793. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-fae89f8d4cc3ff97.js +0 -1
  794. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-fae89f8d4cc3ff97.js +0 -1
  795. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-fae89f8d4cc3ff97.js +0 -1
  796. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-fae89f8d4cc3ff97.js +0 -1
  797. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-fae89f8d4cc3ff97.js +0 -1
  798. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-fae89f8d4cc3ff97.js +0 -1
  799. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-fae89f8d4cc3ff97.js +0 -1
  800. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-fae89f8d4cc3ff97.js +0 -1
  801. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-fae89f8d4cc3ff97.js +0 -1
  802. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-fae89f8d4cc3ff97.js +0 -1
  803. package/.next/static/chunks/app/api/worktrees/[id]/route-fae89f8d4cc3ff97.js +0 -1
  804. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-fae89f8d4cc3ff97.js +0 -1
  805. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-fae89f8d4cc3ff97.js +0 -1
  806. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-fae89f8d4cc3ff97.js +0 -1
  807. package/.next/static/chunks/app/api/worktrees/[id]/search/route-fae89f8d4cc3ff97.js +0 -1
  808. package/.next/static/chunks/app/api/worktrees/[id]/send/route-fae89f8d4cc3ff97.js +0 -1
  809. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-fae89f8d4cc3ff97.js +0 -1
  810. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-fae89f8d4cc3ff97.js +0 -1
  811. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-fae89f8d4cc3ff97.js +0 -1
  812. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-fae89f8d4cc3ff97.js +0 -1
  813. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-fae89f8d4cc3ff97.js +0 -1
  814. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-fae89f8d4cc3ff97.js +0 -1
  815. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-fae89f8d4cc3ff97.js +0 -1
  816. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-fae89f8d4cc3ff97.js +0 -1
  817. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-fae89f8d4cc3ff97.js +0 -1
  818. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-fae89f8d4cc3ff97.js +0 -1
  819. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-fae89f8d4cc3ff97.js +0 -1
  820. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-fae89f8d4cc3ff97.js +0 -1
  821. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-fae89f8d4cc3ff97.js +0 -1
  822. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-fae89f8d4cc3ff97.js +0 -1
  823. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-fae89f8d4cc3ff97.js +0 -1
  824. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-fae89f8d4cc3ff97.js +0 -1
  825. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-fae89f8d4cc3ff97.js +0 -1
  826. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-fae89f8d4cc3ff97.js +0 -1
  827. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-fae89f8d4cc3ff97.js +0 -1
  828. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-fae89f8d4cc3ff97.js +0 -1
  829. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-fae89f8d4cc3ff97.js +0 -1
  830. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-fae89f8d4cc3ff97.js +0 -1
  831. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-fae89f8d4cc3ff97.js +0 -1
  832. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-fae89f8d4cc3ff97.js +0 -1
  833. package/.next/static/chunks/app/api/worktrees/route-fae89f8d4cc3ff97.js +0 -1
  834. package/.next/static/chunks/app/manifest.webmanifest/route-fae89f8d4cc3ff97.js +0 -1
  835. package/.next/static/chunks/app/proxy/[...path]/route-fae89f8d4cc3ff97.js +0 -1
  836. package/.next/static/chunks/app/worktrees/[id]/layout-fae89f8d4cc3ff97.js +0 -1
  837. package/.next/static/chunks/app/worktrees/[id]/page-fdfca039b7f5837e.js +0 -1
  838. package/.next/static/css/e865c4979a41aa03.css +0 -1
  839. package/.next/static/wyFLOpmKpr45BHZ4svYpE/_buildManifest.js +0 -1
  840. /package/.next/static/{wyFLOpmKpr45BHZ4svYpE → 9IXgWfBUtnEnRqnbmErTp}/_ssgManifest.js +0 -0
@@ -4,18 +4,28 @@
4
4
  * Shared between response-poller.ts and API routes
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.CLAUDE_SESSION_ERROR_REGEX_PATTERNS = exports.CLAUDE_SESSION_ERROR_PATTERNS = exports.extractAnsiSequences = exports.stripAnsi = exports.ANTIGRAVITY_SKIP_PATTERNS = exports.ANTIGRAVITY_SELECTION_LIST_PATTERN = exports.ANTIGRAVITY_SEPARATOR_PATTERN = exports.ANTIGRAVITY_THINKING_PATTERN = exports.ANTIGRAVITY_PROMPT_PATTERN = exports.VIBE_LOCAL_THINKING_PATTERN = exports.VIBE_LOCAL_PROMPT_PATTERN = exports.COPILOT_SKIP_PATTERNS = exports.COPILOT_SELECTION_LIST_PATTERN = exports.COPILOT_SEPARATOR_PATTERN = exports.COPILOT_THINKING_PATTERN = exports.COPILOT_PROMPT_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_PROCESSING_INDICATOR = exports.OPENCODE_RESPONSE_COMPLETE = exports.OPENCODE_LOADING_PATTERN = exports.OPENCODE_THINKING_PATTERN = exports.OPENCODE_PROMPT_AFTER_RESPONSE = 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_STATUS_BAR_PATTERN = exports.CODEX_PAGER_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_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;
7
+ exports.COPILOT_SELECTION_FOOTER_PATTERN = exports.COPILOT_BOOT_BANNER_ANCHORS = exports.COPILOT_TRANSCRIPT_CONTINUATION_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_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_STATUS_BAR_PATTERN = exports.CODEX_PAGER_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_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.ANTIGRAVITY_SKIP_PATTERNS = exports.ANTIGRAVITY_SELECTION_LIST_PATTERN = exports.ANTIGRAVITY_SEPARATOR_PATTERN = exports.ANTIGRAVITY_THINKING_PATTERN = exports.ANTIGRAVITY_PROMPT_PATTERN = 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 = void 0;
8
9
  exports.isCodexTurnActive = isCodexTurnActive;
9
10
  exports.findClaudeChromeStart = findClaudeChromeStart;
10
11
  exports.isCodexPromptReady = isCodexPromptReady;
11
12
  exports.getCodexActiveDialog = getCodexActiveDialog;
12
13
  exports.getCodexLifecycleDialog = getCodexLifecycleDialog;
14
+ exports.findOpenCodeChromeStart = findOpenCodeChromeStart;
15
+ exports.findOpenCodeUserEchoEnd = findOpenCodeUserEchoEnd;
16
+ exports.findOpenCodeComposerRows = findOpenCodeComposerRows;
17
+ exports.stripOpenCodeGutter = stripOpenCodeGutter;
18
+ exports.readCopilotStatusBar = readCopilotStatusBar;
19
+ exports.findCopilotChromeStart = findCopilotChromeStart;
20
+ exports.isCopilotSelectionFrame = isCopilotSelectionFrame;
21
+ exports.isCopilotFolderTrustDialog = isCopilotFolderTrustDialog;
13
22
  exports.detectThinking = detectThinking;
14
23
  exports.getCliToolPatterns = getCliToolPatterns;
15
24
  exports.stripBoxDrawing = stripBoxDrawing;
16
25
  exports.buildDetectPromptOptions = buildDetectPromptOptions;
17
26
  const logger_1 = require("../../lib/logger");
18
27
  const ansi_1 = require("./ansi");
28
+ const composer_text_1 = require("./composer-text");
19
29
  const thinking_constants_1 = require("../../config/thinking-constants");
20
30
  const logger = (0, logger_1.createLogger)('cli-patterns');
21
31
  /**
@@ -160,10 +170,6 @@ exports.CLAUDE_PROMPT_PATTERN = /^[>❯](\s*$|\s+\S)/m;
160
170
  * Claude separator pattern
161
171
  */
162
172
  exports.CLAUDE_SEPARATOR_PATTERN = /^─{10,}$/m;
163
- /** How far above the last line the input box's closing separator may sit. */
164
- const CLAUDE_STATUS_BAR_MAX_ROWS = 4;
165
- /** How many rows the input box may span before the block stops looking like the footer. */
166
- const CLAUDE_INPUT_BOX_MAX_ROWS = 40;
167
173
  /**
168
174
  * Locate the start of Claude Code's bottom-pinned footer within a captured pane.
169
175
  *
@@ -192,40 +198,16 @@ const CLAUDE_INPUT_BOX_MAX_ROWS = 40;
192
198
  * @returns Index of the first footer row, or -1 when no footer is present
193
199
  */
194
200
  function findClaudeChromeStart(lines) {
195
- const isSeparator = (line) => /^─{10,}$/.test((0, ansi_1.stripAnsi)(line).trimEnd());
196
- // Callers pass both trimmed panes and raw captures padded with blank rows.
197
- let lastRow = lines.length - 1;
198
- while (lastRow >= 0 && lines[lastRow].trim() === '')
199
- lastRow--;
200
- if (lastRow < 0)
201
- return -1;
202
- // The input box's closing separator sits just above the status bar.
203
- let closingSeparator = -1;
204
- for (let i = lastRow; i >= Math.max(0, lastRow - CLAUDE_STATUS_BAR_MAX_ROWS); i--) {
205
- if (isSeparator(lines[i])) {
206
- closingSeparator = i;
207
- break;
208
- }
209
- }
210
- if (closingSeparator < 0)
211
- return -1;
212
- // Walk up over the input box to the opening separator.
213
- let openingSeparator = -1;
214
- for (let i = closingSeparator - 1; i >= Math.max(0, closingSeparator - CLAUDE_INPUT_BOX_MAX_ROWS); i--) {
215
- if (isSeparator(lines[i])) {
216
- openingSeparator = i;
217
- break;
218
- }
219
- }
220
- if (openingSeparator < 0)
221
- return -1;
222
- // Confirm the rows between the separators really are the input box rather than
223
- // a reply that happens to be fenced by two horizontal rules — truncating one of
224
- // those would silently swallow the tail of a genuine response.
225
- if (!/^[>❯]/.test((0, ansi_1.stripAnsi)(lines[openingSeparator + 1] ?? '')))
201
+ // Issue #1879: the structural search (closing separator → opening separator →
202
+ // prompt glyph, including the "is this really the input box and not a reply
203
+ // fenced by two horizontal rules?" check) moved to `findClaudeInputBox` so the
204
+ // composer reader locates the same box this trimmer does. Behaviour here is
205
+ // unchanged; only the caller of the search moved.
206
+ const box = (0, composer_text_1.findClaudeInputBox)(lines);
207
+ if (box === null)
226
208
  return -1;
227
209
  // Include the reserved hint row directly above the opening separator.
228
- return Math.max(0, openingSeparator - 1);
210
+ return Math.max(0, box.openingSeparator - 1);
229
211
  }
230
212
  /**
231
213
  * Claude trust dialog pattern (Issue #201)
@@ -670,6 +652,36 @@ exports.GEMINI_THINKING_PATTERN = /[\u2800-\u28FF]|Thinking\.\.\./;
670
652
  * Unlike Claude/Codex (which use > or ❯), OpenCode uses a text-based prompt indicator.
671
653
  */
672
654
  exports.OPENCODE_PROMPT_PATTERN = /Ask anything\.\.\./;
655
+ /**
656
+ * OpenCode idle composer pattern (Issue #1883).
657
+ *
658
+ * The `Ask anything...` placeholder as opencode actually draws it: **inside the
659
+ * input box**, behind the box's own gutter (`\u2503`, or `\u2502` on a lighter
660
+ * border style). Two measured facts make that row positive evidence that the
661
+ * composer is empty, rather than the mere absence of a busy marker (design
662
+ * principle D1 in `docs/design/multi-agent-state-architecture.md`):
663
+ *
664
+ * - opencode paints the placeholder **only while the input buffer is empty**.
665
+ * The first typed character replaces the whole row — measured live on
666
+ * opencode 1.18.20, pane 80x200 (`opencode-live-1883/composer-residual.txt`
667
+ * holds `\u2503 echo PREFILLED` where the idle frame holds the placeholder).
668
+ * - the gutter says the row belongs to the input box. `Ask anything...` printed
669
+ * in a response body has no gutter, and reading that as an idle composer is
670
+ * the "the phrase is on screen somewhere" inference D1 forbids.
671
+ *
672
+ * **Match this against the ANSI-stripped frame BEFORE {@link stripBoxDrawing}**,
673
+ * which strips the very gutter this pattern anchors on.
674
+ *
675
+ * The whitespace runs are `[^\S\n]` (horizontal only) on purpose: plain `\s`
676
+ * crosses newlines under the `m` flag, which let the gutter of one row pair up
677
+ * with the phrase several rows below it and matched frames that hold no
678
+ * composer at all (measured on `phrase-in-response.txt`).
679
+ *
680
+ * {@link OPENCODE_PROMPT_PATTERN} stays as it is: `response-checker` and
681
+ * `OPENCODE_SKIP_PATTERNS` want the bare phrase wherever it lands, because they
682
+ * are deleting the row from an extracted response, not judging a session.
683
+ */
684
+ exports.OPENCODE_IDLE_COMPOSER_PATTERN = /^[^\S\n]*[\u2502\u2503][^\S\n]*Ask anything\.\.\./m;
673
685
  /**
674
686
  * OpenCode prompt pattern after response completion (Issue #379)
675
687
  * Shows "tab agents ctrl+p commands" in the TUI status bar after a response finishes.
@@ -689,30 +701,410 @@ exports.OPENCODE_THINKING_PATTERN = /Thinking:/;
689
701
  */
690
702
  exports.OPENCODE_LOADING_PATTERN = /\u2B1D{4,}/;
691
703
  /**
692
- * OpenCode response completion pattern (Issue #379)
693
- * Matches the action summary line: "&#x25A3; {Action} · model" with optional timing "· Ns".
694
- * (U+25A3 square + action word + middle dot + model name [+ middle dot + timing]).
695
- * Action can be "Build", "Compaction", or other OpenCode action names.
696
- * Short responses may omit the timing portion (e.g., "▣ Build · qwen3.5:27b").
697
- * This is the primary completion signal for OpenCode [D2-002].
704
+ * OpenCode's Build summary LINE, in either of the two forms it is drawn in
705
+ * (Issue #379, corrected by Issue #1893).
706
+ *
707
+ * **This is a line filter, not completion evidence.** It matches
708
+ * `▣ <Action> · <model>` with the duration OPTIONAL, and opencode 1.18 draws
709
+ * that duration-less form on a step that is still in flight -- so a frame this
710
+ * pattern matches may be mid-turn, waiting on a permission dialog, or aborted.
711
+ * Use {@link OPENCODE_TURN_COMPLETE_PATTERN} to decide that a turn has finished.
712
+ *
713
+ * The docstring that stood here until #1893 claimed the opposite ("short
714
+ * responses may omit the timing portion"). Measured against opencode 1.18.21 at
715
+ * the production 80x200 geometry, that is wrong in both directions:
716
+ *
717
+ * - a 2.3-second answer still carries its duration
718
+ * (`▣ Build · GPT-5.6 Luna · 2.3s`, `opencode-live-1893/turn-complete-short.txt`),
719
+ * so no completed turn needs the duration-less branch;
720
+ * - the duration-less form is what opencode leaves on screen while a tool call
721
+ * waits for permission and after a rejected one
722
+ * (`opencode-live-1893/permission-bash.txt`, `…/turn-aborted-no-duration.txt`).
723
+ *
724
+ * Kept loose because three callers want the LINE rather than the verdict:
725
+ * `tui-accumulator.ts`, `response-cleaner.ts` and `polling/response-checker.ts`
726
+ * all use it to drop the summary row from an extracted response, and the
727
+ * mid-step row has to be dropped too. #1911 removed the one caller that used it
728
+ * as a turn BOUNDARY rather than a line filter (the "second-to-last ▣" anchor,
729
+ * replaced by {@link findOpenCodeUserEchoEnd}); the name is left alone because
730
+ * the remaining three callers all want the line.
698
731
  */
699
- exports.OPENCODE_RESPONSE_COMPLETE = /\u25A3\s+\w+\s+\u00b7\s+\S+(?:\s+\u00b7\s+(?:[\d]+h\s*)?(?:[\d]+m\s*)?[\d.]+s)?/;
732
+ exports.OPENCODE_RESPONSE_COMPLETE = /\u25A3\s+\w+\s+·\s+\S+(?:\s+·\s+(?:[\d]+h\s*)?(?:[\d]+m\s*)?[\d.]+s)?/;
700
733
  /**
701
- * OpenCode processing indicator pattern (Issue #379)
702
- * Shows "esc interrupt" in the TUI status bar during active model processing.
703
- * Filtered from response extraction via OPENCODE_SKIP_PATTERNS.
734
+ * OpenCode's finished-turn marker: the Build summary line WITH its duration
735
+ * (Issue #1893).
736
+ *
737
+ * `▣ Build · GPT-5.6 Luna · 5.2s`. This is the one tool-specific completion
738
+ * marker design rule D1 recognises today
739
+ * (`docs/design/multi-agent-state-architecture.md` §4 D1 decision 1, item 1),
740
+ * and the duration is the whole of what makes it positive evidence: opencode
741
+ * prints the same row without a duration while a step is still open, which is
742
+ * how a session parked on a permission dialog was published as
743
+ * `ready`/`opencode_response_complete` (#1893) and how `isOpenCodeComplete`
744
+ * saved the dialog body as if it were an answer.
745
+ *
746
+ * The model segment is `[^·\n]+` rather than `\S+` because real model names
747
+ * carry spaces (`GPT-5.6 Luna`): with `\S+` the optional-duration group of
748
+ * {@link OPENCODE_RESPONSE_COMPLETE} could never reach the duration on a
749
+ * two-word model, so "with duration" and "without duration" were the same match
750
+ * there. Excluding the middle dot rather than allowing anything keeps the
751
+ * quantifier unable to swallow its own delimiter (no nested/ambiguous
752
+ * quantifier -- ReDoS safe), and `.`/`[^·\n]` never cross a line without the
753
+ * `m` flag, so the duration has to be on the marker's own row.
754
+ *
755
+ * Durations observed: `2.3s`, `5.2s`, `45.2s`; the `Nh`/`Nm` prefixes are
756
+ * inherited from the #379 pattern and kept for long turns.
757
+ */
758
+ exports.OPENCODE_TURN_COMPLETE_PATTERN = /\u25A3\s+\w+\s+·\s+[^·\n]+·\s+(?:\d+h\s*)?(?:\d+m\s*)?[\d.]+s/;
759
+ /**
760
+ * OpenCode's permission dialog, anchored on its button row (Issue #1893).
761
+ *
762
+ * opencode 1.18 asks for tool permission with a bottom-anchored box whose last
763
+ * interactive row is a horizontal button strip:
764
+ *
765
+ * ```
766
+ * ┃ △ Permission required
767
+ * ┃ # Shell command
768
+ * ┃ $ ls -la
769
+ * ┃ Allow once Allow always Reject ctrl+f fullscreen ⇆ select enter con
770
+ * ```
771
+ *
772
+ * Nothing in the detection layer saw it before #1893: it carries no number, no
773
+ * `(y/n)`, and no "press enter to confirm" footer, so `detectPrompt` answers
774
+ * `isPrompt: false` and the status detector fell through to the Build marker
775
+ * above it. The row is matched as POSITIVE evidence that a decision is pending
776
+ * (design rule D1) -- it is the affordance itself, not the absence of a busy
777
+ * marker.
778
+ *
779
+ * **Match this against the ANSI-stripped frame BEFORE {@link stripBoxDrawing}**,
780
+ * exactly like {@link OPENCODE_IDLE_COMPOSER_PATTERN}: the leading `┃` (or
781
+ * `│` on a lighter border style) is what says the row belongs to the dialog box
782
+ * rather than to a response body that happens to quote the labels -- the
783
+ * "the phrase is on screen somewhere" inference #1883 had to remove.
784
+ *
785
+ * Deliberately NOT anchored on:
786
+ *
787
+ * - `enter confirm`, which is truncated to `enter con` at opencode's own 80
788
+ * column layout (measured);
789
+ * - `△ Permission required` alone, which is a heading rather than an
790
+ * affordance and survives in the fullscreen (`ctrl+f`) view whose key handling
791
+ * was not measured.
792
+ *
793
+ * The three labels are the same for the `bash` and the `edit` dialog (measured:
794
+ * `permission-bash.txt`, `permission-edit.txt`), and the strip is repainted away
795
+ * the moment the dialog is answered, so a matched row is never scrollback
796
+ * (`turn-aborted-no-duration.txt` holds no `Allow once`).
797
+ *
798
+ * The whitespace runs are `[^\S\n]` (horizontal only) for the reason #1883
799
+ * documents: plain `\s` crosses newlines under the `m` flag and would pair a
800
+ * gutter on one row with labels several rows below it.
801
+ */
802
+ exports.OPENCODE_PERMISSION_PATTERN = /^[^\S\n]*[\u2502\u2503][^\S\n]*Allow once[^\S\n]+Allow always[^\S\n]+Reject\b/m;
803
+ /**
804
+ * OpenCode's busy footer, in BOTH of the spellings it is drawn in (Issue #379,
805
+ * widened by Issue #1894).
806
+ *
807
+ * opencode 1.18 needs Escape TWICE to abort a turn, and the first press does not
808
+ * abort anything -- it re-labels the footer:
809
+ *
810
+ * ```
811
+ * ⬝⬝⬝⬝⬝⬝⬝⬝ esc interrupt 6.5K (1%) · $0.00 ctrl+p commands
812
+ * ⬝■■■■■■⬝ esc again to interrupt 7.2K (1%) · $0.00 ctrl+p commands
813
+ * ```
814
+ *
815
+ * Measured on opencode 1.18.21 at the production 80x200 geometry, sampling the
816
+ * footer every ~360 ms after a single Escape: the second spelling is up from
817
+ * 0.31 s to 4.71 s and the row is back to `esc interrupt` at 5.07 s -- a
818
+ * five-second window, exactly as long as the second-press deadline
819
+ * ({@link OPENCODE_INTERRUPT_SECOND_ESCAPE_DELAY_MS} is sized against it). The
820
+ * generation continues throughout; the turn ran to a natural
821
+ * `▣ Build · GPT-5.6 Luna · 11.3s`, 3 runs out of 3.
822
+ *
823
+ * Before #1894 those five seconds matched nothing at all: `detectSessionStatus`
824
+ * lost branch A and fell through to `running`/`default` while the frame was
825
+ * fresh, and to `ready`/`no_recent_output` once the poller's
826
+ * `lastOutputTimestamp` aged past `STALE_OUTPUT_THRESHOLD_MS` -- both of them
827
+ * `statusEvidence: 'none'`, i.e. a generating session
828
+ * published with no evidence and, on the second path, as FINISHED. That is the
829
+ * "vocabulary changed, so `ready` came back" failure design rule D1 names
830
+ * (`docs/design/multi-agent-state-architecture.md` §4 D1, row #1894), and the
831
+ * row is the same positive busy evidence in either spelling.
832
+ *
833
+ * The optional group is `(?:again to )?` rather than a looser `.*` on purpose:
834
+ * it matches the two measured strings and nothing between an `esc` and an
835
+ * `interrupt` several words apart. Linear, no nested quantifiers -- ReDoS safe.
836
+ *
837
+ * Filtered from response extraction via OPENCODE_SKIP_PATTERNS, which shares
838
+ * this constant: the widened row is dropped from a saved answer for the same
839
+ * reason the narrow one was.
704
840
  */
705
- exports.OPENCODE_PROCESSING_INDICATOR = /esc interrupt/;
841
+ exports.OPENCODE_PROCESSING_INDICATOR = /esc (?:again to )?interrupt/;
706
842
  /**
707
- * OpenCode TUI selection list pattern (Issue #473)
708
- * Detects the fuzzy-search selection list overlay in OpenCode TUI
709
- * (e.g., /models, /providers, /connect commands).
843
+ * OpenCode's composer bottom border: ` ╹▀▀▀▀▀▀…` (Issue #1911).
710
844
  *
711
- * Matches header lines of selection overlays. Known headers:
712
- * " Select model esc"
713
- * " Connect a provider esc"
845
+ * `╹` (heavy up) is the corner opencode joins the input box's `┃`
846
+ * gutter to, and the `▀` run is the box's bottom edge. It is the one row of
847
+ * the bottom-anchored chrome that can never appear inside a response body, which
848
+ * makes it the anchor {@link findOpenCodeChromeStart} walks up from.
714
849
  */
715
- exports.OPENCODE_SELECTION_LIST_PATTERN = /^\s*(Select\s+(model|provider)|Connect\s+a\s+provider)/m;
850
+ exports.OPENCODE_COMPOSER_BOTTOM_BORDER = /^[^\S\n]*╹▀{4,}/;
851
+ /**
852
+ * A row that belongs to one of opencode's boxes, matched by its own gutter
853
+ * (Issue #1911).
854
+ *
855
+ * opencode draws three different boxes with the same `┃` gutter (`│`
856
+ * on a lighter border style): the echoed USER PROMPT in the transcript, the
857
+ * COMPOSER pinned to the bottom of the pane, and the PERMISSION DIALOG that
858
+ * replaces the composer. Which one a matched row belongs to is decided by where
859
+ * it sits, not by what it says — see {@link findOpenCodeChromeStart} and
860
+ * {@link findOpenCodeUserEchoEnd}.
861
+ *
862
+ * **Match against the ANSI-stripped frame BEFORE {@link stripBoxDrawing}**,
863
+ * which removes the very gutter this anchors on.
864
+ */
865
+ exports.OPENCODE_GUTTER_ROW_PATTERN = /^[^\S\n]*[│┃]/;
866
+ /**
867
+ * An echoed user prompt row: a gutter row that carries text (Issue #1911).
868
+ *
869
+ * The echo block opencode draws for a submitted message is a blank gutter row,
870
+ * one or more gutter rows holding the message, and another blank gutter row.
871
+ * This matches the middle ones.
872
+ */
873
+ exports.OPENCODE_USER_ECHO_PATTERN = /^[^\S\n]*[│┃][^\S\n]*\S/;
874
+ /**
875
+ * The status cell of opencode's bottom footer (Issue #1911).
876
+ *
877
+ * Measured at the production 80x200 geometry the footer reads
878
+ * `<cwd> 6.4K (1%) · $ctrl+p` / `commands` while idle and
879
+ * `⬝⬝⬝⬝⬝⬝⬝⬝ esc interrupt 6.3K (1%) · $0.00 ctrl+p commands` while running:
880
+ * a context-usage cell followed by the cost sigil. Neither
881
+ * {@link OPENCODE_PROMPT_AFTER_RESPONSE} (`tab agents ctrl+p commands`, which
882
+ * opencode only prints on the FIRST idle frame, before any turn has run) nor
883
+ * {@link OPENCODE_PROCESSING_INDICATOR} covers the idle form, so this row used
884
+ * to be saved as part of the assistant's reply.
885
+ *
886
+ * This is a SECONDARY net. The cwd that shares the row wraps over up to three
887
+ * further rows that carry no signature at all, so the footer is removed
888
+ * structurally by {@link findOpenCodeChromeStart}; this pattern only catches the
889
+ * signed row when that boundary is not available (e.g. a caller holding a
890
+ * fragment rather than a whole pane).
891
+ *
892
+ * Linear, no nested quantifiers — ReDoS safe.
893
+ */
894
+ exports.OPENCODE_FOOTER_STATUS_PATTERN = /\d+(?:\.\d+)?[KMGT]?\s+\(\d+%\)\s+·\s+\$/;
895
+ /**
896
+ * Locate the start of opencode's bottom-anchored chrome within a captured pane
897
+ * (Issue #1911).
898
+ *
899
+ * opencode runs in the alternate screen and reserves the last rows of the pane
900
+ * for chrome that is never transcript content:
901
+ *
902
+ * ```
903
+ * ┃ ← composer box (blank rows + model row),
904
+ * ┃ Build · GPT-5.6 Luna … or the permission dialog that replaces it
905
+ * ╹▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ← composer bottom border
906
+ * /private/tmp/…-share- 6.4K (1%) · $ctrl+p ← footer, cwd wrapped
907
+ * work-github-kewton-… commands over up to three rows
908
+ * ```
909
+ *
910
+ * Everything from the returned index down is chrome. This is the opencode twin
911
+ * of {@link findClaudeChromeStart} and exists for the same reason (#1289): the
912
+ * footer's cwd rows and the composer's model row were reaching saved responses,
913
+ * which is defect 1 of #1911.
914
+ *
915
+ * Found structurally rather than by matching footer text, because the footer's
916
+ * text is opencode's to change and two of its four rows (the cwd continuations)
917
+ * are an arbitrary filesystem path with no signature at all.
918
+ *
919
+ * @param lines - Captured pane lines, ANSI-stripped, box drawing intact.
920
+ * Trailing blank rows are tolerated.
921
+ * @returns Index of the first chrome row, or -1 when no chrome is recognisable.
922
+ */
923
+ function findOpenCodeChromeStart(lines) {
924
+ let last = lines.length - 1;
925
+ while (last >= 0 && lines[last].trim() === '')
926
+ last--;
927
+ if (last < 0)
928
+ return -1;
929
+ const walkUpGutter = (from) => {
930
+ let top = from;
931
+ while (top - 1 >= 0 && exports.OPENCODE_GUTTER_ROW_PATTERN.test(lines[top - 1]))
932
+ top--;
933
+ return top;
934
+ };
935
+ // The composer's bottom border. Searched from the last row upwards over the
936
+ // WHOLE pane rather than over the few rows the footer occupies: on the boot
937
+ // screen opencode centres the composer under its banner (row ~99 of 200) while
938
+ // the footer stays pinned to the bottom, so a window sized for the footer
939
+ // misses the border entirely (measured, `opencode-live-1883/boot-idle.txt`).
940
+ for (let i = last; i >= 0; i--) {
941
+ if (exports.OPENCODE_COMPOSER_BOTTOM_BORDER.test(lines[i])) {
942
+ return walkUpGutter(i);
943
+ }
944
+ }
945
+ // No border: the permission dialog draws over the composer and its own box
946
+ // runs to the last row of the pane (measured, `opencode-live-1893/permission-*.txt`).
947
+ if (exports.OPENCODE_GUTTER_ROW_PATTERN.test(lines[last])) {
948
+ return walkUpGutter(last);
949
+ }
950
+ return -1;
951
+ }
952
+ /**
953
+ * Locate the last row of the NEWEST echoed user prompt in a captured pane
954
+ * (Issue #1911).
955
+ *
956
+ * The turn currently being answered starts on the row after this one, so it is
957
+ * both the extraction anchor (`resolveExtractionStartIndex`'s opencode branch)
958
+ * and the floor the finished-turn marker has to sit below before a frame counts
959
+ * as a completed turn (`isOpenCodeComplete`).
960
+ *
961
+ * Before #1911 the anchor was "the second-to-last `▣ Build` row", which has two
962
+ * measured failure modes: on the first turn of a session there is no second row,
963
+ * so extraction fell back to line 0 and saved the whole pane; and the row it
964
+ * anchors on belongs to the PREVIOUS turn, so the echoed prompt of the current
965
+ * one was always included in the reply.
966
+ *
967
+ * @param lines - Captured pane lines, ANSI-stripped, box drawing intact.
968
+ * @param chromeStart - Result of {@link findOpenCodeChromeStart}; the search
969
+ * stops above it so the composer's and the permission dialog's own gutter rows
970
+ * are never read as an echoed prompt. Pass -1 when no chrome was found.
971
+ * @returns Index of the echo block's last row, or -1 when no echo is on screen
972
+ * (a turn whose head has scrolled out of the alternate-screen pane).
973
+ */
974
+ function findOpenCodeUserEchoEnd(lines, chromeStart) {
975
+ const limit = chromeStart >= 0 ? chromeStart : lines.length;
976
+ for (let i = limit - 1; i >= 0; i--) {
977
+ if (!exports.OPENCODE_USER_ECHO_PATTERN.test(lines[i]))
978
+ continue;
979
+ // The block's trailing blank gutter row(s) belong to the echo, not to the reply.
980
+ let end = i;
981
+ while (end + 1 < limit && exports.OPENCODE_GUTTER_ROW_PATTERN.test(lines[end + 1]))
982
+ end++;
983
+ return end;
984
+ }
985
+ return -1;
986
+ }
987
+ /**
988
+ * The rows of opencode's composer that hold the INPUT BUFFER (Issue #1906).
989
+ *
990
+ * opencode has no prompt marker — no `>` / `❯` / `›` anywhere near its input —
991
+ * so "is the message still sitting in the composer?" cannot be asked the way it
992
+ * is asked of every other TUI. What opencode has instead is a box, and the box
993
+ * has a fixed shape, measured at the production 80x200 geometry across every
994
+ * frame in `opencode-live-1883/`, `opencode-live-1893/` and
995
+ * `opencode-live-1906/`:
996
+ *
997
+ * ```
998
+ * ┃ ← buffer rows: blank when empty,
999
+ * ┃ Review the send path. one row per (wrapped) line of the
1000
+ * ┃ Check newline handling. typed message, or the
1001
+ * ┃ Report findings. `Ask anything...` placeholder on a
1002
+ * ┃ session that has not answered yet
1003
+ * ┃ Build · GPT-5.6 Luna GitHub Copilot ← the agent/model row, ALWAYS last
1004
+ * ╹▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ← the box's bottom border
1005
+ * ```
1006
+ *
1007
+ * The agent/model row is what makes a naive "any guttered row with text" read
1008
+ * wrong: it always carries text, so the composer would never look empty. It is
1009
+ * identified structurally — the last gutter row before the border — rather than
1010
+ * by matching `Build ·` or a model name, both of which are opencode's to change
1011
+ * and neither of which is stable across agents (`Build`, `Plan`, a custom agent).
1012
+ *
1013
+ * Anchored on the border, not on the bottom of the pane, because opencode
1014
+ * centres the whole box under its banner before the first turn (row ~100 of 200)
1015
+ * and only pins it to the bottom afterwards — see {@link findOpenCodeChromeStart},
1016
+ * whose upward walk this shares.
1017
+ *
1018
+ * Returns `null` when no composer is on screen at all. That is the permission
1019
+ * dialog (it replaces the composer and draws no bottom border — measured,
1020
+ * `opencode-live-1893/permission-*.txt`), a full-screen overlay, or a session
1021
+ * still starting.
1022
+ *
1023
+ * @param lines - Captured pane lines, ANSI-stripped, box drawing intact. Must be
1024
+ * the WHOLE pane: a tail window sized for the other tools does not contain the
1025
+ * box on a pre-first-turn frame.
1026
+ * @returns The buffer rows with their gutters intact, or `null` when the
1027
+ * composer is not on screen. An empty array means a box with no buffer row,
1028
+ * which no measured frame produces.
1029
+ */
1030
+ function findOpenCodeComposerRows(lines) {
1031
+ let border = -1;
1032
+ for (let i = lines.length - 1; i >= 0; i--) {
1033
+ if (exports.OPENCODE_COMPOSER_BOTTOM_BORDER.test(lines[i])) {
1034
+ border = i;
1035
+ break;
1036
+ }
1037
+ }
1038
+ if (border < 0)
1039
+ return null;
1040
+ let top = border;
1041
+ while (top - 1 >= 0 && exports.OPENCODE_GUTTER_ROW_PATTERN.test(lines[top - 1]))
1042
+ top--;
1043
+ // `top .. border - 1` are the box's gutter rows; the last of them is the
1044
+ // agent/model row, which belongs to the chrome rather than to the buffer.
1045
+ const modelRow = border - 1;
1046
+ if (modelRow < top)
1047
+ return null;
1048
+ return lines.slice(top, modelRow);
1049
+ }
1050
+ /**
1051
+ * A composer row with its gutter (and the padding either side) removed
1052
+ * (Issue #1906). Blank for an empty buffer row.
1053
+ */
1054
+ function stripOpenCodeGutter(row) {
1055
+ return row.replace(exports.OPENCODE_GUTTER_ROW_PATTERN, '').trim();
1056
+ }
1057
+ /**
1058
+ * OpenCode TUI selection list pattern (Issue #473, narrowed by Issue #1896).
1059
+ *
1060
+ * Detects the fuzzy-search picker overlay opencode draws for `/models`,
1061
+ * `/providers` and `/connect`, anchored on its HEADER ROW COMPLETE WITH the
1062
+ * right-aligned `esc` hatch:
1063
+ *
1064
+ * ```
1065
+ * Select model esc
1066
+ *
1067
+ * Search
1068
+ *
1069
+ * Recent
1070
+ * ● GPT-5.6 Luna GitHub Copilot
1071
+ * ```
1072
+ *
1073
+ * The `esc` is the picker's own dismiss affordance -- positive evidence that an
1074
+ * overlay is open (design rule D1), rather than the presence of two English
1075
+ * words somewhere on the pane. Until #1896 the pattern was the bare phrase, and
1076
+ * `status-detector.ts` tests it against the WHOLE content area (up to ~200 rows,
1077
+ * because the header can sit far above the last row when the list is long), so
1078
+ * an agent that merely wrote `Select model to continue:` in its answer parked the
1079
+ * session on `waiting` / `opencode_selection_list` for the rest of the session
1080
+ * -- measured live on opencode 1.18.21,
1081
+ * `opencode-live-1896/select-model-in-response.txt`.
1082
+ *
1083
+ * Requiring two or more spaces before `esc` is what separates the header row
1084
+ * from prose: the picker right-aligns the hatch across the overlay's width
1085
+ * (37 spaces in the measured frame), while a sentence that happens to end in
1086
+ * "esc" would not.
1087
+ *
1088
+ * NOT additionally anchored on the `Search` row below the header: its distance
1089
+ * from the header is unmeasured for the `Connect a provider` variant (that
1090
+ * overlay needs an unconfigured provider to open, which the live probe could not
1091
+ * produce without touching the operator's real credentials), and the header's
1092
+ * own hatch is already the affordance.
1093
+ *
1094
+ * The header allowlist is deliberately unchanged. opencode 1.18 draws the same
1095
+ * chrome for its ctrl+p command palette (`Commands … esc`), which this pattern
1096
+ * therefore still does not match; that frame lands on `running` / `default`
1097
+ * (measured, `opencode-live-1896/command-palette.txt`) -- i.e. on the
1098
+ * "no evidence" side, which #1708's unclassified-frame guard already covers.
1099
+ * Widening the allowlist is a separate change with its own live frames.
1100
+ *
1101
+ * The whitespace runs are `[^\S\n]` (horizontal only) for the reason Issue #1883
1102
+ * documents: plain `\s` crosses newlines under the `m` flag, which would let a
1103
+ * header on one row pair up with an `esc` several rows below it.
1104
+ *
1105
+ * Linear pattern, no nested quantifiers -- ReDoS safe (S4-001).
1106
+ */
1107
+ exports.OPENCODE_SELECTION_LIST_PATTERN = /^[^\S\n]*(?:Select[^\S\n]+(?:model|provider)|Connect[^\S\n]+a[^\S\n]+provider)[^\S\n]{2,}esc[^\S\n]*$/m;
716
1108
  /**
717
1109
  * [Issue #1495] Footer signature of Claude Code's `/model` local-settings overlay.
718
1110
  * Verified against a real Claude Code v2.1.218 capture, the footer reads:
@@ -758,7 +1150,8 @@ exports.OPENCODE_SEPARATOR_PATTERN = /^[\u2503\u2579\u25A3\u2580\u2500\u250C\u25
758
1150
  * OpenCode skip patterns for response cleaning (Issue #379)
759
1151
  * Lines matching any of these patterns are filtered from extracted responses.
760
1152
  * Includes: TUI separators, loading indicators, Build summary prefix,
761
- * status bar prompts, processing indicators, input prompt, and pasted text markers.
1153
+ * status bar prompts, processing indicators, input prompt, the footer's
1154
+ * context/cost status cell (Issue #1911), and pasted text markers.
762
1155
  */
763
1156
  exports.OPENCODE_SKIP_PATTERNS = [
764
1157
  exports.OPENCODE_SEPARATOR_PATTERN,
@@ -767,6 +1160,7 @@ exports.OPENCODE_SKIP_PATTERNS = [
767
1160
  exports.OPENCODE_PROMPT_AFTER_RESPONSE,
768
1161
  exports.OPENCODE_PROCESSING_INDICATOR,
769
1162
  exports.OPENCODE_PROMPT_PATTERN,
1163
+ exports.OPENCODE_FOOTER_STATUS_PATTERN,
770
1164
  exports.PASTED_TEXT_PATTERN,
771
1165
  ];
772
1166
  /**
@@ -787,24 +1181,432 @@ exports.COPILOT_PROMPT_PATTERN = /^[>❯]\s|^\?\s+/m;
787
1181
  * Note: "Esc to cancel" alone is not used because trust dialog footer also contains it.
788
1182
  * Instead, match the action pattern with parenthesized context: "(Esc to cancel ·"
789
1183
  * Braille spinner characters (U+2800-U+28FF) are also checked.
1184
+ *
1185
+ * Issue #1897: the bare words `Generating` and `Processing` were dropped. This
1186
+ * constant is also a member of {@link COPILOT_SKIP_PATTERNS}, so every
1187
+ * alternative here doubles as a "delete this line from the saved response" rule
1188
+ * and as the tail-window liveness test in `extractResponse`. Those two words are
1189
+ * ordinary English -- a reply whose last line reads "Processing complete." had
1190
+ * the line deleted AND pinned the turn to "still thinking" for as long as it was
1191
+ * on screen, so the response was never saved at all. The remaining alternatives
1192
+ * are all glyph- or punctuation-shaped and cannot occur in prose by accident.
1193
+ * Nothing is lost as a running signal either: #1885 measured 0 matches for this
1194
+ * whole pattern across 44 live generating frames of copilot 1.0.80, whose turn
1195
+ * state is read from the status bar by {@link readCopilotStatusBar} instead.
790
1196
  */
791
- exports.COPILOT_THINKING_PATTERN = /[\u2800-\u28FF]|\(Esc to cancel|Reasoning\s+[■▪▮]|\.\.\.\s+Thinking|Generating|Processing/;
1197
+ exports.COPILOT_THINKING_PATTERN = /[\u2800-\u28FF]|\(Esc to cancel|Reasoning\s+[■▪▮]|\.\.\.\s+Thinking/;
1198
+ /**
1199
+ * Copilot CLI's bottom status bar while a turn is in flight (Issue #1885).
1200
+ *
1201
+ * Measured on copilot 1.0.80 at the production 200x1000 geometry
1202
+ * (`tests/unit/lib/detection/fixtures/copilot-live-1885/`). The bar is the
1203
+ * bottom row of the pane and reads, across 44 captured generating frames:
1204
+ *
1205
+ * " ● Working esc interrupt GPT-5.6 Terra"
1206
+ * " ◉ Working · 1.5 KiB esc interrupt GPT-5.6 Terra"
1207
+ *
1208
+ * The leading glyph cycles through ● ◉ ◎ ○ and the byte counter appears only
1209
+ * once the turn has produced output, so neither is anchored on. `esc interrupt`
1210
+ * is the affordance hint copilot draws for as long as the turn can be
1211
+ * interrupted -- it is on every generating frame and on every tool-execution
1212
+ * frame -- which makes it the same signal opencode's
1213
+ * {@link OPENCODE_PROCESSING_INDICATOR} rests on.
1214
+ *
1215
+ * It is matched against the STATUS BAR ROW ONLY, never a window
1216
+ * (see {@link readCopilotStatusBar}). `status-vocabulary-in-response.txt` is a
1217
+ * live frame where copilot was asked to print this vocabulary and answered
1218
+ * " ● Working esc interrupt" as body text: a window match would have pinned that
1219
+ * finished session to `running` for the rest of its life.
1220
+ *
1221
+ * No /g flag (S4-5: would make test() stateful). No quantifier over a
1222
+ * character class that can match its neighbour (SEC4-001: ReDoS safe).
1223
+ */
1224
+ exports.COPILOT_WORKING_STATUS_PATTERN = /\besc\s+interrupt\b/;
1225
+ /**
1226
+ * Copilot CLI's bottom status bar while no turn is running (Issue #1885).
1227
+ *
1228
+ * The same row as {@link COPILOT_WORKING_STATUS_PATTERN}, in the state copilot
1229
+ * paints when it is NOT working:
1230
+ *
1231
+ * " ← open sidebar · / commands · ? help · tab next tab GPT-5.6 Terra"
1232
+ *
1233
+ * This is copilot's positive completion evidence under design rule D1
1234
+ * (`docs/design/multi-agent-state-architecture.md` §4 D1 decision 1, item 2):
1235
+ * the key-hint bar and the working bar are two renderings of one row, so seeing
1236
+ * the hints is an affirmative observation that the turn is over -- not the
1237
+ * absence of a busy marker somewhere on screen. The composer cannot carry that
1238
+ * evidence on copilot: `❯` between its two full-width rules is drawn during
1239
+ * generation too (measured on every frame of the running fixtures), which is
1240
+ * exactly why the always-visible prompt used to win at step 3 of
1241
+ * `detectSessionStatus` and report a generating session as ready.
1242
+ *
1243
+ * Two alternative spellings of one affordance, because copilot has reworded
1244
+ * this row before: 1.0.80 shows "? help", and the pre-1.0.79 wording survives
1245
+ * in {@link COPILOT_SKIP_PATTERNS} as "? for shortcuts". "/ commands" covers
1246
+ * the slash-command hint independently, so a rewording of either half alone
1247
+ * does not cost the tool its completion evidence.
1248
+ *
1249
+ * No /g flag (S4-5). Linear alternation, no nested quantifiers (SEC4-001).
1250
+ */
1251
+ exports.COPILOT_IDLE_STATUS_PATTERN = /\/\s+commands\b|\?\s+(?:help\b|for\s+shortcuts\b)/;
1252
+ /**
1253
+ * Read copilot's bottom status bar out of a captured frame (Issue #1885).
1254
+ *
1255
+ * Takes the whole frame rather than a row so the positional anchor -- "the
1256
+ * status bar is the bottom row of the pane" -- cannot be lost at a call site.
1257
+ * The scan stops at the first non-blank row from the bottom: if that row is
1258
+ * neither state, this returns null and the caller has no evidence, which is the
1259
+ * D1-correct answer rather than a guess. Two measured frames rely on it:
1260
+ *
1261
+ * - a permission dialog replaces the whole bottom of the pane with its box, so
1262
+ * the bottom row is `╰───…` and neither pattern matches. The dialog then
1263
+ * reaches `detectPrompt` and is reported as `waiting`, unchanged.
1264
+ * - the `/model` picker ends in its own footer
1265
+ * ("↑/↓ to navigate · … · enter to select · esc to cancel"), which is not the
1266
+ * status bar either -- so this reports nothing about it and leaves that
1267
+ * screen to the selection-list branch (Issue #1895's subject).
1268
+ *
1269
+ * @param contentLines - Frame rows, ANSI already stripped, in pane order
1270
+ * @returns The state the bottom row announces, or null when it announces neither
1271
+ */
1272
+ function readCopilotStatusBar(contentLines) {
1273
+ for (let i = contentLines.length - 1; i >= 0; i--) {
1274
+ const row = contentLines[i];
1275
+ if (row.trim() === '')
1276
+ continue;
1277
+ if (exports.COPILOT_WORKING_STATUS_PATTERN.test(row))
1278
+ return 'working';
1279
+ if (exports.COPILOT_IDLE_STATUS_PATTERN.test(row))
1280
+ return 'idle';
1281
+ return null;
1282
+ }
1283
+ return null;
1284
+ }
792
1285
  /**
793
1286
  * Copilot separator pattern (Issue #545)
794
1287
  * Placeholder - to be updated after Phase 1 TUI investigation.
795
1288
  */
796
1289
  exports.COPILOT_SEPARATOR_PATTERN = /^─{10,}$/m;
1290
+ /** How far above the bottom row copilot's closing rule may sit. */
1291
+ const COPILOT_STATUS_BAR_MAX_ROWS = 2;
1292
+ /** How many rows copilot's composer may span before the block stops looking like chrome. */
1293
+ const COPILOT_COMPOSER_MAX_ROWS = 40;
1294
+ /** A full-width horizontal rule, with or without the pane's leading padding. */
1295
+ const COPILOT_RULE_ROW = /^─{10,}$/;
1296
+ /** copilot's composer glyph: legacy `>` and current `❯`, at the pane's own indent. */
1297
+ const COPILOT_COMPOSER_GLYPH = /^ {0,2}[>❯]/;
797
1298
  /**
798
- * Copilot CLI selection list pattern (Issue #547)
799
- * Detects Copilot CLI's interactive selection/navigation prompts:
800
- * - Model picker: "Search models..." / "Select Model"
801
- * - Trust dialog: "↑↓ to navigate · Enter to select · Esc to cancel"
802
- * - Other interactive lists with arrow key navigation
1299
+ * Locate the start of copilot CLI's bottom-pinned chrome within a captured pane
1300
+ * (Issue #1897).
1301
+ *
1302
+ * copilot 1.0.80 runs on the alternate screen and reserves the last five rows of
1303
+ * the pane. Measured at the production 200x1000 geometry
1304
+ * (`tests/unit/lib/detection/fixtures/copilot-live-1885/`), with the transcript
1305
+ * ~970 rows above and nothing but padding in between:
1306
+ *
1307
+ * <cwd> [⎇ <branch>] Session: N AIC used
1308
+ * ──────────────────── ← opening rule
1309
+ * ❯ <composer>
1310
+ * ──────────────────── ← closing rule
1311
+ * ◉ Working · 1.5 KiB esc interrupt GPT-5.6 Terra ← status bar
1312
+ *
1313
+ * The boundary is found structurally -- closing rule, opening rule, composer
1314
+ * glyph -- and never by matching the status bar's wording. That is the same
1315
+ * reasoning {@link findClaudeChromeStart} records (#1289) plus the measurement
1316
+ * behind {@link COPILOT_WORKING_STATUS_PATTERN}: copilot will print its own
1317
+ * status-bar vocabulary as body text when asked to
1318
+ * (`status-vocabulary-in-response.txt` holds ` ● Working esc interrupt` as a
1319
+ * reply), so a vocabulary rule strong enough to delete the real bar also deletes
1320
+ * that reply. Position is the only thing that separates them.
1321
+ *
1322
+ * Without this trim the bar is transcript as far as every consumer is concerned:
1323
+ * it reached the TUI accumulator on every poll and was saved to History as the
1324
+ * agent's answer (#1897's headline symptom, ` Working esc interrupt GPT-5.6
1325
+ * Terra`), and its spinner glyph and byte counter change on every tick, so it
1326
+ * also defeats the content dedup the alternate-screen tools rely on (#1268).
1327
+ *
1328
+ * @param lines - Captured pane rows, ANSI-bearing or not; trailing blanks tolerated
1329
+ * @returns Index of the first chrome row, or -1 when the pane carries no chrome
1330
+ * (a permission dialog draws its box over the whole bottom of the pane, so
1331
+ * there is no composer and no bar -- those frames return -1 and are left to
1332
+ * `detectPrompt`, exactly as {@link readCopilotStatusBar} leaves them)
1333
+ */
1334
+ function findCopilotChromeStart(lines) {
1335
+ const isRule = (line) => COPILOT_RULE_ROW.test((0, ansi_1.stripAnsi)(line).trim());
1336
+ let lastRow = lines.length - 1;
1337
+ while (lastRow >= 0 && (0, ansi_1.stripAnsi)(lines[lastRow]).trim() === '')
1338
+ lastRow--;
1339
+ if (lastRow < 0)
1340
+ return -1;
1341
+ let closingRule = -1;
1342
+ for (let i = lastRow; i >= Math.max(0, lastRow - COPILOT_STATUS_BAR_MAX_ROWS); i--) {
1343
+ if (isRule(lines[i])) {
1344
+ closingRule = i;
1345
+ break;
1346
+ }
1347
+ }
1348
+ if (closingRule < 0)
1349
+ return -1;
1350
+ let openingRule = -1;
1351
+ for (let i = closingRule - 1; i >= Math.max(0, closingRule - COPILOT_COMPOSER_MAX_ROWS); i--) {
1352
+ if (isRule(lines[i])) {
1353
+ openingRule = i;
1354
+ break;
1355
+ }
1356
+ }
1357
+ if (openingRule < 0)
1358
+ return -1;
1359
+ // Confirm the fenced rows are the composer rather than a reply that happens to
1360
+ // sit between two horizontal rules.
1361
+ if (!COPILOT_COMPOSER_GLYPH.test((0, ansi_1.stripAnsi)(lines[openingRule + 1] ?? '')))
1362
+ return -1;
1363
+ // The row above the opening rule is copilot's cwd/branch/session header, which
1364
+ // an overlay (the `/model` picker) replaces with a blank rather than with
1365
+ // transcript -- measured on all five non-dialog fixtures.
1366
+ return Math.max(0, openingRule - 1);
1367
+ }
1368
+ /**
1369
+ * A row copilot draws as part of a box or a collapsed reasoning block
1370
+ * (Issue #1897).
1371
+ *
1372
+ * 1.0.80 renders the model's private reasoning as a `⌄ Thought for 41s` header
1373
+ * followed by rows that each begin `│ `, and draws dialogs inside `╭─╮`/`╰─╯`
1374
+ * frames. {@link COPILOT_SKIP_PATTERNS} already carries a `[╭╮╰╯│]` rule, but
1375
+ * `normalizeCopilotLine` deletes every U+2500..U+257F glyph *before* the skip
1376
+ * patterns are applied, so by the time that rule runs the row it is meant to
1377
+ * catch reads as ordinary prose -- which is how the TUI accumulator came to save
1378
+ * copilot's chain-of-thought as the reply. Matched against the ANSI-stripped row,
1379
+ * before normalisation.
1380
+ *
1381
+ * `─` is deliberately absent: a rule row is {@link COPILOT_SEPARATOR_PATTERN}'s
1382
+ * job, and `── heading ──` is content.
1383
+ */
1384
+ exports.COPILOT_BOX_ROW_PATTERN = /^\s*[│└╰╭╮╯├┤┬┴┼]/;
1385
+ /**
1386
+ * copilot's collapsed-section header (Issue #1897).
803
1387
  *
804
- * No /g flag (S4-5: would make test() stateful).
805
- * No nested quantifiers (SEC4-001: ReDoS safety).
1388
+ * Measured on 1.0.80: `⌄ Thinking…` while the reasoning block is live, replaced
1389
+ * by `⌄ Thought for 41s` once the turn moves on. Anchored on the `⌄` disclosure
1390
+ * glyph rather than on the words, because "Thinking…" also occurs as body text
1391
+ * -- `status-vocabulary-in-response.txt` contains exactly that row as a reply,
1392
+ * and it must survive cleaning.
806
1393
  */
807
- exports.COPILOT_SELECTION_LIST_PATTERN = /Search\s+\w+\.\.\.|Select\s+Model|to (?:navigate|select).*Enter to (?:select|confirm)/m;
1394
+ exports.COPILOT_REASONING_HEADER_PATTERN = /^\s*⌄\s/;
1395
+ /**
1396
+ * copilot's echo of the operator's own prompt in the transcript (Issue #1897).
1397
+ *
1398
+ * 1.0.80 draws every transcript row at the pane's one-column indent -- ` ❯ Reply
1399
+ * with exactly the word: pong` -- while the composer at the bottom of the pane is
1400
+ * at column 0. The bare `^[>❯]` form therefore never matched the echo, so
1401
+ * `resolveExtractionStartIndex`'s copilot branch found no anchor, fell back to
1402
+ * line 0, and handed the launch banner to the cleaner as the turn's reply.
1403
+ *
1404
+ * Bounded to two leading spaces rather than `\s*` so a quoted `> …` line inside a
1405
+ * reply cannot be mistaken for a new turn boundary.
1406
+ */
1407
+ exports.COPILOT_USER_ECHO_PATTERN = /^ {0,2}[>❯]\s+\S/;
1408
+ /**
1409
+ * A wrapped continuation of the copilot transcript row above it (Issue #1897).
1410
+ *
1411
+ * Marker rows (` ❯ `, ` ● `, ` $ `, ` ⌄ `) carry one leading space; the rows they
1412
+ * wrap onto are indented further and carry no marker, and a blank row separates
1413
+ * one block from the next (measured on 1.0.80 at 200x1000). Used to walk past the
1414
+ * tail of a long *user* prompt so the extracted reply does not open with the
1415
+ * second half of the operator's own question.
1416
+ */
1417
+ exports.COPILOT_TRANSCRIPT_CONTINUATION_PATTERN = /^ {2,}\S/;
1418
+ /**
1419
+ * Rows that only copilot's first-launch screen draws (Issue #1897).
1420
+ *
1421
+ * The launch screen is a complete, idle frame: the composer is drawn, the status
1422
+ * bar shows key hints, and nothing about it says "no turn has happened yet". So
1423
+ * `extractResponse` classified it as a finished response and History opened with
1424
+ * the banner as the agent's first message -- before the operator's first prompt.
1425
+ *
1426
+ * These anchors are only ever consulted for a frame that carries no echoed user
1427
+ * prompt at all (see the copilot banner guard in `extractResponse`), which is
1428
+ * what keeps a reply that quotes any of this wording from being suppressed.
1429
+ */
1430
+ exports.COPILOT_BOOT_BANNER_ANCHORS = [
1431
+ /No copilot-instructions\.md found/,
1432
+ /Copilot uses AI, so always check for mistakes\./,
1433
+ /Copilot v\d[\w.]*\s+uses AI/,
1434
+ /^\s*(?:●\s+)?GitHub Copilot\s+v\d/m,
1435
+ /^\s*(?:●\s+)?Tip:\s*\//m,
1436
+ /Describe a task to get started/,
1437
+ /Prefer a visual workspace\?/,
1438
+ ];
1439
+ /**
1440
+ * The key-hint footer copilot draws under a picker, matched one ROW at a time
1441
+ * (Issue #547; rewritten against live 1.0.80 frames by Issue #1895).
1442
+ *
1443
+ * The pattern this replaced --
1444
+ * `/Search\s+\w+\.\.\.|Select\s+Model|to (?:navigate|select).*Enter to (?:select|confirm)/`
1445
+ * -- matched **none** of the eleven pickers 1.0.80 opens (measured; the frames
1446
+ * are in `tests/unit/lib/detection/fixtures/copilot-picker-1895/`, and #1885 /
1447
+ * #1886 / #1913 reached the same result independently). `/model` renders
1448
+ * `❯ Search models…` with U+2026 rather than three periods, no picker carries
1449
+ * the words `Select Model`, and every footer spells its verbs in lower case.
1450
+ *
1451
+ * What all eleven footers do share is the shape of a key-hint bar: `·`-separated
1452
+ * hints carrying either arrow-key navigation or a lower-case dismiss verb.
1453
+ * Measured verbatim, bottom-most first:
1454
+ *
1455
+ * /model ↑/↓ to navigate · ←/→ reasoning effort · tab context window ·
1456
+ * shift+tab group: recommended · enter to select · esc to cancel
1457
+ * /agent n new agent · ? learn more · esc cancel
1458
+ * /theme ↑/↓ to navigate · enter to select · esc to cancel
1459
+ * /permissions 1-2 to select · ↑/↓ to navigate · enter to confirm · esc to cancel
1460
+ * /skills ↑/↓ to navigate · enter to toggle · esc to close
1461
+ * /mcp ↑/↓ to select · enter to show · a to add · esc to close
1462
+ * /settings / search · ↑/↓ navigate · tab switch scope · enter edit ·
1463
+ * ctrl+r reset · ctrl+e editor · esc close
1464
+ * /statusline ↑/↓ nav · enter toggle · esc close
1465
+ * /subagents ↑/↓ to navigate · space on/off · r reset · enter to select · esc to cancel
1466
+ * /resume / search · ↑/↓ navigate · enter select · ←/→ switch tabs · r refresh ·
1467
+ * x delete · s sort:relevance · esc cancel
1468
+ * /session / search · ↑/↓ navigate · enter open · n new · tab switch tabs · a filter:all
1469
+ *
1470
+ * Neither half of the alternation is universal -- `/agent` has no list to walk
1471
+ * so it prints no `↑/↓`, and `/session` offers no `esc` -- but every footer has
1472
+ * one of them, so the union covers 11/11 while each individual disjunct stays
1473
+ * specific enough to be worth requiring. The slash in `↑/↓` is optional only as
1474
+ * a rewording tolerance: the synthetic frames pinned since Issue #547 spell it
1475
+ * `↑↓`, and whether copilot ever drew it that way is not something this Issue
1476
+ * measured. Every 1.0.80 footer above has the slash.
1477
+ *
1478
+ * Three deliberate narrowings keep this off ordinary text:
1479
+ * - the `·` lookahead, so a sentence such as "press esc to cancel" is not a
1480
+ * footer unless it is also a hint bar;
1481
+ * - lower case, which is what 1.0.80 draws. `(Esc to cancel · 2.3 KiB)` -- the
1482
+ * capitalised spelling in {@link COPILOT_THINKING_PATTERN} -- is a *progress*
1483
+ * row, and it would otherwise satisfy both halves of this pattern;
1484
+ * - `cancel|close` only, so the status bar's `esc interrupt`
1485
+ * ({@link COPILOT_WORKING_STATUS_PATTERN}) is not a footer either.
1486
+ *
1487
+ * The narrowings are defence in depth; the load-bearing guard is positional and
1488
+ * lives in {@link isCopilotSelectionFrame} -- copilot's own answer text can and
1489
+ * does contain these exact rows (`picker-vocabulary-in-response.txt` is a live
1490
+ * frame of it), so no window-scoped match on this vocabulary can be safe.
1491
+ *
1492
+ * No /g flag (S4-5: would make test() stateful). `[^\n]*` cannot cross a row and
1493
+ * no quantifier is nested inside another (SEC4-001: ReDoS safe).
1494
+ */
1495
+ exports.COPILOT_SELECTION_FOOTER_PATTERN = /^(?=[^\n]*·)[^\n]*(?:↑\/?↓|\besc\s+(?:to\s+)?(?:cancel|close)\b)/m;
1496
+ /**
1497
+ * How many non-blank rows up from the bottom of the pane may carry the footer.
1498
+ *
1499
+ * Nine of the eleven pickers put it on the bottom row itself; `/agent` and
1500
+ * `/subagents` draw their panel with a closing full-width rule underneath it,
1501
+ * which puts the footer two non-blank rows up. Three is that measurement plus
1502
+ * one row of slack -- deliberately far short of a window that could reach the
1503
+ * transcript, which on the production 200x1000 geometry sits ~950 rows above.
1504
+ */
1505
+ const COPILOT_SELECTION_FOOTER_SCAN_ROWS = 3;
1506
+ /**
1507
+ * Whether the pane is sitting on one of copilot's pickers (Issue #1895).
1508
+ *
1509
+ * Takes the whole frame rather than a window for the same reason
1510
+ * {@link readCopilotStatusBar} does: the evidence is positional, and a call site
1511
+ * cannot be trusted to preserve "near the bottom of the pane" on its own. Two
1512
+ * facts, both measured on 1.0.80, make the position sufficient:
1513
+ *
1514
+ * - **A picker replaces copilot's chrome.** In the idle and generating states
1515
+ * the bottom five rows are cwd / rule / composer / rule / status bar; while a
1516
+ * picker is up, none of them are drawn. So a frame whose bottom row is a
1517
+ * status bar is not a picker, whatever its transcript says -- which is the
1518
+ * whole of the false-positive half of Issue #1895. `detectSessionStatus`
1519
+ * reads the same row for the running verdict at step 0.5, so checking it
1520
+ * first here also fixes the order between the two branches: the status bar
1521
+ * wins, and the picker branch only speaks when copilot has taken it away.
1522
+ * - **An answerable dialog is drawn inside a box; a picker is not.** The
1523
+ * folder-trust and permission dialogs wear the same lower-case
1524
+ * `↑/↓ to navigate · enter to select · esc to cancel` footer, but every one of
1525
+ * their rows reads `│ … │` and the bottom row is `╰─…─╯`. Skipping boxed rows
1526
+ * keeps those on the prompt branch, where they belong: they are the agent
1527
+ * blocked on the human (`hasActivePrompt: true`, exit 10 for `wait`), not a
1528
+ * list the operator opened.
1529
+ *
1530
+ * @param contentLines - Frame rows, ANSI already stripped, in pane order
1531
+ * @returns True when the bottom of the pane is a picker's key-hint footer
1532
+ */
1533
+ function isCopilotSelectionFrame(contentLines) {
1534
+ if (readCopilotStatusBar(contentLines) !== null)
1535
+ return false;
1536
+ let scanned = 0;
1537
+ for (let i = contentLines.length - 1; i >= 0; i--) {
1538
+ const row = contentLines[i];
1539
+ const trimmed = row.trim();
1540
+ if (trimmed === '')
1541
+ continue;
1542
+ if (++scanned > COPILOT_SELECTION_FOOTER_SCAN_ROWS)
1543
+ break;
1544
+ // A boxed row belongs to a dialog, not a picker (see above).
1545
+ if (trimmed.startsWith('│') || trimmed.endsWith('│'))
1546
+ continue;
1547
+ if (exports.COPILOT_SELECTION_FOOTER_PATTERN.test(row))
1548
+ return true;
1549
+ }
1550
+ return false;
1551
+ }
1552
+ /**
1553
+ * Anchors of Copilot CLI's first-launch "Confirm folder trust" dialog (Issue #1886).
1554
+ *
1555
+ * Recorded from copilot 1.0.80 (`tests/fixtures/copilot-folder-trust-1080.ts`):
1556
+ * copilot asks this once per untrusted git repository, before anything else runs,
1557
+ * and the whole dialog is drawn inside a box — every row reads `│ <content>`.
1558
+ * That is why `COPILOT_PROMPT_PATTERN` (`^[>❯]\s`) does not match the frame at
1559
+ * all and `waitForReady` used to spin its full 30-second window against it.
1560
+ *
1561
+ * Both anchors are required. One of them alone would also match this dialog's
1562
+ * text quoted back inside a model response, and a false positive here does not
1563
+ * merely mis-report a status: it sends a bare `1` into a live composer.
1564
+ *
1565
+ * The anchors live here rather than in `cli-tools/copilot` for the same reason
1566
+ * codex's do (Issue #1829): the Auto-Yes poller judges the same screen through
1567
+ * `detectPrompt`, and two copies of the wording would be two chances to disagree
1568
+ * about what this dialog is.
1569
+ */
1570
+ exports.COPILOT_FOLDER_TRUST_ANCHORS = [
1571
+ 'Confirm folder trust',
1572
+ 'Do you trust the files in this folder?',
1573
+ ];
1574
+ /**
1575
+ * The one option CommandMate may answer on the operator's behalf: `1. Yes`,
1576
+ * which grants trust for THIS SESSION only.
1577
+ *
1578
+ * Matching the option text — not just the dialog — is the fail-safe. Option 2
1579
+ * ("Yes, and remember this folder for future sessions") writes `trustedFolders`
1580
+ * into `~/.copilot/config.json`, one file shared by every checkout on the
1581
+ * machine (measured: answering `1` leaves that file byte-identical). If copilot
1582
+ * ever reorders the list so that `1` is the remembering variant, this stops
1583
+ * matching, nothing is sent, and the launch degrades to the pre-#1886 stall
1584
+ * instead of silently persisting a trust grant.
1585
+ *
1586
+ * Written against the box-stripped frame, where the row reads `❯ 1. Yes`.
1587
+ * `[ \t]*$` rather than `\s*$` so the trailing anchor cannot roll onto a later
1588
+ * line and accept `1. Yes, and remember ...`.
1589
+ */
1590
+ exports.COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN = /^[ \t]*(?:[>❯][ \t]*)?1\.[ \t]+Yes[ \t]*$/m;
1591
+ /**
1592
+ * Key that selects {@link COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN}.
1593
+ * Measured on 1.0.80: the digit confirms on its own — sending a trailing Enter
1594
+ * would land on the composer that the dialog's dismissal reveals.
1595
+ */
1596
+ exports.COPILOT_FOLDER_TRUST_ANSWER_KEY = '1';
1597
+ /**
1598
+ * Whether the pane is sitting on the folder-trust dialog with the session-only
1599
+ * option in first position.
1600
+ *
1601
+ * @param output - ANSI-stripped pane capture (box drawing still present)
1602
+ * @returns True when both anchors and the `1. Yes` option row are present
1603
+ */
1604
+ function isCopilotFolderTrustDialog(output) {
1605
+ if (!exports.COPILOT_FOLDER_TRUST_ANCHORS.every((anchor) => output.includes(anchor))) {
1606
+ return false;
1607
+ }
1608
+ return exports.COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN.test(stripBoxDrawing(output));
1609
+ }
808
1610
  /**
809
1611
  * Copilot skip patterns for response cleaning (Issue #545)
810
1612
  * Placeholder patterns - to be refined after Phase 1 TUI investigation.
@@ -813,7 +1615,12 @@ exports.COPILOT_SKIP_PATTERNS = [
813
1615
  exports.PASTED_TEXT_PATTERN,
814
1616
  exports.COPILOT_SEPARATOR_PATTERN,
815
1617
  exports.COPILOT_THINKING_PATTERN,
816
- exports.COPILOT_SELECTION_LIST_PATTERN,
1618
+ // Issue #1895 replaced COPILOT_SELECTION_LIST_PATTERN with the row-scoped
1619
+ // picker footer; the vocabulary it carried (`Search \w+...` / `Select Model`)
1620
+ // is copilot's prose, not its chrome.
1621
+ exports.COPILOT_SELECTION_FOOTER_PATTERN,
1622
+ // Collapsed reasoning header (Issue #1897): "⌄ Thinking…" / "⌄ Thought for 41s"
1623
+ exports.COPILOT_REASONING_HEADER_PATTERN,
817
1624
  // Logo/banner lines
818
1625
  /^GitHub Copilot\s+v/,
819
1626
  /[█▘▝▖▗▔▄▌▐]/,
@@ -1129,8 +1936,35 @@ function buildDetectPromptOptions(cliToolId) {
1129
1936
  }
1130
1937
  // [D2-006] OpenCode prompt "Ask anything..." does not use standard indicators (> / ❯),
1131
1938
  // so requireDefaultIndicator must be false to avoid missing prompt detection.
1939
+ //
1940
+ // [Issue #1896] `hasNumberedDialogs: false` -- opencode 1.18 renders NO dialog
1941
+ // that a typed number drives, so the generic numbered-list inference has
1942
+ // nothing to find on its pane and every hit it scored was transcript text.
1943
+ // Its two interactive surfaces were both measured at the production 80x200
1944
+ // geometry and both are cursor-driven:
1945
+ //
1946
+ // - the permission dialog is a horizontal button strip
1947
+ // ({@link OPENCODE_PERMISSION_PATTERN}, Issue #1893) driven by ←/→ + Enter;
1948
+ // typing a number does nothing to it.
1949
+ // - the pickers (`/models`, `/providers`, `/connect`, and the ctrl+p command
1950
+ // palette) are fuzzy-search lists driven by ↑/↓ + Enter, with no numbers
1951
+ // drawn at all. The first three are what
1952
+ // {@link OPENCODE_SELECTION_LIST_PATTERN} names; the palette shares the
1953
+ // chrome but not the header allowlist, and lands on `running` / `default`.
1954
+ //
1955
+ // Both keep their own POSITIVE detection in `status-detector.ts`, so `wait`
1956
+ // still stops for them (exit 10 via `isSelectionListActive`) and the UI still
1957
+ // renders NavigationButtons: nothing that could be answered before stops being
1958
+ // answered. What ends is the false positive -- a response whose body ends in
1959
+ // `1. / 2. / 3.` + a question was published as
1960
+ // `waiting`/`prompt_detected`/`hasActivePrompt: true`, and Auto-Yes typed `1`
1961
+ // into the composer and SENT IT as a user utterance (Issue #1896).
1962
+ //
1963
+ // `requireDefaultIndicator` is kept at its D2-006 value: it is the correct
1964
+ // setting for opencode's ❯-less rendering should the numbered path ever be
1965
+ // re-enabled, and it still describes the tool.
1132
1966
  if (cliToolId === 'opencode') {
1133
- return { requireDefaultIndicator: false };
1967
+ return { requireDefaultIndicator: false, hasNumberedDialogs: false };
1134
1968
  }
1135
1969
  // [Issue #545] Copilot prompt pattern may not use standard indicators
1136
1970
  if (cliToolId === 'copilot') {