commandmate 0.31.1 → 0.31.3

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 (299) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +170 -170
  3. package/.next/app-path-routes-manifest.json +29 -29
  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.nft.json +1 -1
  14. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  16. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/assistant/messages/route.js +1 -1
  18. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  19. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/assistant/session/route.js +1 -1
  21. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  22. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/assistant/start/route.js +2 -2
  24. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  25. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/assistant/terminal/route.js +2 -2
  27. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  28. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  30. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/capabilities/route.js +1 -1
  35. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  44. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  45. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/hooks/claude-done/route.js +2 -2
  47. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  48. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  50. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  51. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/push/escalation/route.js +2 -2
  55. package/.next/server/app/api/push/escalation/route.js.nft.json +1 -1
  56. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/push/subscriptions/route.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.js +2 -2
  60. package/.next/server/app/api/push/vapid/route.js.nft.json +1 -1
  61. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  67. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  68. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/repositories/clone/route.js +1 -1
  70. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  71. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  72. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/repositories/restore/route.js +1 -1
  74. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  75. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  76. package/.next/server/app/api/repositories/route.js +1 -1
  77. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  78. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/repositories/scan/route.js +1 -1
  80. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  81. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/repositories/sync/route.js +1 -1
  83. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  84. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  87. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.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_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  104. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  105. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  107. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  110. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  113. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  116. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  146. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  148. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  151. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  163. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  167. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  170. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  177. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  179. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  182. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  190. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  191. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  194. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  198. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  199. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  203. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  206. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  209. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  211. package/.next/server/app/api/worktrees/route.js +1 -1
  212. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  213. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  214. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  215. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  216. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  217. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  218. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  219. package/.next/server/app/page_client-reference-manifest.js +1 -1
  220. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  221. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  222. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  223. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  224. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  225. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  226. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  227. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  228. package/.next/server/app/worktrees/[id]/page.js +10 -10
  229. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  230. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  231. package/.next/server/app-paths-manifest.json +29 -29
  232. package/.next/server/chunks/1058.js +1 -1
  233. package/.next/server/chunks/1068.js +1 -1
  234. package/.next/server/chunks/1191.js +2 -2
  235. package/.next/server/chunks/1886.js +1 -1
  236. package/.next/server/chunks/2119.js +1 -1
  237. package/.next/server/chunks/2404.js +1 -1
  238. package/.next/server/chunks/2445.js +1 -1
  239. package/.next/server/chunks/261.js +1 -1
  240. package/.next/server/chunks/2739.js +1 -1
  241. package/.next/server/chunks/3241.js +1 -1
  242. package/.next/server/chunks/3484.js +1 -0
  243. package/.next/server/chunks/358.js +1 -0
  244. package/.next/server/chunks/4325.js +1 -1
  245. package/.next/server/chunks/4393.js +1 -1
  246. package/.next/server/chunks/4443.js +1 -1
  247. package/.next/server/chunks/5017.js +1 -1
  248. package/.next/server/chunks/5120.js +1 -1
  249. package/.next/server/chunks/5164.js +1 -1
  250. package/.next/server/chunks/552.js +3 -3
  251. package/.next/server/chunks/595.js +8 -0
  252. package/.next/server/chunks/6130.js +1 -1
  253. package/.next/server/chunks/8800.js +1 -1
  254. package/.next/server/chunks/8918.js +3 -3
  255. package/.next/server/chunks/9123.js +1 -1
  256. package/.next/server/chunks/9130.js +2 -2
  257. package/.next/server/chunks/9627.js +3 -3
  258. package/.next/server/chunks/9696.js +2 -2
  259. package/.next/server/chunks/9798.js +2 -2
  260. package/.next/server/middleware-manifest.json +5 -5
  261. package/.next/server/pages/500.html +1 -1
  262. package/.next/server/server-reference-manifest.json +1 -1
  263. package/.next/static/chunks/{1783-11c9b4d8a52ebd91.js → 2813-de885de8a4b11910.js} +1 -1
  264. package/.next/static/chunks/4718-07ec4e10186928db.js +1 -0
  265. package/.next/static/chunks/app/worktrees/[id]/page-91b639c90795baa9.js +1 -0
  266. package/.next/static/css/acc4b9c3feb04287.css +1 -0
  267. package/.next/trace +13 -13
  268. package/dist/lib/detection/tools/verified-against.d.ts +24 -24
  269. package/dist/lib/detection/tools/verified-against.js +24 -24
  270. package/dist/server/locales/en/worktree.json +1402 -0
  271. package/dist/server/locales/ja/worktree.json +1402 -0
  272. package/dist/server/src/lib/db/chat-db.js +44 -1
  273. package/dist/server/src/lib/detection/cli-patterns.js +157 -23
  274. package/dist/server/src/lib/detection/model-info-extractor.js +185 -4
  275. package/dist/server/src/lib/detection/tools/antigravity/detect.js +105 -25
  276. package/dist/server/src/lib/detection/tools/antigravity/dialog.js +233 -0
  277. package/dist/server/src/lib/detection/tools/verified-against.js +24 -24
  278. package/dist/server/src/lib/hooks/hook-settings-generator.js +16 -0
  279. package/dist/server/src/lib/hooks/sources/claude/model-switch.js +169 -0
  280. package/dist/server/src/lib/hooks/sources/claude/source.js +14 -1
  281. package/dist/server/src/lib/polling/response-checker.js +17 -1
  282. package/dist/server/src/lib/polling/response-poller-core.js +143 -9
  283. package/dist/server/src/lib/push/index.js +13 -1
  284. package/dist/server/src/lib/push/model-change-push-notifier.js +174 -0
  285. package/dist/server/src/lib/push/notification-dedup.js +2 -1
  286. package/dist/server/src/lib/push/push-sender.js +48 -20
  287. package/dist/server/src/lib/realtime/model-change-broadcast.js +171 -0
  288. package/dist/server/src/lib/realtime/types.js +19 -1
  289. package/dist/server/src/lib/realtime/waiting-broadcast.js +13 -0
  290. package/dist/server/src/lib/session/agent-event-state.js +344 -12
  291. package/package.json +1 -1
  292. package/.next/server/chunks/6894.js +0 -8
  293. package/.next/server/chunks/7187.js +0 -1
  294. package/.next/server/chunks/7472.js +0 -1
  295. package/.next/static/chunks/4718-46e1d2f07c8423ba.js +0 -1
  296. package/.next/static/chunks/app/worktrees/[id]/page-64d4ec3051971760.js +0 -1
  297. package/.next/static/css/5c13ea243dfdcb66.css +0 -1
  298. /package/.next/static/{60mm4_QBuFtFTfo5UMyKU → 0hTIackGXw6v7diXJS6yN}/_buildManifest.js +0 -0
  299. /package/.next/static/{60mm4_QBuFtFTfo5UMyKU → 0hTIackGXw6v7diXJS6yN}/_ssgManifest.js +0 -0
@@ -6,7 +6,7 @@
6
6
  * Issue #479: Extracted from db.ts for single-responsibility separation
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.UNKEYED_USER_MESSAGE_LIMIT = exports.ACTIVE_FILTER = void 0;
9
+ exports.MODEL_CHANGE_REQUEST_ID_PREFIX = exports.UNKEYED_USER_MESSAGE_LIMIT = exports.ACTIVE_FILTER = void 0;
10
10
  exports.getLastAssistantMessageAt = getLastAssistantMessageAt;
11
11
  exports.createMessage = createMessage;
12
12
  exports.updateMessageContent = updateMessageContent;
@@ -28,6 +28,7 @@ exports.getMessageById = getMessageById;
28
28
  exports.updatePromptData = updatePromptData;
29
29
  exports.markPendingPromptsAsAnswered = markPendingPromptsAsAnswered;
30
30
  exports.recordAnsweredPrompt = recordAnsweredPrompt;
31
+ exports.createModelChangeMessage = createModelChangeMessage;
31
32
  const crypto_1 = require("crypto");
32
33
  const logger_1 = require("../../lib/logger");
33
34
  const logger = (0, logger_1.createLogger)('chat-db');
@@ -654,3 +655,45 @@ function recordAnsweredPrompt(db, params) {
654
655
  });
655
656
  return { message, created: true };
656
657
  }
658
+ // ============================================================================
659
+ // Model change rows (Issue #2357)
660
+ // ============================================================================
661
+ /**
662
+ * The `request_id` prefix a model-change row carries (Issue #2357).
663
+ *
664
+ * `chat_messages` has no `system` role — `role` is `user | assistant` and every
665
+ * reader of the column branches on exactly those two — so the sentence "the
666
+ * model changed" is stored as an assistant row and *identified* by its request
667
+ * id instead: `model-changed:<epoch ms>`. A reader that wants to style these
668
+ * rows differently, or a `capture --prompts`-style audit that wants to list
669
+ * them, matches on this prefix rather than on the wording, which is localized
670
+ * at write time and would otherwise have to be matched in every language.
671
+ */
672
+ exports.MODEL_CHANGE_REQUEST_ID_PREFIX = 'model-changed:';
673
+ /**
674
+ * Persist "the model changed" into the instance's history (Issue #2357).
675
+ *
676
+ * One row per transition, written by the model edge's subscriber and nothing
677
+ * else — the chat transcript and the History tab both read this table, so one
678
+ * write reaches both, and the same row is what the `message` frame pushes to a
679
+ * transcript that is open at the time.
680
+ *
681
+ * An assistant row, on purpose: the transcript groups an assistant row that
682
+ * follows no user row as a standalone reply, which is the closest the schema
683
+ * comes to a system line without a migration. The row is a `normal` message
684
+ * (not a `prompt`), so nothing that scans for open dialogs will mistake it for
685
+ * one, and the request id (see {@link MODEL_CHANGE_REQUEST_ID_PREFIX}) is what
686
+ * marks it.
687
+ */
688
+ function createModelChangeMessage(db, params) {
689
+ return createMessage(db, {
690
+ worktreeId: params.worktreeId,
691
+ role: 'assistant',
692
+ content: params.content,
693
+ messageType: 'normal',
694
+ timestamp: new Date(params.at),
695
+ requestId: `${exports.MODEL_CHANGE_REQUEST_ID_PREFIX}${params.at}`,
696
+ cliToolId: params.cliToolId,
697
+ instanceId: params.instanceId ?? params.cliToolId,
698
+ });
699
+ }
@@ -5,7 +5,7 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.COPILOT_TOOL_ROW_PATTERN = exports.COPILOT_TOOL_VERBS = exports.COPILOT_TRANSCRIPT_DIVIDER_PATTERN = exports.COPILOT_USER_ECHO_PATTERN = exports.COPILOT_REASONING_HEADER_PATTERN = exports.COPILOT_BOX_ROW_PATTERN = exports.COPILOT_SEPARATOR_PATTERN = exports.COPILOT_IDLE_STATUS_PATTERN = exports.COPILOT_WORKING_STATUS_PATTERN = exports.COPILOT_THINKING_PATTERN = exports.COPILOT_PROMPT_PATTERN = exports.OPENCODE_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.COMMAND_CODE_SKIP_PATTERNS = exports.COMMAND_CODE_HOOK_NOTICE_PATTERN = exports.COMMAND_CODE_BANNER_PATTERNS = exports.COMMAND_CODE_MODE_INDICATOR_PATTERN = exports.COMMAND_CODE_COMPLETION_PATTERN = exports.COMMAND_CODE_RESPONSE_MARKER_PATTERN = exports.COMMAND_CODE_THINKING_PATTERN = exports.COMMAND_CODE_INTERRUPT_HINT_PATTERN = exports.COMMAND_CODE_SEPARATOR_PATTERN = exports.COMMAND_CODE_PROMPT_PATTERN = exports.COMMAND_CODE_SPINNER_CHARS = exports.ANTIGRAVITY_SKIP_PATTERNS = exports.ANTIGRAVITY_NUMBERED_OPTION_PATTERN = exports.ANTIGRAVITY_NUMBERED_DIALOG_QUESTION_PATTERN = 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 = exports.COPILOT_SELECTION_FOOTER_PATTERN = exports.COPILOT_BOOT_BANNER_ANCHORS = exports.COPILOT_TRANSCRIPT_CONTINUATION_PATTERN = void 0;
8
+ exports.CLAUDE_SESSION_ERROR_REGEX_PATTERNS = exports.CLAUDE_SESSION_ERROR_PATTERNS = exports.extractAnsiSequences = exports.stripAnsi = exports.COMMAND_CODE_SKIP_PATTERNS = exports.COMMAND_CODE_HOOK_NOTICE_PATTERN = exports.COMMAND_CODE_BANNER_PATTERNS = exports.COMMAND_CODE_MODE_INDICATOR_PATTERN = exports.COMMAND_CODE_COMPLETION_PATTERN = exports.COMMAND_CODE_RESPONSE_MARKER_PATTERN = exports.COMMAND_CODE_THINKING_PATTERN = exports.COMMAND_CODE_INTERRUPT_HINT_PATTERN = exports.COMMAND_CODE_SEPARATOR_PATTERN = exports.COMMAND_CODE_PROMPT_PATTERN = exports.COMMAND_CODE_SPINNER_CHARS = exports.ANTIGRAVITY_SKIP_PATTERNS = exports.ANTIGRAVITY_SURVEY_PATTERN = exports.ANTIGRAVITY_DIALOG_MAX_ROWS = exports.ANTIGRAVITY_DIALOG_BOUNDARY_PATTERN = exports.ANTIGRAVITY_SWITCH_MODEL_HEADER_PATTERN = exports.ANTIGRAVITY_NUMBERED_OPTION_PATTERN = exports.ANTIGRAVITY_NAVIGATE_FOOTER_PATTERN = exports.ANTIGRAVITY_SELECTION_LIST_PATTERN = exports.ANTIGRAVITY_SEPARATOR_PATTERN = exports.ANTIGRAVITY_THINKING_PATTERN = exports.ANTIGRAVITY_PROMPT_PATTERN = exports.VIBE_LOCAL_THINKING_PATTERN = exports.VIBE_LOCAL_PROMPT_PATTERN = exports.COPILOT_SKIP_PATTERNS = exports.COPILOT_FOLDER_TRUST_ANSWER_KEY = exports.COPILOT_FOLDER_TRUST_SESSION_OPTION_PATTERN = exports.COPILOT_FOLDER_TRUST_ANCHORS = exports.COPILOT_SELECTION_FOOTER_PATTERN = exports.COPILOT_BOOT_BANNER_ANCHORS = exports.COPILOT_TRANSCRIPT_CONTINUATION_PATTERN = void 0;
9
9
  exports.isCodexTurnActive = isCodexTurnActive;
10
10
  exports.findClaudeChromeStart = findClaudeChromeStart;
11
11
  exports.isCodexPromptReady = isCodexPromptReady;
@@ -19,6 +19,7 @@ exports.readCopilotStatusBar = readCopilotStatusBar;
19
19
  exports.findCopilotChromeStart = findCopilotChromeStart;
20
20
  exports.isCopilotSelectionFrame = isCopilotSelectionFrame;
21
21
  exports.isCopilotFolderTrustDialog = isCopilotFolderTrustDialog;
22
+ exports.locateAntigravityDialogRegion = locateAntigravityDialogRegion;
22
23
  exports.isAntigravityNumberedDialog = isAntigravityNumberedDialog;
23
24
  exports.findCommandCodeChromeStart = findCommandCodeChromeStart;
24
25
  exports.detectThinking = detectThinking;
@@ -1861,25 +1862,125 @@ exports.ANTIGRAVITY_SEPARATOR_PATTERN = /^─{3,}$/m;
1861
1862
  */
1862
1863
  exports.ANTIGRAVITY_SELECTION_LIST_PATTERN = /Switch Model|↑\/↓\s*Navigate/m;
1863
1864
  /**
1864
- * The question line agy draws above its numbered permission dialog
1865
- * (Issue #2270; measured on agy 1.1.25, pane 200x1000, 2026-09-04).
1865
+ * The `↑/↓ Navigate` hint agy draws under every arrow-key screen it owns
1866
+ * (Issue #2364; measured on agy 1.1.27, pane 200x1000, 2026-09-06).
1866
1867
  *
1867
- * Anchored to the whole line so a model's prose that merely quotes the phrase
1868
- * inside a sentence cannot match it.
1868
+ * The same token {@link ANTIGRAVITY_SELECTION_LIST_PATTERN} matches, split out
1869
+ * because the numbered-dialog reader anchors on THIS row and reads upward from
1870
+ * it. It is the one thing all four measured agy dialogs share — the `Do you want
1871
+ * to proceed?` command menu, the `Allow creation of this file?` file menu, the
1872
+ * folder-trust screen and the `/model` picker all end on it — while the words
1873
+ * after it differ on every one (`tab Amend · f full diff`, `tab Amend · ctrl+g
1874
+ * edit/expand command`, `enter Confirm`, `←/→ Effort enter Select`).
1869
1875
  */
1870
- exports.ANTIGRAVITY_NUMBERED_DIALOG_QUESTION_PATTERN = /^\s*Do you want to proceed\?\s*$/m;
1876
+ exports.ANTIGRAVITY_NAVIGATE_FOOTER_PATTERN = /↑\/↓\s*Navigate/;
1871
1877
  /**
1872
- * One numbered option row of that dialog: `> 1. Yes`, ` 4. No`.
1878
+ * One numbered option row of agy's dialogs: `> 1. Yes`, ` 4. No`,
1879
+ * ` 2. No, deny creation`.
1873
1880
  *
1874
- * The `>` gutter marks the highlighted row and is optional, because only one of
1875
- * the four rows carries it.
1881
+ * The `>` gutter marks the highlighted row and is optional, because only one
1882
+ * of the rows carries it.
1876
1883
  */
1877
1884
  exports.ANTIGRAVITY_NUMBERED_OPTION_PATTERN = /^\s*>?\s*\d+\.\s+\S/m;
1878
1885
  /**
1879
- * Is this frame agy's NUMBERED permission dialog rather than one of its
1880
- * arrow-key-only pickers? (Issue #2270)
1886
+ * The header of agy's `/model` picker (Issue #995).
1881
1887
  *
1882
- * Both agy screens share the `↑/↓ Navigate` footer that
1888
+ * Kept as its own exclusion even though the picker's rows already fail the
1889
+ * numbered-row test: the Issue #2364 rule is written as "footer + numbered rows
1890
+ * + NOT the Switch Model picker", and the picker is the one agy screen whose
1891
+ * misreading has a measured cost (#995: NavigationButtons vanished).
1892
+ */
1893
+ exports.ANTIGRAVITY_SWITCH_MODEL_HEADER_PATTERN = /^\s*Switch Model\s*$/;
1894
+ /**
1895
+ * A row that ends the dialog block when reading UPWARD from the footer
1896
+ * (Issue #2364).
1897
+ *
1898
+ * Everything agy draws above its own dialog panel carries one of these:
1899
+ *
1900
+ * - a horizontal rule (the turn separator, the input-box border, or the rule
1901
+ * under the `Command` / `Create file` panel header);
1902
+ * - a `>`-prefixed row that is not a numbered option — the echoed user prompt,
1903
+ * the bare composer, the highlighted row of an UNNUMBERED picker (`> Gemini
1904
+ * 3.8 Flash`, `> Yes, I trust this folder`) or of the slash-command popup
1905
+ * (`> /add-dir Add a directory …`);
1906
+ * - a `●` tool-call row, a `⎿` tool-result row or a `▸ Thought for …` row.
1907
+ *
1908
+ * Bounding the block at the nearest one is what keeps a numbered list in the
1909
+ * MODEL'S PROSE, sitting in the transcript above an open picker or popup, from
1910
+ * being adopted as that screen's options. Wrapped option labels never start
1911
+ * with any of these on the measured frames: agy prints the command text inside
1912
+ * the quotes of `… commands that start with '<cmd>'`, indented under the row
1913
+ * that opened it.
1914
+ *
1915
+ * `stripBoxDrawing` blanks the rule rows before the response poller's copy of
1916
+ * the frame reaches this rule; the `●` / `>` rows survive it, so the block is
1917
+ * bounded the same way on both paths.
1918
+ */
1919
+ exports.ANTIGRAVITY_DIALOG_BOUNDARY_PATTERN = /^\s*(?:─{3,}\s*$|[●⎿▸]|>(?!\s*\d+\.\s+\S))/;
1920
+ /**
1921
+ * How many rows above the `↑/↓ Navigate` footer the dialog block may reach.
1922
+ *
1923
+ * The tallest measured frame (`dialog-bash-wrapped.txt`: header, rule,
1924
+ * `Requesting permission for:`, a four-row command, the question and four
1925
+ * options of which two wrap onto three rows each) spans 18 rows; the cap leaves
1926
+ * room for a longer command without letting a boundary-free frame drag the
1927
+ * whole transcript into the block.
1928
+ */
1929
+ exports.ANTIGRAVITY_DIALOG_MAX_ROWS = 60;
1930
+ /**
1931
+ * agy's post-answer survey row (Issue #2364).
1932
+ *
1933
+ * Drawn once, in place of the composer, after some tool decisions:
1934
+ *
1935
+ * ```
1936
+ * How's the CLI experience so far? Help us improve:
1937
+ * [1] Good [2] Fine [3] Bad [0] Skip
1938
+ *
1939
+ * ? for shortcuts …
1940
+ * ```
1941
+ *
1942
+ * Every option sits on ONE row in `[N] label` form and the screen takes a
1943
+ * typed digit, not the arrow keys; there is no `↑/↓ Navigate` footer and no bare
1944
+ * `>` composer, so before this pattern existed the frame reached the `default`
1945
+ * floor — `running`, with the chat surface showing "generating" over a screen
1946
+ * that was waiting for a keypress. Anchored to the whole row.
1947
+ */
1948
+ exports.ANTIGRAVITY_SURVEY_PATTERN = /^\s*\[1\]\s*Good\s+\[2\]\s*Fine\s+\[3\]\s*Bad\s+\[0\]\s*Skip\s*$/m;
1949
+ /**
1950
+ * Find the rows between the last boundary and the last `↑/↓ Navigate` footer
1951
+ * (Issue #2364).
1952
+ *
1953
+ * The footer is searched from the bottom, so an older dialog still in the
1954
+ * scrollback above a newer one is never the one read. Returns null when the
1955
+ * frame has no footer at all.
1956
+ *
1957
+ * @param lines - ANSI-stripped rows, box drawing optional
1958
+ */
1959
+ function locateAntigravityDialogRegion(lines) {
1960
+ let footer = -1;
1961
+ for (let i = lines.length - 1; i >= 0; i--) {
1962
+ if (exports.ANTIGRAVITY_NAVIGATE_FOOTER_PATTERN.test(lines[i])) {
1963
+ footer = i;
1964
+ break;
1965
+ }
1966
+ }
1967
+ if (footer < 0)
1968
+ return null;
1969
+ const floor = Math.max(0, footer - exports.ANTIGRAVITY_DIALOG_MAX_ROWS);
1970
+ let start = floor;
1971
+ for (let i = footer - 1; i >= floor; i--) {
1972
+ if (exports.ANTIGRAVITY_DIALOG_BOUNDARY_PATTERN.test(lines[i])) {
1973
+ start = i + 1;
1974
+ break;
1975
+ }
1976
+ }
1977
+ return { start, footer };
1978
+ }
1979
+ /**
1980
+ * Is this frame one of agy's NUMBERED dialogs rather than one of its
1981
+ * arrow-key-only pickers? (Issue #2270, re-measured by Issue #2364)
1982
+ *
1983
+ * Both kinds of screen share the `↑/↓ Navigate` footer that
1883
1984
  * {@link ANTIGRAVITY_SELECTION_LIST_PATTERN} matches, which is why #997 could
1884
1985
  * widen that pattern to cover the permission menu — and why the menu then
1885
1986
  * resolved as `antigravity_selection_list`, `hasActivePrompt: false`. On the
@@ -1888,21 +1989,45 @@ exports.ANTIGRAVITY_NUMBERED_OPTION_PATTERN = /^\s*>?\s*\d+\.\s+\S/m;
1888
1989
  * options 2-4 became unreachable, while the poller and the push notification
1889
1990
  * described the very same frame as a `multiple_choice` prompt.
1890
1991
  *
1891
- * The discriminator is the pair below, not the footer:
1892
- *
1893
- * - `Do you want to proceed?` on its own line, and
1894
- * - at least one `N. label` row.
1895
- *
1896
- * The Switch Model picker has neither (its rows are unnumbered model names and
1897
- * its header is `Switch Model`), so it keeps the #995 reading. Every other agy
1898
- * arrow-key TUI keeps it too — this is deliberately a rule about the ONE dialog
1899
- * whose frames were measured, not a general "numbers mean prompt" inference.
1992
+ * #2270 told the two apart by the question line, `Do you want to proceed?`,
1993
+ * because that was the one dialog it had measured. #2364 measured a second one
1994
+ * agy 1.1.27's file-creation menu asks `Allow creation of this file?` above
1995
+ * `1. Yes, allow creation` / `2. No, deny creation` — and it fell straight back
1996
+ * into the selection-list reading. So the rule is now about the STRUCTURE the
1997
+ * dialogs share and the pickers lack:
1998
+ *
1999
+ * - the `↑/↓ Navigate` footer,
2000
+ * - at least two `N. label` rows between the nearest boundary row and that
2001
+ * footer ({@link ANTIGRAVITY_DIALOG_BOUNDARY_PATTERN}), and
2002
+ * - no `Switch Model` header in that region.
2003
+ *
2004
+ * The Switch Model picker, the folder-trust screen and the slash-command popup
2005
+ * all draw unnumbered rows (`> Gemini 3.8 Flash`, `> Yes, I trust this folder`,
2006
+ * `> /add-dir …`), so they keep the #995 reading — and because a `>` row that
2007
+ * is not numbered is itself a boundary, a numbered list in the transcript above
2008
+ * one of them cannot be counted.
2009
+ *
2010
+ * True here means "hand the frame to the agy dialog reader"
2011
+ * (`tools/antigravity/dialog.ts`), never "this is a prompt": a frame that
2012
+ * passes this test and still fails to read is published as an unclassified
2013
+ * frame, not as a selection list and never as "generating".
1900
2014
  *
1901
2015
  * Callers pass the same text they hand {@link ANTIGRAVITY_SELECTION_LIST_PATTERN}.
1902
2016
  */
1903
2017
  function isAntigravityNumberedDialog(text) {
1904
- return (exports.ANTIGRAVITY_NUMBERED_DIALOG_QUESTION_PATTERN.test(text) &&
1905
- exports.ANTIGRAVITY_NUMBERED_OPTION_PATTERN.test(text));
2018
+ const lines = text.split('\n');
2019
+ const region = locateAntigravityDialogRegion(lines);
2020
+ if (region === null)
2021
+ return false;
2022
+ let numberedRows = 0;
2023
+ for (let i = region.start; i < region.footer; i++) {
2024
+ const line = lines[i];
2025
+ if (exports.ANTIGRAVITY_SWITCH_MODEL_HEADER_PATTERN.test(line))
2026
+ return false;
2027
+ if (exports.ANTIGRAVITY_NUMBERED_OPTION_PATTERN.test(line))
2028
+ numberedRows++;
2029
+ }
2030
+ return numberedRows >= 2;
1906
2031
  }
1907
2032
  /**
1908
2033
  * Antigravity (agy) skip patterns for response cleaning (Issue #988)
@@ -2421,6 +2546,15 @@ function buildDetectPromptOptions(cliToolId) {
2421
2546
  // the Pass 1 gate rejects these menus, so Auto-Yes never responds. Treat agy
2422
2547
  // like claude/opencode/copilot so Pass 2 collects its "1. Yes / … / N. No"
2423
2548
  // options and reports isPrompt=true.
2549
+ //
2550
+ // [Issue #2364] The `↑/↓ Navigate` dialogs themselves no longer reach
2551
+ // `detectPrompt` on either production path: `tools/antigravity/detect.ts`
2552
+ // (status) and `detectPromptWithOptions` (response poller) both read them
2553
+ // with `detectAntigravityNumberedDialogPrompt` first, because the generic
2554
+ // multiple-choice pass reads one row per option and agy wraps a long command
2555
+ // across several rows of one label. What this setting still serves is every
2556
+ // OTHER numbered agy screen — `/feedback`'s `1-6 Select & Continue` menu is
2557
+ // the measured one — which the generic pass reads as before.
2424
2558
  if (cliToolId === 'antigravity') {
2425
2559
  return { requireDefaultIndicator: false };
2426
2560
  }
@@ -35,6 +35,7 @@
35
35
  * |-------------|------------------------------------------------------------------|
36
36
  * | codex | footer: `gpt-5.6-sol xhigh · ~/share/work/…` |
37
37
  * | claude | banner: `▝▜█████▛▘ Opus 5 (1M context) with xhigh effort · Claude Max` |
38
+ * | claude | switch: ` ⎿ Set model to Sonnet 5 for this session only` (#2361) |
38
39
  * | antigravity | footer: `? for shortcuts … Gemini 3.7 Flash · hig` |
39
40
  * | antigravity | banner: ` ▀▀▀▀▀▀▀▀ Gemini 3.7 Flash (High)` |
40
41
  * | copilot | footer: `← open sidebar · … · tab next tab GPT-5 mini · Medium` |
@@ -60,7 +61,7 @@
60
61
  * @see Issue #1784, Phase 2 of the model/effort visibility series
61
62
  */
62
63
  Object.defineProperty(exports, "__esModule", { value: true });
63
- exports.ANTIGRAVITY_MODEL_ID_EFFORT_PATTERN = exports.OPENCODE_STEP_MODEL_PATTERN = exports.COPILOT_MODEL_CHANGE_PATTERN = exports.ANTIGRAVITY_BANNER_MODEL_PATTERN = exports.ANTIGRAVITY_STATUS_BAR_HINT_PATTERN = exports.CLAUDE_STARTUP_BANNER_PATTERN = exports.CODEX_FOOTER_MODEL_PATTERN = exports.REASONING_EFFORT_LEVELS = void 0;
64
+ exports.ANTIGRAVITY_MODEL_ID_EFFORT_PATTERN = exports.COMMAND_CODE_BANNER_MODELS_PATTERN = exports.OPENCODE_STEP_MODEL_PATTERN = exports.COPILOT_MODEL_CHANGE_PATTERN = exports.ANTIGRAVITY_BANNER_MODEL_PATTERN = exports.ANTIGRAVITY_STATUS_BAR_HINT_PATTERN = exports.CLAUDE_MODEL_SWITCH_PATTERN = exports.CLAUDE_STARTUP_BANNER_PATTERN = exports.CODEX_FOOTER_MODEL_PATTERN = exports.REASONING_EFFORT_LEVELS = void 0;
64
65
  exports.resolveEffortToken = resolveEffortToken;
65
66
  exports.extractModelInfo = extractModelInfo;
66
67
  exports.deriveEffortFromModelId = deriveEffortFromModelId;
@@ -219,6 +220,89 @@ function readClaudeBanner(line) {
219
220
  return null;
220
221
  return { model, effort: resolveEffortToken(match[2]) };
221
222
  }
223
+ /**
224
+ * Reads `<model>[ with <effort> effort]` off the line Claude prints when the
225
+ * session's model changes (Issue #2361).
226
+ *
227
+ * Measured live on claude 2.1.263 for this Issue
228
+ * (`tests/fixtures/claude-model-switch-2361/`, and that directory's README).
229
+ * The confirmation is the `⎿` stdout row under the `/model` command, in the
230
+ * same place for the picker (`Enter` / `s`) and for `/model <arg>`:
231
+ *
232
+ * ` ⎿ Set model to Sonnet 5 for this session only`
233
+ * ` ⎿ Set model to Haiku 4.5 and saved as your default for new sessions`
234
+ * ` ⎿ Set model to Opus 5 (1M context) and saved as your default for new sessions with high effort`
235
+ * ` ⎿ Kept model as Haiku 4.5` (picker closed with Esc)
236
+ *
237
+ * **The Issue's starting point (`selection-shape.ts`, "Set model to Sonnet 5
238
+ * and saved as your default for new sessions") is one of three suffixes, not
239
+ * the line.** What was measured beyond it:
240
+ *
241
+ * - **The scope suffix comes BEFORE the effort.** `… and saved as your default
242
+ * for new sessions with high effort` — the effort is appended only when the
243
+ * picker's `←/→` row was moved, and is absent otherwise even though the
244
+ * session has one. So the effort is read when printed and left null when
245
+ * not, and `recordCapturedModelInfo` keeps the previous effort — the
246
+ * Issue's rule 3.
247
+ * - **`Kept model as` is the Esc outcome** and names the current model. It is
248
+ * read for the same reason the banner is: it is the TUI stating the model,
249
+ * and on a session whose banner scrolled away it is the only thing on screen
250
+ * that does.
251
+ * - **The banner is rewritten in place on every switch** (fullscreen and
252
+ * inline alike): `Fable 5.1 with xhigh effort` became `Sonnet 5 with xhigh
253
+ * effort` on the same row, `history_size` unchanged — and `/effort` and
254
+ * `/fast` rewrite it too. That decides the precedence in
255
+ * {@link extractModelInfo}: **the banner wins while it is on screen, the
256
+ * line is the fallback for when it is gone**
257
+ * (`fullscreen-switch-sonnet-banner-scrolled.txt`). The Issue asked for
258
+ * "whichever is lower", on the premise that the banner is static; measured,
259
+ * that rule answers the STALE model on `fullscreen-fast-on.txt` — the
260
+ * lowest confirmation there is `Kept model as Haiku 4.5`, printed before a
261
+ * `/fast` moved the session to Opus and rewrote the banner above it to
262
+ * `Opus 5 (1M context) with high effort`.
263
+ * - **Haiku's rewritten banner has no effort clause** (`Haiku 4.5 · API Usage
264
+ * Billing`), so {@link CLAUDE_STARTUP_BANNER_PATTERN} does not read it and
265
+ * the confirmation line is what publishes the model there. The banner
266
+ * pattern is deliberately not widened: without the `with … effort` anchor
267
+ * a box-framed table row containing ` · ` would read as a banner.
268
+ * - **`/fast` prints `⎿ ↯ Fast mode ON · model set to Opus 5 · $10/$50 per
269
+ * Mtok` and is a model switch** (`PostModelSwitch` reported
270
+ * `claude-fable-5-1` → `claude-opus-5[1m]` on the same keypress). It is NOT
271
+ * read: the line spells the model `Opus 5` where the banner and `Kept model
272
+ * as` spell it `Opus 5 (1M context)`, and within one channel #2357's
273
+ * identity rule is exact, so reading it would announce a second, spurious
274
+ * "change" the next time the fuller spelling appears. While the banner is
275
+ * on screen the rewrite covers `/fast`; once it is gone the switch is
276
+ * missed by this reader until the next `/model` line. Issue #2363 closed
277
+ * that gap on the structured side: `PostModelSwitch` is registered and
278
+ * reports `/fast` as `to_model: "claude-opus-5[1m]"` — one spelling, no
279
+ * drift — so this reader stays the fallback for sessions the hook does not
280
+ * reach (`lib/hooks/sources/claude/model-switch`).
281
+ *
282
+ * The `⎿` marker is required. Claude's own prose shares the pane with its
283
+ * chrome, and the 2.1.263 release notes alone contain 75 rows that mention
284
+ * a model (`fullscreen-switch-line-scrolled.txt`, which must read as unknown);
285
+ * the marker is what local-command output carries and prose does not. A value
286
+ * read here latches for the rest of the session.
287
+ *
288
+ * No /g. No nested quantifiers: the lazy label class is bounded by three
289
+ * literal-anchored alternatives and the end of the row; the `[^·]*` after the
290
+ * effort admits the parenthesised `(the effort applies to this session only)`
291
+ * note the binary can append, and stops at the `·` that opens the fast-mode
292
+ * / usage-credit suffixes. The lookahead keeps a row with no name at all from
293
+ * reading its own suffix as one. `ultracode` resolves to no
294
+ * {@link ReasoningEffort} and answers null, like Command Code's `max`.
295
+ */
296
+ exports.CLAUDE_MODEL_SWITCH_PATTERN = /^\s*⎿\s+(?:Set model to|Kept model as)\s+(?!(?:and saved as your default|for this session only)\b)([A-Za-z0-9][A-Za-z0-9 .()[\]_:@/-]*?)(?:\s+(?:and saved as your default for new sessions|for this session only))?(?:\s+with\s+([A-Za-z]+)\s+effort\b[^·]*)?\s*(?:·.*)?$/;
297
+ function readClaudeModelSwitchLine(line) {
298
+ const match = exports.CLAUDE_MODEL_SWITCH_PATTERN.exec(line);
299
+ if (!match)
300
+ return null;
301
+ const model = match[1].trim();
302
+ if (!isPlausibleModelLabel(model))
303
+ return null;
304
+ return { model, effort: match[2] ? resolveEffortToken(match[2]) : null };
305
+ }
222
306
  // =============================================================================
223
307
  // Antigravity
224
308
  // =============================================================================
@@ -452,14 +536,95 @@ function readOpencodeStepMarker(line) {
452
536
  return isPlausibleModelLabel(model) ? { model, effort: null } : null;
453
537
  }
454
538
  // =============================================================================
539
+ // Command Code (Issue #2358)
540
+ // =============================================================================
541
+ /**
542
+ * Reads `<model>[ with <effort> effort]` off the `# models:` row of the Command
543
+ * Code startup banner (Issue #2358).
544
+ *
545
+ * Command Code's hooks carry no model at all
546
+ * (`src/lib/hooks/sources/command-code/source.ts`: no `model` key on any
547
+ * captured payload), so the banner is the only place the value exists. It is
548
+ * the same three rows on 1.40.1, 1.47.1 and 1.49.0, straight under the
549
+ * block-art logo:
550
+ *
551
+ * `# Command Code v1.49.0`
552
+ * `# models: deepseek-v4-flash-(latest) · taste-1`
553
+ * `# /path/to/cwd`
554
+ *
555
+ * **The Issue text says the row is `<model> · <taste>` and that there is no
556
+ * effort. The pane says otherwise.** Measured live on 1.49.0 for this Issue
557
+ * (`tests/fixtures/chat-dialog-card-2254/command-code-model-1-49-0-*.txt`, and
558
+ * that directory's README): the `/model` picker is followed by a second screen,
559
+ * `Select reasoning effort for <model>`
560
+ * (`Default` / `low` / `high` / `max`, the set varying by model), and a
561
+ * non-default choice is printed into the banner —
562
+ *
563
+ * `# models: deepseek-v4-pro-(latest) with high effort · taste-1`
564
+ * `# models: deepseek-v4-flash-(latest) with max effort · taste-1` (also at launch, from config)
565
+ * `# models: kimi-k3 with low effort · taste-1`
566
+ *
567
+ * — while `Default` prints the bare form the 18 earlier fixtures show. So:
568
+ *
569
+ * - **The model is everything before ` with ` / ` · `, kept verbatim.** The
570
+ * `(latest)` suffix is part of the id — it is how the picker spells the same
571
+ * entry (`DeepSeek V4 Flash (latest)`), so stripping it would publish a name
572
+ * the picker never shows. `MODEL_LABEL_SHAPE` admits the parentheses; the
573
+ * bare token shape does not.
574
+ * - **`taste-1` is not a model.** It is Command Code's "taste" setting (the
575
+ * footer reads `? for shortcuts · taste on`), so everything from the dot on
576
+ * is dropped, and the dot itself is optional.
577
+ * - **The effort is read when the banner prints one, through the shared
578
+ * vocabulary.** `low` / `high` resolve; `max` is not a
579
+ * {@link ReasoningEffort} and answers null rather than widening a list every
580
+ * other reader and the UI type depend on. The model half is published either
581
+ * way: the ` with … effort` frame delimits it cleanly, so nothing is
582
+ * half-read.
583
+ *
584
+ * ## After a `/model` switch (measured, 1.49.0)
585
+ *
586
+ * Command Code renders inline (`#{alternate_on}` is 0) and on a **model**
587
+ * change it re-emits its whole output, banner included, without growing the
588
+ * history: the `# models:` row was rewritten in place both while it sat on
589
+ * screen and after 1100 transcript rows had pushed it into scrollback. So
590
+ * bottom-up scanning is the whole rule, and a switch is visible on the next
591
+ * poll for as long as the banner is inside the captured window
592
+ * (`STATUS_DETECTION_CAPTURE_LINES` = 1000 rows from the bottom —
593
+ * `…-switch-banner-scrolled.txt` is a frame past that point, and answers
594
+ * unknown so the latch keeps the pre-switch value).
595
+ *
596
+ * An **effort-only** change on the current model does NOT rewrite the row: in
597
+ * three trials (`max`→`high`, `high`→`max`, `max`→`Default`) the banner kept the
598
+ * effort it first showed for that model, while `config.json` did change. That
599
+ * is a Command Code display defect, and this reader mirrors the screen — the
600
+ * effort published for a model is the one its banner row shows, which is the
601
+ * launch value or the value chosen when the model was first picked.
602
+ *
603
+ * No /g. No nested quantifiers: the lazy `[^·]+?` is bounded by the literal
604
+ * ` with `, the literal `·`, or the end of the line; the optional effort group
605
+ * is anchored on two literals and contains no quantified group of its own.
606
+ */
607
+ exports.COMMAND_CODE_BANNER_MODELS_PATTERN = /^\s*#\s+models:\s*([^·]+?)(?:\s+with\s+([A-Za-z]+)\s+effort)?\s*(?:·|$)/i;
608
+ function readCommandCodeBanner(line) {
609
+ const match = exports.COMMAND_CODE_BANNER_MODELS_PATTERN.exec(line);
610
+ if (!match)
611
+ return null;
612
+ const model = match[1].trim();
613
+ if (!isPlausibleModelLabel(model))
614
+ return null;
615
+ return { model, effort: match[2] ? resolveEffortToken(match[2]) : null };
616
+ }
617
+ // =============================================================================
455
618
  // Public API
456
619
  // =============================================================================
457
620
  /**
458
621
  * Scan a capture from the bottom up, returning the first line that reads.
459
622
  *
460
623
  * Bottom-up is the whole rule: the status bar is the last line of the frame, and
461
- * for Claude "the last banner wins" is how a mid-session `/model` switch which
462
- * prints a fresh banner overtakes the one from session start.
624
+ * for Claude "the last banner wins" is how a fresh banner overtakes the one from
625
+ * session start (on 2.1.263 a `/model` switch rewrites the banner in place
626
+ * instead, and prints a confirmation line the second scan reads once the banner
627
+ * is gone — Issue #2361).
463
628
  *
464
629
  * ANSI is stripped per line rather than over the whole blob so a malformed OSC
465
630
  * sequence can never swallow a newline and merge two lines into one.
@@ -498,7 +663,17 @@ function extractModelInfo(cliToolId, captureText) {
498
663
  case 'codex':
499
664
  return scanFromEnd(captureText, readCodexFooter) ?? unknown();
500
665
  case 'claude':
501
- return scanFromEnd(captureText, readClaudeBanner) ?? unknown();
666
+ // Issue #2361. The banner is live chrome — rewritten in place by
667
+ // `/model`, `/effort` and `/fast` — so it wins for as long as it is on
668
+ // screen, and the lowest `/model` confirmation line is the fallback for
669
+ // the long session whose banner has scrolled away (see
670
+ // `readClaudeModelSwitchLine` for the measured precedence). Claude's
671
+ // hooks name the model on `SessionStart` alone — `/model` fires none of
672
+ // the events CommandMate registers — so on a switch the pane is the only
673
+ // channel that hears it.
674
+ return (scanFromEnd(captureText, readClaudeBanner) ??
675
+ scanFromEnd(captureText, readClaudeModelSwitchLine) ??
676
+ unknown());
502
677
  case 'antigravity':
503
678
  return (scanFromEnd(captureText, readAntigravityStatusBar) ??
504
679
  scanFromEnd(captureText, readAntigravityBanner) ??
@@ -520,6 +695,12 @@ function extractModelInfo(cliToolId, captureText) {
520
695
  }
521
696
  case 'opencode':
522
697
  return scanFromEnd(captureText, readOpencodeStepMarker) ?? unknown();
698
+ case 'command-code':
699
+ // Issue #2358. The banner is the only source — hooks carry no model — and
700
+ // bottom-up is the same "last banner wins" rule Claude uses: a relaunch in
701
+ // the same pane overtakes the banner above it, and a `/model` switch
702
+ // rewrites the one row in place (see `readCommandCodeBanner`).
703
+ return scanFromEnd(captureText, readCommandCodeBanner) ?? unknown();
523
704
  default:
524
705
  return unknown();
525
706
  }