commandmate 0.45.1 → 0.46.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +319 -315
  3. package/.next/app-path-routes-manifest.json +15 -15
  4. package/.next/build-manifest.json +5 -5
  5. package/.next/prerender-manifest.json +3 -3
  6. package/.next/react-loadable-manifest.json +4 -4
  7. package/.next/required-server-files.json +1 -1
  8. package/.next/server/app/_not-found/page.js +1 -1
  9. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  10. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  18. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/capabilities/route.js +1 -1
  20. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  29. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/hooks/claude-done/route.js +9 -9
  31. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  32. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  34. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
  41. package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/relays/route.js.nft.json +1 -1
  43. package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  47. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  48. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/repositories/clone/route.js +1 -1
  50. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  51. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/repositories/restore/route.js +1 -1
  54. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  55. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/repositories/route.js +1 -1
  57. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  58. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/repositories/scan/route.js +1 -1
  60. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  61. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/repositories/sync/route.js +1 -1
  63. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  64. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  67. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  72. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  76. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  82. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  83. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  84. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  86. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  88. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  89. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +3 -3
  93. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  95. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  96. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
  98. package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
  99. package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +3 -3
  103. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  113. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  130. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  132. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  135. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/logs/route.js +9 -9
  138. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  148. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  152. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  155. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +3 -3
  157. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +3 -3
  159. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/schedules/route.js +3 -3
  161. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  165. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  167. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  178. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  179. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  181. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  182. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  185. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  191. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  198. package/.next/server/app/api/worktrees/route.js +1 -1
  199. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  200. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/login/page.js +1 -1
  202. package/.next/server/app/login/page.js.nft.json +1 -1
  203. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  204. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  205. package/.next/server/app/more/page.js +1 -1
  206. package/.next/server/app/more/page.js.nft.json +1 -1
  207. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  208. package/.next/server/app/offline/page.js +1 -1
  209. package/.next/server/app/offline/page.js.nft.json +1 -1
  210. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  211. package/.next/server/app/page.js +1 -1
  212. package/.next/server/app/page.js.nft.json +1 -1
  213. package/.next/server/app/page_client-reference-manifest.js +1 -1
  214. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  215. package/.next/server/app/repositories/page.js +2 -2
  216. package/.next/server/app/repositories/page.js.nft.json +1 -1
  217. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  218. package/.next/server/app/review/page.js +1 -1
  219. package/.next/server/app/review/page.js.nft.json +1 -1
  220. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  221. package/.next/server/app/sessions/page.js +1 -1
  222. package/.next/server/app/sessions/page.js.nft.json +1 -1
  223. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  224. package/.next/server/app/skills/[skillId]/page.js +1 -1
  225. package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
  226. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  227. package/.next/server/app/skills/installed/page.js +1 -1
  228. package/.next/server/app/skills/installed/page.js.nft.json +1 -1
  229. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  230. package/.next/server/app/skills/page.js +1 -1
  231. package/.next/server/app/skills/page.js.nft.json +1 -1
  232. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  233. package/.next/server/app/worktrees/[id]/files/[...path]/page.js +1 -1
  234. package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
  235. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  236. package/.next/server/app/worktrees/[id]/page.js +12 -9
  237. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  238. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  239. package/.next/server/app/worktrees/[id]/terminal/page.js +1 -1
  240. package/.next/server/app/worktrees/[id]/terminal/page.js.nft.json +1 -1
  241. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  242. package/.next/server/app-paths-manifest.json +15 -15
  243. package/.next/server/chunks/1341.js +1 -1
  244. package/.next/server/chunks/1501.js +2 -2
  245. package/.next/server/chunks/1559.js +1 -1
  246. package/.next/server/chunks/2119.js +1 -1
  247. package/.next/server/chunks/2283.js +15 -13
  248. package/.next/server/chunks/2404.js +4 -4
  249. package/.next/server/chunks/2445.js +1 -1
  250. package/.next/server/chunks/2460.js +1 -1
  251. package/.next/server/chunks/2560.js +1 -1
  252. package/.next/server/chunks/2908.js +1 -1
  253. package/.next/server/chunks/2984.js +25 -0
  254. package/.next/server/chunks/3543.js +1 -1
  255. package/.next/server/chunks/3945.js +1 -1
  256. package/.next/server/chunks/4072.js +15 -0
  257. package/.next/server/chunks/4207.js +1 -1
  258. package/.next/server/chunks/4718.js +3 -3
  259. package/.next/server/chunks/4837.js +3 -3
  260. package/.next/server/chunks/5209.js +1 -1
  261. package/.next/server/chunks/5292.js +2 -2
  262. package/.next/server/chunks/5845.js +1 -1
  263. package/.next/server/chunks/6130.js +1 -1
  264. package/.next/server/chunks/6345.js +1 -0
  265. package/.next/server/chunks/6401.js +1 -1
  266. package/.next/server/chunks/6722.js +1 -0
  267. package/.next/server/chunks/8098.js +1 -1
  268. package/.next/server/chunks/8356.js +1 -1
  269. package/.next/server/chunks/8581.js +25 -29
  270. package/.next/server/chunks/8728.js +2 -2
  271. package/.next/server/chunks/8791.js +1 -1
  272. package/.next/server/chunks/8800.js +4 -4
  273. package/.next/server/chunks/8918.js +5 -5
  274. package/.next/server/chunks/9390.js +1 -1
  275. package/.next/server/chunks/9627.js +2 -1
  276. package/.next/server/chunks/9731.js +1 -1
  277. package/.next/server/middleware-build-manifest.js +1 -1
  278. package/.next/server/middleware-manifest.json +5 -5
  279. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  280. package/.next/server/pages/500.html +1 -1
  281. package/.next/server/pages/_error.js +2 -2
  282. package/.next/server/server-reference-manifest.json +1 -1
  283. package/.next/static/chunks/{2407-86890b00eeecf391.js → 2407-9703c569370b8a9d.js} +1 -1
  284. package/.next/static/chunks/{2619-a305ad4810f1393a.js → 2619-04bc32f026a0d946.js} +1 -1
  285. package/.next/static/chunks/2717.1583400c272dc1d9.js +1 -0
  286. package/.next/static/chunks/2770-db80aedf6384d594.js +1 -0
  287. package/.next/static/chunks/2863-6a07ec82fb52f4dd.js +1 -0
  288. package/.next/static/chunks/3201-c01f1feed69020e6.js +1 -0
  289. package/.next/static/chunks/4768-ad6f82f034f21eae.js +1 -0
  290. package/.next/static/chunks/5371-0dc947683e46e78c.js +1 -0
  291. package/.next/static/chunks/5794-4eee51ff1e878aa6.js +1 -0
  292. package/.next/static/chunks/5927-54315d21f323e204.js +1 -0
  293. package/.next/static/chunks/602-25e45a2422d2a3ea.js +1 -0
  294. package/.next/static/chunks/6606-02ddc006686a6b7d.js +1 -0
  295. package/.next/static/chunks/6654-f3534f35f16644bc.js +1 -0
  296. package/.next/static/chunks/7730-011e137be64403ae.js +1 -0
  297. package/.next/static/chunks/8165-263172c17ae8e8c3.js +1 -0
  298. package/.next/static/chunks/{8407-9a72e6f07c5d5458.js → 8407-155f84e5ba05f1d5.js} +1 -1
  299. package/.next/static/chunks/8606-cf6bdbff44a764cf.js +1 -0
  300. package/.next/static/chunks/934-a37509667baa86ee.js +1 -0
  301. package/.next/static/chunks/9465-e5a351baa941f31b.js +1 -0
  302. package/.next/static/chunks/app/layout-3e357690446cd2da.js +1 -0
  303. package/.next/static/chunks/app/repositories/page-71f5a5ac29b0370d.js +1 -0
  304. package/.next/static/chunks/app/review/page-e2fd4a590646a2d8.js +1 -0
  305. package/.next/static/chunks/app/sessions/page-9859ed61e93e6890.js +1 -0
  306. package/.next/static/chunks/app/skills/[skillId]/page-52ba58712faf3378.js +1 -0
  307. package/.next/static/chunks/app/worktrees/[id]/page-effbf0796881dd5a.js +1 -0
  308. package/.next/static/chunks/app/worktrees/[id]/terminal/{page-c601f3b3ece6557e.js → page-373ea37b16d930c7.js} +1 -1
  309. package/.next/static/chunks/{webpack-ee3ccbe378c4aa06.js → webpack-468b7b33030234b3.js} +1 -1
  310. package/.next/static/css/743f79ff19ab91e9.css +1 -0
  311. package/.next/trace +13 -13
  312. package/dist/cli/commands/wait.d.ts.map +1 -1
  313. package/dist/cli/commands/wait.js +6 -1
  314. package/dist/cli/types/api-responses.d.ts +8 -6
  315. package/dist/cli/types/api-responses.d.ts.map +1 -1
  316. package/dist/lib/polling/auto-yes-suppression-reason.d.ts +13 -1
  317. package/dist/lib/polling/auto-yes-suppression-reason.d.ts.map +1 -1
  318. package/dist/lib/polling/auto-yes-suppression-reason.js +3 -0
  319. package/dist/server/locales/en/worktree.json +46 -16
  320. package/dist/server/locales/ja/worktree.json +46 -16
  321. package/dist/server/src/config/activity-bar-config.js +56 -9
  322. package/dist/server/src/lib/assistant-response-saver.js +13 -0
  323. package/dist/server/src/lib/auto-yes-poller.js +252 -54
  324. package/dist/server/src/lib/conversation-logger.js +14 -2
  325. package/dist/server/src/lib/db/chat-db.js +2 -1
  326. package/dist/server/src/lib/history/user-turn-recorder.js +14 -0
  327. package/dist/server/src/lib/hooks/sources/antigravity/history.js +28 -0
  328. package/dist/server/src/lib/hooks/sources/claude/history.js +7 -0
  329. package/dist/server/src/lib/hooks/sources/codex/history.js +7 -0
  330. package/dist/server/src/lib/hooks/sources/command-code/history.js +7 -0
  331. package/dist/server/src/lib/hooks/sources/transcript-history.js +34 -0
  332. package/dist/server/src/lib/log-manager.js +7 -2
  333. package/dist/server/src/lib/polling/auto-yes-enter-fallback-state.js +22 -3
  334. package/dist/server/src/lib/polling/auto-yes-poller-state.js +234 -0
  335. package/dist/server/src/lib/polling/auto-yes-suppression-reason.js +3 -0
  336. package/dist/server/src/lib/polling/pending-scraped-response.js +119 -3
  337. package/dist/server/src/lib/polling/poller-owner.js +110 -0
  338. package/dist/server/src/lib/polling/prompt-dedup-state.js +26 -7
  339. package/dist/server/src/lib/polling/prompt-dedup.js +50 -22
  340. package/dist/server/src/lib/polling/response-checker.js +212 -36
  341. package/dist/server/src/lib/polling/response-dedup.js +112 -20
  342. package/dist/server/src/lib/polling/response-poller-core.js +178 -38
  343. package/dist/server/src/lib/polling/structured-history-gate.js +20 -1
  344. package/dist/server/src/lib/prompt-answer-sender.js +59 -12
  345. package/dist/server/src/lib/realtime/terminal-broadcast.js +14 -0
  346. package/dist/server/src/lib/session/chat-turn-progress.js +57 -6
  347. package/dist/server/src/lib/session/current-output-builder.js +19 -0
  348. package/dist/server/src/lib/session/next-action-helper.js +2 -15
  349. package/dist/server/src/lib/session/worktree-session-reconcile.js +83 -10
  350. package/dist/server/src/lib/timer-manager.js +7 -0
  351. package/dist/server/src/lib/tmux/tmux.js +24 -2
  352. package/dist/server/src/lib/verification/env-clean-gate.js +41 -0
  353. package/dist/server/src/lib/verification/gate-runner.js +17 -11
  354. package/dist/server/src/lib/verification/scope-gate.js +169 -3
  355. package/dist/server/src/types/sidebar.js +1 -0
  356. package/docs/en/architecture.md +26 -14
  357. package/docs/en/user-guide/webapp-guide.md +31 -18
  358. package/package.json +1 -1
  359. package/release-notes/0.46.0.json +110 -0
  360. package/release-notes/0.46.1.json +40 -0
  361. package/.next/server/chunks/1674.js +0 -15
  362. package/.next/server/chunks/5625.js +0 -25
  363. package/.next/server/chunks/6927.js +0 -1
  364. package/.next/server/chunks/9355.js +0 -1
  365. package/.next/static/chunks/1642-0f1bf8fb8161e10a.js +0 -1
  366. package/.next/static/chunks/2770-827a64760bab8a3a.js +0 -1
  367. package/.next/static/chunks/3922.0bc2e4e168d2b522.js +0 -1
  368. package/.next/static/chunks/4727-4c69d1aa4118cc09.js +0 -1
  369. package/.next/static/chunks/4768-fc0aa1d0891cac08.js +0 -1
  370. package/.next/static/chunks/5371-af1c2b68e983da61.js +0 -1
  371. package/.next/static/chunks/5521-c358c31f60e5e689.js +0 -1
  372. package/.next/static/chunks/6192-a67df090838b9aad.js +0 -1
  373. package/.next/static/chunks/6322-f1b30ed0ee43518f.js +0 -1
  374. package/.next/static/chunks/6654-ac431270fac1a283.js +0 -1
  375. package/.next/static/chunks/8165-3525fb42f1b4976e.js +0 -1
  376. package/.next/static/chunks/8318-01e7d1e5ad0a15a3.js +0 -1
  377. package/.next/static/chunks/8606-79c36d4c204bbd38.js +0 -1
  378. package/.next/static/chunks/9619-6c17a271f7f98fbb.js +0 -1
  379. package/.next/static/chunks/998-2eb5883186abd0bd.js +0 -1
  380. package/.next/static/chunks/app/layout-eaa6365f8f942e88.js +0 -1
  381. package/.next/static/chunks/app/repositories/page-6f7511f4ac8449e2.js +0 -1
  382. package/.next/static/chunks/app/review/page-95f749caae382f46.js +0 -1
  383. package/.next/static/chunks/app/sessions/page-ebfed2c80e916fb8.js +0 -1
  384. package/.next/static/chunks/app/skills/[skillId]/page-e4b14031f946c007.js +0 -1
  385. package/.next/static/chunks/app/worktrees/[id]/page-3372b78fde232b1f.js +0 -1
  386. package/.next/static/css/6faeb04a0b6819d4.css +0 -1
  387. /package/.next/static/{vYIpFRCU_Mt0wtG8F_3-6 → QxDf7lm-JJkWoj-TyWiSB}/_buildManifest.js +0 -0
  388. /package/.next/static/{vYIpFRCU_Mt0wtG8F_3-6 → QxDf7lm-JJkWoj-TyWiSB}/_ssgManifest.js +0 -0
@@ -8,6 +8,9 @@ exports.holdScrapedResponse = holdScrapedResponse;
8
8
  exports.discardPendingScrapedResponse = discardPendingScrapedResponse;
9
9
  exports.flushPendingScrapedResponse = flushPendingScrapedResponse;
10
10
  exports.settleExpiredPendingScrapedResponse = settleExpiredPendingScrapedResponse;
11
+ exports.listPendingScrapedResponseKeys = listPendingScrapedResponseKeys;
12
+ exports.retargetPendingScrapedResponse = retargetPendingScrapedResponse;
13
+ exports.movePendingScrapedResponses = movePendingScrapedResponses;
11
14
  const db_instance_1 = require("../../lib/db/db-instance");
12
15
  const db_1 = require("../../lib/db");
13
16
  const ws_server_1 = require("../../lib/ws-server");
@@ -17,6 +20,7 @@ const response_dedup_1 = require("./response-dedup");
17
20
  const structured_history_gate_1 = require("./structured-history-gate");
18
21
  const stop_history_capture_1 = require("../../lib/hooks/stop-history-capture");
19
22
  const global_state_1 = require("../global-state");
23
+ const poller_owner_1 = require("./poller-owner");
20
24
  const logger = (0, logger_1.createLogger)('response-poller');
21
25
  // ============================================================================
22
26
  // The held scrape (Issue #2436)
@@ -71,14 +75,35 @@ function hasPendingScrapedResponse(pollerKey) {
71
75
  * deadline. Replaces, because a frame that moved on is a better copy of the
72
76
  * same turn; keeps, because a pane that redraws every tick would otherwise push
73
77
  * its own deadline forward forever and the hold would stop being bounded.
78
+ *
79
+ * Issue #3663: refused to a tick whose chain has been stopped (see
80
+ * `mayActForPollerKey`) — a stop, a stalled-tick restart or a worktree-ID
81
+ * migration retired it while it awaited the reader, and whatever is held under
82
+ * the key now belongs to someone else. The response hash that tick registered
83
+ * is not taken back here: a migration does not hand a running tick's hash on in
84
+ * the first place (`migrateResponsePollerWorktreeIds`), so the successor judges
85
+ * the screen itself.
86
+ *
87
+ * @returns Whether the reply is held
74
88
  */
75
89
  function holdScrapedResponse(pollerKey, pending) {
90
+ if (!(0, poller_owner_1.mayActForPollerKey)(pollerKey)) {
91
+ const caller = (0, poller_owner_1.currentPollerOwner)();
92
+ logger.info('pending-scrape-hold-refused', {
93
+ worktreeId: pending.worktreeId,
94
+ cliToolId: pending.cliToolId,
95
+ instanceId: pending.instanceId,
96
+ generation: caller?.generation,
97
+ });
98
+ return false;
99
+ }
76
100
  const existing = pendingScrapedResponses.get(pollerKey);
77
101
  if (existing) {
78
102
  existing.content = pending.content;
79
- return;
103
+ return true;
80
104
  }
81
105
  pendingScrapedResponses.set(pollerKey, pending);
106
+ return true;
82
107
  }
83
108
  /**
84
109
  * Drop a held scrape without writing it (Issue #2436).
@@ -88,6 +113,10 @@ function holdScrapedResponse(pollerKey, pending) {
88
113
  * duplicate this Issue exists to stop.
89
114
  */
90
115
  function discardPendingScrapedResponse(pollerKey) {
116
+ // Issue #3663: a stopped tick's reader answer is about a turn it no longer
117
+ // owns; what is held under the key now may be another chain's.
118
+ if (!(0, poller_owner_1.mayActForPollerKey)(pollerKey))
119
+ return;
91
120
  pendingScrapedResponses.delete(pollerKey);
92
121
  }
93
122
  /**
@@ -110,15 +139,26 @@ function discardPendingScrapedResponse(pollerKey) {
110
139
  * conversation log is fired afterwards and not waited for, because it is a
111
140
  * secondary record and the row is the one History reads.
112
141
  *
142
+ * Issue #3663: refused (false, nothing written or dropped) to a tick whose
143
+ * chain has been stopped. `stopPollingByKey` already turns such a tick's stop
144
+ * away; this covers the expiry settle, the other caller.
145
+ *
113
146
  * @param pollerKey - Poller key ("worktreeId:instanceId")
114
147
  * @param reason - What ended the hold; logged, for the operator reading back
115
148
  * @returns Whether a held reply was written
116
149
  */
117
150
  function flushPendingScrapedResponse(pollerKey, reason) {
151
+ // Issue #3663: a stopped tick does not confirm what is held under the key.
152
+ if (!(0, poller_owner_1.mayActForPollerKey)(pollerKey))
153
+ return false;
118
154
  const pending = pendingScrapedResponses.get(pollerKey);
119
155
  if (!pending)
120
156
  return false;
121
157
  pendingScrapedResponses.delete(pollerKey);
158
+ return writePendingScrapedResponse(pending, reason);
159
+ }
160
+ /** Write one held reply that has already been taken off its key. */
161
+ function writePendingScrapedResponse(pending, reason) {
122
162
  try {
123
163
  const db = (0, db_instance_1.getDbInstance)();
124
164
  const message = (0, db_1.createMessage)(db, {
@@ -171,12 +211,28 @@ function flushPendingScrapedResponse(pollerKey, reason) {
171
211
  * parse against writing a pane dump that is about to be superseded.
172
212
  */
173
213
  async function settleExpiredPendingScrapedResponse(pollerKey) {
214
+ if (!(0, poller_owner_1.mayActForPollerKey)(pollerKey))
215
+ return;
174
216
  const pending = pendingScrapedResponses.get(pollerKey);
175
217
  if (!pending || Date.now() < pending.expiresAt)
176
218
  return;
177
219
  const captured = await (0, structured_history_gate_1.captureStructuredHistoryTurn)(pending.worktreeId, pending.cliToolId, pending.instanceId, { worktreePath: pending.worktreePath, transcriptPathHint: pending.transcriptPathHint });
220
+ // Issue #3663: the read is awaited, and a migration, a stop or a restart can
221
+ // land in between. The answer is acted on only if this caller still owns the
222
+ // key AND the hold under it is the one that was read about — after an A↔B
223
+ // swap the key holds B's reply, and dropping or writing it on A's answer
224
+ // would lose it or write it twice.
225
+ if (!(0, poller_owner_1.mayActForPollerKey)(pollerKey) || pendingScrapedResponses.get(pollerKey) !== pending) {
226
+ logger.info('pending-scrape-settle-abandoned', {
227
+ worktreeId: pending.worktreeId,
228
+ cliToolId: pending.cliToolId,
229
+ instanceId: pending.instanceId,
230
+ captured,
231
+ });
232
+ return;
233
+ }
178
234
  if (captured) {
179
- discardPendingScrapedResponse(pollerKey);
235
+ pendingScrapedResponses.delete(pollerKey);
180
236
  (0, response_dedup_1.settleStructuredHistoryRecheck)(pollerKey);
181
237
  logger.info('pending-scrape-superseded', {
182
238
  worktreeId: pending.worktreeId,
@@ -186,5 +242,65 @@ async function settleExpiredPendingScrapedResponse(pollerKey) {
186
242
  });
187
243
  return;
188
244
  }
189
- flushPendingScrapedResponse(pollerKey, 'hold-expired');
245
+ pendingScrapedResponses.delete(pollerKey);
246
+ writePendingScrapedResponse(pending, 'hold-expired');
247
+ }
248
+ // ============================================================================
249
+ // Worktree-ID migration (Issue #3663)
250
+ // ============================================================================
251
+ /** Keys that hold a scrape right now. For the migration to choose what moves. */
252
+ function listPendingScrapedResponseKeys() {
253
+ return Array.from(pendingScrapedResponses.keys());
254
+ }
255
+ /**
256
+ * Point the scrape held under `pollerKey` at `newWorktreeId`, in place.
257
+ *
258
+ * For a chain the migration stops instead of moving (it could not resolve the
259
+ * chain's tool): the stop writes the hold, and written under the old ID it
260
+ * would fail the row's foreign key — the rename has already happened — and be
261
+ * lost.
262
+ *
263
+ * @returns Whether a scrape was held under the key
264
+ */
265
+ function retargetPendingScrapedResponse(pollerKey, newWorktreeId) {
266
+ const pending = pendingScrapedResponses.get(pollerKey);
267
+ if (!pending)
268
+ return false;
269
+ pendingScrapedResponses.set(pollerKey, { ...pending, worktreeId: newWorktreeId });
270
+ return true;
271
+ }
272
+ /**
273
+ * Move the held scrapes of a whole migration batch.
274
+ *
275
+ * Every source is lifted before any destination is written, so a swap (A→B,
276
+ * B→A) or a chain (A→B→C) cannot overwrite a scrape that has not moved yet —
277
+ * the rule the dedup state follows (#3553). Each scrape keeps its content,
278
+ * deadline, timestamp and metadata; only its worktree ID becomes the new one.
279
+ *
280
+ * A scrape already under a destination is never dropped to make room: it is
281
+ * written first, under the ID it carries, and the moved one takes the key.
282
+ *
283
+ * Moves with `oldKey === newKey` and sources holding nothing are ignored.
284
+ *
285
+ * @param moves - Poller key moves applied together
286
+ */
287
+ function movePendingScrapedResponses(moves) {
288
+ const lifted = [];
289
+ for (const { oldKey, newKey, newWorktreeId } of moves) {
290
+ if (oldKey === newKey)
291
+ continue;
292
+ const pending = pendingScrapedResponses.get(oldKey);
293
+ if (!pending)
294
+ continue;
295
+ pendingScrapedResponses.delete(oldKey);
296
+ lifted.push({ newKey, pending: { ...pending, worktreeId: newWorktreeId } });
297
+ }
298
+ for (const { newKey, pending } of lifted) {
299
+ const displaced = pendingScrapedResponses.get(newKey);
300
+ if (displaced) {
301
+ pendingScrapedResponses.delete(newKey);
302
+ writePendingScrapedResponse(displaced, 'migration-displaced');
303
+ }
304
+ pendingScrapedResponses.set(newKey, pending);
305
+ }
190
306
  }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /**
3
+ * The ownership token of one response poller chain, and the question "may the
4
+ * code running now still act for this poller key?" (Issue #2223, #3663).
5
+ *
6
+ * In a module of its own, importing nothing from the poller, so that
7
+ * `./pending-scraped-response` can ask the question without importing
8
+ * `./response-poller-core` — which imports the checker that imports the held
9
+ * scrape, and would close a new import cycle (#3482).
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RetiredSnapshotError = exports.snapshotOwnerStorage = exports.pollerOwnerStorage = void 0;
13
+ exports.currentPollerOwner = currentPollerOwner;
14
+ exports.mayActForPollerKey = mayActForPollerKey;
15
+ exports.pollerKeyOf = pollerKeyOf;
16
+ exports.mayActForAgentInstance = mayActForAgentInstance;
17
+ exports.maySnapshotPublish = maySnapshotPublish;
18
+ const async_hooks_1 = require("async_hooks");
19
+ const global_state_1 = require("../global-state");
20
+ /**
21
+ * Carries the running tick's ownership token through `checkForResponse()`.
22
+ *
23
+ * On `globalThis` for the reason the coordinator is (#2223): the poller module
24
+ * is evaluated once per bundle, and a token stored by one bundle's tick has to
25
+ * be readable by the code another bundle's copy of the checker runs.
26
+ */
27
+ exports.pollerOwnerStorage = (0, global_state_1.getOrInitGlobal)('__responsePollerOwnerStorage', () => new async_hooks_1.AsyncLocalStorage());
28
+ /** The ownership token of the tick the caller is running inside, if any. */
29
+ function currentPollerOwner() {
30
+ return exports.pollerOwnerStorage.getStore();
31
+ }
32
+ /**
33
+ * Whether the code running now may change what is kept under `pollerKey`
34
+ * (Issue #3663), or save a reply under it at once (Issue #3684).
35
+ *
36
+ * What is turned away is exactly one thing: a tick whose chain has been
37
+ * stopped, acting on its OWN key. Code outside any tick — a route,
38
+ * `session-cleanup`, the migration itself — may. So may code acting on another
39
+ * key from inside a tick: the relay a worker's tick fires on completion
40
+ * delivers to the requester and restarts the requester's poller in the
41
+ * worker's async context, and that restart's stop must write the requester's
42
+ * held reply (the same line `stopPollingByKey`'s stale-stop check draws). A
43
+ * chain that is merely `superseded` (a restart queued behind the
44
+ * tick it is running) still owns the turn it is finishing: its hold is what the
45
+ * restart's stop writes out (#2436), so it is not turned away here.
46
+ */
47
+ function mayActForPollerKey(pollerKey) {
48
+ const caller = currentPollerOwner();
49
+ return caller === undefined || caller.pollerKey !== pollerKey || !caller.stopped;
50
+ }
51
+ /**
52
+ * The poller key of an agent instance (Issue #3705) — the same spelling as
53
+ * `getPollerKey` in `./response-poller-core`, which delegates here, so that the
54
+ * transcript readers, the user-turn recorder, the cursor advance and the
55
+ * Markdown log can name the key they write under without importing the core.
56
+ */
57
+ function pollerKeyOf(worktreeId, cliToolId, instanceId) {
58
+ return `${worktreeId}:${instanceId ?? cliToolId}`;
59
+ }
60
+ /**
61
+ * {@link mayActForPollerKey} for an agent instance (Issue #3705).
62
+ *
63
+ * Asked by the writers a tick reaches through an `await` of its own — the four
64
+ * transcript readers, `recordUserTurn`, `advanceCapturedLineForTranscriptTurn` —
65
+ * after their last `await` and before their first write. The Stop hook, a
66
+ * route and every other caller outside a tick are not turned away, and neither
67
+ * is a tick acting for another instance.
68
+ */
69
+ function mayActForAgentInstance(target) {
70
+ return mayActForPollerKey(pollerKeyOf(target.worktreeId, target.cliToolId, target.instanceId));
71
+ }
72
+ /**
73
+ * Carries the ownership token of the tick whose terminal snapshot is being
74
+ * built (Issue #3705).
75
+ *
76
+ * A storage of its own rather than {@link pollerOwnerStorage}: only the core
77
+ * enters it, around `broadcastTerminalSnapshot`, so a snapshot started by a
78
+ * route or by the Auto-Yes poller — or by code that merely inherited a tick's
79
+ * context — is never asked about an owner it does not carry.
80
+ */
81
+ exports.snapshotOwnerStorage = (0, global_state_1.getOrInitGlobal)('__responsePollerSnapshotStorage', () => new async_hooks_1.AsyncLocalStorage());
82
+ /**
83
+ * Whether the snapshot being built now may still write and publish
84
+ * (Issue #3705).
85
+ *
86
+ * Asked after every `await` of the snapshot — in `broadcastTerminalSnapshot`,
87
+ * `buildCurrentOutput` and the chat-turn progress it detaches — not only when
88
+ * the tick decides to start one: a successor that takes the key while the
89
+ * capture is in flight would otherwise have its screen, its status latch and
90
+ * its progress frames overwritten by the turn that just ended. A chain that was
91
+ * merely stopped and has no successor still publishes its final snapshot, as
92
+ * before #2223. Outside a snapshot the core started, always true.
93
+ */
94
+ function maySnapshotPublish() {
95
+ const owner = exports.snapshotOwnerStorage.getStore();
96
+ return owner === undefined || !owner.superseded;
97
+ }
98
+ /**
99
+ * Thrown by `buildCurrentOutput` when {@link maySnapshotPublish} turns it away
100
+ * mid-build (Issue #3705), so that nothing after the `await` it resumed from —
101
+ * the status latch, the unclassified-frame row, the structured prompt row, the
102
+ * progress frame — is written. `broadcastTerminalSnapshot` catches it.
103
+ */
104
+ class RetiredSnapshotError extends Error {
105
+ constructor() {
106
+ super('terminal snapshot of a superseded poller tick');
107
+ this.name = 'RetiredSnapshotError';
108
+ }
109
+ }
110
+ exports.RetiredSnapshotError = RetiredSnapshotError;
@@ -37,6 +37,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
37
37
  exports.recordPromptDedupSkip = recordPromptDedupSkip;
38
38
  exports.getPromptDedupSkips = getPromptDedupSkips;
39
39
  exports.renamePromptDedupSkips = renamePromptDedupSkips;
40
+ exports.renamePromptDedupSkipsBatch = renamePromptDedupSkipsBatch;
40
41
  exports.clearPromptDedupSkips = clearPromptDedupSkips;
41
42
  const auto_yes_state_1 = require("../../lib/auto-yes-state");
42
43
  const global_state_1 = require("../global-state");
@@ -80,13 +81,31 @@ function getPromptDedupSkips(worktreeId, cliToolId, instanceId) {
80
81
  * No-op when the IDs match or nothing is recorded under the old one.
81
82
  */
82
83
  function renamePromptDedupSkips(oldWorktreeId, newWorktreeId, cliToolId, instanceId) {
83
- if (oldWorktreeId === newWorktreeId)
84
- return;
85
- const oldKey = (0, auto_yes_state_1.buildCompositeKey)(oldWorktreeId, cliToolId, instanceId);
86
- const record = promptDedupSkips.get(oldKey);
87
- promptDedupSkips.delete(oldKey);
88
- if (record !== undefined) {
89
- promptDedupSkips.set((0, auto_yes_state_1.buildCompositeKey)(newWorktreeId, cliToolId, instanceId), record);
84
+ renamePromptDedupSkipsBatch([{ oldWorktreeId, newWorktreeId, cliToolId, instanceId }]);
85
+ }
86
+ /**
87
+ * Carry the tallies of a whole batch of sessions across a worktree-ID rename
88
+ * (Issue #3553).
89
+ *
90
+ * Every source tally is lifted before any is written, so a swap (A→B, B→A) or
91
+ * a chain (A→B→C) cannot overwrite a tally that has not moved yet. Per entry
92
+ * this is exactly {@link renamePromptDedupSkips}.
93
+ */
94
+ function renamePromptDedupSkipsBatch(renames) {
95
+ const lifted = [];
96
+ for (const { oldWorktreeId, newWorktreeId, cliToolId, instanceId } of renames) {
97
+ if (oldWorktreeId === newWorktreeId)
98
+ continue;
99
+ const oldKey = (0, auto_yes_state_1.buildCompositeKey)(oldWorktreeId, cliToolId, instanceId);
100
+ lifted.push({
101
+ newKey: (0, auto_yes_state_1.buildCompositeKey)(newWorktreeId, cliToolId, instanceId),
102
+ record: promptDedupSkips.get(oldKey),
103
+ });
104
+ promptDedupSkips.delete(oldKey);
105
+ }
106
+ for (const { newKey, record } of lifted) {
107
+ if (record !== undefined)
108
+ promptDedupSkips.set(newKey, record);
90
109
  }
91
110
  }
92
111
  /** Drop every recorded tally. Test seam. */
@@ -34,6 +34,7 @@ exports.claimDuplicatePromptSkipLog = claimDuplicatePromptSkipLog;
34
34
  exports.resetDuplicatePromptSkipStreak = resetDuplicatePromptSkipStreak;
35
35
  exports.clearPromptHashCache = clearPromptHashCache;
36
36
  exports.renamePromptHashCacheKey = renamePromptHashCacheKey;
37
+ exports.renamePromptHashCacheKeys = renamePromptHashCacheKeys;
37
38
  exports.normalizePromptForDedup = normalizePromptForDedup;
38
39
  const crypto_1 = require("crypto");
39
40
  const global_state_1 = require("../global-state");
@@ -95,10 +96,14 @@ function claimDuplicatePromptSkipLog(pollerKey) {
95
96
  * End the current run of duplicate prompt ticks for this pollerKey without
96
97
  * touching the cached hash (Issue #3538).
97
98
  *
98
- * Called by `response-checker` on every tick that does not reach the prompt
99
- * guard with a live prompt — a working screen, an unfinished frame, a reply.
100
- * The prompt is no longer on screen, so if the same prompt comes back the next
101
- * duplicate is the first of a new run and logs. The hash stays: whether the
99
+ * Called by `response-checker` in two places: `extractCompletedTurn`, when the
100
+ * frame was read and is unfinished (a working screen), and `checkForResponse`,
101
+ * when a finished frame carries no live prompt (a reply). The prompt is no
102
+ * longer on screen, so if the same prompt comes back the next duplicate is the
103
+ * first of a new run and logs. Not called on a tick that skipped extraction on
104
+ * the line count (a null result) or returned on the cursor, nor on a tick that
105
+ * ended before extraction: none of them says the prompt has left the screen,
106
+ * so the run carries on through them. The hash stays: whether the
102
107
  * returning prompt is saved again is the guard's question (#565), and this
103
108
  * Issue only thins the log line.
104
109
  *
@@ -126,30 +131,53 @@ function clearPromptHashCache(pollerKey) {
126
131
  * re-save the prompt it is currently sitting on as a fresh message, which is
127
132
  * the duplicate this module exists to prevent.
128
133
  *
129
- * No-op when nothing is cached under `oldKey`.
134
+ * No-op when nothing is cached under `oldKey`. A batch of renames whose keys
135
+ * overlap must go through {@link renamePromptHashCacheKeys} instead.
130
136
  *
131
137
  * @param oldKey - Poller key the cache entry lives under
132
138
  * @param newKey - Poller key it should live under
133
139
  */
134
140
  function renamePromptHashCacheKey(oldKey, newKey) {
135
- if (oldKey === newKey)
136
- return;
137
- const hash = promptHashCache.get(oldKey);
138
- const streak = duplicatePromptSkipStreak.get(oldKey);
139
- promptHashCache.delete(oldKey);
140
- duplicatePromptSkipStreak.delete(oldKey);
141
- if (hash === undefined)
142
- return;
143
- promptHashCache.set(newKey, hash);
144
- // Issue #3538: the skip count moves with the hash, so a rename mid-run does
145
- // not restart the thinning and log as if a new run had begun. Whenever the
146
- // hash under `newKey` is replaced, so is its count — a count left over from
147
- // the hash that was there before is about a different prompt.
148
- if (streak !== undefined) {
149
- duplicatePromptSkipStreak.set(newKey, streak);
141
+ renamePromptHashCacheKeys([{ oldKey, newKey }]);
142
+ }
143
+ /**
144
+ * Move the prompt hash and its skip count for a whole batch of pollerKeys
145
+ * (Issue #3553).
146
+ *
147
+ * Every source key is lifted before any destination is written, so a swap
148
+ * (A→B, B→A) or a chain (A→B→C) cannot overwrite a source that has not moved
149
+ * yet. Per pair this is exactly {@link renamePromptHashCacheKey}: nothing
150
+ * happens at the destination when the source held no hash.
151
+ *
152
+ * @param renames - Poller key moves applied together; `oldKey === newKey` is ignored
153
+ */
154
+ function renamePromptHashCacheKeys(renames) {
155
+ const lifted = [];
156
+ for (const { oldKey, newKey } of renames) {
157
+ if (oldKey === newKey)
158
+ continue;
159
+ lifted.push({
160
+ newKey,
161
+ hash: promptHashCache.get(oldKey),
162
+ streak: duplicatePromptSkipStreak.get(oldKey),
163
+ });
164
+ promptHashCache.delete(oldKey);
165
+ duplicatePromptSkipStreak.delete(oldKey);
150
166
  }
151
- else {
152
- duplicatePromptSkipStreak.delete(newKey);
167
+ for (const { newKey, hash, streak } of lifted) {
168
+ if (hash === undefined)
169
+ continue;
170
+ promptHashCache.set(newKey, hash);
171
+ // Issue #3538: the skip count moves with the hash, so a rename mid-run does
172
+ // not restart the thinning and log as if a new run had begun. Whenever the
173
+ // hash under `newKey` is replaced, so is its count — a count left over from
174
+ // the hash that was there before is about a different prompt.
175
+ if (streak !== undefined) {
176
+ duplicatePromptSkipStreak.set(newKey, streak);
177
+ }
178
+ else {
179
+ duplicatePromptSkipStreak.delete(newKey);
180
+ }
153
181
  }
154
182
  }
155
183
  /**