commandmate 0.30.1 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +164 -164
  3. package/.next/app-path-routes-manifest.json +28 -28
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +9 -9
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update-check/route.js +1 -1
  12. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/assistant/conversation/route.js +1 -1
  14. package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
  15. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/assistant/current-output/route.js +1 -1
  17. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  18. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/assistant/messages/route.js +1 -1
  20. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  21. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/assistant/session/route.js +1 -1
  23. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  24. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/assistant/start/route.js +3 -3
  26. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  27. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/assistant/terminal/route.js +4 -4
  29. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  30. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/assistant/tools/route.js +1 -1
  32. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  33. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/capabilities/route.js +1 -1
  38. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  47. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  48. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/hooks/claude-done/route.js +1 -1
  50. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  51. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  53. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  54. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  55. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  65. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  66. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/repositories/clone/route.js +1 -1
  68. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  69. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/repositories/restore/route.js +1 -1
  72. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  73. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/repositories/route.js +1 -1
  75. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  76. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/repositories/scan/route.js +1 -1
  78. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  79. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/repositories/sync/route.js +1 -1
  81. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  82. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/settings/default-agents/route.js +1 -1
  85. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  86. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/skills/[id]/route.js +1 -1
  90. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/skills/route.js +1 -1
  95. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/slash-commands/route.js +1 -1
  97. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  107. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  110. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  113. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  119. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  150. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  153. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  156. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  168. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  172. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  175. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +4 -3
  177. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  179. package/.next/server/app/api/worktrees/[id]/schedules/route.js +4 -3
  180. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  182. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  184. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +2 -2
  186. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  187. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  191. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  199. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  203. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  206. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  207. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  209. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  211. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  212. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  214. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  215. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  217. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  218. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  219. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  220. package/.next/server/app/api/worktrees/route.js +1 -1
  221. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  222. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  223. package/.next/server/app/chat/page.js +2 -2
  224. package/.next/server/app/chat/page.js.nft.json +1 -1
  225. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  226. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  227. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/more/page.js +2 -2
  229. package/.next/server/app/more/page.js.nft.json +1 -1
  230. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  231. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  232. package/.next/server/app/page.js +1 -1
  233. package/.next/server/app/page.js.nft.json +1 -1
  234. package/.next/server/app/page_client-reference-manifest.js +1 -1
  235. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  236. package/.next/server/app/repositories/page.js +2 -2
  237. package/.next/server/app/repositories/page.js.nft.json +1 -1
  238. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  239. package/.next/server/app/review/page.js +1 -1
  240. package/.next/server/app/review/page.js.nft.json +1 -1
  241. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  242. package/.next/server/app/sessions/page.js +1 -1
  243. package/.next/server/app/sessions/page.js.nft.json +1 -1
  244. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  245. package/.next/server/app/skills/[skillId]/page.js +2 -2
  246. package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
  247. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  248. package/.next/server/app/skills/installed/page.js +2 -2
  249. package/.next/server/app/skills/installed/page.js.nft.json +1 -1
  250. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  251. package/.next/server/app/skills/page.js +1 -1
  252. package/.next/server/app/skills/page.js.nft.json +1 -1
  253. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  254. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  255. package/.next/server/app/worktrees/[id]/page.js +10 -10
  256. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  257. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  258. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  259. package/.next/server/app-paths-manifest.json +28 -28
  260. package/.next/server/chunks/1058.js +1 -1
  261. package/.next/server/chunks/1068.js +1 -1
  262. package/.next/server/chunks/1262.js +1 -1
  263. package/.next/server/chunks/1886.js +3 -3
  264. package/.next/server/chunks/1990.js +103 -0
  265. package/.next/server/chunks/2119.js +1 -1
  266. package/.next/server/chunks/2328.js +1 -1
  267. package/.next/server/chunks/2404.js +1 -1
  268. package/.next/server/chunks/2445.js +1 -1
  269. package/.next/server/chunks/261.js +1 -1
  270. package/.next/server/chunks/3123.js +1 -1
  271. package/.next/server/chunks/3241.js +1 -1
  272. package/.next/server/chunks/3480.js +5 -4
  273. package/.next/server/chunks/4299.js +1 -1
  274. package/.next/server/chunks/4393.js +1 -1
  275. package/.next/server/chunks/4443.js +1 -5
  276. package/.next/server/chunks/5017.js +1 -1
  277. package/.next/server/chunks/5043.js +1 -1
  278. package/.next/server/chunks/5164.js +1 -1
  279. package/.next/server/chunks/552.js +2 -2
  280. package/.next/server/chunks/6072.js +1 -1
  281. package/.next/server/chunks/6130.js +1 -1
  282. package/.next/server/chunks/663.js +4 -3
  283. package/.next/server/chunks/6894.js +2 -2
  284. package/.next/server/chunks/7187.js +1 -0
  285. package/.next/server/chunks/7472.js +1 -1
  286. package/.next/server/chunks/{880.js → 7859.js} +6 -6
  287. package/.next/server/chunks/7905.js +1 -1
  288. package/.next/server/chunks/8800.js +2 -2
  289. package/.next/server/chunks/8918.js +7 -0
  290. package/.next/server/chunks/9123.js +2 -2
  291. package/.next/server/chunks/9130.js +4 -4
  292. package/.next/server/chunks/9627.js +1 -1
  293. package/.next/server/chunks/9696.js +2 -2
  294. package/.next/server/chunks/9798.js +1 -1
  295. package/.next/server/middleware-manifest.json +5 -5
  296. package/.next/server/pages/500.html +1 -1
  297. package/.next/server/server-reference-manifest.json +1 -1
  298. package/.next/static/chunks/1783-11c9b4d8a52ebd91.js +1 -0
  299. package/.next/static/chunks/4718-de1224c9e8a6e7fc.js +1 -0
  300. package/.next/static/chunks/6022-2fa0b5a82d4ce7b6.js +1 -0
  301. package/.next/static/chunks/{5229-6c89475b61bd2c8b.js → 6170-951b9f5fe6b4b3b5.js} +1 -1
  302. package/.next/static/chunks/app/chat/{page-9aa2011410895b0d.js → page-37d7615d17d7e2a0.js} +1 -1
  303. package/.next/static/chunks/app/layout-4c2f21e3f653ee4c.js +1 -0
  304. package/.next/static/chunks/app/more/{page-333bba1c8bbc9c11.js → page-353a3924e6d7968e.js} +1 -1
  305. package/.next/static/chunks/app/{page-214f7ffa13a0cf10.js → page-c2bf871d953a1d6f.js} +1 -1
  306. package/.next/static/chunks/app/repositories/{page-4951cac905e50224.js → page-7d0f26df0537254c.js} +1 -1
  307. package/.next/static/chunks/app/review/{page-a0899b2d285318c3.js → page-e3f141b2829973e9.js} +1 -1
  308. package/.next/static/chunks/app/sessions/{page-fb36145ec732092a.js → page-53f188ed9ca49e5f.js} +1 -1
  309. package/.next/static/chunks/app/skills/[skillId]/{page-9099e26b60442873.js → page-80569b720aea59cc.js} +1 -1
  310. package/.next/static/chunks/app/skills/installed/{page-182e32368696d824.js → page-dbd2690ad72da95b.js} +1 -1
  311. package/.next/static/chunks/app/skills/{page-d3fdc88239ebe0ab.js → page-dacd36f9c11aa7da.js} +1 -1
  312. package/.next/static/chunks/app/worktrees/[id]/page-97205088520255a5.js +1 -0
  313. package/.next/static/css/5c13ea243dfdcb66.css +1 -0
  314. package/.next/trace +13 -13
  315. package/README.md +37 -11
  316. package/dist/cli/commands/attach.d.ts +50 -0
  317. package/dist/cli/commands/attach.d.ts.map +1 -0
  318. package/dist/cli/commands/attach.js +204 -0
  319. package/dist/cli/commands/capture.d.ts.map +1 -1
  320. package/dist/cli/commands/capture.js +114 -0
  321. package/dist/cli/commands/instances.d.ts.map +1 -1
  322. package/dist/cli/commands/instances.js +23 -2
  323. package/dist/cli/commands/ls.d.ts.map +1 -1
  324. package/dist/cli/commands/ls.js +41 -1
  325. package/dist/cli/config/cli-dependencies.d.ts.map +1 -1
  326. package/dist/cli/config/cli-dependencies.js +34 -0
  327. package/dist/cli/program.d.ts.map +1 -1
  328. package/dist/cli/program.js +5 -0
  329. package/dist/cli/types/index.d.ts +36 -0
  330. package/dist/cli/types/index.d.ts.map +1 -1
  331. package/dist/config/tmux-pane-config.d.ts +153 -0
  332. package/dist/config/tmux-pane-config.d.ts.map +1 -0
  333. package/dist/config/tmux-pane-config.js +172 -0
  334. package/dist/lib/cli-tools/session-name.d.ts +44 -0
  335. package/dist/lib/cli-tools/session-name.d.ts.map +1 -0
  336. package/dist/lib/cli-tools/session-name.js +57 -0
  337. package/dist/lib/cli-tools/types.d.ts +1 -1
  338. package/dist/lib/cli-tools/types.d.ts.map +1 -1
  339. package/dist/lib/cli-tools/types.js +6 -1
  340. package/dist/lib/cli-tools/validation.d.ts +34 -0
  341. package/dist/lib/cli-tools/validation.d.ts.map +1 -0
  342. package/dist/lib/cli-tools/validation.js +41 -0
  343. package/dist/lib/detection/status-reason.d.ts +18 -0
  344. package/dist/lib/detection/status-reason.d.ts.map +1 -1
  345. package/dist/lib/detection/status-reason.js +18 -0
  346. package/dist/lib/detection/tools/verified-against.d.ts +57 -7
  347. package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
  348. package/dist/lib/detection/tools/verified-against.js +59 -8
  349. package/dist/lib/detection/version-probes.d.ts +26 -5
  350. package/dist/lib/detection/version-probes.d.ts.map +1 -1
  351. package/dist/lib/detection/version-probes.js +28 -6
  352. package/dist/lib/session/tmux-session-surface.d.ts +369 -0
  353. package/dist/lib/session/tmux-session-surface.d.ts.map +1 -0
  354. package/dist/lib/session/tmux-session-surface.js +525 -0
  355. package/dist/server/src/config/cli-tool-timing-config.js +12 -1
  356. package/dist/server/src/config/detection-evidence-config.js +5 -0
  357. package/dist/server/src/config/schedule-config.js +28 -1
  358. package/dist/server/src/lib/cli-tools/antigravity.js +2 -2
  359. package/dist/server/src/lib/cli-tools/base.js +13 -8
  360. package/dist/server/src/lib/cli-tools/claude.js +20 -0
  361. package/dist/server/src/lib/cli-tools/codex.js +205 -61
  362. package/dist/server/src/lib/cli-tools/command-code.js +349 -0
  363. package/dist/server/src/lib/cli-tools/composer-spec.js +6 -0
  364. package/dist/server/src/lib/cli-tools/copilot.js +2 -2
  365. package/dist/server/src/lib/cli-tools/gemini.js +2 -2
  366. package/dist/server/src/lib/cli-tools/graceful-exit.js +16 -1
  367. package/dist/server/src/lib/cli-tools/index.js +4 -1
  368. package/dist/server/src/lib/cli-tools/install-hints.js +131 -0
  369. package/dist/server/src/lib/cli-tools/liveness-spec.js +18 -0
  370. package/dist/server/src/lib/cli-tools/manager.js +2 -0
  371. package/dist/server/src/lib/cli-tools/opencode.js +2 -2
  372. package/dist/server/src/lib/cli-tools/start-availability.js +18 -11
  373. package/dist/server/src/lib/cli-tools/types.js +6 -1
  374. package/dist/server/src/lib/cli-tools/vibe-local.js +2 -2
  375. package/dist/server/src/lib/cmate-parser.js +6 -0
  376. package/dist/server/src/lib/detection/cli-patterns.js +441 -8
  377. package/dist/server/src/lib/detection/opencode-modal-overlay.js +66 -100
  378. package/dist/server/src/lib/detection/selection-shape.js +341 -0
  379. package/dist/server/src/lib/detection/sgr-background.js +210 -0
  380. package/dist/server/src/lib/detection/status-detector.js +6 -0
  381. package/dist/server/src/lib/detection/status-reason.js +18 -0
  382. package/dist/server/src/lib/detection/tools/antigravity/detect.js +38 -15
  383. package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +392 -0
  384. package/dist/server/src/lib/detection/tools/codex/detect.js +83 -2
  385. package/dist/server/src/lib/detection/tools/command-code/detect.js +159 -0
  386. package/dist/server/src/lib/detection/tools/registry.js +6 -4
  387. package/dist/server/src/lib/detection/tools/verified-against.js +59 -8
  388. package/dist/server/src/lib/detection/version-probes.js +28 -6
  389. package/dist/server/src/lib/hooks/sources/antigravity/history.js +101 -21
  390. package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +39 -0
  391. package/dist/server/src/lib/hooks/sources/claude/history.js +245 -21
  392. package/dist/server/src/lib/hooks/sources/claude/transcript.js +175 -13
  393. package/dist/server/src/lib/hooks/sources/codex/history.js +84 -15
  394. package/dist/server/src/lib/hooks/sources/codex/hooks-config.js +130 -17
  395. package/dist/server/src/lib/hooks/sources/codex/relay-install.js +145 -0
  396. package/dist/server/src/lib/hooks/sources/command-code/history.js +865 -0
  397. package/dist/server/src/lib/hooks/sources/command-code/hooks-config.js +390 -0
  398. package/dist/server/src/lib/hooks/sources/command-code/source.js +290 -0
  399. package/dist/server/src/lib/hooks/sources/command-code/tool-id.js +18 -0
  400. package/dist/server/src/lib/hooks/sources/command-code/transcript.js +604 -0
  401. package/dist/server/src/lib/hooks/sources/index.js +3 -1
  402. package/dist/server/src/lib/hooks/sources/opencode/history.js +57 -3
  403. package/dist/server/src/lib/hooks/sources/opencode/transcript.js +24 -28
  404. package/dist/server/src/lib/hooks/sources/registry.js +4 -0
  405. package/dist/server/src/lib/hooks/sources/turn-body.js +77 -19
  406. package/dist/server/src/lib/hooks/stop-history-capture.js +58 -25
  407. package/dist/server/src/lib/job-executor.js +12 -0
  408. package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +6 -0
  409. package/dist/server/src/lib/polling/response-checker.js +112 -7
  410. package/dist/server/src/lib/polling/structured-history-gate.js +15 -8
  411. package/dist/server/src/lib/realtime/types.js +15 -5
  412. package/dist/server/src/lib/response-cleaner.js +24 -1
  413. package/dist/server/src/lib/response-extractor.js +11 -0
  414. package/dist/server/src/lib/session/claude-executor.js +223 -4
  415. package/dist/server/src/lib/session/cli-session.js +52 -0
  416. package/dist/server/src/lib/session/tmux-session-surface.js +525 -0
  417. package/dist/server/src/lib/skills/compatibility-matrix.js +117 -1
  418. package/dist/server/src/lib/tmux/geometry-delegation.js +143 -0
  419. package/dist/server/src/lib/tmux/read-mode-pager.js +76 -10
  420. package/dist/server/src/lib/tmux/read-mode.js +44 -2
  421. package/dist/server/src/lib/tmux/session-hook-scripts.js +249 -0
  422. package/dist/server/src/lib/tmux/session-hooks.js +122 -0
  423. package/dist/server/src/lib/tmux/session-status-options.js +213 -0
  424. package/dist/server/src/lib/tmux/tmux.js +79 -2
  425. package/dist/server/src/lib/version-checker.js +110 -0
  426. package/dist/server/src/lib/ws-server.js +16 -10
  427. package/dist/server/src/types/agent-transcript.js +73 -1
  428. package/dist/server/src/types/terminal-keys.js +131 -3
  429. package/dist/types/terminal-keys.d.ts +100 -3
  430. package/dist/types/terminal-keys.d.ts.map +1 -1
  431. package/dist/types/terminal-keys.js +131 -3
  432. package/package.json +1 -1
  433. package/.next/server/chunks/3099.js +0 -5
  434. package/.next/server/chunks/7824.js +0 -1
  435. package/.next/static/chunks/3916-0e929d089282dc5d.js +0 -1
  436. package/.next/static/chunks/6022-7a7d1760fc9814c7.js +0 -1
  437. package/.next/static/chunks/6381-dbf04a99647f6018.js +0 -1
  438. package/.next/static/chunks/app/layout-6a26ea22d5cf03dc.js +0 -1
  439. package/.next/static/chunks/app/worktrees/[id]/page-aac399392ec8c273.js +0 -1
  440. package/.next/static/css/23f9c40ecc458c77.css +0 -1
  441. /package/.next/static/{pcpB4K6KreMzu2qbhvuRY → nXW4dPkpE_9xUf_9ySRff}/_buildManifest.js +0 -0
  442. /package/.next/static/{pcpB4K6KreMzu2qbhvuRY → nXW4dPkpE_9xUf_9ySRff}/_ssgManifest.js +0 -0
@@ -75,15 +75,24 @@
75
75
  * of `detectSessionStatus` passes the raw `capture-pane -e` output
76
76
  * (`lib/tmux/tmux.ts` always passes `-e`).
77
77
  *
78
- * A leaf module by design: it imports the ANSI primitives, the column rule and
79
- * the excerpt bound and nothing else.
78
+ * A leaf module by design: it imports the SGR background scan, the column rule
79
+ * and the excerpt bound and nothing else.
80
+ *
81
+ * The scan itself moved to `sgr-background.ts` in Issue #2323, which needed the
82
+ * same reading for a card's scroll-follow; that move also repaired a
83
+ * foreground/background confusion in the walk (`38;2;r;g;b` channels were read
84
+ * as 16-colour background codes), so a syntax-highlighted transcript row now
85
+ * produces fewer spurious edges here than it did. It cannot produce more, so no
86
+ * rectangle this module used to read can have stopped being one.
80
87
  *
81
88
  * @module lib/detection/opencode-modal-overlay
82
89
  */
83
90
  Object.defineProperty(exports, "__esModule", { value: true });
84
91
  exports.OPENCODE_OVERLAY_TRUNCATION_MARKER = exports.OPENCODE_OVERLAY_EXCERPT_MAX_BYTES = exports.OPENCODE_OVERLAY_HEADER_ROW_LIMIT = exports.OPENCODE_OVERLAY_MIN_ROWS = exports.OPENCODE_OVERLAY_MIN_WIDTH = exports.OPENCODE_OVERLAY_MIN_LEFT = exports.OPENCODE_MODAL_OVERLAY_RECOVERY_KEY = exports.OPENCODE_MODAL_OVERLAY_ID = void 0;
85
92
  exports.detectOpenCodeModalOverlay = detectOpenCodeModalOverlay;
93
+ exports.extractOpenCodeModalOverlayFrame = extractOpenCodeModalOverlayFrame;
86
94
  const excerpt_1 = require("./excerpt");
95
+ const sgr_background_1 = require("./sgr-background");
87
96
  const terminal_columns_1 = require("./terminal-columns");
88
97
  /**
89
98
  * Published `sessionStatusReason` for this signature.
@@ -204,98 +213,6 @@ const ESCAPE_HATCH_WORD = 'esc';
204
213
  * a theme that paints the gutter itself is covered by the same rule.
205
214
  */
206
215
  const BOX_GUTTER = /^[│┃╹]/;
207
- /**
208
- * Every ANSI sequence, in the repository's own spelling.
209
- *
210
- * Restated from `ANSI_PATTERN` (`ansi.ts`) rather than imported because this
211
- * module needs to walk the sequences IN ORDER while counting columns, and that
212
- * one is a shared `g`-flagged instance whose `lastIndex` a caller must not
213
- * disturb. `tests/unit/detection-opencode-modal-overlay-2112.test.ts` asserts
214
- * the text this scan produces is byte-identical to `stripAnsi`'s, so the
215
- * restatement cannot drift silently.
216
- */
217
- const ANSI_SEQUENCE = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\[[0-9;]*m/g;
218
- /** An SGR sequence, with its parameters. Only these can change the background. */
219
- const SGR_PARAMETERS = /^(?:\x1b\[|\[)([0-9;]*)m$/;
220
- /**
221
- * Fold one SGR sequence's parameters into the current background.
222
- *
223
- * Handles the three forms tmux emits: the 16-colour codes (`40`–`47`,
224
- * `100`–`107`), the 256-colour and 24-bit extended forms (`48;5;n`,
225
- * `48;2;r;g;b`), and the two resets (`0`, `49`). Foreground and attribute codes
226
- * leave the background alone, which is what keeps a syntax-highlighted
227
- * transcript row from producing dozens of spurious edges.
228
- */
229
- function applySgr(current, parameters) {
230
- const parts = (parameters === '' ? '0' : parameters).split(';');
231
- let bg = current;
232
- for (let i = 0; i < parts.length; i++) {
233
- const code = Number(parts[i] === '' ? '0' : parts[i]);
234
- if (!Number.isFinite(code))
235
- continue;
236
- if (code === 0 || code === 49) {
237
- bg = null;
238
- }
239
- else if ((code >= 40 && code <= 47) || (code >= 100 && code <= 107)) {
240
- bg = parts[i];
241
- }
242
- else if (code === 48) {
243
- if (parts[i + 1] === '2') {
244
- bg = parts.slice(i, i + 5).join(';');
245
- i += 4;
246
- }
247
- else if (parts[i + 1] === '5') {
248
- bg = parts.slice(i, i + 3).join(';');
249
- i += 2;
250
- }
251
- }
252
- }
253
- return bg;
254
- }
255
- /** Measure one captured row: its text, its background runs and their edges. */
256
- function scanRow(line) {
257
- ANSI_SEQUENCE.lastIndex = 0;
258
- const segments = [];
259
- let text = '';
260
- let bg = null;
261
- let columns = 0;
262
- let segmentStart = 0;
263
- let cursor = 0;
264
- let match;
265
- while ((match = ANSI_SEQUENCE.exec(line)) !== null) {
266
- const chunk = line.slice(cursor, match.index);
267
- text += chunk;
268
- columns += (0, terminal_columns_1.visibleWidth)(chunk);
269
- cursor = match.index + match[0].length;
270
- const sgr = SGR_PARAMETERS.exec(match[0]);
271
- if (sgr === null)
272
- continue;
273
- const next = applySgr(bg, sgr[1]);
274
- if (next === bg)
275
- continue;
276
- if (columns > segmentStart)
277
- segments.push({ bg, start: segmentStart, end: columns });
278
- bg = next;
279
- segmentStart = columns;
280
- }
281
- const tail = line.slice(cursor);
282
- text += tail;
283
- columns += (0, terminal_columns_1.visibleWidth)(tail);
284
- if (columns > segmentStart)
285
- segments.push({ bg, start: segmentStart, end: columns });
286
- const edges = new Set(segments.map(segment => segment.start));
287
- if (segments.length > 0)
288
- edges.add(segments[segments.length - 1].end);
289
- return { text, segments, edges, width: columns };
290
- }
291
- /** The background painted at one column, or `null` for the terminal default. */
292
- function backgroundAt(row, column) {
293
- for (const segment of row.segments) {
294
- if (segment.start <= column && column < segment.end)
295
- return segment.bg;
296
- }
297
- return null;
298
- }
299
216
  /**
300
217
  * Does this row carry the rectangle `[left, right)`?
301
218
  *
@@ -319,16 +236,17 @@ function carriesRectangle(row, left, right) {
319
236
  if (segment.bg === null)
320
237
  return false;
321
238
  }
322
- if (backgroundAt(row, left - 1) === backgroundAt(row, left))
239
+ if ((0, sgr_background_1.backgroundAt)(row, left - 1) === (0, sgr_background_1.backgroundAt)(row, left))
323
240
  return false;
324
- if (right < row.width && backgroundAt(row, right) === backgroundAt(row, right - 1))
241
+ if (right < row.width && (0, sgr_background_1.backgroundAt)(row, right) === (0, sgr_background_1.backgroundAt)(row, right - 1))
325
242
  return false;
326
243
  if (BOX_GUTTER.test((0, terminal_columns_1.sliceColumns)(row.text, left - 1, left)))
327
244
  return false;
328
245
  return !BOX_GUTTER.test((0, terminal_columns_1.sliceColumns)(row.text, left, right));
329
246
  }
330
247
  /**
331
- * The modal overlay painted over an opencode transcript, or null.
248
+ * The modal overlay painted over an opencode transcript, plus the frame rows it
249
+ * spans — or null.
332
250
  *
333
251
  * Call it only for opencode: the rule is about opencode's own dialog chrome, and
334
252
  * every other tool is left exactly as it was (Issue #2112 changes no other
@@ -346,12 +264,14 @@ function carriesRectangle(row, left, right) {
346
264
  *
347
265
  * A caveat the seeding makes easy to miss: two identical rows are two entries in
348
266
  * `carrying`, so the title-bar check below compares object identity rather than
349
- * value.
267
+ * value — and `frameRowStart` / `frameRowEnd` are read the same way, by asking
268
+ * `rows.indexOf(...)` for the first and last object in `carrying` rather than by
269
+ * re-matching text.
350
270
  *
351
271
  * @param frame - The capture with its ANSI intact (`capture-pane -e`)
352
272
  */
353
- function detectOpenCodeModalOverlay(frame) {
354
- const rows = frame.split('\n').map(scanRow);
273
+ function findOpenCodeModalOverlay(frame) {
274
+ const rows = frame.split('\n').map(sgr_background_1.scanRowBackgrounds);
355
275
  const examined = new Set();
356
276
  let best = null;
357
277
  for (const row of rows) {
@@ -391,6 +311,8 @@ function detectOpenCodeModalOverlay(frame) {
391
311
  right,
392
312
  rows: carrying.length,
393
313
  headerRow,
314
+ frameRowStart: rows.indexOf(carrying[0]),
315
+ frameRowEnd: rows.indexOf(carrying[carrying.length - 1]),
394
316
  };
395
317
  }
396
318
  }
@@ -398,3 +320,47 @@ function detectOpenCodeModalOverlay(frame) {
398
320
  }
399
321
  return best;
400
322
  }
323
+ /**
324
+ * The modal overlay painted over an opencode transcript, or null.
325
+ *
326
+ * @param frame - The capture with its ANSI intact (`capture-pane -e`)
327
+ * @see findOpenCodeModalOverlay
328
+ */
329
+ function detectOpenCodeModalOverlay(frame) {
330
+ const match = findOpenCodeModalOverlay(frame);
331
+ if (match === null)
332
+ return null;
333
+ return {
334
+ id: match.id,
335
+ headerText: match.headerText,
336
+ left: match.left,
337
+ right: match.right,
338
+ rows: match.rows,
339
+ headerRow: match.headerRow,
340
+ };
341
+ }
342
+ /**
343
+ * The rows of `frame` covered by opencode's modal overlay, full width and with
344
+ * ANSI intact — or `null` when no overlay is found (Issue #2309).
345
+ *
346
+ * opencode paints its overlay mid-transcript rather than clearing the pane for
347
+ * it (measured: `tests/fixtures/opencode-live-2047/w200/command-palette.txt`
348
+ * shows the conversation on both sides of a centred 60-column box). A dialog
349
+ * card that just took "the whole frame minus blank runs" would drag that
350
+ * transcript in with it and render the overlay as a smear across a page of
351
+ * unrelated text; cropping to the rectangle's own row span is what makes the
352
+ * card show the dialog and nothing else.
353
+ *
354
+ * Column-crop is deliberately NOT done here: the card already scrolls
355
+ * sideways for a 200-column frame (`ChatDialogCard`'s `overflow-auto`), and
356
+ * slicing columns would cut an open SGR sequence started to the rectangle's
357
+ * left, losing the colour state the row depends on.
358
+ *
359
+ * @param frame - The capture with its ANSI intact (`capture-pane -e`)
360
+ */
361
+ function extractOpenCodeModalOverlayFrame(frame) {
362
+ const match = findOpenCodeModalOverlay(frame);
363
+ if (match === null)
364
+ return null;
365
+ return frame.split('\n').slice(match.frameRowStart, match.frameRowEnd + 1).join('\n');
366
+ }
@@ -0,0 +1,341 @@
1
+ "use strict";
2
+ /**
3
+ * What a selection-list frame OFFERS, read off the frame itself (Issue #2297).
4
+ *
5
+ * Issue #2254 gave the chat surface a dialog card, and gave every selection list
6
+ * the same controls: `NavigationButtons`, i.e. ▲▼◀▶ Enter Esc. That is the right
7
+ * verb for a moving highlight and it is not the whole story, because the TUIs
8
+ * disagree about what CONFIRMS:
9
+ *
10
+ * | measured screen | what the footer says |
11
+ * |-------------------------------------|---------------------------------------------------------------|
12
+ * | claude 2.1.259/2.1.260 `/model` | `Enter to set as default · s to use this session only · Esc` |
13
+ * | codex 0.151.0 `/model` | `Press enter to confirm or esc to go back` |
14
+ * | copilot 1.0.80 `/permissions` | `1-2 to select · ↑/↓ to navigate · enter to confirm · esc` |
15
+ * | copilot 1.0.80 `/model` | `↑/↓ to navigate · … · enter to select · esc to cancel`, over a `❯ Search models…` row |
16
+ * | Command Code 1.40.1 `/model` | `type to search · ↑/↓ navigate · … · enter to select · esc` |
17
+ * | antigravity `Switch Model` | name rows, no numbers |
18
+ *
19
+ * So the surface cannot pick its buttons from the tool id. It picks them from
20
+ * the frame it is already drawing, which is what this module reads.
21
+ *
22
+ * ## The three readings, and why each one is worth its own field
23
+ *
24
+ * **`optionCount`** — how many numbered options the dialog is offering, so the
25
+ * card can put a `1`…`N` row under it and turn a seven-step arrow walk into one
26
+ * tap. Zero means "no numbered list here", which is the honest answer for
27
+ * antigravity's `Switch Model` and Command Code's name list, and those keep the
28
+ * arrows they already work with.
29
+ *
30
+ * **`offersSessionScope`** — the footer names a key that takes the highlighted
31
+ * row for THIS SESSION. Only claude's `/model` does, and it is the whole reason
32
+ * Issue #2297 exists: `Enter` on that overlay rewrites `model` in
33
+ * `~/.claude/settings.json` (Issue #1495) and `s` does not, and the chat surface
34
+ * published the first and not the second.
35
+ *
36
+ * **`hasFilterInput`** — the dialog has a focused search box. This is the guard
37
+ * that keeps `optionCount` from being a trap: on copilot's `/model` and Command
38
+ * Code's picker a typed character goes into the filter, not into a selection, so
39
+ * a number button there would silently type `4` into a search field.
40
+ *
41
+ * ## MEASURED: on claude's `/model`, a number key is not a cursor move
42
+ *
43
+ * Issue #2297's plan B reads "number buttons move the highlight, then the tool's
44
+ * own confirm key commits". A live probe on claude 2.1.260 (private tmux socket,
45
+ * 200x1000) says otherwise: pressing `4` on the `/model` overlay answered
46
+ * `Set model to Sonnet 5 and saved as your default for new sessions` and
47
+ * rewrote `~/.claude/settings.json` in one keystroke. The number key IS the
48
+ * commit, and on that screen the commit is the global write the Issue is about.
49
+ *
50
+ * That is why {@link shouldOfferOptionNumbers} refuses the number row exactly
51
+ * where {@link SelectionListShape.offersSessionScope} is true. On claude's
52
+ * `/model` the card offers arrows plus the two LABELLED commits (`s` = this
53
+ * session, `Enter` = set as default) and no unlabelled one-tap default write;
54
+ * every other numbered list — codex's picker, copilot's `/permissions`, claude's
55
+ * own `Enter to select`/`Enter to confirm` dialogs — keeps its numbers.
56
+ *
57
+ * ## Pure, leaf, browser-safe
58
+ *
59
+ * `./ansi` is the only import, exactly as `lib/terminal-display-normalize`
60
+ * takes it: the consumer is `ChatSurface`, a client component, and pulling
61
+ * `cli-patterns` (logger, tool registry types) into the browser bundle to reach
62
+ * three regexes would be the wrong trade. The command-code detector imports
63
+ * {@link COMMAND_CODE_SELECTION_LIST_FOOTER} back out of here so the pattern is
64
+ * written once.
65
+ */
66
+ Object.defineProperty(exports, "__esModule", { value: true });
67
+ exports.COMMAND_CODE_SELECTION_LIST_FOOTER = exports.SET_AS_DEFAULT_FOOTER_PATTERN = exports.SESSION_SCOPE_FOOTER_PATTERN = exports.MAX_OPTION_NUMBER = exports.SELECTION_SHAPE_TAIL_LINE_COUNT = void 0;
68
+ exports.extractCommandCodeSelectionListFrame = extractCommandCodeSelectionListFrame;
69
+ exports.readSelectionListShape = readSelectionListShape;
70
+ exports.shouldOfferOptionNumbers = shouldOfferOptionNumbers;
71
+ const ansi_1 = require("./ansi");
72
+ /**
73
+ * How many rows up from the last content row the shape is read.
74
+ *
75
+ * The dialog is at the END of the content on every capture measured for Issue
76
+ * #2254 — including the top-anchored ones, where "the end of the content" is
77
+ * row 32 of a 1000-row pane and everything below it is padding. Forty rows
78
+ * covers the tallest dialog in `tests/fixtures/chat-dialog-card-2254/`
79
+ * (copilot's `/theme` panel is 15 rows, Command Code's provider-grouped model
80
+ * list is ~70 and is deliberately NOT fully covered — see `optionCount`, which
81
+ * wants the run nearest the footer rather than every number on the pane).
82
+ *
83
+ * Bounded rather than unbounded because the alternative reads the transcript: a
84
+ * markdown answer that happens to contain `1.` / `2.` sits hundreds of rows
85
+ * above the dialog on a 200x1000 pane and must not be counted as options.
86
+ */
87
+ exports.SELECTION_SHAPE_TAIL_LINE_COUNT = 40;
88
+ /** Highest option number a single keystroke can deliver (`10` is two keys). */
89
+ exports.MAX_OPTION_NUMBER = 9;
90
+ /**
91
+ * One numbered option row.
92
+ *
93
+ * The prefix is `[^0-9A-Za-z]*` rather than `\s*` because every measured dialog
94
+ * puts something in front of the number: a selection caret (`❯` claude/copilot,
95
+ * `›` codex, `●` gemini), a panel border (`│` copilot's boxed pickers), or a
96
+ * bullet. Requiring a non-alphanumeric prefix is what keeps `id 3. foo` and a
97
+ * wrapped sentence ending in a digit out.
98
+ *
99
+ * The trailing `\s+\S` requires the option to have a LABEL, which is what stops
100
+ * a diff gutter (`5 - export default getUser;`, live in
101
+ * `copilot-picker-1895/picker-theme.txt`) from matching: it has no `.` or `)`
102
+ * after the digit, and this pattern requires one.
103
+ */
104
+ const OPTION_ROW_PATTERN = /^[^0-9A-Za-z]*([1-9])[.)]\s+\S/;
105
+ /**
106
+ * claude's session-scope footer, verbatim from the live captures.
107
+ *
108
+ * `s to use this session only`. Not anchored to a line start because the footer
109
+ * shares its row with the other two hints.
110
+ */
111
+ exports.SESSION_SCOPE_FOOTER_PATTERN = /\bs\s+to\s+use\s+this\s+session\s+only\b/i;
112
+ /**
113
+ * The footer half that says `Enter` writes a default rather than confirming.
114
+ *
115
+ * Kept separate from {@link SESSION_SCOPE_FOOTER_PATTERN} so the card can label
116
+ * the two buttons from what the frame actually claims, instead of asserting
117
+ * claude's wording for a screen that may not carry it.
118
+ */
119
+ exports.SET_AS_DEFAULT_FOOTER_PATTERN = /\bEnter\s+to\s+set\s+as\s+default\b/i;
120
+ /**
121
+ * A focused search/filter row inside the dialog.
122
+ *
123
+ * Three measured spellings, and nothing wider — this predicate SUPPRESSES a
124
+ * control, so a false positive costs the user their number buttons:
125
+ * - `Type to search models...` / `type to search` (Command Code 1.40.1);
126
+ * - `Search models…` (copilot 1.0.80's `/model`, recorded verbatim in
127
+ * `cli-patterns.ts`'s `COPILOT_SELECTION_FOOTER_PATTERN` docblock);
128
+ * - `/ search` (copilot's `/session` and `/settings` footers).
129
+ *
130
+ * Deliberately does NOT match claude's `/model` blurb ("Switch between Claude
131
+ * models…") or codex's ("Access legacy models by running codex -m…"), neither of
132
+ * which contains the word.
133
+ */
134
+ const FILTER_INPUT_PATTERN = /\btype\s+to\s+search\b|\bsearch\s+\w+\s*(?:…|\.\.\.)|(?:^|·)\s*\/\s+search\b/im;
135
+ /**
136
+ * Command Code's picker footer (v1.40.1, measured at 200x1000 for Issue #2297).
137
+ *
138
+ * type to search · ↑/↓ navigate · shift+↑/↓ jump provider · enter to select · esc to cancel
139
+ *
140
+ * Before this Issue no detector branch matched it, so the overlay fell through
141
+ * to the `default` floor and the chat surface raised its `unclassified` card —
142
+ * whose controls are the `1`–`9` / `y` / `n` answer keys, every one of which
143
+ * would have been typed into that `Type to search models...` box. The
144
+ * command-code detector imports this and answers
145
+ * `STATUS_REASON.COMMAND_CODE_SELECTION_LIST` instead, which puts the arrow pad
146
+ * on the card.
147
+ *
148
+ * Lower case is what Command Code draws, and the `·` separator keeps the pattern
149
+ * off ordinary prose — the same two narrowings `COPILOT_SELECTION_FOOTER_PATTERN`
150
+ * settled on for the same reason.
151
+ */
152
+ exports.COMMAND_CODE_SELECTION_LIST_FOOTER = /\benter\s+to\s+select\b\s*[·•]\s*esc\s+to\s+cancel\b/i;
153
+ /**
154
+ * The horizontal rule Command Code draws directly above a full-screen dialog.
155
+ *
156
+ * Command Code is an INLINE tool (`alternate_on=0`): opening `/model` does not
157
+ * clear the pane, it paints the picker under whatever the session has already
158
+ * printed. On the capture taken for Issue #2326 that is 256 rows of banner and
159
+ * transcript followed by a 77-row picker, and this rule row is the seam between
160
+ * them — 200 columns of U+2500 at the production `TUI_PANE_WIDTH`, the only
161
+ * such row anywhere on the frame while the picker is open (the composer's own
162
+ * two rules are not drawn while a dialog has the screen).
163
+ *
164
+ * Matched as "nothing but the rule glyph", not as "contains one", because a box
165
+ * border (`╭──…──╮`, which is how copilot draws ITS pickers) carries corners and
166
+ * must NOT be read as this seam — see
167
+ * {@link extractCommandCodeSelectionListFrame} for why that non-match is the
168
+ * safe answer rather than a missed case.
169
+ */
170
+ const COMMAND_CODE_RULE_ROW_PATTERN = /^\u2500+$/;
171
+ /**
172
+ * How wide a rule row must be before it counts as the dialog seam.
173
+ *
174
+ * The measured row is the full pane width (200 columns), and a pure function
175
+ * cannot know that width, so this is a floor rather than an equality: it only
176
+ * has to reject a short dash run inside a reply. Forty columns is a quarter of
177
+ * the production pane and wider than any decorative rule measured in
178
+ * `tests/fixtures/`.
179
+ */
180
+ const COMMAND_CODE_RULE_MIN_COLUMNS = 40;
181
+ /**
182
+ * The rows of a Command Code dialog, cut out of the pane it is painted on
183
+ * (Issue #2326).
184
+ *
185
+ * ## Why the dialog card needs a rectangle here at all
186
+ *
187
+ * Issue #2309 gave a selection list every compacted row of the frame instead of
188
+ * a 12–20 row tail, because a search-type picker is tens of rows long and a
189
+ * tail slice threw away rows the arrows could still reach. That is right for a
190
+ * tool that clears the screen. Command Code does not: measured on 2026-09-05
191
+ * (v1.47.1, private socket, 200x1000), a five-turn session with `/model` open
192
+ * gives a 333-row frame of which **256 rows are banner and transcript** and 77
193
+ * are the picker. The card drew all 333, so the picker sat below the fold and
194
+ * the arrow-moved highlight — which {@link findHighlightLineIndex} does now
195
+ * locate correctly, Issue #2323 — was scrolled to inside a box whose visible
196
+ * thirty rows were somebody's earlier conversation.
197
+ *
198
+ * `extractOpenCodeModalOverlayFrame` solves the same problem for opencode by
199
+ * reading its painted rectangle. Command Code paints no rectangle (only the
200
+ * selected ROW carries a background, which is exactly what #2323 turned into
201
+ * the highlight rule), so the seam is read from the two things the picker draws
202
+ * that the transcript does not: the rule above it, and the footer below it.
203
+ *
204
+ * ## The cut
205
+ *
206
+ * Bottom edge: the LAST row matching {@link COMMAND_CODE_SELECTION_LIST_FOOTER}
207
+ * — the same pattern the command-code detector already classifies the screen
208
+ * with, so the card cannot disagree with the detector about whether a picker is
209
+ * up. Top edge: the row AFTER the nearest {@link COMMAND_CODE_RULE_ROW_PATTERN}
210
+ * above that footer (the rule itself is the transcript's boundary, not the
211
+ * dialog's first row; the blank that usually follows it is dropped by the
212
+ * caller's blank-run compaction).
213
+ *
214
+ * ## Both non-matches are the safe answer
215
+ *
216
+ * `null` means "do not crop", and the caller then behaves exactly as it did
217
+ * before this Issue. Two frames take that path deliberately:
218
+ *
219
+ * - **no footer** — the picker was closed between the flags being read and the
220
+ * pane being captured, or the frame is some other dialog. Cropping on a
221
+ * guess would blank the card, which Issue #2326 calls out as worse than
222
+ * showing too much;
223
+ * - **a footer but no rule above it** — copilot's `/model` footer is
224
+ * `↑/↓ to navigate · … · enter to select · esc to cancel` and matches the
225
+ * same pattern, but copilot draws its picker in a corner-bordered box, so no
226
+ * row is nothing-but-rule and copilot's card is returned untouched. Verified
227
+ * on every committed fixture by `dialog-frame-2326.test.ts`.
228
+ *
229
+ * The one degradation this accepts: if the picker's own rule has scrolled off
230
+ * the top of the capture, the nearest rule above the footer is an older one and
231
+ * the crop keeps some transcript. That is strictly less than the whole pane,
232
+ * which is what the frame would otherwise be.
233
+ *
234
+ * @param frame - a raw `capture-pane -p -e` frame, ANSI intact
235
+ * @returns the dialog's own rows, ANSI intact, or `null` to crop nothing
236
+ */
237
+ function extractCommandCodeSelectionListFrame(frame) {
238
+ const lines = frame.replace(/\r\n/g, '\n').split('\n');
239
+ let footer = -1;
240
+ for (let i = lines.length - 1; i >= 0; i -= 1) {
241
+ if (exports.COMMAND_CODE_SELECTION_LIST_FOOTER.test((0, ansi_1.stripAnsi)(lines[i]))) {
242
+ footer = i;
243
+ break;
244
+ }
245
+ }
246
+ if (footer < 0)
247
+ return null;
248
+ for (let i = footer - 1; i >= 0; i -= 1) {
249
+ const row = (0, ansi_1.stripAnsi)(lines[i]).trim();
250
+ if (row.length < COMMAND_CODE_RULE_MIN_COLUMNS)
251
+ continue;
252
+ if (!COMMAND_CODE_RULE_ROW_PATTERN.test(row))
253
+ continue;
254
+ return lines.slice(i + 1, footer + 1).join('\n');
255
+ }
256
+ return null;
257
+ }
258
+ /** The reading for a frame that carries no dialog at all. */
259
+ const EMPTY_SHAPE = {
260
+ optionCount: 0,
261
+ offersSessionScope: false,
262
+ commitsDefaultOnEnter: false,
263
+ hasFilterInput: false,
264
+ };
265
+ /** The last {@link SELECTION_SHAPE_TAIL_LINE_COUNT} rows that carry content. */
266
+ function tailLines(frame) {
267
+ const lines = (0, ansi_1.stripAnsi)(frame.replace(/\r\n/g, '\n')).split('\n');
268
+ let last = lines.length - 1;
269
+ while (last >= 0 && lines[last].trim() === '')
270
+ last -= 1;
271
+ if (last < 0)
272
+ return [];
273
+ return lines.slice(Math.max(0, last + 1 - exports.SELECTION_SHAPE_TAIL_LINE_COUNT), last + 1);
274
+ }
275
+ /**
276
+ * Count the LAST run of option rows numbered `1, 2, 3, …`.
277
+ *
278
+ * Restarting the run on every fresh `1` is what makes the codex launch frame
279
+ * safe: whatever numbered rows preceded the picker, the count that survives is
280
+ * the one belonging to the run nearest the footer. A number out of sequence ends
281
+ * the run without erasing what it had already reached, so copilot's `/session`
282
+ * list — which numbers past `9` — still reports its first nine.
283
+ */
284
+ function countTrailingOptionRun(lines) {
285
+ let reached = 0;
286
+ let running = 0;
287
+ for (const line of lines) {
288
+ const match = OPTION_ROW_PATTERN.exec(line);
289
+ if (match === null)
290
+ continue;
291
+ const value = Number(match[1]);
292
+ if (value === running + 1) {
293
+ running = value;
294
+ reached = value;
295
+ }
296
+ else if (value === 1) {
297
+ running = 1;
298
+ reached = 1;
299
+ }
300
+ else {
301
+ running = 0;
302
+ }
303
+ }
304
+ return Math.min(reached, exports.MAX_OPTION_NUMBER);
305
+ }
306
+ /**
307
+ * Read what the dialog on this frame offers.
308
+ *
309
+ * @param frame - a raw `capture-pane -p -e` frame (`PaneTerminalState.output`)
310
+ * @returns the shape; all-false / zero for an empty or missing frame
311
+ */
312
+ function readSelectionListShape(frame) {
313
+ if (!frame)
314
+ return EMPTY_SHAPE;
315
+ const lines = tailLines(frame);
316
+ if (lines.length === 0)
317
+ return EMPTY_SHAPE;
318
+ const tail = lines.join('\n');
319
+ return {
320
+ optionCount: countTrailingOptionRun(lines),
321
+ offersSessionScope: exports.SESSION_SCOPE_FOOTER_PATTERN.test(tail),
322
+ commitsDefaultOnEnter: exports.SET_AS_DEFAULT_FOOTER_PATTERN.test(tail),
323
+ hasFilterInput: FILTER_INPUT_PATTERN.test(tail),
324
+ };
325
+ }
326
+ /**
327
+ * Whether the card may draw a `1`…`N` row for this shape.
328
+ *
329
+ * Two refusals, both measured rather than defensive:
330
+ *
331
+ * - **a session-scope footer.** On claude's `/model` a number key commits AND
332
+ * rewrites the global default in one press (probed live on 2.1.260), so a
333
+ * number button there is an unlabelled version of the exact write Issue
334
+ * #2297 is about. That screen gets the two labelled commit buttons instead.
335
+ * - **a filter input.** copilot's `/model` and Command Code's picker put a
336
+ * focused search box on the dialog, where a `4` is four characters of a
337
+ * query and not the fourth model.
338
+ */
339
+ function shouldOfferOptionNumbers(shape) {
340
+ return shape.optionCount > 0 && !shape.offersSessionScope && !shape.hasFilterInput;
341
+ }