commandmate 0.46.0 → 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 (285) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +259 -259
  3. package/.next/app-path-routes-manifest.json +14 -14
  4. package/.next/build-manifest.json +5 -5
  5. package/.next/prerender-manifest.json +9 -9
  6. package/.next/react-loadable-manifest.json +2 -2
  7. package/.next/required-server-files.json +1 -1
  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/release-notes/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/app/update/route_client-reference-manifest.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/auth/login/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/capabilities/route.js +1 -1
  18. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  27. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/hooks/claude-done/route.js +9 -9
  29. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  30. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  32. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
  39. package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/relays/route.js.nft.json +1 -1
  41. package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  45. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  46. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/repositories/clone/route.js +1 -1
  48. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  49. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  51. package/.next/server/app/api/repositories/restore/route.js +1 -1
  52. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  53. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/repositories/route.js +1 -1
  55. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  56. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/repositories/scan/route.js +1 -1
  58. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  59. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/repositories/sync/route.js +1 -1
  61. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  62. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  65. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  70. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  72. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  76. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  81. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  82. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  84. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  86. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  87. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  92. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  93. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
  95. package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
  96. package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  113. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  126. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  128. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  131. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/logs/route.js +9 -9
  134. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  144. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  148. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  151. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  158. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  160. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  171. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  174. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  178. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  179. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  182. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  191. package/.next/server/app/api/worktrees/route.js +1 -1
  192. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  193. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  195. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  196. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  197. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  198. package/.next/server/app/page_client-reference-manifest.js +1 -1
  199. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  201. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  202. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  203. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  204. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  205. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  206. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  207. package/.next/server/app/worktrees/[id]/page.js +7 -7
  208. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  209. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  210. package/.next/server/app-paths-manifest.json +14 -14
  211. package/.next/server/chunks/1501.js +2 -2
  212. package/.next/server/chunks/1559.js +1 -1
  213. package/.next/server/chunks/2460.js +1 -1
  214. package/.next/server/chunks/2908.js +1 -1
  215. package/.next/server/chunks/2984.js +25 -0
  216. package/.next/server/chunks/5209.js +1 -1
  217. package/.next/server/chunks/5292.js +2 -2
  218. package/.next/server/chunks/5845.js +1 -1
  219. package/.next/server/chunks/6130.js +1 -1
  220. package/.next/server/chunks/6401.js +1 -1
  221. package/.next/server/chunks/6722.js +1 -1
  222. package/.next/server/chunks/8581.js +4 -4
  223. package/.next/server/chunks/8728.js +2 -2
  224. package/.next/server/chunks/8791.js +1 -1
  225. package/.next/server/chunks/8918.js +5 -5
  226. package/.next/server/chunks/9390.js +1 -1
  227. package/.next/server/chunks/9627.js +2 -1
  228. package/.next/server/chunks/9731.js +1 -1
  229. package/.next/server/middleware-build-manifest.js +1 -1
  230. package/.next/server/middleware-manifest.json +5 -5
  231. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  232. package/.next/server/pages/500.html +1 -1
  233. package/.next/server/server-reference-manifest.json +1 -1
  234. package/.next/static/chunks/{2407-acb644c5487e1720.js → 2407-9703c569370b8a9d.js} +1 -1
  235. package/.next/static/chunks/{2717.21abf5b6bbd45520.js → 2717.1583400c272dc1d9.js} +1 -1
  236. package/.next/static/chunks/5371-0dc947683e46e78c.js +1 -0
  237. package/.next/static/chunks/5794-4eee51ff1e878aa6.js +1 -0
  238. package/.next/static/chunks/{8407-9a72e6f07c5d5458.js → 8407-155f84e5ba05f1d5.js} +1 -1
  239. package/.next/static/chunks/app/{layout-ae30ce63569c22be.js → layout-3e357690446cd2da.js} +1 -1
  240. package/.next/static/chunks/app/worktrees/[id]/page-effbf0796881dd5a.js +1 -0
  241. package/.next/static/chunks/{webpack-c0b821f340afdebf.js → webpack-468b7b33030234b3.js} +1 -1
  242. package/.next/trace +13 -13
  243. package/dist/cli/commands/wait.d.ts.map +1 -1
  244. package/dist/cli/commands/wait.js +6 -1
  245. package/dist/cli/types/api-responses.d.ts +8 -6
  246. package/dist/cli/types/api-responses.d.ts.map +1 -1
  247. package/dist/lib/polling/auto-yes-suppression-reason.d.ts +13 -1
  248. package/dist/lib/polling/auto-yes-suppression-reason.d.ts.map +1 -1
  249. package/dist/lib/polling/auto-yes-suppression-reason.js +3 -0
  250. package/dist/server/src/lib/assistant-response-saver.js +13 -0
  251. package/dist/server/src/lib/auto-yes-poller.js +252 -54
  252. package/dist/server/src/lib/conversation-logger.js +14 -2
  253. package/dist/server/src/lib/db/chat-db.js +2 -1
  254. package/dist/server/src/lib/history/user-turn-recorder.js +14 -0
  255. package/dist/server/src/lib/hooks/sources/antigravity/history.js +28 -0
  256. package/dist/server/src/lib/hooks/sources/claude/history.js +7 -0
  257. package/dist/server/src/lib/hooks/sources/codex/history.js +7 -0
  258. package/dist/server/src/lib/hooks/sources/command-code/history.js +7 -0
  259. package/dist/server/src/lib/hooks/sources/transcript-history.js +34 -0
  260. package/dist/server/src/lib/log-manager.js +7 -2
  261. package/dist/server/src/lib/polling/auto-yes-enter-fallback-state.js +22 -3
  262. package/dist/server/src/lib/polling/auto-yes-poller-state.js +234 -0
  263. package/dist/server/src/lib/polling/auto-yes-suppression-reason.js +3 -0
  264. package/dist/server/src/lib/polling/pending-scraped-response.js +119 -3
  265. package/dist/server/src/lib/polling/poller-owner.js +110 -0
  266. package/dist/server/src/lib/polling/response-checker.js +202 -39
  267. package/dist/server/src/lib/polling/response-dedup.js +8 -0
  268. package/dist/server/src/lib/polling/response-poller-core.js +131 -12
  269. package/dist/server/src/lib/polling/structured-history-gate.js +20 -1
  270. package/dist/server/src/lib/prompt-answer-sender.js +59 -12
  271. package/dist/server/src/lib/realtime/terminal-broadcast.js +14 -0
  272. package/dist/server/src/lib/session/chat-turn-progress.js +57 -6
  273. package/dist/server/src/lib/session/current-output-builder.js +19 -0
  274. package/dist/server/src/lib/session/worktree-session-reconcile.js +83 -10
  275. package/dist/server/src/lib/timer-manager.js +7 -0
  276. package/dist/server/src/lib/tmux/tmux.js +24 -2
  277. package/dist/server/src/lib/verification/env-clean-gate.js +30 -2
  278. package/package.json +1 -1
  279. package/release-notes/0.46.1.json +40 -0
  280. package/.next/server/chunks/5625.js +0 -25
  281. package/.next/static/chunks/5371-a94ed618148287a0.js +0 -1
  282. package/.next/static/chunks/5794-947fb4934d8be193.js +0 -1
  283. package/.next/static/chunks/app/worktrees/[id]/page-2eb1d0fd0a077b7e.js +0 -1
  284. /package/.next/static/{zI2nQ6WKboSbFbMF4EtrJ → QxDf7lm-JJkWoj-TyWiSB}/_buildManifest.js +0 -0
  285. /package/.next/static/{zI2nQ6WKboSbFbMF4EtrJ → QxDf7lm-JJkWoj-TyWiSB}/_ssgManifest.js +0 -0
@@ -524,6 +524,10 @@ async function captureAntigravityTranscriptTurn(target, capture = {}, report) {
524
524
  // what the promotion to "final" rests on.
525
525
  const instanceKey = keyOf(target);
526
526
  const stopAt = await resolveAntigravityStopAt(target);
527
+ // Issue #3705: the follow list below is this instance's, and a tick retired
528
+ // while the reads above ran no longer speaks for it. Nothing is written yet.
529
+ if (!(0, transcript_history_1.mayReaderWrite)(target, logger, 'antigravity-transcript-write-refused', 'follow-list'))
530
+ return false;
527
531
  const completions = new Map();
528
532
  for (const turn of built.turns) {
529
533
  completions.set(turn.stepIndex, (0, transcript_1.resolveAntigravityTurnCompletion)(turn, stopAt));
@@ -546,6 +550,9 @@ async function captureAntigravityTranscriptTurn(target, capture = {}, report) {
546
550
  });
547
551
  }
548
552
  const pending = await selectUnwrittenAntigravityTurns(target, built.turns);
553
+ // Issue #3705: `unsettledStepsFor` below may drop the follow list.
554
+ if (!(0, transcript_history_1.mayReaderWrite)(target, logger, 'antigravity-transcript-write-refused', 'follow-list'))
555
+ return false;
549
556
  const writtenTurns = built.turns.slice(0, built.turns.length - pending.turns.length);
550
557
  // Before anything is written: the rows that are already there (#2438). This
551
558
  // is deliberately ahead of the early return below, because "the newest turn
@@ -598,6 +605,11 @@ async function captureAntigravityTranscriptTurn(target, capture = {}, report) {
598
605
  // An unconfirmed one joins the follow list so that its conclusion is still
599
606
  // picked up once three later turns have pushed it out of #2438's window.
600
607
  if (captured) {
608
+ // Issue #3705: after the write's own `await`. The row is there (it was
609
+ // written while the tick still owned the key), so the answer is true;
610
+ // the follow list and the cursor are no longer this tick's to move.
611
+ if (!(0, transcript_history_1.mayReaderWrite)(target, logger, 'antigravity-transcript-write-refused', 'follow-list'))
612
+ return captured;
601
613
  noteUnsettledAntigravityTurn(target, instanceKey, turn, completions.get(turn.stepIndex) ?? (0, transcript_1.resolveAntigravityTurnCompletion)(turn, stopAt));
602
614
  }
603
615
  }
@@ -810,6 +822,10 @@ async function growAntigravityTurnRow(target, existing, rendered, path) {
810
822
  Promise.resolve().then(() => __importStar(require('../../../../lib/db'))),
811
823
  Promise.resolve().then(() => __importStar(require('../../../../lib/ws-server'))),
812
824
  ]);
825
+ // Issue #3705: by row id, so a retired tick would grow a row the successor —
826
+ // or the migration — has since taken over.
827
+ if (!(0, transcript_history_1.mayReaderWrite)(target, logger, 'antigravity-transcript-write-refused', 'grow'))
828
+ return false;
813
829
  updateMessageContent(getDbInstance(), existing.id, rendered.body);
814
830
  broadcastMessage('message_updated', {
815
831
  worktreeId: target.worktreeId,
@@ -866,6 +882,11 @@ async function refreshAntigravityTurnRows(target, candidates, path, follow) {
866
882
  const db = getDbInstance();
867
883
  let updated = 0;
868
884
  for (const turn of candidates) {
885
+ // Issue #3705: asked at the top of every pass — the first comes after the
886
+ // imports, every later one after the previous turn's grow — because both
887
+ // follow-list writes below come before this pass's own `await`.
888
+ if (!(0, transcript_history_1.mayReaderWrite)(target, logger, 'antigravity-transcript-write-refused', 'follow-list'))
889
+ break;
869
890
  // Issue #2443: the row lookup moved ahead of the writable check, because
870
891
  // the follow list is a statement about ROWS. A turn that is open again has a
871
892
  // row whose body is provisional by definition and must stay followed, and a
@@ -1067,6 +1088,13 @@ async function writeAntigravityTurn(target, turn, rendered, timestampMs, path, r
1067
1088
  await growAntigravityTurnRow(target, existing, rendered, path);
1068
1089
  return true;
1069
1090
  }
1091
+ // Issue #3705: the last `await` (the imports) is behind us and the row and its
1092
+ // broadcast follow with none between. A tick retired meanwhile writes no row
1093
+ // under the instance it lost — the request id only stops the SAME row being
1094
+ // written twice — and answers false: History does not hold the turn.
1095
+ if (!(0, transcript_history_1.mayReaderWrite)(target, logger, 'antigravity-transcript-write-refused', 'reply-row')) {
1096
+ return false;
1097
+ }
1070
1098
  const message = createMessage(db, {
1071
1099
  worktreeId: target.worktreeId,
1072
1100
  role: 'assistant',
@@ -1238,6 +1238,13 @@ async function writeClaudeTurn(target, turn, rendered, timestampMs, path, report
1238
1238
  await growClaudeTurnRow(target, existing, rendered, path);
1239
1239
  return true;
1240
1240
  }
1241
+ // Issue #3705: the last `await` (the imports) is behind us and the row and its
1242
+ // broadcast follow with none between. A tick retired meanwhile writes no row
1243
+ // under the instance it lost — the request id only stops the SAME row being
1244
+ // written twice — and answers false: History does not hold the turn.
1245
+ if (!(0, transcript_history_1.mayReaderWrite)(target, logger, 'claude-transcript-write-refused', 'reply-row')) {
1246
+ return false;
1247
+ }
1241
1248
  const message = createMessage(db, {
1242
1249
  worktreeId: target.worktreeId,
1243
1250
  role: 'assistant',
@@ -729,6 +729,13 @@ async function writeCodexTurn(target, turn, rendered, timestampMs, windowFacts,
729
729
  itemsInWindow: turn.items.length,
730
730
  });
731
731
  }
732
+ // Issue #3705: the last `await` (the imports) is behind us and the row and its
733
+ // broadcast follow with none between. A tick retired meanwhile writes no row
734
+ // under the instance it lost — the request id only stops the SAME row being
735
+ // written twice — and answers false: History does not hold the turn.
736
+ if (!(0, transcript_history_1.mayReaderWrite)(target, logger, 'codex-transcript-write-refused', 'reply-row')) {
737
+ return false;
738
+ }
732
739
  const message = createMessage(db, {
733
740
  worktreeId: target.worktreeId,
734
741
  role: 'assistant',
@@ -765,6 +765,13 @@ async function writeCommandCodeTurn(target, turn, rendered, timestampMs, path, r
765
765
  await growCommandCodeTurnRow(target, existing, rendered, path);
766
766
  return true;
767
767
  }
768
+ // Issue #3705: the last `await` (the imports) is behind us and the row and its
769
+ // broadcast follow with none between. A tick retired meanwhile writes no row
770
+ // under the instance it lost — the request id only stops the SAME row being
771
+ // written twice — and answers false: History does not hold the turn.
772
+ if (!(0, transcript_history_1.mayReaderWrite)(target, logger, 'command-code-transcript-write-refused', 'reply-row')) {
773
+ return false;
774
+ }
768
775
  const message = createMessage(db, {
769
776
  worktreeId: target.worktreeId,
770
777
  role: 'assistant',
@@ -41,6 +41,7 @@ var __importStar = (this && this.__importStar) || (function () {
41
41
  };
42
42
  })();
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.mayReaderWrite = mayReaderWrite;
44
45
  exports.resolveAssistantTimestampMs = resolveAssistantTimestampMs;
45
46
  exports.nextTurnOpensAt = nextTurnOpensAt;
46
47
  exports.isReadableFile = isReadableFile;
@@ -51,6 +52,35 @@ exports.growTurnRowTo = growTurnRowTo;
51
52
  exports.refreshTurnRowsTo = refreshTurnRowsTo;
52
53
  const promises_1 = require("fs/promises");
53
54
  const path_1 = require("path");
55
+ const poller_owner_1 = require("../../../lib/polling/poller-owner");
56
+ /**
57
+ * Whether the reader may still write for `target` now, logging the refusal when
58
+ * it may not (Issue #3705).
59
+ *
60
+ * Asked by every reader write — a reply row, its growth, a user row, its key,
61
+ * the follow list — after the last `await` before it and with none between it
62
+ * and the write. The question is the poller's (`mayActForAgentInstance`): only
63
+ * a response-poller tick whose chain was stopped (a stop, a restart past
64
+ * `STALLED_TICK_TIMEOUT`, a worktree-ID migration) and that is reading for its
65
+ * own instance is turned away. The Stop hook, a route and a tick reading for
66
+ * another instance write as before. Answering false writes nothing — the
67
+ * request id of a row makes a write idempotent, it does not make a retired
68
+ * tick's write right, and a grow or a key is not idempotent at all.
69
+ *
70
+ * @param refusedEvent - The tool's own log event for the refusal
71
+ * @param write - What was about to be written, for the log line
72
+ */
73
+ function mayReaderWrite(target, logger, refusedEvent, write) {
74
+ if ((0, poller_owner_1.mayActForAgentInstance)(target))
75
+ return true;
76
+ logger.info(refusedEvent, {
77
+ worktreeId: target.worktreeId,
78
+ instanceId: target.instanceId ?? target.cliToolId,
79
+ generation: (0, poller_owner_1.currentPollerOwner)()?.generation,
80
+ write,
81
+ });
82
+ return false;
83
+ }
54
84
  /**
55
85
  * When the assistant row for this turn is dated.
56
86
  *
@@ -213,6 +243,10 @@ async function growTurnRowTo(target, existing, rendered, path, logger, updatedEv
213
243
  Promise.resolve().then(() => __importStar(require('../../../lib/db'))),
214
244
  Promise.resolve().then(() => __importStar(require('../../../lib/ws-server'))),
215
245
  ]);
246
+ // Issue #3705: by row id, so a retired tick would grow a row the successor —
247
+ // or the migration — has since taken over.
248
+ if (!mayReaderWrite(target, logger, 'transcript-write-refused', 'grow'))
249
+ return false;
216
250
  updateMessageContent(getDbInstance(), existing.id, rendered.body);
217
251
  broadcastMessage('message_updated', {
218
252
  worktreeId: target.worktreeId,
@@ -69,7 +69,8 @@ function getLogFilePath(worktreeId, cliToolId = 'claude') {
69
69
  * @param userMessage - User's message
70
70
  * @param claudeResponse - Claude's response
71
71
  * @param cliToolId - CLI tool ID (claude, codex, gemini)
72
- * @returns Path to the created log file
72
+ * @param options - See {@link CreateLogOptions}
73
+ * @returns Path to the created log file, or null when `options.mayWrite` refused it
73
74
  *
74
75
  * @example
75
76
  * ```typescript
@@ -81,7 +82,7 @@ function getLogFilePath(worktreeId, cliToolId = 'claude') {
81
82
  * );
82
83
  * ```
83
84
  */
84
- async function createLog(worktreeId, userMessage, claudeResponse, cliToolId = 'claude') {
85
+ async function createLog(worktreeId, userMessage, claudeResponse, cliToolId = 'claude', options = {}) {
85
86
  await ensureLogDirectory(cliToolId);
86
87
  const logPath = getLogFilePath(worktreeId, cliToolId);
87
88
  const timestamp = (0, date_fns_1.format)(new Date(), 'yyyy-MM-dd HH:mm:ss');
@@ -105,6 +106,10 @@ async function createLog(worktreeId, userMessage, claudeResponse, cliToolId = 'c
105
106
  logContent += `### ${displayName}\n\n`;
106
107
  logContent += `${claudeResponse}\n\n`;
107
108
  logContent += `---\n\n`;
109
+ // Issue #3705: after the two awaits above and right before the write — the
110
+ // only place the caller's question can still be answered for this entry.
111
+ if (options.mayWrite && !options.mayWrite())
112
+ return null;
108
113
  await promises_1.default.writeFile(logPath, logContent, 'utf-8');
109
114
  return logPath;
110
115
  }
@@ -52,15 +52,29 @@ const lastEnterFallbacks = (0, global_state_1.getOrInitGlobal)('__autoYesEnterFa
52
52
  /**
53
53
  * Record that Auto-Yes sent its Enter to a screen.
54
54
  *
55
+ * Issue #3706: `sent.epoch` is the session epoch the Enter was decided for. The
56
+ * Enter's `send-keys` is awaited, and a new session begun meanwhile has already
57
+ * dropped the record ({@link beginEnterFallbackSession}); the old send coming
58
+ * back must not put one back about the new process. So a record whose epoch is
59
+ * no longer the current one is not written. Omitted, the current epoch is used.
60
+ *
55
61
  * @param at - Epoch ms; defaults to now. Overridable so tests are deterministic.
62
+ * @returns Whether the record was written
56
63
  */
57
64
  function recordEnterFallbackSent(worktreeId, cliToolId, instanceId, sent, at = Date.now()) {
58
- lastEnterFallbacks.set((0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId), {
65
+ const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
66
+ const current = getEnterFallbackSessionEpoch(key);
67
+ const { epoch = current, ...rest } = sent;
68
+ if (epoch !== current)
69
+ return false;
70
+ lastEnterFallbacks.set(key, {
59
71
  outcome: 'sent',
60
- ...sent,
72
+ ...rest,
61
73
  sentAt: at,
62
74
  at,
75
+ epoch,
63
76
  });
77
+ return true;
64
78
  }
65
79
  /**
66
80
  * Record that the screen the last Enter went to is still up. A no-op when there
@@ -77,7 +91,12 @@ function recordEnterFallbackNoEffect(worktreeId, cliToolId, instanceId, screenKe
77
91
  }
78
92
  /** @returns The last Enter for this session, or null when Auto-Yes never sent one. */
79
93
  function getLastEnterFallback(worktreeId, cliToolId, instanceId) {
80
- return lastEnterFallbacks.get((0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId)) ?? null;
94
+ const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
95
+ const record = lastEnterFallbacks.get(key);
96
+ // Issue #3706: a record of an earlier session says nothing about this one.
97
+ if (!record || record.epoch !== getEnterFallbackSessionEpoch(key))
98
+ return null;
99
+ return record;
81
100
  }
82
101
  /**
83
102
  * The record as published, judged against the prompt the payload carries.
@@ -8,8 +8,20 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.promptFrameKey = promptFrameKey;
10
10
  exports.warnOncePerFrame = warnOncePerFrame;
11
+ exports.partialAnswerScreenKey = partialAnswerScreenKey;
12
+ exports.getPartialAnswer = getPartialAnswer;
13
+ exports.forgetPartialAnswer = forgetPartialAnswer;
14
+ exports.forgetPartialAnswersByWorktree = forgetPartialAnswersByWorktree;
15
+ exports.clearPartialAnswers = clearPartialAnswers;
16
+ exports.beginSendAttempt = beginSendAttempt;
17
+ exports.settleSendAttempt = settleSendAttempt;
18
+ exports.hasMovedSendInFlight = hasMovedSendInFlight;
19
+ exports.movePartialAnswers = movePartialAnswers;
11
20
  const prompt_key_1 = require("../detection/prompt-key");
12
21
  const logger_1 = require("../../lib/logger");
22
+ const auto_yes_state_1 = require("../auto-yes-state");
23
+ const global_state_1 = require("../global-state");
24
+ const auto_yes_enter_fallback_state_1 = require("./auto-yes-enter-fallback-state");
13
25
  const logger = (0, logger_1.createLogger)('auto-yes-poller');
14
26
  /**
15
27
  * Issue #2995: what makes two ticks "the same prompt" for `warnOncePerFrame`.
@@ -50,3 +62,225 @@ function warnOncePerFrame(pollerState, frameKey, event, fields) {
50
62
  pollerState.lastSkipWarnKey = key;
51
63
  logger.warn(event, fields);
52
64
  }
65
+ /**
66
+ * Which prompt a stopped answer is about (Issue #3706): the type, the question,
67
+ * the option labels and `approvalTarget` — what {@link promptFrameKey} tells
68
+ * apart — but NOT where the cursor is. The keys that were sent may have moved
69
+ * the cursor themselves (a `Down` whose Enter was withheld), and that must not
70
+ * make the same list read as a new one; a different list or a different command
71
+ * under the same question is a new prompt and is answered.
72
+ */
73
+ function partialAnswerScreenKey(promptData) {
74
+ const options = promptData.type === 'multiple_choice'
75
+ ? promptData.options.map((o) => `${o.number}.${o.label}`).join('\n')
76
+ : promptData.options.join('\n');
77
+ return [(0, prompt_key_1.generatePromptKey)(promptData), options, withoutCursorMarks(promptData.approvalTarget ?? '')].join('\u0000');
78
+ }
79
+ /**
80
+ * `approvalTarget` with the cursor taken out: the generic parser copies the
81
+ * option panel into it, `❯` row included, so a moved cursor would otherwise
82
+ * read as another prompt. Leading indentation goes too — the cursor row is the
83
+ * one indented differently.
84
+ */
85
+ function withoutCursorMarks(text) {
86
+ return text
87
+ .split('\n')
88
+ .map((line) => line.replace(/^[\s\u276F\u203A>\u25B6\u25BA\u25CF\u25CB\u25C9\u2192]+/u, ''))
89
+ .join('\n');
90
+ }
91
+ /** compositeKey -> the answer stopped part-way. globalThis for hot reload (#153). */
92
+ const partialAnswers = (0, global_state_1.getOrInitGlobal)('__autoYesPartialAnswers', () => new Map());
93
+ /**
94
+ * The answer stopped part-way that still applies: same session epoch, and the
95
+ * caller checks the prompt. Null when none, or when it was about another session.
96
+ */
97
+ function getPartialAnswer(compositeKey, epoch) {
98
+ const partial = partialAnswers.get(compositeKey);
99
+ if (!partial)
100
+ return null;
101
+ if (partial.epoch !== epoch) {
102
+ partialAnswers.delete(compositeKey);
103
+ return null;
104
+ }
105
+ return partial;
106
+ }
107
+ /**
108
+ * Forget it: the prompt left the screen, another prompt came up, or the session ended.
109
+ *
110
+ * The sends still in flight that record under this key — moved here or not —
111
+ * are expired too (Issue #3713, re-instruction 2): they were registered before
112
+ * the screen they were typing at was seen gone, so their stop, coming back
113
+ * later, must not bring the memory back and leave the next confirmation of the
114
+ * same command unanswered. A send registered after this call is a new attempt
115
+ * and records as before. Expiring is the mark: it drops the attempt from the
116
+ * registry, so no per-key "forgotten up to seq" state has to outlive it.
117
+ *
118
+ * @param screenKey - Given when the memory is dropped because ANOTHER prompt is
119
+ * on screen (re-instruction 3): only the sends at the forgotten memory's
120
+ * screen are expired. A send at the screen now shown (Y, carried here by a
121
+ * move while still in flight) stays — it keeps the successor off Y, and its
122
+ * stop is still remembered when it comes back. Omitted (the prompt left the
123
+ * screen), every send under the key is expired.
124
+ */
125
+ function forgetPartialAnswer(compositeKey, screenKey) {
126
+ partialAnswers.delete(compositeKey);
127
+ for (const attempt of [...sendAttempts]) {
128
+ if (attempt.recordKey !== compositeKey)
129
+ continue;
130
+ if (screenKey !== undefined && attempt.screenKey !== screenKey)
131
+ continue;
132
+ expireSendAttempt(attempt);
133
+ }
134
+ }
135
+ /**
136
+ * {@link forgetPartialAnswer} for every instance of a worktree, and the sends
137
+ * still in flight there are expired (Issue #3713): a slow tick that comes back
138
+ * after the worktree's sessions went away records nothing. For the worktree
139
+ * being deleted only; disabling every agent keeps both (`stopAutoYesPollingByWorktree`'s
140
+ * `keepPartialAnswers`).
141
+ */
142
+ function forgetPartialAnswersByWorktree(worktreeId) {
143
+ for (const key of (0, auto_yes_state_1.filterCompositeKeysByWorktree)([...partialAnswers.keys()], worktreeId)) {
144
+ partialAnswers.delete(key);
145
+ }
146
+ const inWorktree = new Set((0, auto_yes_state_1.filterCompositeKeysByWorktree)([...sendAttempts].map((attempt) => attempt.recordKey), worktreeId));
147
+ for (const attempt of [...sendAttempts]) {
148
+ if (inWorktree.has(attempt.recordKey))
149
+ expireSendAttempt(attempt);
150
+ }
151
+ }
152
+ /** Forget every one, and expire every send in flight: server shutdown, and a test seam. */
153
+ function clearPartialAnswers() {
154
+ partialAnswers.clear();
155
+ for (const attempt of [...sendAttempts])
156
+ expireSendAttempt(attempt);
157
+ }
158
+ /** The sends in flight. globalThis for hot reload (#153), like the Map above. */
159
+ const sendAttempts = (0, global_state_1.getOrInitGlobal)('__autoYesSendAttempts', () => new Set());
160
+ const sendAttemptSeq = (0, global_state_1.getOrInitGlobal)('__autoYesSendAttemptSeq', () => ({ last: 0 }));
161
+ /** Register a send about to start (the poller, before `sendPromptAnswer`). */
162
+ function beginSendAttempt(compositeKey, screenKey, epoch) {
163
+ const attempt = {
164
+ seq: ++sendAttemptSeq.last,
165
+ screenKey,
166
+ recordKey: compositeKey,
167
+ recordEpoch: epoch,
168
+ moved: false,
169
+ state: 'pending',
170
+ };
171
+ sendAttempts.add(attempt);
172
+ return attempt;
173
+ }
174
+ /**
175
+ * The send came back. `keysSent` — it was stopped with keys already on the
176
+ * pane — records the partial answer under the attempt's key as it is now, when
177
+ * that key's session is still the one the keys went to; otherwise (sent in
178
+ * full, stopped before any key, or failed) only the attempt itself is removed.
179
+ * A second call, or a call on an expired attempt, does nothing.
180
+ */
181
+ function settleSendAttempt(attempt, keysSent, at = Date.now()) {
182
+ if (attempt.state !== 'pending')
183
+ return;
184
+ attempt.state = 'settled';
185
+ sendAttempts.delete(attempt);
186
+ if (!keysSent)
187
+ return;
188
+ // A relaunch since (`beginAgentSession`): the process the keys went to is gone.
189
+ if ((0, auto_yes_enter_fallback_state_1.getEnterFallbackSessionEpoch)(attempt.recordKey) !== attempt.recordEpoch)
190
+ return;
191
+ // A send registered later (the successor's, after a move) already recorded
192
+ // the same session's newer screen: that is what is in the input now.
193
+ const recorded = partialAnswers.get(attempt.recordKey);
194
+ if (recorded !== undefined && recorded.epoch === attempt.recordEpoch && recorded.seq > attempt.seq)
195
+ return;
196
+ partialAnswers.set(attempt.recordKey, {
197
+ screenKey: attempt.screenKey,
198
+ epoch: attempt.recordEpoch,
199
+ at,
200
+ seq: attempt.seq,
201
+ });
202
+ }
203
+ function expireSendAttempt(attempt) {
204
+ if (attempt.state === 'pending')
205
+ attempt.state = 'expired';
206
+ sendAttempts.delete(attempt);
207
+ }
208
+ /**
209
+ * Is a send that a worktree ID move carried to `compositeKey` still in flight
210
+ * at this screen of this session (Issue #3713)? Its keys may already be on the
211
+ * pane, so the poller under the new key does not type at the same prompt until
212
+ * it comes back. Sends that were not moved are not counted: the paths without a
213
+ * move stay as they were.
214
+ */
215
+ function hasMovedSendInFlight(compositeKey, epoch, screenKey) {
216
+ for (const attempt of sendAttempts) {
217
+ if (attempt.moved &&
218
+ attempt.recordKey === compositeKey &&
219
+ attempt.recordEpoch === epoch &&
220
+ attempt.screenKey === screenKey) {
221
+ return true;
222
+ }
223
+ }
224
+ return false;
225
+ }
226
+ /**
227
+ * Carry the partial answers and the sends in flight of the sessions a worktree
228
+ * ID move renamed to their new keys (Issue #3713). Synchronous: the caller runs
229
+ * it right after the renames, before any poller restarts.
230
+ *
231
+ * Only what belongs to the session that moved goes: the source's epoch must
232
+ * still be `sourceEpoch`, and so must the record's. Every source is read before
233
+ * any destination is written, so a swap (A↔B) or a chain (A→B, B→C) moves each
234
+ * record once, with its own session. At a destination, what was recorded for
235
+ * the session that used to have that name is dropped — its process is not the
236
+ * one now there. The epochs themselves (and the Enter fallback's record) are not
237
+ * moved: a record takes the destination key's current epoch.
238
+ *
239
+ * @param moves - Only the renames that succeeded in both stages
240
+ * @returns The new keys that received a partial answer or a send in flight
241
+ */
242
+ function movePartialAnswers(moves) {
243
+ const carried = moves
244
+ .filter((move) => move.oldKey !== move.newKey)
245
+ .map((move) => {
246
+ const current = (0, auto_yes_enter_fallback_state_1.getEnterFallbackSessionEpoch)(move.oldKey) === move.sourceEpoch;
247
+ const partial = partialAnswers.get(move.oldKey);
248
+ return {
249
+ move,
250
+ partial: current && partial !== undefined && partial.epoch === move.sourceEpoch ? partial : null,
251
+ attempts: current
252
+ ? [...sendAttempts].filter((attempt) => attempt.recordKey === move.oldKey && attempt.recordEpoch === move.sourceEpoch)
253
+ : [],
254
+ };
255
+ });
256
+ const carriedAttempts = new Set(carried.flatMap((entry) => entry.attempts));
257
+ // Detach every source first — only what is carried: a record the epochs
258
+ // left out (a session begun under the old key while the renames ran) stays.
259
+ for (const { move, partial } of carried) {
260
+ if (partial !== null && partialAnswers.get(move.oldKey) === partial)
261
+ partialAnswers.delete(move.oldKey);
262
+ }
263
+ // The destinations' previous sessions' records.
264
+ for (const { move } of carried) {
265
+ partialAnswers.delete(move.newKey);
266
+ for (const attempt of [...sendAttempts]) {
267
+ if (attempt.recordKey === move.newKey && !carriedAttempts.has(attempt))
268
+ expireSendAttempt(attempt);
269
+ }
270
+ }
271
+ // Then arrive.
272
+ const received = [];
273
+ for (const { move, partial, attempts } of carried) {
274
+ const epoch = (0, auto_yes_enter_fallback_state_1.getEnterFallbackSessionEpoch)(move.newKey);
275
+ if (partial !== null)
276
+ partialAnswers.set(move.newKey, { ...partial, epoch });
277
+ for (const attempt of attempts) {
278
+ attempt.recordKey = move.newKey;
279
+ attempt.recordEpoch = epoch;
280
+ attempt.moved = true;
281
+ }
282
+ if (partial !== null || attempts.length > 0)
283
+ received.push(move.newKey);
284
+ }
285
+ return received;
286
+ }
@@ -1,2 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PARTIAL_ANSWER_SUPPRESSION_REASON = void 0;
4
+ /** Issue #3706: the reason the poller records for an answer stopped part-way. */
5
+ exports.PARTIAL_ANSWER_SUPPRESSION_REASON = 'partial-answer';