commandmate 0.30.0 → 0.30.2

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 (254) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +158 -158
  3. package/.next/app-path-routes-manifest.json +34 -34
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +3 -3
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update-check/route.js +1 -1
  12. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
  14. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  16. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/assistant/messages/route.js +1 -1
  18. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  19. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/assistant/session/route.js +1 -1
  21. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  22. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/assistant/start/route.js +2 -2
  24. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  25. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/assistant/terminal/route.js +2 -2
  27. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  28. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  30. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/capabilities/route.js +1 -1
  35. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  41. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  44. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  45. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/hooks/claude-done/route.js +2 -2
  47. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  48. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  50. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  51. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  55. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  60. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  62. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  63. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/repositories/clone/route.js +1 -1
  65. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  66. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/repositories/restore/route.js +1 -1
  69. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  70. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/repositories/route.js +1 -1
  72. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  73. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/repositories/scan/route.js +1 -1
  75. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  76. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/repositories/sync/route.js +1 -1
  78. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  79. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  82. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  94. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  99. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  101. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  103. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  108. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  113. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  116. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  119. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  137. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  139. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  141. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  153. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  157. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  159. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  166. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  168. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.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.nft.json +1 -1
  199. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  201. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  202. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  203. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  204. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  205. package/.next/server/app/page_client-reference-manifest.js +1 -1
  206. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  208. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  209. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  210. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  211. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  212. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  213. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  214. package/.next/server/app/worktrees/[id]/page.js +12 -12
  215. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  216. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  217. package/.next/server/app-paths-manifest.json +34 -34
  218. package/.next/server/chunks/1058.js +1 -1
  219. package/.next/server/chunks/1886.js +2 -2
  220. package/.next/server/chunks/2119.js +1 -1
  221. package/.next/server/chunks/2445.js +1 -1
  222. package/.next/server/chunks/3099.js +5 -0
  223. package/.next/server/chunks/5017.js +1 -1
  224. package/.next/server/chunks/5043.js +1 -0
  225. package/.next/server/chunks/552.js +25 -0
  226. package/.next/server/chunks/6130.js +1 -1
  227. package/.next/server/chunks/6894.js +1 -1
  228. package/.next/server/chunks/9696.js +2 -2
  229. package/.next/server/middleware-manifest.json +5 -5
  230. package/.next/server/pages/500.html +1 -1
  231. package/.next/server/pages-manifest.json +1 -1
  232. package/.next/server/server-reference-manifest.json +1 -1
  233. package/.next/static/chunks/{6381-28d0e95620aa018e.js → 6381-147dde2a967e9458.js} +1 -1
  234. package/.next/static/chunks/app/worktrees/[id]/page-2f73d69187936627.js +1 -0
  235. package/.next/static/css/23f9c40ecc458c77.css +1 -0
  236. package/.next/trace +13 -13
  237. package/dist/server/src/lib/history/user-turn-recorder.js +9 -4
  238. package/dist/server/src/lib/hooks/agent-event-service.js +40 -6
  239. package/dist/server/src/lib/hooks/sources/antigravity/history.js +125 -18
  240. package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +39 -0
  241. package/dist/server/src/lib/hooks/sources/claude/history.js +312 -21
  242. package/dist/server/src/lib/hooks/sources/claude/transcript.js +175 -13
  243. package/dist/server/src/lib/hooks/sources/codex/history.js +100 -13
  244. package/dist/server/src/lib/hooks/stop-history-capture.js +194 -0
  245. package/dist/server/src/lib/polling/response-checker.js +43 -3
  246. package/dist/server/src/lib/polling/structured-history-gate.js +131 -6
  247. package/dist/server/src/lib/session/current-output-builder.js +118 -16
  248. package/package.json +1 -1
  249. package/.next/server/chunks/2827.js +0 -29
  250. package/.next/server/chunks/6781.js +0 -1
  251. package/.next/static/chunks/app/worktrees/[id]/page-d48b95ed554bcd13.js +0 -1
  252. package/.next/static/css/61e10d4b1b11b193.css +0 -1
  253. /package/.next/static/{7K0XXFu_ty4wRSkl4X21E → QXxQbXWoo7ldUyOcv7PCZ}/_buildManifest.js +0 -0
  254. /package/.next/static/{7K0XXFu_ty4wRSkl4X21E → QXxQbXWoo7ldUyOcv7PCZ}/_ssgManifest.js +0 -0
@@ -90,13 +90,14 @@ var __importStar = (this && this.__importStar) || (function () {
90
90
  };
91
91
  })();
92
92
  Object.defineProperty(exports, "__esModule", { value: true });
93
- exports.CLAUDE_TRANSCRIPT_TAIL_BYTES = void 0;
93
+ exports.CLAUDE_TURN_RECHECK_LIMIT = exports.CLAUDE_TRANSCRIPT_TAIL_BYTES = void 0;
94
94
  exports.resetClaudeTranscriptSessions = resetClaudeTranscriptSessions;
95
95
  exports.resolveClaudeSessionId = resolveClaudeSessionId;
96
96
  exports.claudeProjectsRoot = claudeProjectsRoot;
97
97
  exports.claudeTranscriptPath = claudeTranscriptPath;
98
98
  exports.acceptClaudeTranscriptHint = acceptClaudeTranscriptHint;
99
99
  exports.captureClaudeTranscriptTurn = captureClaudeTranscriptTurn;
100
+ exports.resolveClaudeTranscriptPath = resolveClaudeTranscriptPath;
100
101
  exports.readClaudeTurnProgress = readClaudeTurnProgress;
101
102
  const promises_1 = require("fs/promises");
102
103
  const os_1 = require("os");
@@ -113,8 +114,9 @@ const logger = (0, logger_1.createLogger)('lib/hooks/sources/claude/history');
113
114
  * The file grows for the life of the session and a long one is tens of
114
115
  * megabytes — the largest on this machine on 2026-08-31 was 23 MB — so reading
115
116
  * it whole on every finished turn would be the most expensive thing the poller
116
- * does. Only the newest turn is ever written (see {@link captureClaudeTranscriptTurn}),
117
- * so only the newest turn has to be in the window.
117
+ * does. Only turns whose prompt record is inside the window are ever written
118
+ * (see {@link captureClaudeTranscriptTurn}), which is also what stops a turn the
119
+ * window opened halfway through being written from its middle.
118
120
  *
119
121
  * 4 MiB is roughly two orders of magnitude above the measured size of a single
120
122
  * turn and still small enough to read and parse in one tick. A turn that
@@ -216,15 +218,38 @@ function acceptClaudeTranscriptHint(homeDir, hint) {
216
218
  return resolved;
217
219
  }
218
220
  /**
219
- * Read the newest turn out of this instance's transcript and write it.
220
- *
221
- * **Only the newest turn**, and that is the deliberate difference from
222
- * opencode's backfill. Every earlier turn of this session already has a
223
- * `chat_messages` row that the *scraper* wrote, and writing a Markdown row for
224
- * it as well would put the same reply in History twice once as prose and once
225
- * as the pane drew it. The scraper wrote exactly one row per turn and this
226
- * writes exactly one row per turn, so the swap is one-for-one and history is
227
- * neither duplicated nor rewritten.
221
+ * Read this instance's unwritten turns out of its transcript and write them.
222
+ *
223
+ * ## Why this is no longer "only the newest turn" (Issue #2246)
224
+ *
225
+ * #2121 wrote `built.turns.at(-1)` and nothing else, for a reason that was
226
+ * sound and is still half true: every earlier turn of this session already has
227
+ * a `chat_messages` row that the *scraper* wrote, and writing a Markdown row
228
+ * for it as well would put the same reply in History twice — once as prose and
229
+ * once as the pane drew it.
230
+ *
231
+ * What that argument did not cover is a turn **no writer recorded at all**. The
232
+ * trigger for this reader is the poller deciding a turn finished, so a poll that
233
+ * misjudges one completion (#2247's launch-banner heuristic, measured on
234
+ * 2026-09-02) does not merely delay the turn: by the time the next completion is
235
+ * judged, "the newest turn" is the *next* one, and the missed turn is nobody's.
236
+ * One dropped completion cost one turn permanently.
237
+ *
238
+ * So the unit of work is now "every turn in the window that is not already a
239
+ * row", written oldest first, and what preserves #2121's argument is the
240
+ * **anchor**: the newest turn in the window that this reader has already written
241
+ * is where the backfill starts. Turns after it are turns this reader was live
242
+ * for, so a scraper row for them exists only in the case the anchor cannot see
243
+ * — the reader answering false once for a transient reason (an empty body) and
244
+ * the scraper saving that turn's pane copy. That trade is deliberate and in the
245
+ * direction every Issue in this subsystem picks: two writers duplicate a reply,
246
+ * no writer loses one.
247
+ *
248
+ * When the window holds **no** anchor — a session the reader has never written
249
+ * for, and equally the first read after a `/clear` — this falls back to #2121's
250
+ * behaviour exactly: the newest turn, and nothing before it. That is the case
251
+ * where the earlier turns really are the scraper's, and there is no evidence in
252
+ * the window that says otherwise.
228
253
  *
229
254
  * The return value is the poller's instruction, so the two failure directions
230
255
  * are worth stating plainly. **True** means this path has recorded the turn and
@@ -234,10 +259,15 @@ function acceptClaudeTranscriptHint(homeDir, hint) {
234
259
  * false, which is the fail-open the acceptance criteria require: two writers
235
260
  * duplicate a reply, no writer loses one.
236
261
  *
262
+ * **It is the newest turn the answer is about**, backfill or not. A run that
263
+ * wrote three missed turns and then found the newest one still empty answers
264
+ * false, because the scrape the poller is holding is the pane's copy of *that*
265
+ * turn and dropping it would lose it.
266
+ *
237
267
  * Never throws.
238
268
  *
239
269
  * @param target - The instance whose turn just ended
240
- * @returns Whether History now holds this turn as the agent's own Markdown
270
+ * @returns Whether History now holds this instance's newest turn as Markdown
241
271
  */
242
272
  async function captureClaudeTranscriptTurn(target, capture) {
243
273
  const instanceId = target.instanceId ?? target.cliToolId;
@@ -262,8 +292,7 @@ async function captureClaudeTranscriptTurn(target, capture) {
262
292
  return false;
263
293
  const parsed = (0, transcript_1.parseClaudeTranscript)(text);
264
294
  const built = (0, transcript_1.buildClaudeTurns)(parsed.records, sessionId ?? '');
265
- const turn = built.turns.at(-1);
266
- if (!turn) {
295
+ if (built.turns.length === 0) {
267
296
  logger.info('claude-transcript-no-turn', {
268
297
  worktreeId: target.worktreeId,
269
298
  instanceId,
@@ -294,8 +323,49 @@ async function captureClaudeTranscriptTurn(target, capture) {
294
323
  sidechainRecords: built.sidechainRecords,
295
324
  });
296
325
  }
297
- const userRow = await recordClaudeUserTurn(target, turn);
298
- return await writeClaudeTurn(target, (0, transcript_1.renderClaudeTurn)(turn), resolveAssistantTimestampMs(turn, userRow), path);
326
+ const pending = await selectUnwrittenClaudeTurns(target, built.turns);
327
+ // Before anything is written: the rows that are already there (#2264). This
328
+ // is deliberately ahead of the early return below, because "the newest turn
329
+ // is already a row" is the state the nine short rows the Issue measured were
330
+ // stuck in — the reader answered true and did nothing while the transcript
331
+ // beside it held the missing paragraph.
332
+ await refreshClaudeTurnRows(target, built.turns.slice(0, built.turns.length - pending.turns.length).slice(-exports.CLAUDE_TURN_RECHECK_LIMIT), path);
333
+ if (pending.turns.length === 0) {
334
+ // The anchor is the newest turn in the window, so there is nothing to
335
+ // write and the newest turn is a row. True, for the reason
336
+ // {@link writeClaudeTurn} answers true to an already-saved turn: a second
337
+ // poll of one finished turn must not put the pane's copy on top of it.
338
+ logger.debug('claude-transcript-turns-already-saved', {
339
+ worktreeId: target.worktreeId,
340
+ instanceId,
341
+ turnsInWindow: built.turns.length,
342
+ });
343
+ return true;
344
+ }
345
+ if (pending.turns.length > 1) {
346
+ // The #2246 case, and the one worth a line in the log: more than one turn
347
+ // was unwritten, so a completion went unnoticed at the time.
348
+ logger.info('claude-transcript-backfilling-turns', {
349
+ worktreeId: target.worktreeId,
350
+ instanceId,
351
+ path,
352
+ pendingTurns: pending.turns.length,
353
+ turnsInWindow: built.turns.length,
354
+ anchored: pending.anchored,
355
+ });
356
+ }
357
+ // Oldest first, and the ordering is load-bearing twice over: History sorts
358
+ // by timestamp, and each turn's `/send` row is adopted against the previous
359
+ // turn's start, so a later turn must not get to claim a row an earlier one
360
+ // is about to ask for.
361
+ let captured = false;
362
+ for (let index = 0; index < pending.turns.length; index += 1) {
363
+ const turn = pending.turns[index];
364
+ const previousStartedAt = index === 0 ? pending.previousStartedAt : pending.turns[index - 1].startedAt;
365
+ const userRow = await recordClaudeUserTurn(target, turn, previousStartedAt);
366
+ captured = await writeClaudeTurn(target, turn, (0, transcript_1.renderClaudeTurn)(turn), resolveAssistantTimestampMs(turn, userRow), path);
367
+ }
368
+ return captured;
299
369
  }
300
370
  catch (error) {
301
371
  logger.error('claude-transcript-capture-failed', {
@@ -306,6 +376,78 @@ async function captureClaudeTranscriptTurn(target, capture) {
306
376
  return false;
307
377
  }
308
378
  }
379
+ /**
380
+ * The turns {@link captureClaudeTranscriptTurn} still has to write (Issue #2246).
381
+ *
382
+ * The search runs **backwards from the newest turn** and stops at the first one
383
+ * that is already a row. That turn is the *anchor*, and everything after it is
384
+ * pending — by construction, since the anchor is the newest written turn in the
385
+ * window.
386
+ *
387
+ * Two properties of that rule are worth stating because both were required:
388
+ *
389
+ * - **Order, not time.** The comparison is the transcript's own record order
390
+ * and never a timestamp. A turn's assistant row is dated one millisecond
391
+ * after its user row (`resolveAssistantTimestampMs`), so the rows do not
392
+ * carry an ordering that could be trusted for this.
393
+ * - **The window bounds it.** `buildClaudeTurns` only opens a turn on a prompt
394
+ * record, so a turn whose prompt fell outside
395
+ * {@link CLAUDE_TRANSCRIPT_TAIL_BYTES} is not in `turns` at all and cannot be
396
+ * backfilled from its middle. Its records are counted as
397
+ * `orphanedAssistantRecords` instead, which is what the caller reports.
398
+ *
399
+ * A window with no anchor answers with the newest turn alone. See
400
+ * {@link captureClaudeTranscriptTurn} for why that is #2121's behaviour rather
401
+ * than a degraded one.
402
+ *
403
+ * @param turns - Every turn in the window, oldest first
404
+ */
405
+ async function selectUnwrittenClaudeTurns(target, turns) {
406
+ const [{ getDbInstance }, { findMessageByRequestId }] = await Promise.all([
407
+ Promise.resolve().then(() => __importStar(require('../../../../lib/db/db-instance'))),
408
+ Promise.resolve().then(() => __importStar(require('../../../../lib/db'))),
409
+ ]);
410
+ const db = getDbInstance();
411
+ for (let index = turns.length - 1; index >= 0; index -= 1) {
412
+ const requestId = (0, agent_transcript_1.claudeTurnRequestId)(turns[index].promptUuid);
413
+ if (!findMessageByRequestId(db, target.worktreeId, requestId))
414
+ continue;
415
+ return {
416
+ turns: turns.slice(index + 1),
417
+ previousStartedAt: turns[index].startedAt,
418
+ anchored: true,
419
+ };
420
+ }
421
+ return {
422
+ turns: turns.slice(-1),
423
+ previousStartedAt: turns.length > 1 ? turns[turns.length - 2].startedAt : 0,
424
+ anchored: false,
425
+ };
426
+ }
427
+ /**
428
+ * The transcript file this instance would be read from, or null (Issue #2246).
429
+ *
430
+ * The same two steps {@link captureClaudeTranscriptTurn} opens with — resolve
431
+ * the session pointer, then check the filesystem — asked without reading or
432
+ * writing anything. The Stop receiver uses it to decide whether waiting half a
433
+ * second and asking again could possibly help: a session with no transcript to
434
+ * name will not have grown one by then, and a hook handler that sleeps for
435
+ * nothing is a hook handler that slows every turn of every tool.
436
+ *
437
+ * Never throws.
438
+ */
439
+ async function resolveClaudeTranscriptPath(target, capture) {
440
+ try {
441
+ const homeDir = capture.homeDir ?? (0, os_1.homedir)();
442
+ if (typeof capture.worktreePath !== 'string' || capture.worktreePath.length === 0) {
443
+ return null;
444
+ }
445
+ return await locateClaudeTranscript(homeDir, capture, await resolveClaudeSessionId(target));
446
+ }
447
+ catch {
448
+ return null;
449
+ }
450
+ }
309
451
  /**
310
452
  * The key for a body read with no prompt record in the window.
311
453
  *
@@ -357,6 +499,11 @@ function collectHeadlessClaudeTurn(records, sessionId) {
357
499
  promptIsOperatorInput: false,
358
500
  blocks,
359
501
  assistantRecords,
502
+ // Never handed to a writer, so neither flag can be read off it; false is the
503
+ // value that would refuse the write if one were ever attempted.
504
+ closed: false,
505
+ superseded: false,
506
+ stopReasonObserved: false,
360
507
  overflowed,
361
508
  };
362
509
  }
@@ -463,8 +610,14 @@ async function readClaudeTurnProgress(target, capture) {
463
610
  * agent really did reply, and #2121's behaviour for those turns is unchanged.
464
611
  *
465
612
  * Never throws; `recordUserTurn` reports its failures in the return value.
613
+ *
614
+ * @param previousStartedAt - When the turn before this one opened, or 0. Widens
615
+ * `/send` adoption backwards to that instant (Issue #2246): a prompt the agent
616
+ * queued for eleven minutes is still the row CommandMate wrote when it sent
617
+ * the text, and #2196's symmetric two-minute window cannot reach it. Never
618
+ * narrows — see {@link RecordUserTurnOptions}.
466
619
  */
467
- async function recordClaudeUserTurn(target, turn) {
620
+ async function recordClaudeUserTurn(target, turn, previousStartedAt = 0) {
468
621
  const instanceId = target.instanceId ?? target.cliToolId;
469
622
  if (!turn.promptIsOperatorInput) {
470
623
  logger.debug('claude-transcript-user-turn-skipped', {
@@ -475,7 +628,8 @@ async function recordClaudeUserTurn(target, turn) {
475
628
  });
476
629
  return { outcome: 'skipped', messageId: null, timestampMs: null };
477
630
  }
478
- const recorded = await (0, user_turn_recorder_1.recordUserTurn)(target, (0, agent_transcript_1.claudePromptRequestId)(turn.promptUuid), turn.promptText, turn.startedAt);
631
+ const adoption = previousStartedAt > 0 ? { adoptionFromMs: previousStartedAt } : {};
632
+ const recorded = await (0, user_turn_recorder_1.recordUserTurn)(target, (0, agent_transcript_1.claudePromptRequestId)(turn.promptUuid), turn.promptText, turn.startedAt, adoption);
479
633
  if (recorded.outcome === 'failed') {
480
634
  logger.warn('claude-transcript-user-turn-failed', {
481
635
  worktreeId: target.worktreeId,
@@ -574,6 +728,113 @@ async function readClaudeTranscriptTail(path) {
574
728
  await handle?.close().catch(() => { });
575
729
  }
576
730
  }
731
+ /**
732
+ * How many already-written turns are re-rendered and compared (Issue #2264).
733
+ *
734
+ * The repair half of #2264 has to look at rows the reader has **already**
735
+ * written, which is the one thing the anchor rule deliberately does not do — so
736
+ * it is bounded here rather than by the window. Three, because the poller runs
737
+ * every two seconds and re-rendering the whole 4 MiB window on every tick would
738
+ * turn a repair into the most expensive thing the poll does, while a row that is
739
+ * going to grow grows within a second of being written.
740
+ *
741
+ * The cost of the bound is only paid by rows the old code left short: those are
742
+ * repaired on the next read that still has the turn among its newest three, and
743
+ * a session that has moved four turns past one of them keeps it. The Issue's own
744
+ * nine rows were all the newest turn at the time, so all nine are inside it.
745
+ */
746
+ exports.CLAUDE_TURN_RECHECK_LIMIT = 3;
747
+ /**
748
+ * Replace a saved row whose body has since grown (Issue #2264).
749
+ *
750
+ * The second half of the fix, and the half that repairs what the first half
751
+ * only stops happening again. A row keyed `claude-turn:<uuid>` is written once
752
+ * and every later read answers "already saved" — so the nine short rows the
753
+ * Issue measured were frozen, and the scrape that could have replaced them was
754
+ * suppressed two seconds later by that same idempotency answer.
755
+ *
756
+ * **Strictly longer, never merely different.** Equality is the ordinary case and
757
+ * must cost nothing, and a body that got *shorter* between two reads is not a
758
+ * turn that grew — it is a window that slid, or a truncation marker, and
759
+ * overwriting a full reply with a shorter one is the one outcome worse than the
760
+ * bug. Longer implies different, so one comparison covers both halves of the
761
+ * Issue's "differs and is longer".
762
+ *
763
+ * `message_updated`, never `message`: the row already existed and was already
764
+ * delivered when it was created (#2195), so a client that appended instead of
765
+ * replacing would show the reply twice.
766
+ *
767
+ * @param existing - The row `findMessageByRequestId` answered with
768
+ * @returns Whether the row was replaced
769
+ */
770
+ async function growClaudeTurnRow(target, existing, rendered, path) {
771
+ const instanceId = target.instanceId ?? target.cliToolId;
772
+ const previousLength = existing.content.length;
773
+ if (rendered.body.length <= previousLength)
774
+ return false;
775
+ const [{ getDbInstance }, { updateMessageContent }, { broadcastMessage }] = await Promise.all([
776
+ Promise.resolve().then(() => __importStar(require('../../../../lib/db/db-instance'))),
777
+ Promise.resolve().then(() => __importStar(require('../../../../lib/db'))),
778
+ Promise.resolve().then(() => __importStar(require('../../../../lib/ws-server'))),
779
+ ]);
780
+ updateMessageContent(getDbInstance(), existing.id, rendered.body);
781
+ broadcastMessage('message_updated', {
782
+ worktreeId: target.worktreeId,
783
+ message: { ...existing, content: rendered.body },
784
+ });
785
+ logger.info('claude-transcript-turn-updated', {
786
+ worktreeId: target.worktreeId,
787
+ instanceId,
788
+ sessionId: rendered.sessionId,
789
+ requestId: existing.requestId,
790
+ path,
791
+ previousLength,
792
+ bodyLength: rendered.body.length,
793
+ textBlocks: rendered.textBlocks,
794
+ toolBlocks: rendered.toolBlocks,
795
+ });
796
+ return true;
797
+ }
798
+ /**
799
+ * Re-read the newest already-written turns and grow the short ones (#2264).
800
+ *
801
+ * Runs before the pending turns are written and independently of whether there
802
+ * are any — the case it exists for is precisely the one
803
+ * {@link captureClaudeTranscriptTurn} used to return `true` from without doing
804
+ * anything: the newest turn already has a row, and that row is missing its last
805
+ * paragraph.
806
+ *
807
+ * Turns that are still open are skipped rather than compared. Their body is by
808
+ * definition not the final one, and a repair that raced the agent would rewrite
809
+ * the row on every poll of a long turn.
810
+ *
811
+ * The database is asked before the turn is rendered, so a candidate with no row
812
+ * — every candidate, in a session this reader has never written to — costs one
813
+ * indexed lookup and no Markdown.
814
+ *
815
+ * @param candidates - Already-written turns, oldest first, at most {@link CLAUDE_TURN_RECHECK_LIMIT}
816
+ * @returns How many rows were replaced
817
+ */
818
+ async function refreshClaudeTurnRows(target, candidates, path) {
819
+ if (candidates.length === 0)
820
+ return 0;
821
+ const [{ getDbInstance }, { findMessageByRequestId }] = await Promise.all([
822
+ Promise.resolve().then(() => __importStar(require('../../../../lib/db/db-instance'))),
823
+ Promise.resolve().then(() => __importStar(require('../../../../lib/db'))),
824
+ ]);
825
+ const db = getDbInstance();
826
+ let updated = 0;
827
+ for (const turn of candidates) {
828
+ if (!(0, transcript_1.isClaudeTurnWritable)(turn))
829
+ continue;
830
+ const existing = findMessageByRequestId(db, target.worktreeId, (0, agent_transcript_1.claudeTurnRequestId)(turn.promptUuid));
831
+ if (!existing)
832
+ continue;
833
+ if (await growClaudeTurnRow(target, existing, (0, transcript_1.renderClaudeTurn)(turn), path))
834
+ updated += 1;
835
+ }
836
+ return updated;
837
+ }
577
838
  /**
578
839
  * Write one rendered turn, unless it is already there.
579
840
  *
@@ -588,8 +849,33 @@ async function readClaudeTranscriptTail(path) {
588
849
  *
589
850
  * @returns Whether History holds this turn as the agent's own Markdown
590
851
  */
591
- async function writeClaudeTurn(target, rendered, timestampMs, path) {
852
+ async function writeClaudeTurn(target, turn, rendered, timestampMs, path) {
592
853
  const instanceId = target.instanceId ?? target.cliToolId;
854
+ if (!(0, transcript_1.isClaudeTurnWritable)(turn)) {
855
+ // The agent has not said `end_turn` for this prompt and no later prompt has
856
+ // taken over, so what is in the file is a turn in progress. Writing it would
857
+ // put a reply with its last paragraph missing into History **permanently** —
858
+ // the row is keyed on the prompt's `uuid`, so every later read finds it and
859
+ // answers "already saved". That is Issue #2264 exactly: 9 of `claude-2`'s 20
860
+ // turns on 2026-09-03 were saved as a bare `> **Tool calls (1)**` with not
861
+ // one character of prose, because the Stop hook beat the last append and the
862
+ // emptiness guard below cannot see the difference — a turn cut off after its
863
+ // tool calls renders a *non-empty* body.
864
+ //
865
+ // Handing it back to the scraper costs the Markdown rendering for this turn
866
+ // and nothing else: the Stop receiver asks again after a short delay, and
867
+ // the poller asks again when the pane returns to the composer.
868
+ logger.info('claude-transcript-turn-open', {
869
+ worktreeId: target.worktreeId,
870
+ instanceId,
871
+ sessionId: rendered.sessionId,
872
+ promptUuid: rendered.promptUuid,
873
+ assistantRecords: turn.assistantRecords,
874
+ textBlocks: rendered.textBlocks,
875
+ toolBlocks: rendered.toolBlocks,
876
+ });
877
+ return false;
878
+ }
593
879
  if (rendered.body.length === 0) {
594
880
  // The turn is open but the agent has not written anything to the file yet —
595
881
  // the prompt record is there and the assistant records are not. Answering
@@ -619,12 +905,17 @@ async function writeClaudeTurn(target, rendered, timestampMs, path) {
619
905
  Promise.resolve().then(() => __importStar(require('../../../../lib/ws-server'))),
620
906
  ]);
621
907
  const db = getDbInstance();
622
- if (findMessageByRequestId(db, target.worktreeId, requestId)) {
908
+ const existing = findMessageByRequestId(db, target.worktreeId, requestId);
909
+ if (existing) {
623
910
  logger.debug('claude-transcript-turn-already-saved', {
624
911
  worktreeId: target.worktreeId,
625
912
  instanceId,
626
913
  requestId,
627
914
  });
915
+ // The row may still be one of the short ones #2264 was reported for, and
916
+ // this is the one place that knows both the row and the turn. See
917
+ // {@link growClaudeTurnRow}.
918
+ await growClaudeTurnRow(target, existing, rendered, path);
628
919
  return true;
629
920
  }
630
921
  const message = createMessage(db, {