commandmate 0.29.2 → 0.30.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 (647) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +278 -271
  3. package/.next/app-path-routes-manifest.json +35 -34
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +3 -3
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/routes-manifest.json +8 -8
  8. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/app/update-check/route.js +1 -1
  13. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/assistant/conversation/route.js +1 -1
  15. package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
  16. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/assistant/current-output/route.js +1 -1
  18. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  19. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/assistant/messages/route.js +1 -1
  21. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  22. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/assistant/session/route.js +1 -1
  24. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  25. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/assistant/start/route.js +18 -18
  27. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  28. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/assistant/terminal/route.js +19 -19
  30. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  31. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/assistant/tools/route.js +1 -1
  33. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  34. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/capabilities/route.js +1 -1
  39. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/daily-summary/route.js +1 -1
  41. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  49. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  50. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  51. package/.next/server/app/api/hooks/claude-done/route.js +2 -2
  52. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  53. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  55. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  56. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/push/escalation/route.js +1 -1
  60. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/push/vapid/route.js +1 -1
  63. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  69. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  70. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/repositories/clone/route.js +1 -1
  72. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  73. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/repositories/restore/route.js +1 -1
  76. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  77. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/repositories/route.js +1 -1
  79. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  80. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/repositories/scan/route.js +1 -1
  82. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  83. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/repositories/sync/route.js +1 -1
  85. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  86. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/settings/default-agents/route.js +1 -1
  89. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  90. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/settings/default-surface-mode/route.js +1 -0
  92. package/.next/server/app/api/settings/default-surface-mode/route.js.nft.json +1 -0
  93. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -0
  94. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  110. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  113. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  116. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/cli-reference/route.js +1 -0
  118. package/.next/server/app/api/worktrees/[id]/cli-reference/route.js.nft.json +1 -0
  119. package/.next/server/app/api/worktrees/[id]/{start-polling → cli-reference}/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  124. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  154. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  157. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  160. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  174. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/resolve-target/route.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  179. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  182. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  189. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +1 -1
  191. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  192. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  199. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  203. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  206. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  207. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  209. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  210. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  211. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  212. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  214. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  215. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  217. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  218. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  219. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  220. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  221. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  222. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  223. package/.next/server/app/api/worktrees/apply-default-agents/route.js +1 -1
  224. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  225. package/.next/server/app/api/worktrees/route.js +1 -1
  226. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  227. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  229. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  230. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  231. package/.next/server/app/more/page.js +2 -2
  232. package/.next/server/app/more/page.js.nft.json +1 -1
  233. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  234. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  235. package/.next/server/app/page_client-reference-manifest.js +1 -1
  236. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  237. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  238. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  239. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  240. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  241. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  242. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  243. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  244. package/.next/server/app/worktrees/[id]/page.js +12 -12
  245. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  246. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  247. package/.next/server/app/worktrees/[id]/terminal/page.js +3 -3
  248. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  249. package/.next/server/app-paths-manifest.json +35 -34
  250. package/.next/server/chunks/1058.js +1 -1
  251. package/.next/server/chunks/1068.js +1 -1
  252. package/.next/server/chunks/1191.js +1 -1
  253. package/.next/server/chunks/1341.js +1 -1
  254. package/.next/server/chunks/1886.js +3 -3
  255. package/.next/server/chunks/2119.js +1 -1
  256. package/.next/server/chunks/2445.js +1 -1
  257. package/.next/server/chunks/261.js +1 -0
  258. package/.next/server/chunks/2739.js +1 -0
  259. package/.next/server/chunks/2816.js +1 -1
  260. package/.next/server/chunks/2827.js +29 -0
  261. package/.next/server/chunks/3123.js +1 -0
  262. package/.next/server/chunks/3241.js +1 -1
  263. package/.next/server/chunks/3543.js +1 -1
  264. package/.next/server/chunks/3945.js +1 -1
  265. package/.next/server/chunks/4325.js +1 -0
  266. package/.next/server/chunks/4390.js +1 -1
  267. package/.next/server/chunks/4393.js +1 -1
  268. package/.next/server/chunks/4443.js +6 -0
  269. package/.next/server/chunks/5017.js +1 -1
  270. package/.next/server/chunks/5120.js +1 -0
  271. package/.next/server/chunks/6130.js +1 -1
  272. package/.next/server/chunks/6337.js +1 -1
  273. package/.next/server/chunks/663.js +1 -1
  274. package/.next/server/chunks/6894.js +8 -0
  275. package/.next/server/chunks/7685.js +1 -1
  276. package/.next/server/chunks/7836.js +1 -0
  277. package/.next/server/chunks/8356.js +1 -1
  278. package/.next/server/chunks/880.js +1 -1
  279. package/.next/server/chunks/8807.js +1 -1
  280. package/.next/server/chunks/9123.js +2 -2
  281. package/.next/server/chunks/9130.js +3 -3
  282. package/.next/server/chunks/9627.js +48 -26
  283. package/.next/server/chunks/9696.js +3 -0
  284. package/.next/server/chunks/9798.js +1 -1
  285. package/.next/server/middleware-manifest.json +5 -5
  286. package/.next/server/pages/500.html +1 -1
  287. package/.next/server/server-reference-manifest.json +1 -1
  288. package/.next/server/src/middleware.js +1 -1
  289. package/.next/server/src/middleware.js.map +1 -1
  290. package/.next/static/7K0XXFu_ty4wRSkl4X21E/_buildManifest.js +1 -0
  291. package/.next/static/chunks/{4882-388e94fe0a03c2ba.js → 3916-0e929d089282dc5d.js} +1 -1
  292. package/.next/static/chunks/{5229-b2a81bb8fb5c19e9.js → 5229-6c89475b61bd2c8b.js} +1 -1
  293. package/.next/static/chunks/6022-7a7d1760fc9814c7.js +1 -0
  294. package/.next/static/chunks/6381-28d0e95620aa018e.js +1 -0
  295. package/.next/static/chunks/app/api/agents/update/route-ee11f7b8a34cba8c.js +1 -0
  296. package/.next/static/chunks/app/api/agents/versions/route-ee11f7b8a34cba8c.js +1 -0
  297. package/.next/static/chunks/app/api/app/update/route-ee11f7b8a34cba8c.js +1 -0
  298. package/.next/static/chunks/app/api/app/update-check/route-ee11f7b8a34cba8c.js +1 -0
  299. package/.next/static/chunks/app/api/assistant/conversation/route-ee11f7b8a34cba8c.js +1 -0
  300. package/.next/static/chunks/app/api/assistant/current-output/route-ee11f7b8a34cba8c.js +1 -0
  301. package/.next/static/chunks/app/api/assistant/messages/route-ee11f7b8a34cba8c.js +1 -0
  302. package/.next/static/chunks/app/api/assistant/session/route-ee11f7b8a34cba8c.js +1 -0
  303. package/.next/static/chunks/app/api/assistant/start/route-ee11f7b8a34cba8c.js +1 -0
  304. package/.next/static/chunks/app/api/assistant/terminal/route-ee11f7b8a34cba8c.js +1 -0
  305. package/.next/static/chunks/app/api/assistant/tools/route-ee11f7b8a34cba8c.js +1 -0
  306. package/.next/static/chunks/app/api/auth/login/route-ee11f7b8a34cba8c.js +1 -0
  307. package/.next/static/chunks/app/api/auth/logout/route-ee11f7b8a34cba8c.js +1 -0
  308. package/.next/static/chunks/app/api/auth/status/route-ee11f7b8a34cba8c.js +1 -0
  309. package/.next/static/chunks/app/api/capabilities/route-ee11f7b8a34cba8c.js +1 -0
  310. package/.next/static/chunks/app/api/daily-summary/route-ee11f7b8a34cba8c.js +1 -0
  311. package/.next/static/chunks/app/api/daily-summary/status/route-ee11f7b8a34cba8c.js +1 -0
  312. package/.next/static/chunks/app/api/external-apps/[id]/health/route-ee11f7b8a34cba8c.js +1 -0
  313. package/.next/static/chunks/app/api/external-apps/[id]/route-ee11f7b8a34cba8c.js +1 -0
  314. package/.next/static/chunks/app/api/external-apps/route-ee11f7b8a34cba8c.js +1 -0
  315. package/.next/static/chunks/app/api/fs/browse/route-ee11f7b8a34cba8c.js +1 -0
  316. package/.next/static/chunks/app/api/fs/recent-paths/route-ee11f7b8a34cba8c.js +1 -0
  317. package/.next/static/chunks/app/api/hooks/agent-event/route-ee11f7b8a34cba8c.js +1 -0
  318. package/.next/static/chunks/app/api/hooks/claude-done/route-ee11f7b8a34cba8c.js +1 -0
  319. package/.next/static/chunks/app/api/hooks/permission-request/route-ee11f7b8a34cba8c.js +1 -0
  320. package/.next/static/chunks/app/api/metrics/vibe/route-ee11f7b8a34cba8c.js +1 -0
  321. package/.next/static/chunks/app/api/ollama/models/route-ee11f7b8a34cba8c.js +1 -0
  322. package/.next/static/chunks/app/api/push/escalation/route-ee11f7b8a34cba8c.js +1 -0
  323. package/.next/static/chunks/app/api/push/subscriptions/route-ee11f7b8a34cba8c.js +1 -0
  324. package/.next/static/chunks/app/api/push/vapid/route-ee11f7b8a34cba8c.js +1 -0
  325. package/.next/static/chunks/app/api/remote/pair/route-ee11f7b8a34cba8c.js +1 -0
  326. package/.next/static/chunks/app/api/repositories/[id]/route-ee11f7b8a34cba8c.js +1 -0
  327. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-ee11f7b8a34cba8c.js +1 -0
  328. package/.next/static/chunks/app/api/repositories/[id]/todos/route-ee11f7b8a34cba8c.js +1 -0
  329. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-ee11f7b8a34cba8c.js +1 -0
  330. package/.next/static/chunks/app/api/repositories/clone/route-ee11f7b8a34cba8c.js +1 -0
  331. package/.next/static/chunks/app/api/repositories/excluded/route-ee11f7b8a34cba8c.js +1 -0
  332. package/.next/static/chunks/app/api/repositories/restore/route-ee11f7b8a34cba8c.js +1 -0
  333. package/.next/static/chunks/app/api/repositories/route-ee11f7b8a34cba8c.js +1 -0
  334. package/.next/static/chunks/app/api/repositories/scan/route-ee11f7b8a34cba8c.js +1 -0
  335. package/.next/static/chunks/app/api/repositories/sync/route-ee11f7b8a34cba8c.js +1 -0
  336. package/.next/static/chunks/app/api/repositories/validate-path/route-ee11f7b8a34cba8c.js +1 -0
  337. package/.next/static/chunks/app/api/settings/default-agents/route-ee11f7b8a34cba8c.js +1 -0
  338. package/.next/static/chunks/app/api/settings/default-surface-mode/route-ee11f7b8a34cba8c.js +1 -0
  339. package/.next/static/chunks/app/api/sidebar/group-order/route-ee11f7b8a34cba8c.js +1 -0
  340. package/.next/static/chunks/app/api/skills/[id]/route-ee11f7b8a34cba8c.js +1 -0
  341. package/.next/static/chunks/app/api/skills/installations/route-ee11f7b8a34cba8c.js +1 -0
  342. package/.next/static/chunks/app/api/skills/operations/route-ee11f7b8a34cba8c.js +1 -0
  343. package/.next/static/chunks/app/api/skills/reindex/route-ee11f7b8a34cba8c.js +1 -0
  344. package/.next/static/chunks/app/api/skills/route-ee11f7b8a34cba8c.js +1 -0
  345. package/.next/static/chunks/app/api/slash-commands/route-ee11f7b8a34cba8c.js +1 -0
  346. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-ee11f7b8a34cba8c.js +1 -0
  347. package/.next/static/chunks/app/api/tasks/[taskId]/route-ee11f7b8a34cba8c.js +1 -0
  348. package/.next/static/chunks/app/api/templates/[id]/route-ee11f7b8a34cba8c.js +1 -0
  349. package/.next/static/chunks/app/api/templates/route-ee11f7b8a34cba8c.js +1 -0
  350. package/.next/static/chunks/app/api/todos/route-ee11f7b8a34cba8c.js +1 -0
  351. package/.next/static/chunks/app/api/verification/runs/[runId]/route-ee11f7b8a34cba8c.js +1 -0
  352. package/.next/static/chunks/app/api/verification/runs/route-ee11f7b8a34cba8c.js +1 -0
  353. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-ee11f7b8a34cba8c.js +1 -0
  354. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-ee11f7b8a34cba8c.js +1 -0
  355. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-ee11f7b8a34cba8c.js +1 -0
  356. package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-ee11f7b8a34cba8c.js +1 -0
  357. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-ee11f7b8a34cba8c.js +1 -0
  358. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-ee11f7b8a34cba8c.js +1 -0
  359. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-ee11f7b8a34cba8c.js +1 -0
  360. package/.next/static/chunks/app/api/worktrees/[id]/env/route-ee11f7b8a34cba8c.js +1 -0
  361. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-ee11f7b8a34cba8c.js +1 -0
  362. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-ee11f7b8a34cba8c.js +1 -0
  363. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-ee11f7b8a34cba8c.js +1 -0
  364. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-ee11f7b8a34cba8c.js +1 -0
  365. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-ee11f7b8a34cba8c.js +1 -0
  366. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-ee11f7b8a34cba8c.js +1 -0
  367. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-ee11f7b8a34cba8c.js +1 -0
  368. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-ee11f7b8a34cba8c.js +1 -0
  369. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-ee11f7b8a34cba8c.js +1 -0
  370. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-ee11f7b8a34cba8c.js +1 -0
  371. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-ee11f7b8a34cba8c.js +1 -0
  372. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-ee11f7b8a34cba8c.js +1 -0
  373. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-ee11f7b8a34cba8c.js +1 -0
  374. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-ee11f7b8a34cba8c.js +1 -0
  375. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-ee11f7b8a34cba8c.js +1 -0
  376. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-ee11f7b8a34cba8c.js +1 -0
  377. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-ee11f7b8a34cba8c.js +1 -0
  378. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-ee11f7b8a34cba8c.js +1 -0
  379. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-ee11f7b8a34cba8c.js +1 -0
  380. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-ee11f7b8a34cba8c.js +1 -0
  381. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-ee11f7b8a34cba8c.js +1 -0
  382. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-ee11f7b8a34cba8c.js +1 -0
  383. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-ee11f7b8a34cba8c.js +1 -0
  384. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-ee11f7b8a34cba8c.js +1 -0
  385. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-ee11f7b8a34cba8c.js +1 -0
  386. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-ee11f7b8a34cba8c.js +1 -0
  387. package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-ee11f7b8a34cba8c.js +1 -0
  388. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-ee11f7b8a34cba8c.js +1 -0
  389. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-ee11f7b8a34cba8c.js +1 -0
  390. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-ee11f7b8a34cba8c.js +1 -0
  391. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-ee11f7b8a34cba8c.js +1 -0
  392. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-ee11f7b8a34cba8c.js +1 -0
  393. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-ee11f7b8a34cba8c.js +1 -0
  394. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-ee11f7b8a34cba8c.js +1 -0
  395. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-ee11f7b8a34cba8c.js +1 -0
  396. package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-ee11f7b8a34cba8c.js +1 -0
  397. package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-ee11f7b8a34cba8c.js +1 -0
  398. package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-ee11f7b8a34cba8c.js +1 -0
  399. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-ee11f7b8a34cba8c.js +1 -0
  400. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-ee11f7b8a34cba8c.js +1 -0
  401. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-ee11f7b8a34cba8c.js +1 -0
  402. package/.next/static/chunks/app/api/worktrees/[id]/route-ee11f7b8a34cba8c.js +1 -0
  403. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-ee11f7b8a34cba8c.js +1 -0
  404. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-ee11f7b8a34cba8c.js +1 -0
  405. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-ee11f7b8a34cba8c.js +1 -0
  406. package/.next/static/chunks/app/api/worktrees/[id]/search/route-ee11f7b8a34cba8c.js +1 -0
  407. package/.next/static/chunks/app/api/worktrees/[id]/send/route-ee11f7b8a34cba8c.js +1 -0
  408. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-ee11f7b8a34cba8c.js +1 -0
  409. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-ee11f7b8a34cba8c.js +1 -0
  410. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-ee11f7b8a34cba8c.js +1 -0
  411. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-ee11f7b8a34cba8c.js +1 -0
  412. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-ee11f7b8a34cba8c.js +1 -0
  413. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-ee11f7b8a34cba8c.js +1 -0
  414. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-ee11f7b8a34cba8c.js +1 -0
  415. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-ee11f7b8a34cba8c.js +1 -0
  416. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-ee11f7b8a34cba8c.js +1 -0
  417. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-ee11f7b8a34cba8c.js +1 -0
  418. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-ee11f7b8a34cba8c.js +1 -0
  419. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-ee11f7b8a34cba8c.js +1 -0
  420. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-ee11f7b8a34cba8c.js +1 -0
  421. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-ee11f7b8a34cba8c.js +1 -0
  422. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-ee11f7b8a34cba8c.js +1 -0
  423. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-ee11f7b8a34cba8c.js +1 -0
  424. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-ee11f7b8a34cba8c.js +1 -0
  425. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-ee11f7b8a34cba8c.js +1 -0
  426. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-ee11f7b8a34cba8c.js +1 -0
  427. package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-ee11f7b8a34cba8c.js +1 -0
  428. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-ee11f7b8a34cba8c.js +1 -0
  429. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-ee11f7b8a34cba8c.js +1 -0
  430. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-ee11f7b8a34cba8c.js +1 -0
  431. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-ee11f7b8a34cba8c.js +1 -0
  432. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-ee11f7b8a34cba8c.js +1 -0
  433. package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-ee11f7b8a34cba8c.js +1 -0
  434. package/.next/static/chunks/app/api/worktrees/route-ee11f7b8a34cba8c.js +1 -0
  435. package/.next/static/chunks/app/manifest.webmanifest/route-ee11f7b8a34cba8c.js +1 -0
  436. package/.next/static/chunks/app/more/{page-75d3783da0d49a25.js → page-333bba1c8bbc9c11.js} +1 -1
  437. package/.next/static/chunks/app/proxy/[...path]/route-ee11f7b8a34cba8c.js +1 -0
  438. package/.next/static/chunks/app/worktrees/[id]/layout-ee11f7b8a34cba8c.js +1 -0
  439. package/.next/static/chunks/app/worktrees/[id]/page-d48b95ed554bcd13.js +1 -0
  440. package/.next/static/chunks/app/worktrees/[id]/terminal/page-2631bc5c4b0a9fb8.js +1 -0
  441. package/.next/static/css/61e10d4b1b11b193.css +1 -0
  442. package/.next/trace +13 -13
  443. package/.next/types/app/api/settings/default-surface-mode/route.ts +347 -0
  444. package/.next/types/app/api/worktrees/[id]/{start-polling → cli-reference}/route.ts +3 -3
  445. package/.next/types/routes.d.ts +3 -2
  446. package/.next/types/validator.ts +18 -9
  447. package/dist/server/server.js +58 -0
  448. package/dist/server/src/lib/claude-output.js +1 -0
  449. package/dist/server/src/lib/db/app-settings-db.js +60 -0
  450. package/dist/server/src/lib/db/chat-db.js +120 -7
  451. package/dist/server/src/lib/detection/status-detector.js +3 -2
  452. package/dist/server/src/lib/env.js +122 -0
  453. package/dist/server/src/lib/git/worktrees.js +154 -0
  454. package/dist/server/src/lib/history/transcript-tail.js +80 -0
  455. package/dist/server/src/lib/history/user-turn-recorder.js +247 -0
  456. package/dist/server/src/lib/hooks/permission-decision-service.js +85 -1
  457. package/dist/server/src/lib/hooks/sources/antigravity/history.js +519 -0
  458. package/dist/server/src/lib/hooks/sources/antigravity/source.js +7 -0
  459. package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +407 -0
  460. package/dist/server/src/lib/hooks/sources/claude/history.js +654 -0
  461. package/dist/server/src/lib/hooks/sources/claude/source.js +4 -0
  462. package/dist/server/src/lib/hooks/sources/claude/transcript.js +518 -0
  463. package/dist/server/src/lib/hooks/sources/codex/history.js +576 -0
  464. package/dist/server/src/lib/hooks/sources/codex/source.js +4 -0
  465. package/dist/server/src/lib/hooks/sources/codex/transcript.js +448 -0
  466. package/dist/server/src/lib/hooks/sources/copilot/source.js +2 -0
  467. package/dist/server/src/lib/hooks/sources/gemini/source.js +2 -0
  468. package/dist/server/src/lib/hooks/sources/legacy-relay.js +3 -0
  469. package/dist/server/src/lib/hooks/sources/opencode/history.js +57 -0
  470. package/dist/server/src/lib/hooks/sources/opencode/source.js +4 -0
  471. package/dist/server/src/lib/hooks/sources/opencode/transcript.js +10 -28
  472. package/dist/server/src/lib/hooks/sources/turn-body.js +118 -0
  473. package/dist/server/src/lib/polling/prompt-dedup.js +2 -4
  474. package/dist/server/src/lib/polling/response-checker.js +44 -3
  475. package/dist/server/src/lib/polling/response-dedup.js +2 -4
  476. package/dist/server/src/lib/polling/response-poller-core.js +191 -29
  477. package/dist/server/src/lib/polling/structured-history-gate.js +147 -16
  478. package/dist/server/src/lib/push/push-sender.js +21 -1
  479. package/dist/server/src/lib/push/waiting-push-notifier.js +126 -8
  480. package/dist/server/src/lib/realtime/publisher-registry.js +171 -0
  481. package/dist/server/src/lib/realtime/terminal-broadcast.js +14 -1
  482. package/dist/server/src/lib/realtime/types.js +96 -1
  483. package/dist/server/src/lib/session/current-output-builder.js +263 -4
  484. package/dist/server/src/lib/session/send-user-message.js +90 -2
  485. package/dist/server/src/lib/tui-accumulator.js +2 -8
  486. package/dist/server/src/lib/ws-server.js +143 -6
  487. package/dist/server/src/types/agent-transcript.js +241 -5
  488. package/dist/server/src/types/ui-state.js +24 -1
  489. package/package.json +1 -1
  490. package/public/sw.js +15 -1
  491. package/.next/server/app/api/worktrees/[id]/start-polling/route.js +0 -1
  492. package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +0 -1
  493. package/.next/server/chunks/1714.js +0 -7
  494. package/.next/server/chunks/2198.js +0 -1
  495. package/.next/server/chunks/221.js +0 -25
  496. package/.next/server/chunks/2759.js +0 -8
  497. package/.next/server/chunks/3558.js +0 -1
  498. package/.next/server/chunks/9508.js +0 -1
  499. package/.next/static/0YoRrahue4Vchxg1z83IQ/_buildManifest.js +0 -1
  500. package/.next/static/chunks/1379-af7af9e08f47c979.js +0 -1
  501. package/.next/static/chunks/6381-9ba5198c0a6ff197.js +0 -1
  502. package/.next/static/chunks/app/api/agents/update/route-1c30fb8d4d6fa6ef.js +0 -1
  503. package/.next/static/chunks/app/api/agents/versions/route-1c30fb8d4d6fa6ef.js +0 -1
  504. package/.next/static/chunks/app/api/app/update/route-1c30fb8d4d6fa6ef.js +0 -1
  505. package/.next/static/chunks/app/api/app/update-check/route-1c30fb8d4d6fa6ef.js +0 -1
  506. package/.next/static/chunks/app/api/assistant/conversation/route-1c30fb8d4d6fa6ef.js +0 -1
  507. package/.next/static/chunks/app/api/assistant/current-output/route-1c30fb8d4d6fa6ef.js +0 -1
  508. package/.next/static/chunks/app/api/assistant/messages/route-1c30fb8d4d6fa6ef.js +0 -1
  509. package/.next/static/chunks/app/api/assistant/session/route-1c30fb8d4d6fa6ef.js +0 -1
  510. package/.next/static/chunks/app/api/assistant/start/route-1c30fb8d4d6fa6ef.js +0 -1
  511. package/.next/static/chunks/app/api/assistant/terminal/route-1c30fb8d4d6fa6ef.js +0 -1
  512. package/.next/static/chunks/app/api/assistant/tools/route-1c30fb8d4d6fa6ef.js +0 -1
  513. package/.next/static/chunks/app/api/auth/login/route-1c30fb8d4d6fa6ef.js +0 -1
  514. package/.next/static/chunks/app/api/auth/logout/route-1c30fb8d4d6fa6ef.js +0 -1
  515. package/.next/static/chunks/app/api/auth/status/route-1c30fb8d4d6fa6ef.js +0 -1
  516. package/.next/static/chunks/app/api/capabilities/route-1c30fb8d4d6fa6ef.js +0 -1
  517. package/.next/static/chunks/app/api/daily-summary/route-1c30fb8d4d6fa6ef.js +0 -1
  518. package/.next/static/chunks/app/api/daily-summary/status/route-1c30fb8d4d6fa6ef.js +0 -1
  519. package/.next/static/chunks/app/api/external-apps/[id]/health/route-1c30fb8d4d6fa6ef.js +0 -1
  520. package/.next/static/chunks/app/api/external-apps/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  521. package/.next/static/chunks/app/api/external-apps/route-1c30fb8d4d6fa6ef.js +0 -1
  522. package/.next/static/chunks/app/api/fs/browse/route-1c30fb8d4d6fa6ef.js +0 -1
  523. package/.next/static/chunks/app/api/fs/recent-paths/route-1c30fb8d4d6fa6ef.js +0 -1
  524. package/.next/static/chunks/app/api/hooks/agent-event/route-1c30fb8d4d6fa6ef.js +0 -1
  525. package/.next/static/chunks/app/api/hooks/claude-done/route-1c30fb8d4d6fa6ef.js +0 -1
  526. package/.next/static/chunks/app/api/hooks/permission-request/route-1c30fb8d4d6fa6ef.js +0 -1
  527. package/.next/static/chunks/app/api/metrics/vibe/route-1c30fb8d4d6fa6ef.js +0 -1
  528. package/.next/static/chunks/app/api/ollama/models/route-1c30fb8d4d6fa6ef.js +0 -1
  529. package/.next/static/chunks/app/api/push/escalation/route-1c30fb8d4d6fa6ef.js +0 -1
  530. package/.next/static/chunks/app/api/push/subscriptions/route-1c30fb8d4d6fa6ef.js +0 -1
  531. package/.next/static/chunks/app/api/push/vapid/route-1c30fb8d4d6fa6ef.js +0 -1
  532. package/.next/static/chunks/app/api/remote/pair/route-1c30fb8d4d6fa6ef.js +0 -1
  533. package/.next/static/chunks/app/api/repositories/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  534. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-1c30fb8d4d6fa6ef.js +0 -1
  535. package/.next/static/chunks/app/api/repositories/[id]/todos/route-1c30fb8d4d6fa6ef.js +0 -1
  536. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-1c30fb8d4d6fa6ef.js +0 -1
  537. package/.next/static/chunks/app/api/repositories/clone/route-1c30fb8d4d6fa6ef.js +0 -1
  538. package/.next/static/chunks/app/api/repositories/excluded/route-1c30fb8d4d6fa6ef.js +0 -1
  539. package/.next/static/chunks/app/api/repositories/restore/route-1c30fb8d4d6fa6ef.js +0 -1
  540. package/.next/static/chunks/app/api/repositories/route-1c30fb8d4d6fa6ef.js +0 -1
  541. package/.next/static/chunks/app/api/repositories/scan/route-1c30fb8d4d6fa6ef.js +0 -1
  542. package/.next/static/chunks/app/api/repositories/sync/route-1c30fb8d4d6fa6ef.js +0 -1
  543. package/.next/static/chunks/app/api/repositories/validate-path/route-1c30fb8d4d6fa6ef.js +0 -1
  544. package/.next/static/chunks/app/api/settings/default-agents/route-1c30fb8d4d6fa6ef.js +0 -1
  545. package/.next/static/chunks/app/api/sidebar/group-order/route-1c30fb8d4d6fa6ef.js +0 -1
  546. package/.next/static/chunks/app/api/skills/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  547. package/.next/static/chunks/app/api/skills/installations/route-1c30fb8d4d6fa6ef.js +0 -1
  548. package/.next/static/chunks/app/api/skills/operations/route-1c30fb8d4d6fa6ef.js +0 -1
  549. package/.next/static/chunks/app/api/skills/reindex/route-1c30fb8d4d6fa6ef.js +0 -1
  550. package/.next/static/chunks/app/api/skills/route-1c30fb8d4d6fa6ef.js +0 -1
  551. package/.next/static/chunks/app/api/slash-commands/route-1c30fb8d4d6fa6ef.js +0 -1
  552. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-1c30fb8d4d6fa6ef.js +0 -1
  553. package/.next/static/chunks/app/api/tasks/[taskId]/route-1c30fb8d4d6fa6ef.js +0 -1
  554. package/.next/static/chunks/app/api/templates/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  555. package/.next/static/chunks/app/api/templates/route-1c30fb8d4d6fa6ef.js +0 -1
  556. package/.next/static/chunks/app/api/todos/route-1c30fb8d4d6fa6ef.js +0 -1
  557. package/.next/static/chunks/app/api/verification/runs/[runId]/route-1c30fb8d4d6fa6ef.js +0 -1
  558. package/.next/static/chunks/app/api/verification/runs/route-1c30fb8d4d6fa6ef.js +0 -1
  559. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-1c30fb8d4d6fa6ef.js +0 -1
  560. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-1c30fb8d4d6fa6ef.js +0 -1
  561. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-1c30fb8d4d6fa6ef.js +0 -1
  562. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-1c30fb8d4d6fa6ef.js +0 -1
  563. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-1c30fb8d4d6fa6ef.js +0 -1
  564. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-1c30fb8d4d6fa6ef.js +0 -1
  565. package/.next/static/chunks/app/api/worktrees/[id]/env/route-1c30fb8d4d6fa6ef.js +0 -1
  566. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-1c30fb8d4d6fa6ef.js +0 -1
  567. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-1c30fb8d4d6fa6ef.js +0 -1
  568. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
  569. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-1c30fb8d4d6fa6ef.js +0 -1
  570. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-1c30fb8d4d6fa6ef.js +0 -1
  571. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-1c30fb8d4d6fa6ef.js +0 -1
  572. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-1c30fb8d4d6fa6ef.js +0 -1
  573. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-1c30fb8d4d6fa6ef.js +0 -1
  574. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-1c30fb8d4d6fa6ef.js +0 -1
  575. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-1c30fb8d4d6fa6ef.js +0 -1
  576. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-1c30fb8d4d6fa6ef.js +0 -1
  577. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-1c30fb8d4d6fa6ef.js +0 -1
  578. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-1c30fb8d4d6fa6ef.js +0 -1
  579. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-1c30fb8d4d6fa6ef.js +0 -1
  580. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-1c30fb8d4d6fa6ef.js +0 -1
  581. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-1c30fb8d4d6fa6ef.js +0 -1
  582. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-1c30fb8d4d6fa6ef.js +0 -1
  583. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-1c30fb8d4d6fa6ef.js +0 -1
  584. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-1c30fb8d4d6fa6ef.js +0 -1
  585. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-1c30fb8d4d6fa6ef.js +0 -1
  586. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-1c30fb8d4d6fa6ef.js +0 -1
  587. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-1c30fb8d4d6fa6ef.js +0 -1
  588. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-1c30fb8d4d6fa6ef.js +0 -1
  589. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-1c30fb8d4d6fa6ef.js +0 -1
  590. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-1c30fb8d4d6fa6ef.js +0 -1
  591. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-1c30fb8d4d6fa6ef.js +0 -1
  592. package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-1c30fb8d4d6fa6ef.js +0 -1
  593. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-1c30fb8d4d6fa6ef.js +0 -1
  594. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-1c30fb8d4d6fa6ef.js +0 -1
  595. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-1c30fb8d4d6fa6ef.js +0 -1
  596. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-1c30fb8d4d6fa6ef.js +0 -1
  597. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-1c30fb8d4d6fa6ef.js +0 -1
  598. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-1c30fb8d4d6fa6ef.js +0 -1
  599. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-1c30fb8d4d6fa6ef.js +0 -1
  600. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-1c30fb8d4d6fa6ef.js +0 -1
  601. package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-1c30fb8d4d6fa6ef.js +0 -1
  602. package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-1c30fb8d4d6fa6ef.js +0 -1
  603. package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-1c30fb8d4d6fa6ef.js +0 -1
  604. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-1c30fb8d4d6fa6ef.js +0 -1
  605. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-1c30fb8d4d6fa6ef.js +0 -1
  606. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-1c30fb8d4d6fa6ef.js +0 -1
  607. package/.next/static/chunks/app/api/worktrees/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  608. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-1c30fb8d4d6fa6ef.js +0 -1
  609. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-1c30fb8d4d6fa6ef.js +0 -1
  610. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-1c30fb8d4d6fa6ef.js +0 -1
  611. package/.next/static/chunks/app/api/worktrees/[id]/search/route-1c30fb8d4d6fa6ef.js +0 -1
  612. package/.next/static/chunks/app/api/worktrees/[id]/send/route-1c30fb8d4d6fa6ef.js +0 -1
  613. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-1c30fb8d4d6fa6ef.js +0 -1
  614. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-1c30fb8d4d6fa6ef.js +0 -1
  615. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-1c30fb8d4d6fa6ef.js +0 -1
  616. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-1c30fb8d4d6fa6ef.js +0 -1
  617. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-1c30fb8d4d6fa6ef.js +0 -1
  618. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-1c30fb8d4d6fa6ef.js +0 -1
  619. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-1c30fb8d4d6fa6ef.js +0 -1
  620. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-1c30fb8d4d6fa6ef.js +0 -1
  621. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-1c30fb8d4d6fa6ef.js +0 -1
  622. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-1c30fb8d4d6fa6ef.js +0 -1
  623. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-1c30fb8d4d6fa6ef.js +0 -1
  624. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-1c30fb8d4d6fa6ef.js +0 -1
  625. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-1c30fb8d4d6fa6ef.js +0 -1
  626. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-1c30fb8d4d6fa6ef.js +0 -1
  627. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-1c30fb8d4d6fa6ef.js +0 -1
  628. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-1c30fb8d4d6fa6ef.js +0 -1
  629. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-1c30fb8d4d6fa6ef.js +0 -1
  630. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
  631. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-1c30fb8d4d6fa6ef.js +0 -1
  632. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
  633. package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-1c30fb8d4d6fa6ef.js +0 -1
  634. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-1c30fb8d4d6fa6ef.js +0 -1
  635. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-1c30fb8d4d6fa6ef.js +0 -1
  636. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-1c30fb8d4d6fa6ef.js +0 -1
  637. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-1c30fb8d4d6fa6ef.js +0 -1
  638. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-1c30fb8d4d6fa6ef.js +0 -1
  639. package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-1c30fb8d4d6fa6ef.js +0 -1
  640. package/.next/static/chunks/app/api/worktrees/route-1c30fb8d4d6fa6ef.js +0 -1
  641. package/.next/static/chunks/app/manifest.webmanifest/route-1c30fb8d4d6fa6ef.js +0 -1
  642. package/.next/static/chunks/app/proxy/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
  643. package/.next/static/chunks/app/worktrees/[id]/layout-1c30fb8d4d6fa6ef.js +0 -1
  644. package/.next/static/chunks/app/worktrees/[id]/page-ce6279d581d1df95.js +0 -1
  645. package/.next/static/chunks/app/worktrees/[id]/terminal/page-00ad5d9a62a71cab.js +0 -1
  646. package/.next/static/css/b326c8a734e1928e.css +0 -1
  647. /package/.next/static/{0YoRrahue4Vchxg1z83IQ → 7K0XXFu_ty4wRSkl4X21E}/_ssgManifest.js +0 -0
@@ -1,32 +1,62 @@
1
1
  "use strict";
2
2
  /**
3
- * Whether somebody better-informed is already recording this turn (Issue #2041).
3
+ * Whether somebody better-informed is already recording this turn (Issue #2041,
4
+ * extended for Claude Code in #2121, codex in #2197 and antigravity in #2198).
4
5
  *
5
6
  * The poller's job has always been to be the only writer of conversation
6
- * history, because for five of the six tools the terminal is the only place the
7
- * reply exists. opencode is the exception: since #1763 CommandMate holds an SSE
8
- * connection to the agent's own server, and since this Issue that connection
9
- * carries the reply's Markdown source. Two writers for one turn would put the
10
- * same answer in History twice once as the agent wrote it and once as its TUI
11
- * drew it — so one of them has to stand down, and it is the one reading the
12
- * screen.
7
+ * history, because for most of the six tools the terminal is the only place the
8
+ * reply exists. Four of them now have a second writer: opencode publishes its
9
+ * replies over the SSE stream CommandMate subscribes to (#1763/#2041), and
10
+ * claude, codex and antigravity each keep their own transcript file on disk.
11
+ * Two writers for one turn would put the same answer in History twice — once as
12
+ * the agent wrote it and once as its TUI drew it — so one of them has to stand
13
+ * down, and it is the one reading the screen.
13
14
  *
14
15
  * ## Why this is a module and not an `if`
15
16
  *
16
17
  * Two reasons, and the second is the one that matters. The obvious one is that
17
18
  * `response-checker` is 1,000 lines with a single tool-agnostic spine, and a
18
19
  * `cliToolId === 'opencode' && …` in the middle of the save path is exactly the
19
- * kind of branch that gets copied to the next tool that grows a server. The
20
- * real one is the import: `@/lib/hooks/sources/opencode/subscription` reaches
21
- * the whole opencode client through its module graph, and the poller's tests
22
- * replace that graph wholesale. One named seam is one thing to stub.
20
+ * kind of branch that gets copied to the next tool that grows a reader. The real
21
+ * one is the import: `@/lib/hooks/sources/opencode/subscription` reaches the
22
+ * whole opencode client through its module graph, and the poller's tests replace
23
+ * that graph wholesale. One named seam is one thing to stub.
24
+ *
25
+ * ## The tool names are gone (Issue #2197)
26
+ *
27
+ * Until this Issue the two functions below opened with `if (cliToolId !==
28
+ * 'opencode')` and `if (cliToolId !== CLAUDE_CLI_TOOL_ID)`, which is the branch
29
+ * the module comment above says it exists to prevent — the third tool arrived
30
+ * and the third `!==` was about to be written. What replaces them is a value the
31
+ * source declares about itself:
32
+ * `AgentSourceCapabilities.transcriptHistory` (`'pull' | 'push' | null`, see
33
+ * `lib/hooks/agent-event-types`). A tool with no second writer says `null` and
34
+ * both questions below answer false for it without naming it — which is what let
35
+ * #2198 add antigravity by editing its own `source.ts` and this file's reader
36
+ * table and nothing else, and what leaves gemini and copilot on the scraper
37
+ * without a line of code mentioning them.
38
+ *
39
+ * The word has three values rather than two because the two shapes are asked
40
+ * *different questions*:
41
+ *
42
+ * - **push** — a subscription is already receiving the reply, so the only thing
43
+ * to ask is whether that connection is live
44
+ * ({@link isStructuredHistoryWriterLive}).
45
+ * - **pull** — there is no connection, only a file, and nothing reads it until
46
+ * something asks. So the question is not "is anyone recording?" but "record
47
+ * it now, and tell me whether you did"
48
+ * ({@link captureStructuredHistoryTurn}). The call has to be here rather than
49
+ * in the hook receiver for a reason beyond tidiness: a hook post is answered
50
+ * and forgotten, so the only moment CommandMate knows a turn is *finished and
51
+ * about to be written* is this one, and doing the handover at the point of
52
+ * the write is what makes it impossible for both writers to run.
23
53
  *
24
54
  * ## What is NOT gated
25
55
  *
26
56
  * Only the two calls that *record the reply* — the `chat_messages` row and the
27
57
  * Markdown conversation log. Prompt rows, Auto-Yes, the waiting-episode edges,
28
58
  * push notifications, task events and the session-state cursor all stay on the
29
- * scraper, because none of them are things the event stream duplicates: a
59
+ * scraper, because none of them are things the second writer duplicates: a
30
60
  * `permission.asked` becomes a pending decision, never a history row, and the
31
61
  * push fan-out has no second producer at all. Gating them would trade a
32
62
  * duplicated reply for a silent notification, which is the worse failure.
@@ -35,14 +65,61 @@
35
65
  */
36
66
  Object.defineProperty(exports, "__esModule", { value: true });
37
67
  exports.isStructuredHistoryWriterLive = isStructuredHistoryWriterLive;
68
+ exports.captureStructuredHistoryTurn = captureStructuredHistoryTurn;
38
69
  const logger_1 = require("../../lib/logger");
39
70
  const subscription_1 = require("../../lib/hooks/sources/opencode/subscription");
71
+ const history_1 = require("../../lib/hooks/sources/claude/history");
72
+ const history_2 = require("../../lib/hooks/sources/codex/history");
73
+ const history_3 = require("../../lib/hooks/sources/antigravity/history");
74
+ const tool_id_1 = require("../../lib/hooks/sources/claude/tool-id");
75
+ const tool_id_2 = require("../../lib/hooks/sources/codex/tool-id");
76
+ const tool_id_3 = require("../../lib/hooks/sources/antigravity/tool-id");
77
+ const registry_1 = require("../../lib/hooks/sources/registry");
40
78
  const logger = (0, logger_1.createLogger)('lib/polling/structured-history-gate');
79
+ /**
80
+ * Which reader answers for which tool.
81
+ *
82
+ * The one place a tool id still appears, and it is a dispatch table rather than
83
+ * a decision: *whether* to ask is
84
+ * `AgentSourceCapabilities.transcriptHistory === 'pull'`, and this only says who
85
+ * to ask. It cannot be folded into the capability itself because #1921 D3
86
+ * requires every declared capability to be JSON-serialisable — the block is
87
+ * copied onto the wire in `structuredEvents.source`, so a capability that were a
88
+ * function would vanish silently on the way out.
89
+ *
90
+ * A tool that declares `'pull'` and is missing here is a bug, and a loud one:
91
+ * {@link captureStructuredHistoryTurn} logs it and falls back to the scraper.
92
+ */
93
+ const PULL_TRANSCRIPT_READERS = {
94
+ [tool_id_1.CLAUDE_CLI_TOOL_ID]: (target, capture) => (0, history_1.captureClaudeTranscriptTurn)(target, capture),
95
+ [tool_id_2.CODEX_CLI_TOOL_ID]: (target, capture) => (0, history_2.captureCodexTranscriptTurn)(target, capture),
96
+ [tool_id_3.ANTIGRAVITY_CLI_TOOL_ID]: (target, capture) => (0, history_3.captureAntigravityTranscriptTurn)(target, capture),
97
+ };
98
+ /**
99
+ * What this tool's source says about who records its replies.
100
+ *
101
+ * Never throws: a registry that cannot be reached is one that declares nothing,
102
+ * and nothing means the scraper keeps writing — the safe direction, as
103
+ * everywhere else in this module.
104
+ */
105
+ function transcriptHistoryModeOf(cliToolId) {
106
+ try {
107
+ return (0, registry_1.getAgentEventSource)(cliToolId).capabilities.transcriptHistory ?? null;
108
+ }
109
+ catch (error) {
110
+ logger.warn('structured-history-capability-unavailable', {
111
+ cliToolId,
112
+ error: error instanceof Error ? error.message : String(error),
113
+ });
114
+ return null;
115
+ }
116
+ }
41
117
  /**
42
118
  * Whether the agent's own server is recording this instance's replies.
43
119
  *
44
- * False for every tool but opencode, and false for an opencode instance whose
45
- * subscription is anything other than `live`see
120
+ * False for every tool whose source does not declare `transcriptHistory: 'push'`
121
+ * today that is all of them but opencode and false for an opencode instance
122
+ * whose subscription is anything other than `live`; see
46
123
  * {@link isOpencodeStructuredHistoryLive} for why `lost` counts as "nobody is
47
124
  * writing this down" rather than as "somebody will". The fallback direction is
48
125
  * the safe one: two writers duplicate a reply, no writer loses it.
@@ -54,9 +131,12 @@ const logger = (0, logger_1.createLogger)('lib/polling/structured-history-gate')
54
131
  * @param instanceId - The agent instance; defaults to the primary
55
132
  */
56
133
  function isStructuredHistoryWriterLive(worktreeId, cliToolId, instanceId) {
57
- if (cliToolId !== 'opencode')
134
+ if (transcriptHistoryModeOf(cliToolId) !== 'push')
58
135
  return false;
59
136
  try {
137
+ // One probe, because there is one push source. A second one adds a table
138
+ // here of the shape `PULL_TRANSCRIPT_READERS` already has; it does not add
139
+ // another `cliToolId ===`.
60
140
  return (0, subscription_1.isOpencodeStructuredHistoryLive)({
61
141
  worktreeId,
62
142
  cliToolId,
@@ -73,3 +153,54 @@ function isStructuredHistoryWriterLive(worktreeId, cliToolId, instanceId) {
73
153
  return false;
74
154
  }
75
155
  }
156
+ /**
157
+ * Ask the pull-mode structured writer to record this turn now (#2121, #2197).
158
+ *
159
+ * The file-backed half of the stand-down. Returns true when `chat_messages`
160
+ * holds this turn as the agent's own Markdown — because this call wrote it, or
161
+ * because an earlier poll of the same finished turn already did — and the caller
162
+ * must therefore drop the scraped copy.
163
+ *
164
+ * False for every tool that does not declare `transcriptHistory: 'pull'`, and
165
+ * false for one that does whenever anything at all prevented the write: no
166
+ * session pointer (a pane started without hooks, or with hooks codex has not
167
+ * been told to trust), no transcript file, an unreadable one, a window with no
168
+ * prompt in it, or a turn the agent has not finished writing. That is the
169
+ * fail-open every one of these Issues' acceptance criteria asks for in as many
170
+ * words — 転写ファイルが無い / 読めない場合は従来のスクレイプ経路にフォール
171
+ * バックする. Two writers duplicate a reply; no writer loses one.
172
+ *
173
+ * Never throws, for the same reason {@link isStructuredHistoryWriterLive} does
174
+ * not: this runs inside the poller's save path, and an exception here would cost
175
+ * the scraped reply as well as the structured one.
176
+ *
177
+ * @param worktreeId - The worktree
178
+ * @param cliToolId - The tool driving the pane
179
+ * @param instanceId - The agent instance; defaults to the primary
180
+ * @param capture - Where to look; see {@link StructuredHistoryCapture}
181
+ */
182
+ async function captureStructuredHistoryTurn(worktreeId, cliToolId, instanceId, capture) {
183
+ if (transcriptHistoryModeOf(cliToolId) !== 'pull')
184
+ return false;
185
+ const reader = PULL_TRANSCRIPT_READERS[cliToolId];
186
+ if (!reader) {
187
+ logger.warn('structured-history-reader-missing', {
188
+ worktreeId,
189
+ cliToolId,
190
+ instanceId: instanceId ?? cliToolId,
191
+ });
192
+ return false;
193
+ }
194
+ try {
195
+ return await reader({ worktreeId, cliToolId, instanceId: instanceId ?? cliToolId }, capture);
196
+ }
197
+ catch (error) {
198
+ logger.warn('structured-history-capture-unavailable', {
199
+ worktreeId,
200
+ cliToolId,
201
+ instanceId: instanceId ?? cliToolId,
202
+ error: error instanceof Error ? error.message : String(error),
203
+ });
204
+ return false;
205
+ }
206
+ }
@@ -317,9 +317,29 @@ async function notifyPushSubscribers(event, now = Date.now()) {
317
317
  // from one that was never attempted — `push-send-failed` is per device and
318
318
  // sits below the default log level's attention, and success said nothing at
319
319
  // all. One line per fan-out names both halves, and no endpoint.
320
+ //
321
+ // Issue #2133: it also names *whose* fan-out it was. Without the subject,
322
+ // two worktrees notifying in the same second print two identical lines, so
323
+ // the UAT steps that pass by counting zero notifications
324
+ // (`docs/qa/2001-cross-device-dismissal-uat.md` T-4 / T-6 / T-7) read a
325
+ // neighbour's push as their own — which is what the Epic #2002 run hit on
326
+ // 2026-08-29, and only the co-timed `resolution-push-sent` (which does carry
327
+ // `worktreeId`) rescued the reading. A waiting push has no such partner.
328
+ //
329
+ // The key names match `resolution-push-notifier`'s context on purpose, so
330
+ // both halves of one episode grep together. `instanceId` resolves exactly as
331
+ // the episode dedup key above does, and is left absent — `JSON.stringify`
332
+ // drops `undefined` — rather than logged as an empty string when no producer
333
+ // named an instance.
320
334
  const delivered = outcomes.filter(Boolean).length;
321
335
  const failed = outcomes.length - delivered;
322
- logger.info('push-fanout-complete', { kind: event.kind, delivered, failed });
336
+ logger.info('push-fanout-complete', {
337
+ kind: event.kind,
338
+ worktreeId: event.worktreeId,
339
+ instanceId: event.instanceId ?? event.agentName,
340
+ delivered,
341
+ failed,
342
+ });
323
343
  }
324
344
  catch (err) {
325
345
  logger.warn('push-fanout-error', {
@@ -39,19 +39,31 @@
39
39
  * closes — so an install with nothing waiting has no timer, and one that never
40
40
  * configured VAPID never even gets that far.
41
41
  *
42
+ * ## Holding a wait that has not named itself
43
+ *
44
+ * The edge fires once, and for a dialog drawn between two probes it fires
45
+ * before anything on the pane can be classified — so #2156's `AskUserQuestion`
46
+ * arrived here as `unclassified` and was announced as "check the terminal"
47
+ * although the app could answer it. The kind is refreshed in place afterwards
48
+ * and that refresh is deliberately not an edge, so the fix is on this side:
49
+ * an unnamed wait is held for {@link CLASSIFICATION_GRACE_MS} and then sent
50
+ * under whatever the episode is called at that point. One notification either
51
+ * way — no correction push, and nothing at all if the wait ended meanwhile.
52
+ *
42
53
  * Everything here is advisory: a failure must not disturb the status read that
43
54
  * observed the edge (`emit` contains listener throws) nor the poller.
44
55
  *
45
56
  * @module lib/push/waiting-push-notifier
46
57
  */
47
58
  Object.defineProperty(exports, "__esModule", { value: true });
48
- exports.ESCALATION_TICK_MS = void 0;
59
+ exports.CLASSIFICATION_GRACE_MS = exports.ESCALATION_TICK_MS = void 0;
49
60
  exports.handleWaitingTransition = handleWaitingTransition;
50
61
  exports.runEscalationTick = runEscalationTick;
51
62
  exports.startWaitingPushNotifier = startWaitingPushNotifier;
52
63
  exports.stopWaitingPushNotifier = stopWaitingPushNotifier;
53
64
  exports.isWaitingPushNotifierActive = isWaitingPushNotifierActive;
54
65
  exports.pendingEscalationCount = pendingEscalationCount;
66
+ exports.heldWaitCount = heldWaitCount;
55
67
  const auto_yes_state_1 = require("../../lib/auto-yes-state");
56
68
  const db_instance_1 = require("../../lib/db/db-instance");
57
69
  const worktree_db_1 = require("../../lib/db/worktree-db");
@@ -65,8 +77,33 @@ const vapid_1 = require("./vapid");
65
77
  const logger = (0, logger_1.createLogger)('push/waiting-notifier');
66
78
  /** How often outstanding waits are re-checked. Minute granularity is enough. */
67
79
  exports.ESCALATION_TICK_MS = 60_000;
80
+ /**
81
+ * How long a wait that has not named itself yet is held before it notifies
82
+ * (Issue #2156).
83
+ *
84
+ * `AskUserQuestion` opens the episode before the pane carries anything the
85
+ * screen scraper can read, so the *first* classification of that wait is
86
+ * `unclassified` and the body would say "check the terminal" about a dialog the
87
+ * app can answer. `waiting-episode-state` refreshes the kind in place on the
88
+ * next probe and deliberately emits nothing for it (a wait that changes
89
+ * character is still one wait), so the notifier only ever saw the provisional
90
+ * verdict.
91
+ *
92
+ * Measured on the session in the Issue: the edge opened at 00:08:38.837 with no
93
+ * usable classification and the next status probe refined it to `prompt` at
94
+ * 00:08:44.863 — 6.03 s later; 8 s is that measurement plus one probe's jitter
95
+ * and nothing more, because the hold is silence on the phone and it is meant to
96
+ * buy exactly one reclassification.
97
+ *
98
+ * Only an unnamed wait pays it: `prompt` and `menu` are positive verdicts and
99
+ * still notify on the edge itself.
100
+ */
101
+ exports.CLASSIFICATION_GRACE_MS = 8_000;
68
102
  const pending = globalThis.__waitingPushPending ??
69
103
  (globalThis.__waitingPushPending = new Map());
104
+ /** Composite key -> the timer holding that wait's first notification (#2156). */
105
+ const graceTimers = globalThis.__waitingPushGraceTimers ??
106
+ (globalThis.__waitingPushGraceTimers = new Map());
70
107
  /**
71
108
  * The worktree's display name, for the notification title.
72
109
  *
@@ -109,6 +146,73 @@ async function sendWaitingPush(wait, escalated, now) {
109
146
  });
110
147
  }
111
148
  }
149
+ /**
150
+ * Whether this classification is still provisional (Issue #2156).
151
+ *
152
+ * `unclassified` is what `deriveWaitingKind` returns for a frame the scraper
153
+ * could not read at all, and a null kind is the same admission from a producer
154
+ * that passed none — both mean "waiting, but nobody has said what for" and both
155
+ * are the verdict that arrives first when a dialog is drawn between two probes.
156
+ * `prompt` and `menu` are positive readings of the pane and are taken at once.
157
+ */
158
+ function isUnnamedWait(kind) {
159
+ return kind === null || kind === undefined || kind === 'unclassified';
160
+ }
161
+ /** Drop the hold on this wait without sending anything. */
162
+ function cancelGrace(key) {
163
+ const timer = graceTimers.get(key);
164
+ if (timer === undefined)
165
+ return;
166
+ clearTimeout(timer);
167
+ graceTimers.delete(key);
168
+ }
169
+ /**
170
+ * The Auto-Yes gate, then the fan-out.
171
+ *
172
+ * In that order because `shouldSendWaitingPush` records the episode at the
173
+ * moment it decides to send, so a notification dropped after the fan-out began
174
+ * would still consume the episode's one slot — see `prompt-push-gate`.
175
+ */
176
+ function gateAndSend(wait, now) {
177
+ if ((0, prompt_push_gate_1.isPromptPushSuppressed)({
178
+ worktreeId: wait.worktreeId,
179
+ cliToolId: wait.cliToolId,
180
+ instanceId: wait.instanceId,
181
+ waitingSince: wait.since,
182
+ })) {
183
+ return;
184
+ }
185
+ void sendWaitingPush(wait, false, now);
186
+ }
187
+ /**
188
+ * The grace elapsed: send the held wait with whatever it is called *now*
189
+ * (Issue #2156).
190
+ *
191
+ * The episode store is the authority here for the same reason it is in
192
+ * {@link runEscalationTick}: it carries the classification every later probe
193
+ * refined, and its absence is the wait having ended. Nothing is sent in that
194
+ * case — a wait answered inside the grace never needed a notification, and
195
+ * dropping it is the direction #1999/#2000 asked for rather than a correction
196
+ * push chasing one that was already wrong.
197
+ */
198
+ function releaseHeldWait(key) {
199
+ graceTimers.delete(key);
200
+ const held = pending.get(key);
201
+ // Gone means the closing edge dropped it, or a reminder already claimed it.
202
+ if (held === undefined)
203
+ return;
204
+ const episode = (0, waiting_episode_state_1.getWaitingEpisode)(held.worktreeId, held.cliToolId, held.instanceId);
205
+ if (episode === null || episode.since !== held.since) {
206
+ pending.delete(key);
207
+ stopEscalationTimerIfIdle();
208
+ return;
209
+ }
210
+ // Written back so the reminder quotes the settled kind even if the episode is
211
+ // gone by the time it runs.
212
+ const settled = { ...held, kind: episode.kind };
213
+ pending.set(key, settled);
214
+ gateAndSend(settled, Date.now());
215
+ }
112
216
  function startEscalationTimer() {
113
217
  if (globalThis.__waitingPushEscalationTimer !== undefined)
114
218
  return;
@@ -143,6 +247,8 @@ function handleWaitingTransition(transition) {
143
247
  return;
144
248
  const key = (0, auto_yes_state_1.buildCompositeKey)(transition.worktreeId, transition.cliToolId, transition.instanceId);
145
249
  if (!transition.waiting || transition.since === null) {
250
+ // Issue #2156: a wait still inside its grace is answered, not notified.
251
+ cancelGrace(key);
146
252
  pending.delete(key);
147
253
  stopEscalationTimerIfIdle();
148
254
  // Issue #2001: this is the moment the notification on every *other* device
@@ -180,15 +286,20 @@ function handleWaitingTransition(transition) {
180
286
  // episode at the moment it decides to send.
181
287
  pending.set(key, wait);
182
288
  startEscalationTimer();
183
- if ((0, prompt_push_gate_1.isPromptPushSuppressed)({
184
- worktreeId: wait.worktreeId,
185
- cliToolId: wait.cliToolId,
186
- instanceId: wait.instanceId,
187
- waitingSince: wait.since,
188
- })) {
289
+ // Issue #2156: a wait nobody has named yet is held for one probe interval so
290
+ // it can notify under the kind it turns out to be, rather than under the
291
+ // placeholder it opened with. A named wait notifies on the edge, as before.
292
+ if (isUnnamedWait(wait.kind)) {
293
+ cancelGrace(key);
294
+ const timer = setTimeout(() => {
295
+ releaseHeldWait(key);
296
+ }, exports.CLASSIFICATION_GRACE_MS);
297
+ // Same reasoning as the escalation interval: never hold the process open.
298
+ timer.unref?.();
299
+ graceTimers.set(key, timer);
189
300
  return;
190
301
  }
191
- void sendWaitingPush(wait, false, transition.at);
302
+ gateAndSend(wait, transition.at);
192
303
  }
193
304
  /**
194
305
  * Re-notify every wait that has outlived the threshold, once each.
@@ -267,6 +378,9 @@ function stopWaitingPushNotifier() {
267
378
  existing();
268
379
  globalThis.__waitingPushUnsubscribe = undefined;
269
380
  }
381
+ for (const timer of graceTimers.values())
382
+ clearTimeout(timer);
383
+ graceTimers.clear();
270
384
  pending.clear();
271
385
  stopEscalationTimerIfIdle();
272
386
  }
@@ -278,3 +392,7 @@ function isWaitingPushNotifierActive() {
278
392
  function pendingEscalationCount() {
279
393
  return pending.size;
280
394
  }
395
+ /** How many waits are held waiting to be classified (#2156). Test seam. */
396
+ function heldWaitCount() {
397
+ return graceTimers.size;
398
+ }
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ /**
3
+ * Process-local registry naming the one module instance that owns live
4
+ * WebSocket rooms (Issue #2220).
5
+ *
6
+ * ## The failure this exists to close
7
+ *
8
+ * `ws-server` keeps `wss`, `clients` and `rooms` in its module scope, and only
9
+ * the instance the custom server called `setupWebSocket()` on ever holds a
10
+ * socket. That was believed to be a `next dev` nicety; it is not. A production
11
+ * build has two graphs, and the build artifacts say so:
12
+ *
13
+ * ```
14
+ * dist/server/server.js -> require("./src/lib/ws-server") // owner
15
+ * .next/server/app/api/**\/route.js -> .next/server/chunks/<n>.js // a second copy
16
+ * ```
17
+ *
18
+ * `setupWebSocket` appears in the `.next` chunk only as an exported binding —
19
+ * grep it and the sole hit is the export map, never a call. So the route
20
+ * bundle's `rooms` is empty for the life of the process, and every
21
+ * `broadcast()` reached from a route handler returned in silence.
22
+ *
23
+ * ## What is shared and what is not
24
+ *
25
+ * Only the *capability* crosses the boundary: four functions the owner hands
26
+ * over. `wss`, the socket set, `clients` and `rooms` stay inside the owner's
27
+ * module scope, so a route bundle can ask for a frame to be published but can
28
+ * neither enumerate nor mutate the connection state. Putting the maps
29
+ * themselves on `globalThis` would work — same process, same `globalThis` — but
30
+ * it exposes the central state to every bundle and leaves ownership undefined
31
+ * once two instances have both initialised.
32
+ *
33
+ * This is the shape #1788 already uses for the waiting edge
34
+ * (`waiting-episode-state`'s `globalThis` listener set, written by
35
+ * `ws-server`'s `setupWebSocket`), and it is measurably cross-bundle in the same
36
+ * build: `__sessionWaitingTransitionListeners` appears in both `dist/server` and
37
+ * the `.next` chunks.
38
+ *
39
+ * ## Ownership
40
+ *
41
+ * Registration is a generation counter that only ever moves forward, and
42
+ * withdrawal is authorised by the token handed out at registration. A stale
43
+ * instance calling `closeWebSocket()` after a newer one has taken over
44
+ * therefore cannot silence the live server — the classic HMR / re-entered
45
+ * `setupWebSocket` hazard.
46
+ *
47
+ * ## Import discipline
48
+ *
49
+ * This module must stay a leaf: it imports the logger and nothing else. Both
50
+ * `ws-server` and every producer reach it, so an edge back into either would
51
+ * rebuild the module-scope cycle `tests/unit/guards/no-ws-server-manager-cycle-1984.test.ts`
52
+ * exists to forbid.
53
+ *
54
+ * @module lib/realtime/publisher-registry
55
+ */
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.UNROUTED_PUBLISH_WARN_INTERVAL_MS = void 0;
58
+ exports.registerRoomPublisher = registerRoomPublisher;
59
+ exports.unregisterRoomPublisher = unregisterRoomPublisher;
60
+ exports.getRoomPublisher = getRoomPublisher;
61
+ exports.getRoomPublisherGeneration = getRoomPublisherGeneration;
62
+ exports.recordUnroutedPublish = recordUnroutedPublish;
63
+ exports.getUnroutedPublishStats = getUnroutedPublishStats;
64
+ exports.__resetRoomPublisherRegistryForTest = __resetRoomPublisherRegistryForTest;
65
+ const logger_1 = require("../../lib/logger");
66
+ const logger = (0, logger_1.createLogger)('publisher-registry');
67
+ /** At most one warning per minute; the rest are counted, not printed. */
68
+ exports.UNROUTED_PUBLISH_WARN_INTERVAL_MS = 60_000;
69
+ function unroutedState() {
70
+ return (globalThis.__realtimeUnroutedPublish ??= {
71
+ total: 0,
72
+ suppressed: 0,
73
+ lastWarnedAt: null,
74
+ operations: {},
75
+ });
76
+ }
77
+ /**
78
+ * Claim ownership of the process's rooms.
79
+ *
80
+ * Called from `setupWebSocket()` and nowhere else. A second call supersedes the
81
+ * first rather than being rejected: re-entering `setupWebSocket` builds a new
82
+ * `WebSocketServer`, and the newest one is the one holding sockets.
83
+ *
84
+ * @param publisher - The owner's implementation, closed over its own maps.
85
+ * @returns A handle whose `unregister()` is honoured only while it is current.
86
+ */
87
+ function registerRoomPublisher(publisher) {
88
+ const token = (globalThis.__realtimeRoomPublisherGeneration ?? 0) + 1;
89
+ globalThis.__realtimeRoomPublisherGeneration = token;
90
+ globalThis.__realtimeRoomPublisher = { generation: token, publisher };
91
+ // A live owner means the frames counted below are no longer being dropped;
92
+ // carrying the old totals forward would keep warning about a fixed process.
93
+ globalThis.__realtimeUnroutedPublish = undefined;
94
+ return {
95
+ token,
96
+ unregister: () => unregisterRoomPublisher(token),
97
+ };
98
+ }
99
+ /**
100
+ * Withdraw the registration identified by `token`.
101
+ *
102
+ * A token that is not the current generation is ignored. That is the whole
103
+ * point: under HMR — or in a suite that stands two servers up — the instance
104
+ * being torn down is frequently *not* the one that owns the live sockets, and
105
+ * its `closeWebSocket()` must not take the running server's publisher with it.
106
+ *
107
+ * @returns Whether this call actually cleared the registration.
108
+ */
109
+ function unregisterRoomPublisher(token) {
110
+ const current = globalThis.__realtimeRoomPublisher;
111
+ if (!current || current.generation !== token)
112
+ return false;
113
+ globalThis.__realtimeRoomPublisher = undefined;
114
+ return true;
115
+ }
116
+ /** The owner's publisher, or null when no instance has claimed the rooms. */
117
+ function getRoomPublisher() {
118
+ return globalThis.__realtimeRoomPublisher?.publisher ?? null;
119
+ }
120
+ /** Generation of the current registration; 0 when there is none. */
121
+ function getRoomPublisherGeneration() {
122
+ return globalThis.__realtimeRoomPublisher?.generation ?? 0;
123
+ }
124
+ /**
125
+ * Note that a publish found no owner, warning at most once a minute.
126
+ *
127
+ * Without this the failure has no symptom at all. The room lookup returns
128
+ * `undefined`, the function returns, and the browser still shows the socket as
129
+ * `connected` — because it is: the socket is healthy and only the server-side
130
+ * publisher is missing. That is the state #2220 sat in unnoticed. The counters
131
+ * are readable through {@link getUnroutedPublishStats} so a test can assert the
132
+ * signal exists rather than trusting a log line.
133
+ *
134
+ * @param operation - The surface that lost the frame, e.g. `'broadcast'`.
135
+ * @param worktreeId - Room the frame was addressed to.
136
+ */
137
+ function recordUnroutedPublish(operation, worktreeId, now = Date.now()) {
138
+ const state = unroutedState();
139
+ state.total += 1;
140
+ state.operations[operation] = (state.operations[operation] ?? 0) + 1;
141
+ if (state.lastWarnedAt !== null && now - state.lastWarnedAt < exports.UNROUTED_PUBLISH_WARN_INTERVAL_MS) {
142
+ state.suppressed += 1;
143
+ return;
144
+ }
145
+ const suppressed = state.suppressed;
146
+ state.suppressed = 0;
147
+ state.lastWarnedAt = now;
148
+ logger.warn('realtime:no-room-publisher', {
149
+ operation,
150
+ worktreeId,
151
+ total: state.total,
152
+ suppressedSinceLastWarning: suppressed,
153
+ operations: { ...state.operations },
154
+ });
155
+ }
156
+ /** Read-only view of the unrouted-publish counters. */
157
+ function getUnroutedPublishStats() {
158
+ const state = unroutedState();
159
+ return { ...state, operations: { ...state.operations } };
160
+ }
161
+ /**
162
+ * Drop the registration and the counters.
163
+ *
164
+ * Test seam. The generation counter is deliberately NOT reset — a suite that
165
+ * reset it could hand two different registrations the same token and stop
166
+ * exercising the ownership rule this module is built around.
167
+ */
168
+ function __resetRoomPublisherRegistryForTest() {
169
+ globalThis.__realtimeRoomPublisher = undefined;
170
+ globalThis.__realtimeUnroutedPublish = undefined;
171
+ }
@@ -23,7 +23,8 @@ const logger_1 = require("../../lib/logger");
23
23
  const manager_1 = require("../../lib/cli-tools/manager");
24
24
  const tmux_capture_cache_1 = require("../../lib/tmux/tmux-capture-cache");
25
25
  const logger = (0, logger_1.createLogger)('terminal-broadcast');
26
- const versionCounters = new Map();
26
+ const versionCounters = globalThis.__terminalSnapshotVersions ??
27
+ (globalThis.__terminalSnapshotVersions = new Map());
27
28
  exports.INTERACTION_SNAPSHOT_RETRY_DELAYS_MS = [100, 250, 500, 750];
28
29
  function nextVersion(key) {
29
30
  const version = (versionCounters.get(key) ?? 0) + 1;
@@ -54,6 +55,12 @@ function snapshotFingerprint(payload) {
54
55
  return JSON.stringify([
55
56
  payload.fullOutput ?? '',
56
57
  payload.isRunning,
58
+ // Issue #2240: part of the frame since the snapshot started carrying it, so
59
+ // a redraw whose only change is the verdict (`waiting` -> `running` on an
60
+ // answered dialog, say) is still published. Leaving it out would put the
61
+ // field back in the position this issue took it out of — present on the
62
+ // wire, but not deliverable by the path that actually feeds a live turn.
63
+ payload.sessionStatus,
57
64
  payload.thinking ?? false,
58
65
  payload.isPromptWaiting ?? false,
59
66
  payload.isSelectionListActive ?? false,
@@ -76,6 +83,12 @@ function emitTerminalSnapshot(worktreeId, cliToolId, payload, instanceId) {
76
83
  instanceId: resolvedInstanceId,
77
84
  output: payload.fullOutput ?? '',
78
85
  isRunning: payload.isRunning,
86
+ // Issue #2240: straight through, so push and poll answer the same question
87
+ // with the same value. `/current-output` returns this very payload, so the
88
+ // two paths differ only in transport. Not `?? something` — the builder
89
+ // types it as a required `string` and publishes `'idle'` for a session that
90
+ // is not running, so there is no absent case to invent a default for.
91
+ sessionStatus: payload.sessionStatus,
79
92
  thinking: payload.thinking ?? false,
80
93
  isPromptWaiting: payload.isPromptWaiting ?? false,
81
94
  promptData: payload.promptData ?? null,