commandmate 0.29.2 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (647) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +278 -271
  3. package/.next/app-path-routes-manifest.json +35 -34
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +3 -3
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/routes-manifest.json +8 -8
  8. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
  11. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/app/update-check/route.js +1 -1
  13. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/assistant/conversation/route.js +1 -1
  15. package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
  16. package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/assistant/current-output/route.js +1 -1
  18. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  19. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/assistant/messages/route.js +1 -1
  21. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  22. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/assistant/session/route.js +1 -1
  24. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  25. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/assistant/start/route.js +18 -18
  27. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  28. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/assistant/terminal/route.js +19 -19
  30. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  31. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/assistant/tools/route.js +1 -1
  33. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  34. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/capabilities/route.js +1 -1
  39. package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/daily-summary/route.js +1 -1
  41. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/hooks/agent-event/route.js +1 -1
  49. package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
  50. package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
  51. package/.next/server/app/api/hooks/claude-done/route.js +2 -2
  52. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  53. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/hooks/permission-request/route.js +1 -1
  55. package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
  56. package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
  57. package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
  58. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/push/escalation/route.js +1 -1
  60. package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/push/vapid/route.js +1 -1
  63. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  64. package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  66. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  69. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  70. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/repositories/clone/route.js +1 -1
  72. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  73. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/repositories/restore/route.js +1 -1
  76. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  77. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  78. package/.next/server/app/api/repositories/route.js +1 -1
  79. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  80. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/repositories/scan/route.js +1 -1
  82. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  83. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/repositories/sync/route.js +1 -1
  85. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  86. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
  88. package/.next/server/app/api/settings/default-agents/route.js +1 -1
  89. package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
  90. package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/settings/default-surface-mode/route.js +1 -0
  92. package/.next/server/app/api/settings/default-surface-mode/route.js.nft.json +1 -0
  93. package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -0
  94. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
  97. package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
  103. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  106. package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  109. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  110. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  113. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
  116. package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/cli-reference/route.js +1 -0
  118. package/.next/server/app/api/worktrees/[id]/cli-reference/route.js.nft.json +1 -0
  119. package/.next/server/app/api/worktrees/[id]/{start-polling → cli-reference}/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  122. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  124. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  125. package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  128. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  140. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  143. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  146. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  149. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  152. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
  154. package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
  155. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  157. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  160. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  164. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  167. package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  173. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  174. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/resolve-target/route.js +1 -1
  176. package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  179. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  182. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  185. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  188. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  189. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +1 -1
  191. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
  192. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
  194. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
  196. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
  197. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
  199. package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
  200. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  203. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  206. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  207. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  209. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  210. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  211. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  212. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  214. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  215. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  217. package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
  218. package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
  219. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
  220. package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
  221. package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
  222. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  223. package/.next/server/app/api/worktrees/apply-default-agents/route.js +1 -1
  224. package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
  225. package/.next/server/app/api/worktrees/route.js +1 -1
  226. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  227. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  229. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  230. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  231. package/.next/server/app/more/page.js +2 -2
  232. package/.next/server/app/more/page.js.nft.json +1 -1
  233. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  234. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  235. package/.next/server/app/page_client-reference-manifest.js +1 -1
  236. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  237. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  238. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  239. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  240. package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
  241. package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
  242. package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  243. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  244. package/.next/server/app/worktrees/[id]/page.js +12 -12
  245. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  246. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  247. package/.next/server/app/worktrees/[id]/terminal/page.js +3 -3
  248. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  249. package/.next/server/app-paths-manifest.json +35 -34
  250. package/.next/server/chunks/1058.js +1 -1
  251. package/.next/server/chunks/1068.js +1 -1
  252. package/.next/server/chunks/1191.js +1 -1
  253. package/.next/server/chunks/1341.js +1 -1
  254. package/.next/server/chunks/1886.js +3 -3
  255. package/.next/server/chunks/2119.js +1 -1
  256. package/.next/server/chunks/2445.js +1 -1
  257. package/.next/server/chunks/261.js +1 -0
  258. package/.next/server/chunks/2739.js +1 -0
  259. package/.next/server/chunks/2816.js +1 -1
  260. package/.next/server/chunks/2827.js +29 -0
  261. package/.next/server/chunks/3123.js +1 -0
  262. package/.next/server/chunks/3241.js +1 -1
  263. package/.next/server/chunks/3543.js +1 -1
  264. package/.next/server/chunks/3945.js +1 -1
  265. package/.next/server/chunks/4325.js +1 -0
  266. package/.next/server/chunks/4390.js +1 -1
  267. package/.next/server/chunks/4393.js +1 -1
  268. package/.next/server/chunks/4443.js +6 -0
  269. package/.next/server/chunks/5017.js +1 -1
  270. package/.next/server/chunks/5120.js +1 -0
  271. package/.next/server/chunks/6130.js +1 -1
  272. package/.next/server/chunks/6337.js +1 -1
  273. package/.next/server/chunks/663.js +1 -1
  274. package/.next/server/chunks/6894.js +8 -0
  275. package/.next/server/chunks/7685.js +1 -1
  276. package/.next/server/chunks/7836.js +1 -0
  277. package/.next/server/chunks/8356.js +1 -1
  278. package/.next/server/chunks/880.js +1 -1
  279. package/.next/server/chunks/8807.js +1 -1
  280. package/.next/server/chunks/9123.js +2 -2
  281. package/.next/server/chunks/9130.js +3 -3
  282. package/.next/server/chunks/9627.js +48 -26
  283. package/.next/server/chunks/9696.js +3 -0
  284. package/.next/server/chunks/9798.js +1 -1
  285. package/.next/server/middleware-manifest.json +5 -5
  286. package/.next/server/pages/500.html +1 -1
  287. package/.next/server/server-reference-manifest.json +1 -1
  288. package/.next/server/src/middleware.js +1 -1
  289. package/.next/server/src/middleware.js.map +1 -1
  290. package/.next/static/7K0XXFu_ty4wRSkl4X21E/_buildManifest.js +1 -0
  291. package/.next/static/chunks/{4882-388e94fe0a03c2ba.js → 3916-0e929d089282dc5d.js} +1 -1
  292. package/.next/static/chunks/{5229-b2a81bb8fb5c19e9.js → 5229-6c89475b61bd2c8b.js} +1 -1
  293. package/.next/static/chunks/6022-7a7d1760fc9814c7.js +1 -0
  294. package/.next/static/chunks/6381-28d0e95620aa018e.js +1 -0
  295. package/.next/static/chunks/app/api/agents/update/route-ee11f7b8a34cba8c.js +1 -0
  296. package/.next/static/chunks/app/api/agents/versions/route-ee11f7b8a34cba8c.js +1 -0
  297. package/.next/static/chunks/app/api/app/update/route-ee11f7b8a34cba8c.js +1 -0
  298. package/.next/static/chunks/app/api/app/update-check/route-ee11f7b8a34cba8c.js +1 -0
  299. package/.next/static/chunks/app/api/assistant/conversation/route-ee11f7b8a34cba8c.js +1 -0
  300. package/.next/static/chunks/app/api/assistant/current-output/route-ee11f7b8a34cba8c.js +1 -0
  301. package/.next/static/chunks/app/api/assistant/messages/route-ee11f7b8a34cba8c.js +1 -0
  302. package/.next/static/chunks/app/api/assistant/session/route-ee11f7b8a34cba8c.js +1 -0
  303. package/.next/static/chunks/app/api/assistant/start/route-ee11f7b8a34cba8c.js +1 -0
  304. package/.next/static/chunks/app/api/assistant/terminal/route-ee11f7b8a34cba8c.js +1 -0
  305. package/.next/static/chunks/app/api/assistant/tools/route-ee11f7b8a34cba8c.js +1 -0
  306. package/.next/static/chunks/app/api/auth/login/route-ee11f7b8a34cba8c.js +1 -0
  307. package/.next/static/chunks/app/api/auth/logout/route-ee11f7b8a34cba8c.js +1 -0
  308. package/.next/static/chunks/app/api/auth/status/route-ee11f7b8a34cba8c.js +1 -0
  309. package/.next/static/chunks/app/api/capabilities/route-ee11f7b8a34cba8c.js +1 -0
  310. package/.next/static/chunks/app/api/daily-summary/route-ee11f7b8a34cba8c.js +1 -0
  311. package/.next/static/chunks/app/api/daily-summary/status/route-ee11f7b8a34cba8c.js +1 -0
  312. package/.next/static/chunks/app/api/external-apps/[id]/health/route-ee11f7b8a34cba8c.js +1 -0
  313. package/.next/static/chunks/app/api/external-apps/[id]/route-ee11f7b8a34cba8c.js +1 -0
  314. package/.next/static/chunks/app/api/external-apps/route-ee11f7b8a34cba8c.js +1 -0
  315. package/.next/static/chunks/app/api/fs/browse/route-ee11f7b8a34cba8c.js +1 -0
  316. package/.next/static/chunks/app/api/fs/recent-paths/route-ee11f7b8a34cba8c.js +1 -0
  317. package/.next/static/chunks/app/api/hooks/agent-event/route-ee11f7b8a34cba8c.js +1 -0
  318. package/.next/static/chunks/app/api/hooks/claude-done/route-ee11f7b8a34cba8c.js +1 -0
  319. package/.next/static/chunks/app/api/hooks/permission-request/route-ee11f7b8a34cba8c.js +1 -0
  320. package/.next/static/chunks/app/api/metrics/vibe/route-ee11f7b8a34cba8c.js +1 -0
  321. package/.next/static/chunks/app/api/ollama/models/route-ee11f7b8a34cba8c.js +1 -0
  322. package/.next/static/chunks/app/api/push/escalation/route-ee11f7b8a34cba8c.js +1 -0
  323. package/.next/static/chunks/app/api/push/subscriptions/route-ee11f7b8a34cba8c.js +1 -0
  324. package/.next/static/chunks/app/api/push/vapid/route-ee11f7b8a34cba8c.js +1 -0
  325. package/.next/static/chunks/app/api/remote/pair/route-ee11f7b8a34cba8c.js +1 -0
  326. package/.next/static/chunks/app/api/repositories/[id]/route-ee11f7b8a34cba8c.js +1 -0
  327. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-ee11f7b8a34cba8c.js +1 -0
  328. package/.next/static/chunks/app/api/repositories/[id]/todos/route-ee11f7b8a34cba8c.js +1 -0
  329. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-ee11f7b8a34cba8c.js +1 -0
  330. package/.next/static/chunks/app/api/repositories/clone/route-ee11f7b8a34cba8c.js +1 -0
  331. package/.next/static/chunks/app/api/repositories/excluded/route-ee11f7b8a34cba8c.js +1 -0
  332. package/.next/static/chunks/app/api/repositories/restore/route-ee11f7b8a34cba8c.js +1 -0
  333. package/.next/static/chunks/app/api/repositories/route-ee11f7b8a34cba8c.js +1 -0
  334. package/.next/static/chunks/app/api/repositories/scan/route-ee11f7b8a34cba8c.js +1 -0
  335. package/.next/static/chunks/app/api/repositories/sync/route-ee11f7b8a34cba8c.js +1 -0
  336. package/.next/static/chunks/app/api/repositories/validate-path/route-ee11f7b8a34cba8c.js +1 -0
  337. package/.next/static/chunks/app/api/settings/default-agents/route-ee11f7b8a34cba8c.js +1 -0
  338. package/.next/static/chunks/app/api/settings/default-surface-mode/route-ee11f7b8a34cba8c.js +1 -0
  339. package/.next/static/chunks/app/api/sidebar/group-order/route-ee11f7b8a34cba8c.js +1 -0
  340. package/.next/static/chunks/app/api/skills/[id]/route-ee11f7b8a34cba8c.js +1 -0
  341. package/.next/static/chunks/app/api/skills/installations/route-ee11f7b8a34cba8c.js +1 -0
  342. package/.next/static/chunks/app/api/skills/operations/route-ee11f7b8a34cba8c.js +1 -0
  343. package/.next/static/chunks/app/api/skills/reindex/route-ee11f7b8a34cba8c.js +1 -0
  344. package/.next/static/chunks/app/api/skills/route-ee11f7b8a34cba8c.js +1 -0
  345. package/.next/static/chunks/app/api/slash-commands/route-ee11f7b8a34cba8c.js +1 -0
  346. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-ee11f7b8a34cba8c.js +1 -0
  347. package/.next/static/chunks/app/api/tasks/[taskId]/route-ee11f7b8a34cba8c.js +1 -0
  348. package/.next/static/chunks/app/api/templates/[id]/route-ee11f7b8a34cba8c.js +1 -0
  349. package/.next/static/chunks/app/api/templates/route-ee11f7b8a34cba8c.js +1 -0
  350. package/.next/static/chunks/app/api/todos/route-ee11f7b8a34cba8c.js +1 -0
  351. package/.next/static/chunks/app/api/verification/runs/[runId]/route-ee11f7b8a34cba8c.js +1 -0
  352. package/.next/static/chunks/app/api/verification/runs/route-ee11f7b8a34cba8c.js +1 -0
  353. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-ee11f7b8a34cba8c.js +1 -0
  354. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-ee11f7b8a34cba8c.js +1 -0
  355. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-ee11f7b8a34cba8c.js +1 -0
  356. package/.next/static/chunks/app/api/worktrees/[id]/cli-reference/route-ee11f7b8a34cba8c.js +1 -0
  357. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-ee11f7b8a34cba8c.js +1 -0
  358. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-ee11f7b8a34cba8c.js +1 -0
  359. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-ee11f7b8a34cba8c.js +1 -0
  360. package/.next/static/chunks/app/api/worktrees/[id]/env/route-ee11f7b8a34cba8c.js +1 -0
  361. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-ee11f7b8a34cba8c.js +1 -0
  362. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-ee11f7b8a34cba8c.js +1 -0
  363. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-ee11f7b8a34cba8c.js +1 -0
  364. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-ee11f7b8a34cba8c.js +1 -0
  365. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-ee11f7b8a34cba8c.js +1 -0
  366. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-ee11f7b8a34cba8c.js +1 -0
  367. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-ee11f7b8a34cba8c.js +1 -0
  368. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-ee11f7b8a34cba8c.js +1 -0
  369. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-ee11f7b8a34cba8c.js +1 -0
  370. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-ee11f7b8a34cba8c.js +1 -0
  371. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-ee11f7b8a34cba8c.js +1 -0
  372. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-ee11f7b8a34cba8c.js +1 -0
  373. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-ee11f7b8a34cba8c.js +1 -0
  374. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-ee11f7b8a34cba8c.js +1 -0
  375. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-ee11f7b8a34cba8c.js +1 -0
  376. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-ee11f7b8a34cba8c.js +1 -0
  377. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-ee11f7b8a34cba8c.js +1 -0
  378. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-ee11f7b8a34cba8c.js +1 -0
  379. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-ee11f7b8a34cba8c.js +1 -0
  380. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-ee11f7b8a34cba8c.js +1 -0
  381. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-ee11f7b8a34cba8c.js +1 -0
  382. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-ee11f7b8a34cba8c.js +1 -0
  383. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-ee11f7b8a34cba8c.js +1 -0
  384. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-ee11f7b8a34cba8c.js +1 -0
  385. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-ee11f7b8a34cba8c.js +1 -0
  386. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-ee11f7b8a34cba8c.js +1 -0
  387. package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-ee11f7b8a34cba8c.js +1 -0
  388. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-ee11f7b8a34cba8c.js +1 -0
  389. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-ee11f7b8a34cba8c.js +1 -0
  390. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-ee11f7b8a34cba8c.js +1 -0
  391. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-ee11f7b8a34cba8c.js +1 -0
  392. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-ee11f7b8a34cba8c.js +1 -0
  393. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-ee11f7b8a34cba8c.js +1 -0
  394. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-ee11f7b8a34cba8c.js +1 -0
  395. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-ee11f7b8a34cba8c.js +1 -0
  396. package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-ee11f7b8a34cba8c.js +1 -0
  397. package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-ee11f7b8a34cba8c.js +1 -0
  398. package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-ee11f7b8a34cba8c.js +1 -0
  399. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-ee11f7b8a34cba8c.js +1 -0
  400. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-ee11f7b8a34cba8c.js +1 -0
  401. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-ee11f7b8a34cba8c.js +1 -0
  402. package/.next/static/chunks/app/api/worktrees/[id]/route-ee11f7b8a34cba8c.js +1 -0
  403. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-ee11f7b8a34cba8c.js +1 -0
  404. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-ee11f7b8a34cba8c.js +1 -0
  405. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-ee11f7b8a34cba8c.js +1 -0
  406. package/.next/static/chunks/app/api/worktrees/[id]/search/route-ee11f7b8a34cba8c.js +1 -0
  407. package/.next/static/chunks/app/api/worktrees/[id]/send/route-ee11f7b8a34cba8c.js +1 -0
  408. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-ee11f7b8a34cba8c.js +1 -0
  409. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-ee11f7b8a34cba8c.js +1 -0
  410. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-ee11f7b8a34cba8c.js +1 -0
  411. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-ee11f7b8a34cba8c.js +1 -0
  412. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-ee11f7b8a34cba8c.js +1 -0
  413. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-ee11f7b8a34cba8c.js +1 -0
  414. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-ee11f7b8a34cba8c.js +1 -0
  415. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-ee11f7b8a34cba8c.js +1 -0
  416. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-ee11f7b8a34cba8c.js +1 -0
  417. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-ee11f7b8a34cba8c.js +1 -0
  418. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-ee11f7b8a34cba8c.js +1 -0
  419. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-ee11f7b8a34cba8c.js +1 -0
  420. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-ee11f7b8a34cba8c.js +1 -0
  421. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-ee11f7b8a34cba8c.js +1 -0
  422. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-ee11f7b8a34cba8c.js +1 -0
  423. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-ee11f7b8a34cba8c.js +1 -0
  424. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-ee11f7b8a34cba8c.js +1 -0
  425. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-ee11f7b8a34cba8c.js +1 -0
  426. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-ee11f7b8a34cba8c.js +1 -0
  427. package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-ee11f7b8a34cba8c.js +1 -0
  428. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-ee11f7b8a34cba8c.js +1 -0
  429. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-ee11f7b8a34cba8c.js +1 -0
  430. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-ee11f7b8a34cba8c.js +1 -0
  431. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-ee11f7b8a34cba8c.js +1 -0
  432. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-ee11f7b8a34cba8c.js +1 -0
  433. package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-ee11f7b8a34cba8c.js +1 -0
  434. package/.next/static/chunks/app/api/worktrees/route-ee11f7b8a34cba8c.js +1 -0
  435. package/.next/static/chunks/app/manifest.webmanifest/route-ee11f7b8a34cba8c.js +1 -0
  436. package/.next/static/chunks/app/more/{page-75d3783da0d49a25.js → page-333bba1c8bbc9c11.js} +1 -1
  437. package/.next/static/chunks/app/proxy/[...path]/route-ee11f7b8a34cba8c.js +1 -0
  438. package/.next/static/chunks/app/worktrees/[id]/layout-ee11f7b8a34cba8c.js +1 -0
  439. package/.next/static/chunks/app/worktrees/[id]/page-d48b95ed554bcd13.js +1 -0
  440. package/.next/static/chunks/app/worktrees/[id]/terminal/page-2631bc5c4b0a9fb8.js +1 -0
  441. package/.next/static/css/61e10d4b1b11b193.css +1 -0
  442. package/.next/trace +13 -13
  443. package/.next/types/app/api/settings/default-surface-mode/route.ts +347 -0
  444. package/.next/types/app/api/worktrees/[id]/{start-polling → cli-reference}/route.ts +3 -3
  445. package/.next/types/routes.d.ts +3 -2
  446. package/.next/types/validator.ts +18 -9
  447. package/dist/server/server.js +58 -0
  448. package/dist/server/src/lib/claude-output.js +1 -0
  449. package/dist/server/src/lib/db/app-settings-db.js +60 -0
  450. package/dist/server/src/lib/db/chat-db.js +120 -7
  451. package/dist/server/src/lib/detection/status-detector.js +3 -2
  452. package/dist/server/src/lib/env.js +122 -0
  453. package/dist/server/src/lib/git/worktrees.js +154 -0
  454. package/dist/server/src/lib/history/transcript-tail.js +80 -0
  455. package/dist/server/src/lib/history/user-turn-recorder.js +247 -0
  456. package/dist/server/src/lib/hooks/permission-decision-service.js +85 -1
  457. package/dist/server/src/lib/hooks/sources/antigravity/history.js +519 -0
  458. package/dist/server/src/lib/hooks/sources/antigravity/source.js +7 -0
  459. package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +407 -0
  460. package/dist/server/src/lib/hooks/sources/claude/history.js +654 -0
  461. package/dist/server/src/lib/hooks/sources/claude/source.js +4 -0
  462. package/dist/server/src/lib/hooks/sources/claude/transcript.js +518 -0
  463. package/dist/server/src/lib/hooks/sources/codex/history.js +576 -0
  464. package/dist/server/src/lib/hooks/sources/codex/source.js +4 -0
  465. package/dist/server/src/lib/hooks/sources/codex/transcript.js +448 -0
  466. package/dist/server/src/lib/hooks/sources/copilot/source.js +2 -0
  467. package/dist/server/src/lib/hooks/sources/gemini/source.js +2 -0
  468. package/dist/server/src/lib/hooks/sources/legacy-relay.js +3 -0
  469. package/dist/server/src/lib/hooks/sources/opencode/history.js +57 -0
  470. package/dist/server/src/lib/hooks/sources/opencode/source.js +4 -0
  471. package/dist/server/src/lib/hooks/sources/opencode/transcript.js +10 -28
  472. package/dist/server/src/lib/hooks/sources/turn-body.js +118 -0
  473. package/dist/server/src/lib/polling/prompt-dedup.js +2 -4
  474. package/dist/server/src/lib/polling/response-checker.js +44 -3
  475. package/dist/server/src/lib/polling/response-dedup.js +2 -4
  476. package/dist/server/src/lib/polling/response-poller-core.js +191 -29
  477. package/dist/server/src/lib/polling/structured-history-gate.js +147 -16
  478. package/dist/server/src/lib/push/push-sender.js +21 -1
  479. package/dist/server/src/lib/push/waiting-push-notifier.js +126 -8
  480. package/dist/server/src/lib/realtime/publisher-registry.js +171 -0
  481. package/dist/server/src/lib/realtime/terminal-broadcast.js +14 -1
  482. package/dist/server/src/lib/realtime/types.js +96 -1
  483. package/dist/server/src/lib/session/current-output-builder.js +263 -4
  484. package/dist/server/src/lib/session/send-user-message.js +90 -2
  485. package/dist/server/src/lib/tui-accumulator.js +2 -8
  486. package/dist/server/src/lib/ws-server.js +143 -6
  487. package/dist/server/src/types/agent-transcript.js +241 -5
  488. package/dist/server/src/types/ui-state.js +24 -1
  489. package/package.json +1 -1
  490. package/public/sw.js +15 -1
  491. package/.next/server/app/api/worktrees/[id]/start-polling/route.js +0 -1
  492. package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +0 -1
  493. package/.next/server/chunks/1714.js +0 -7
  494. package/.next/server/chunks/2198.js +0 -1
  495. package/.next/server/chunks/221.js +0 -25
  496. package/.next/server/chunks/2759.js +0 -8
  497. package/.next/server/chunks/3558.js +0 -1
  498. package/.next/server/chunks/9508.js +0 -1
  499. package/.next/static/0YoRrahue4Vchxg1z83IQ/_buildManifest.js +0 -1
  500. package/.next/static/chunks/1379-af7af9e08f47c979.js +0 -1
  501. package/.next/static/chunks/6381-9ba5198c0a6ff197.js +0 -1
  502. package/.next/static/chunks/app/api/agents/update/route-1c30fb8d4d6fa6ef.js +0 -1
  503. package/.next/static/chunks/app/api/agents/versions/route-1c30fb8d4d6fa6ef.js +0 -1
  504. package/.next/static/chunks/app/api/app/update/route-1c30fb8d4d6fa6ef.js +0 -1
  505. package/.next/static/chunks/app/api/app/update-check/route-1c30fb8d4d6fa6ef.js +0 -1
  506. package/.next/static/chunks/app/api/assistant/conversation/route-1c30fb8d4d6fa6ef.js +0 -1
  507. package/.next/static/chunks/app/api/assistant/current-output/route-1c30fb8d4d6fa6ef.js +0 -1
  508. package/.next/static/chunks/app/api/assistant/messages/route-1c30fb8d4d6fa6ef.js +0 -1
  509. package/.next/static/chunks/app/api/assistant/session/route-1c30fb8d4d6fa6ef.js +0 -1
  510. package/.next/static/chunks/app/api/assistant/start/route-1c30fb8d4d6fa6ef.js +0 -1
  511. package/.next/static/chunks/app/api/assistant/terminal/route-1c30fb8d4d6fa6ef.js +0 -1
  512. package/.next/static/chunks/app/api/assistant/tools/route-1c30fb8d4d6fa6ef.js +0 -1
  513. package/.next/static/chunks/app/api/auth/login/route-1c30fb8d4d6fa6ef.js +0 -1
  514. package/.next/static/chunks/app/api/auth/logout/route-1c30fb8d4d6fa6ef.js +0 -1
  515. package/.next/static/chunks/app/api/auth/status/route-1c30fb8d4d6fa6ef.js +0 -1
  516. package/.next/static/chunks/app/api/capabilities/route-1c30fb8d4d6fa6ef.js +0 -1
  517. package/.next/static/chunks/app/api/daily-summary/route-1c30fb8d4d6fa6ef.js +0 -1
  518. package/.next/static/chunks/app/api/daily-summary/status/route-1c30fb8d4d6fa6ef.js +0 -1
  519. package/.next/static/chunks/app/api/external-apps/[id]/health/route-1c30fb8d4d6fa6ef.js +0 -1
  520. package/.next/static/chunks/app/api/external-apps/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  521. package/.next/static/chunks/app/api/external-apps/route-1c30fb8d4d6fa6ef.js +0 -1
  522. package/.next/static/chunks/app/api/fs/browse/route-1c30fb8d4d6fa6ef.js +0 -1
  523. package/.next/static/chunks/app/api/fs/recent-paths/route-1c30fb8d4d6fa6ef.js +0 -1
  524. package/.next/static/chunks/app/api/hooks/agent-event/route-1c30fb8d4d6fa6ef.js +0 -1
  525. package/.next/static/chunks/app/api/hooks/claude-done/route-1c30fb8d4d6fa6ef.js +0 -1
  526. package/.next/static/chunks/app/api/hooks/permission-request/route-1c30fb8d4d6fa6ef.js +0 -1
  527. package/.next/static/chunks/app/api/metrics/vibe/route-1c30fb8d4d6fa6ef.js +0 -1
  528. package/.next/static/chunks/app/api/ollama/models/route-1c30fb8d4d6fa6ef.js +0 -1
  529. package/.next/static/chunks/app/api/push/escalation/route-1c30fb8d4d6fa6ef.js +0 -1
  530. package/.next/static/chunks/app/api/push/subscriptions/route-1c30fb8d4d6fa6ef.js +0 -1
  531. package/.next/static/chunks/app/api/push/vapid/route-1c30fb8d4d6fa6ef.js +0 -1
  532. package/.next/static/chunks/app/api/remote/pair/route-1c30fb8d4d6fa6ef.js +0 -1
  533. package/.next/static/chunks/app/api/repositories/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  534. package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-1c30fb8d4d6fa6ef.js +0 -1
  535. package/.next/static/chunks/app/api/repositories/[id]/todos/route-1c30fb8d4d6fa6ef.js +0 -1
  536. package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-1c30fb8d4d6fa6ef.js +0 -1
  537. package/.next/static/chunks/app/api/repositories/clone/route-1c30fb8d4d6fa6ef.js +0 -1
  538. package/.next/static/chunks/app/api/repositories/excluded/route-1c30fb8d4d6fa6ef.js +0 -1
  539. package/.next/static/chunks/app/api/repositories/restore/route-1c30fb8d4d6fa6ef.js +0 -1
  540. package/.next/static/chunks/app/api/repositories/route-1c30fb8d4d6fa6ef.js +0 -1
  541. package/.next/static/chunks/app/api/repositories/scan/route-1c30fb8d4d6fa6ef.js +0 -1
  542. package/.next/static/chunks/app/api/repositories/sync/route-1c30fb8d4d6fa6ef.js +0 -1
  543. package/.next/static/chunks/app/api/repositories/validate-path/route-1c30fb8d4d6fa6ef.js +0 -1
  544. package/.next/static/chunks/app/api/settings/default-agents/route-1c30fb8d4d6fa6ef.js +0 -1
  545. package/.next/static/chunks/app/api/sidebar/group-order/route-1c30fb8d4d6fa6ef.js +0 -1
  546. package/.next/static/chunks/app/api/skills/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  547. package/.next/static/chunks/app/api/skills/installations/route-1c30fb8d4d6fa6ef.js +0 -1
  548. package/.next/static/chunks/app/api/skills/operations/route-1c30fb8d4d6fa6ef.js +0 -1
  549. package/.next/static/chunks/app/api/skills/reindex/route-1c30fb8d4d6fa6ef.js +0 -1
  550. package/.next/static/chunks/app/api/skills/route-1c30fb8d4d6fa6ef.js +0 -1
  551. package/.next/static/chunks/app/api/slash-commands/route-1c30fb8d4d6fa6ef.js +0 -1
  552. package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-1c30fb8d4d6fa6ef.js +0 -1
  553. package/.next/static/chunks/app/api/tasks/[taskId]/route-1c30fb8d4d6fa6ef.js +0 -1
  554. package/.next/static/chunks/app/api/templates/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  555. package/.next/static/chunks/app/api/templates/route-1c30fb8d4d6fa6ef.js +0 -1
  556. package/.next/static/chunks/app/api/todos/route-1c30fb8d4d6fa6ef.js +0 -1
  557. package/.next/static/chunks/app/api/verification/runs/[runId]/route-1c30fb8d4d6fa6ef.js +0 -1
  558. package/.next/static/chunks/app/api/verification/runs/route-1c30fb8d4d6fa6ef.js +0 -1
  559. package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-1c30fb8d4d6fa6ef.js +0 -1
  560. package/.next/static/chunks/app/api/worktrees/[id]/capture/route-1c30fb8d4d6fa6ef.js +0 -1
  561. package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-1c30fb8d4d6fa6ef.js +0 -1
  562. package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-1c30fb8d4d6fa6ef.js +0 -1
  563. package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-1c30fb8d4d6fa6ef.js +0 -1
  564. package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-1c30fb8d4d6fa6ef.js +0 -1
  565. package/.next/static/chunks/app/api/worktrees/[id]/env/route-1c30fb8d4d6fa6ef.js +0 -1
  566. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-1c30fb8d4d6fa6ef.js +0 -1
  567. package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-1c30fb8d4d6fa6ef.js +0 -1
  568. package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
  569. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-1c30fb8d4d6fa6ef.js +0 -1
  570. package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-1c30fb8d4d6fa6ef.js +0 -1
  571. package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-1c30fb8d4d6fa6ef.js +0 -1
  572. package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-1c30fb8d4d6fa6ef.js +0 -1
  573. package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-1c30fb8d4d6fa6ef.js +0 -1
  574. package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-1c30fb8d4d6fa6ef.js +0 -1
  575. package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-1c30fb8d4d6fa6ef.js +0 -1
  576. package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-1c30fb8d4d6fa6ef.js +0 -1
  577. package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-1c30fb8d4d6fa6ef.js +0 -1
  578. package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-1c30fb8d4d6fa6ef.js +0 -1
  579. package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-1c30fb8d4d6fa6ef.js +0 -1
  580. package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-1c30fb8d4d6fa6ef.js +0 -1
  581. package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-1c30fb8d4d6fa6ef.js +0 -1
  582. package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-1c30fb8d4d6fa6ef.js +0 -1
  583. package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-1c30fb8d4d6fa6ef.js +0 -1
  584. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-1c30fb8d4d6fa6ef.js +0 -1
  585. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-1c30fb8d4d6fa6ef.js +0 -1
  586. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-1c30fb8d4d6fa6ef.js +0 -1
  587. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-1c30fb8d4d6fa6ef.js +0 -1
  588. package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-1c30fb8d4d6fa6ef.js +0 -1
  589. package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-1c30fb8d4d6fa6ef.js +0 -1
  590. package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-1c30fb8d4d6fa6ef.js +0 -1
  591. package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-1c30fb8d4d6fa6ef.js +0 -1
  592. package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-1c30fb8d4d6fa6ef.js +0 -1
  593. package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-1c30fb8d4d6fa6ef.js +0 -1
  594. package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-1c30fb8d4d6fa6ef.js +0 -1
  595. package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-1c30fb8d4d6fa6ef.js +0 -1
  596. package/.next/static/chunks/app/api/worktrees/[id]/logs/route-1c30fb8d4d6fa6ef.js +0 -1
  597. package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-1c30fb8d4d6fa6ef.js +0 -1
  598. package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-1c30fb8d4d6fa6ef.js +0 -1
  599. package/.next/static/chunks/app/api/worktrees/[id]/memos/route-1c30fb8d4d6fa6ef.js +0 -1
  600. package/.next/static/chunks/app/api/worktrees/[id]/messages/route-1c30fb8d4d6fa6ef.js +0 -1
  601. package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-1c30fb8d4d6fa6ef.js +0 -1
  602. package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-1c30fb8d4d6fa6ef.js +0 -1
  603. package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-1c30fb8d4d6fa6ef.js +0 -1
  604. package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-1c30fb8d4d6fa6ef.js +0 -1
  605. package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-1c30fb8d4d6fa6ef.js +0 -1
  606. package/.next/static/chunks/app/api/worktrees/[id]/respond/route-1c30fb8d4d6fa6ef.js +0 -1
  607. package/.next/static/chunks/app/api/worktrees/[id]/route-1c30fb8d4d6fa6ef.js +0 -1
  608. package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-1c30fb8d4d6fa6ef.js +0 -1
  609. package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-1c30fb8d4d6fa6ef.js +0 -1
  610. package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-1c30fb8d4d6fa6ef.js +0 -1
  611. package/.next/static/chunks/app/api/worktrees/[id]/search/route-1c30fb8d4d6fa6ef.js +0 -1
  612. package/.next/static/chunks/app/api/worktrees/[id]/send/route-1c30fb8d4d6fa6ef.js +0 -1
  613. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-1c30fb8d4d6fa6ef.js +0 -1
  614. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-1c30fb8d4d6fa6ef.js +0 -1
  615. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-1c30fb8d4d6fa6ef.js +0 -1
  616. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-1c30fb8d4d6fa6ef.js +0 -1
  617. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-1c30fb8d4d6fa6ef.js +0 -1
  618. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-1c30fb8d4d6fa6ef.js +0 -1
  619. package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-1c30fb8d4d6fa6ef.js +0 -1
  620. package/.next/static/chunks/app/api/worktrees/[id]/skills/route-1c30fb8d4d6fa6ef.js +0 -1
  621. package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-1c30fb8d4d6fa6ef.js +0 -1
  622. package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-1c30fb8d4d6fa6ef.js +0 -1
  623. package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-1c30fb8d4d6fa6ef.js +0 -1
  624. package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-1c30fb8d4d6fa6ef.js +0 -1
  625. package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-1c30fb8d4d6fa6ef.js +0 -1
  626. package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-1c30fb8d4d6fa6ef.js +0 -1
  627. package/.next/static/chunks/app/api/worktrees/[id]/timers/route-1c30fb8d4d6fa6ef.js +0 -1
  628. package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-1c30fb8d4d6fa6ef.js +0 -1
  629. package/.next/static/chunks/app/api/worktrees/[id]/todos/route-1c30fb8d4d6fa6ef.js +0 -1
  630. package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
  631. package/.next/static/chunks/app/api/worktrees/[id]/tree/route-1c30fb8d4d6fa6ef.js +0 -1
  632. package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
  633. package/.next/static/chunks/app/api/worktrees/[id]/verify/config/route-1c30fb8d4d6fa6ef.js +0 -1
  634. package/.next/static/chunks/app/api/worktrees/[id]/verify/route-1c30fb8d4d6fa6ef.js +0 -1
  635. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route-1c30fb8d4d6fa6ef.js +0 -1
  636. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-1c30fb8d4d6fa6ef.js +0 -1
  637. package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-1c30fb8d4d6fa6ef.js +0 -1
  638. package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-1c30fb8d4d6fa6ef.js +0 -1
  639. package/.next/static/chunks/app/api/worktrees/apply-default-agents/route-1c30fb8d4d6fa6ef.js +0 -1
  640. package/.next/static/chunks/app/api/worktrees/route-1c30fb8d4d6fa6ef.js +0 -1
  641. package/.next/static/chunks/app/manifest.webmanifest/route-1c30fb8d4d6fa6ef.js +0 -1
  642. package/.next/static/chunks/app/proxy/[...path]/route-1c30fb8d4d6fa6ef.js +0 -1
  643. package/.next/static/chunks/app/worktrees/[id]/layout-1c30fb8d4d6fa6ef.js +0 -1
  644. package/.next/static/chunks/app/worktrees/[id]/page-ce6279d581d1df95.js +0 -1
  645. package/.next/static/chunks/app/worktrees/[id]/terminal/page-00ad5d9a62a71cab.js +0 -1
  646. package/.next/static/css/b326c8a734e1928e.css +0 -1
  647. /package/.next/static/{0YoRrahue4Vchxg1z83IQ → 7K0XXFu_ty4wRSkl4X21E}/_ssgManifest.js +0 -0
@@ -6,13 +6,15 @@
6
6
  * Issue #479: Extracted from db.ts for single-responsibility separation
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.ACTIVE_FILTER = void 0;
9
+ exports.UNKEYED_USER_MESSAGE_LIMIT = exports.ACTIVE_FILTER = void 0;
10
10
  exports.getLastAssistantMessageAt = getLastAssistantMessageAt;
11
11
  exports.createMessage = createMessage;
12
12
  exports.updateMessageContent = updateMessageContent;
13
13
  exports.getMessages = getMessages;
14
14
  exports.getLastUserMessage = getLastUserMessage;
15
15
  exports.findMessageByRequestId = findMessageByRequestId;
16
+ exports.findUnkeyedUserMessages = findUnkeyedUserMessages;
17
+ exports.setMessageRequestId = setMessageRequestId;
16
18
  exports.getLastMessage = getLastMessage;
17
19
  exports.deleteAllMessages = deleteAllMessages;
18
20
  exports.deleteMessageById = deleteMessageById;
@@ -125,7 +127,7 @@ function updateMessageContent(db, messageId, content, options) {
125
127
  * Get messages for a worktree, optionally filtered by CLI tool
126
128
  */
127
129
  function getMessages(db, worktreeId, options = {}) {
128
- const { before, limit = 50, cliToolId, instanceId, includeArchived = false, messageType, limitUnit = 'messages' } = options;
130
+ const { before, limit = 50, cliToolId, instanceId, includeArchived = false, messageType, limitUnit = 'messages', matchResolvedInstance = false } = options;
129
131
  // Build the shared scope clause (worktree + before cursor + archived + instance/cli
130
132
  // filter) and its bound params. Used for both the message-unit and pair-unit paths
131
133
  // so their filtering stays identical.
@@ -138,7 +140,19 @@ function getMessages(db, worktreeId, options = {}) {
138
140
  clause += ` ${exports.ACTIVE_FILTER}`;
139
141
  }
140
142
  // Issue #868: instance filter takes precedence; otherwise fall back to CLI tool filter.
141
- if (instanceId) {
143
+ // Issue #2219: `matchResolvedInstance` reads both columns through the same
144
+ // COALESCE defaults `mapChatMessage` applies, so pre-#868 rows
145
+ // (`instance_id IS NULL`) count as the primary instance instead of
146
+ // vanishing. See the option's doc comment for why the tool filter joins in.
147
+ if (instanceId && matchResolvedInstance) {
148
+ if (cliToolId) {
149
+ clause += ` AND COALESCE(cli_tool_id, 'claude') = ?`;
150
+ params.push(cliToolId);
151
+ }
152
+ clause += ` AND COALESCE(instance_id, cli_tool_id, 'claude') = ?`;
153
+ params.push(instanceId);
154
+ }
155
+ else if (instanceId) {
142
156
  clause += ` AND instance_id = ?`;
143
157
  params.push(instanceId);
144
158
  }
@@ -229,6 +243,80 @@ function findMessageByRequestId(db, worktreeId, requestId) {
229
243
  const row = stmt.get(worktreeId, requestId);
230
244
  return row ? mapChatMessage(row) : null;
231
245
  }
246
+ /**
247
+ * How many candidate rows {@link findUnkeyedUserMessages} returns.
248
+ *
249
+ * The caller compares content in JavaScript, so this bounds the work rather than
250
+ * the correctness. Twenty is far above the number of user rows one instance can
251
+ * accumulate inside the caller's few-minute window and still small enough that
252
+ * the query is never the expensive part of a poll.
253
+ */
254
+ exports.UNKEYED_USER_MESSAGE_LIMIT = 20;
255
+ /**
256
+ * User rows for one instance that no producer has claimed yet (Issue #2196).
257
+ *
258
+ * The lookup behind "the operator's input is already in History — `/send` put it
259
+ * there". A row qualifies when it is this instance's, is a `user` row, sits in
260
+ * the caller's time window, and has **no `request_id`**: that last condition is
261
+ * what makes the query safe to answer a *claim* with, because a row that already
262
+ * carries a key belongs to whoever wrote it and must not be re-pointed at
263
+ * another turn.
264
+ *
265
+ * Content is deliberately not compared here. "The same text" is a normalisation
266
+ * question (trailing whitespace, `\r\n`, a composer that reflowed the body), and
267
+ * SQL is the wrong place to decide it — see `normalizeUserTurnContent` in
268
+ * `lib/history/user-turn-recorder`, which owns that rule and is the only thing
269
+ * that has to change when the rule does.
270
+ *
271
+ * `COALESCE` on both tool columns is not defensive noise: rows written before
272
+ * Issue #868 carry `instance_id IS NULL`, and `mapChatMessage` reads those as
273
+ * the primary instance. A bare `instance_id = ?` would make those rows
274
+ * invisible here while the UI still shows them, so the operator would see their
275
+ * `/send` row *and* a second row this Issue inserted.
276
+ *
277
+ * `ACTIVE_FILTER` applies: an archived row has been cleared out of History, and
278
+ * adopting one would key a turn to a row nobody can see.
279
+ *
280
+ * @returns Candidate rows, newest first
281
+ */
282
+ function findUnkeyedUserMessages(db, query) {
283
+ const stmt = db.prepare(`
284
+ SELECT id, worktree_id, role, content, summary, timestamp, log_file_name, request_id, message_type, prompt_data, cli_tool_id, instance_id, archived
285
+ FROM chat_messages
286
+ WHERE worktree_id = ?
287
+ AND role = 'user'
288
+ AND request_id IS NULL
289
+ AND COALESCE(cli_tool_id, 'claude') = ?
290
+ AND COALESCE(instance_id, cli_tool_id, 'claude') = ?
291
+ AND timestamp >= ? AND timestamp <= ?
292
+ ${exports.ACTIVE_FILTER}
293
+ ORDER BY timestamp DESC
294
+ LIMIT ?
295
+ `);
296
+ const rows = stmt.all(query.worktreeId, query.cliToolId, query.instanceId, query.fromMs, query.toMs, query.limit ?? exports.UNKEYED_USER_MESSAGE_LIMIT);
297
+ return rows.map(mapChatMessage);
298
+ }
299
+ /**
300
+ * Claim an unkeyed row for a producer, without touching anything else on it
301
+ * (Issue #2196).
302
+ *
303
+ * A compare-and-set and not an `UPDATE … WHERE id = ?`: the `request_id IS NULL`
304
+ * in the predicate is what makes two pollers racing on the same row safe, since
305
+ * the loser changes nothing and is told so. {@link updateMessageContent} could
306
+ * set the column too, but it also rewrites `content`, and rewriting the
307
+ * operator's own words as a side effect of keying their row is exactly the
308
+ * failure this Issue is trying not to introduce.
309
+ *
310
+ * @returns Whether this call is the one that claimed the row
311
+ */
312
+ function setMessageRequestId(db, messageId, requestId) {
313
+ const stmt = db.prepare(`
314
+ UPDATE chat_messages
315
+ SET request_id = ?
316
+ WHERE id = ? AND request_id IS NULL
317
+ `);
318
+ return stmt.run(requestId, messageId).changes > 0;
319
+ }
232
320
  /**
233
321
  * Fetch the most recent message for a worktree (any role).
234
322
  * Used to determine if waiting for Claude's response.
@@ -431,14 +519,27 @@ function updatePromptData(db, messageId, promptData) {
431
519
  * Mark all pending prompts as answered for a worktree/CLI tool
432
520
  * This is called when we detect Claude has started processing (new response detected)
433
521
  * which means any pending prompts must have been answered via terminal
522
+ *
523
+ * @param onUpdated - Issue #2195. Invoked once per row that was actually
524
+ * stamped, with the row as it now reads. This sweep is the one prompt-status
525
+ * writer that produced no realtime frame, so a prompt card stayed "pending"
526
+ * in every open pane until the next history poll — up to 15s once #2195
527
+ * demoted that poll to a fallback. The caller supplies the broadcast rather
528
+ * than this module reaching for `ws-server`: the DB layer has no business
529
+ * importing the socket, and the two sweep callers that are *not* a poller
530
+ * (the worktree list/detail routes) have no room to broadcast into anyway.
531
+ * Throwing from the callback is the caller's problem; it is not caught here.
434
532
  */
435
- function markPendingPromptsAsAnswered(db, worktreeId, cliToolId, instanceId) {
533
+ function markPendingPromptsAsAnswered(db, worktreeId, cliToolId, instanceId, onUpdated) {
436
534
  // Find all pending prompt messages for this worktree/CLI tool.
437
535
  // Issue #868: When instanceId is provided, scope to that instance only;
438
536
  // otherwise fall back to the legacy cli_tool_id scoping.
439
537
  const resolvedInstanceId = instanceId ?? cliToolId;
538
+ // Issue #2195: the full column set, not just (id, prompt_data) — `onUpdated`
539
+ // publishes a `ChatMessage`, and re-reading each row afterwards would be a
540
+ // second query per prompt for data this statement already has to visit.
440
541
  const selectStmt = db.prepare(`
441
- SELECT id, prompt_data
542
+ SELECT id, worktree_id, role, content, summary, timestamp, log_file_name, request_id, message_type, prompt_data, cli_tool_id, instance_id, archived
442
543
  FROM chat_messages
443
544
  WHERE worktree_id = ?
444
545
  AND instance_id = ?
@@ -458,9 +559,12 @@ function markPendingPromptsAsAnswered(db, worktreeId, cliToolId, instanceId) {
458
559
  WHERE id = ?
459
560
  `);
460
561
  let updatedCount = 0;
562
+ const updated = [];
461
563
  for (const row of rows) {
462
564
  try {
463
- const promptData = JSON.parse(row.prompt_data);
565
+ const promptData = JSON.parse(row.prompt_data ?? 'null');
566
+ if (!promptData || typeof promptData !== 'object')
567
+ continue;
464
568
  promptData.status = 'answered';
465
569
  promptData.answer = '(answered via terminal)';
466
570
  promptData.answeredAt = new Date().toISOString();
@@ -468,13 +572,22 @@ function markPendingPromptsAsAnswered(db, worktreeId, cliToolId, instanceId) {
468
572
  // prompts nothing else claimed, so all that is known is that the agent
469
573
  // moved on — i.e. someone acted in the terminal.
470
574
  promptData.answeredBy = 'terminal';
471
- updateStmt.run(JSON.stringify(promptData), row.id);
575
+ const serialized = JSON.stringify(promptData);
576
+ updateStmt.run(serialized, row.id);
472
577
  updatedCount++;
578
+ if (onUpdated) {
579
+ updated.push(mapChatMessage({ ...row, prompt_data: serialized }));
580
+ }
473
581
  }
474
582
  catch {
475
583
  // Skip if prompt_data is invalid JSON
476
584
  }
477
585
  }
586
+ // Published after every write lands, so a listener that reacts by reading the
587
+ // table back cannot observe a half-swept instance.
588
+ for (const message of updated) {
589
+ onUpdated?.(message);
590
+ }
478
591
  return updatedCount;
479
592
  }
480
593
  /**
@@ -72,8 +72,9 @@ exports.SELECTION_LIST_REASONS = new Set([
72
72
  * one: branch A of the opencode block answers `opencode_processing_indicator`
73
73
  * for the footer that reads `esc interrupt`, which is opencode's ONLY signal
74
74
  * while it is between the submitted prompt and the first transcript row. A
75
- * scraper-only session (no hooks) therefore showed no thinking indicator in
76
- * `MessageList` for exactly the stretch where one is wanted.
75
+ * scraper-only session (no hooks) therefore showed no thinking indicator on the
76
+ * chat surface for exactly the stretch where one is wanted. The consumer is
77
+ * `ChatSurface`, which reads this through `current-output`'s `thinking` flag.
77
78
  *
78
79
  * `DEFAULT` is deliberately absent: it is the "output changed recently" fallback
79
80
  * and says nothing about the agent having announced itself, so promoting it
@@ -8,6 +8,9 @@
8
8
  *
9
9
  * Issue #135: DB path resolution fix
10
10
  * Uses getDefaultDbPath() from db-path-resolver.ts for consistent DB path handling
11
+ *
12
+ * Issue #2132: startup self-check for ".env exists but nothing was loaded"
13
+ * See {@link runDotenvSelfCheck}.
11
14
  */
12
15
  var __importDefault = (this && this.__importDefault) || function (mod) {
13
16
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -17,12 +20,17 @@ exports.ENV_MAPPING = void 0;
17
20
  exports.resetWarnedKeys = resetWarnedKeys;
18
21
  exports.getEnvWithFallback = getEnvWithFallback;
19
22
  exports.getEnvByKey = getEnvByKey;
23
+ exports.parseDotenvKeys = parseDotenvKeys;
24
+ exports.inspectDotenvLoad = inspectDotenvLoad;
25
+ exports.formatDotenvReportLines = formatDotenvReportLines;
26
+ exports.runDotenvSelfCheck = runDotenvSelfCheck;
20
27
  exports.resetDatabasePathWarning = resetDatabasePathWarning;
21
28
  exports.getDatabasePathWithDeprecationWarning = getDatabasePathWithDeprecationWarning;
22
29
  exports.getLogConfig = getLogConfig;
23
30
  exports.getServerPort = getServerPort;
24
31
  exports.getEnv = getEnv;
25
32
  exports.validateEnv = validateEnv;
33
+ const fs_1 = __importDefault(require("fs"));
26
34
  const path_1 = __importDefault(require("path"));
27
35
  const db_path_resolver_1 = require("./db/db-path-resolver");
28
36
  // ============================================================
@@ -84,6 +92,120 @@ function getEnvWithFallback(newKey, oldKey) {
84
92
  function getEnvByKey(key) {
85
93
  return getEnvWithFallback(key, exports.ENV_MAPPING[key]);
86
94
  }
95
+ /** `KEY`, `export KEY`, ` KEY ` — the assignment forms a `.env` line can take. */
96
+ const DOTENV_ASSIGNMENT = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
97
+ /**
98
+ * The variable names a `.env` file declares, in file order, without duplicates.
99
+ *
100
+ * Values are never returned. `CM_VAPID_PRIVATE_KEY` lives in this file, and the
101
+ * only reason to parse it here is to count how many of its NAMES arrived.
102
+ */
103
+ function parseDotenvKeys(contents) {
104
+ const keys = [];
105
+ const seen = new Set();
106
+ for (const line of contents.split(/\r?\n/)) {
107
+ const match = DOTENV_ASSIGNMENT.exec(line);
108
+ if (!match)
109
+ continue;
110
+ const key = match[1];
111
+ if (seen.has(key))
112
+ continue;
113
+ seen.add(key);
114
+ keys.push(key);
115
+ }
116
+ return keys;
117
+ }
118
+ /**
119
+ * Compare the `.env` on disk against the environment this process actually got.
120
+ *
121
+ * @returns `null` when there is nothing to compare — no `.env`, an unreadable
122
+ * one, or one that declares no variables. None of those is a fault worth a
123
+ * line of startup output.
124
+ */
125
+ function inspectDotenvLoad(options = {}) {
126
+ const { cwd = process.cwd(), env = process.env } = options;
127
+ const envPath = path_1.default.join(cwd, '.env');
128
+ let contents;
129
+ try {
130
+ if (!fs_1.default.existsSync(envPath))
131
+ return null;
132
+ contents = fs_1.default.readFileSync(envPath, 'utf8');
133
+ }
134
+ catch {
135
+ // Unreadable is a permissions question, not a loading question.
136
+ return null;
137
+ }
138
+ const declaredKeys = parseDotenvKeys(contents);
139
+ if (declaredKeys.length === 0)
140
+ return null;
141
+ const presentKeys = declaredKeys.filter((key) => env[key] !== undefined);
142
+ return {
143
+ envPath,
144
+ declaredKeys,
145
+ presentKeys,
146
+ loadFailed: presentKeys.length === 0,
147
+ };
148
+ }
149
+ /** How many key names the report is willing to print before it says "and N more". */
150
+ const DOTENV_REPORT_KEY_LIMIT = 8;
151
+ /**
152
+ * The lines {@link runDotenvSelfCheck} prints — empty when the load worked.
153
+ *
154
+ * Exported so the wording is pinned by a test rather than by a screenshot.
155
+ */
156
+ function formatDotenvReportLines(inspection) {
157
+ if (!inspection.loadFailed)
158
+ return [];
159
+ const shown = inspection.declaredKeys.slice(0, DOTENV_REPORT_KEY_LIMIT);
160
+ const omitted = inspection.declaredKeys.length - shown.length;
161
+ const names = omitted > 0 ? `${shown.join(', ')}, and ${omitted} more` : shown.join(', ');
162
+ return [
163
+ `[env] ${inspection.envPath} declares ${inspection.declaredKeys.length} variable(s) `
164
+ + 'and NOT ONE of them is set in this process: '
165
+ + `${names}.`,
166
+ '[env] The server is running on defaults. Web Push, the database path and the '
167
+ + 'worktree root are all configured through those variables, so this is very '
168
+ + 'unlikely to be what you wanted.',
169
+ '[env] Most likely cause (Issue #2132): the server was started by hand after '
170
+ + '`source scripts/load-env.sh` from a shell that is not bash. That script now '
171
+ + 'refuses instead of exporting nothing, so re-run it and read what it says.',
172
+ '[env] Supported restart, no rebuild: ./scripts/restart-nobuild.sh '
173
+ + '(or ./scripts/start.sh --daemon)',
174
+ ];
175
+ }
176
+ /**
177
+ * Report, in one place at startup, that `.env` exists and none of it arrived.
178
+ *
179
+ * Same contract as `runVapidSelfCheck` in `lib/push/vapid.ts`, deliberately:
180
+ * fail-open, never throws, never blocks `listen`, and a healthy install prints
181
+ * NOTHING — which is what makes the presence of a line meaningful.
182
+ *
183
+ * It exists because the failure it names is invisible from inside the process.
184
+ * Every consumer of these variables has a defensible default, so a server that
185
+ * received none of them starts, listens, and answers requests; what it does not
186
+ * do is send a single push notification, and it may open a different database
187
+ * than the one the operator believes they are looking at. During the Epic #2002
188
+ * device UAT the only signal was the VAPID warning, and reading it as "push is
189
+ * broken" rather than "the environment is empty" cost two UAT rounds.
190
+ *
191
+ * @returns The inspection, or `null` when there was nothing to check.
192
+ */
193
+ function runDotenvSelfCheck(options = {}) {
194
+ const { warn = (message) => console.warn(message) } = options;
195
+ try {
196
+ const inspection = inspectDotenvLoad(options);
197
+ if (!inspection)
198
+ return null;
199
+ for (const line of formatDotenvReportLines(inspection)) {
200
+ warn(line);
201
+ }
202
+ return inspection;
203
+ }
204
+ catch {
205
+ // A diagnostic must never be the reason a server fails to start.
206
+ return null;
207
+ }
208
+ }
87
209
  // ============================================================
88
210
  // [Issue #135] DATABASE_PATH Deprecation Support
89
211
  // ============================================================
@@ -16,6 +16,8 @@ exports.scanMultipleRepositories = scanMultipleRepositories;
16
16
  exports.deriveIdIgnoringOwnHistory = deriveIdIgnoringOwnHistory;
17
17
  exports.syncWorktreesToDB = syncWorktreesToDB;
18
18
  exports.repositoryExistsOnDisk = repositoryExistsOnDisk;
19
+ exports.directoryIsConfirmedAbsent = directoryIsConfirmedAbsent;
20
+ exports.reclaimGhostRepositories = reclaimGhostRepositories;
19
21
  exports.pruneStaleRepositoryWorktrees = pruneStaleRepositoryWorktrees;
20
22
  const child_process_1 = require("child_process");
21
23
  const util_1 = require("util");
@@ -179,6 +181,27 @@ function getRepositoryPaths() {
179
181
  */
180
182
  async function scanWorktrees(rootDir) {
181
183
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
184
+ // Issue #2165: a repository whose directory has been removed used to reach
185
+ // `execAsync` with a `cwd` that no longer exists, and Node reports that as
186
+ // `spawn /bin/sh ENOENT` — an error about the *shell*, not about the missing
187
+ // directory. It is neither `not a git repository` nor exit 128, so the catch
188
+ // below re-threw it and `scanMultipleRepositories` logged it at ERROR. Two
189
+ // costs: a wasted child process per repository per scan, and a permanent
190
+ // ERROR line whose text sends the reader after `/bin/sh` and `PATH` (that
191
+ // misdiagnosis actually happened — see the Issue).
192
+ //
193
+ // Deliberately {@link directoryIsConfirmedAbsent} rather than
194
+ // `fs.existsSync`: only a positively-confirmed absence is allowed to skip the
195
+ // scan. An unreadable or unreachable path (EACCES, EIO, a hung network mount)
196
+ // still goes to git, still fails, and is still reported at ERROR — that IS a
197
+ // real failure and must not be silently downgraded to "the directory is gone".
198
+ //
199
+ // A directory that exists but is no longer a git repository is untouched by
200
+ // this guard: it keeps taking the git exit-128 path below and returns [].
201
+ if (directoryIsConfirmedAbsent(rootDir)) {
202
+ logger.warn('repository:scan-skipped-missing-dir', { repoPath: rootDir });
203
+ return [];
204
+ }
182
205
  try {
183
206
  const { stdout } = await execAsync('git worktree list', {
184
207
  cwd: rootDir,
@@ -479,6 +502,137 @@ function repositoryExistsOnDisk(repoPath) {
479
502
  return true;
480
503
  }
481
504
  }
505
+ /**
506
+ * Whether a path is **positively confirmed** not to exist.
507
+ *
508
+ * Issue #2165. `fs.existsSync()` cannot answer this: it collapses "the entry is
509
+ * not there" and "I could not find out" into the same `false`. It is
510
+ * `accessSync(F_OK)` underneath, so an unreadable parent directory (EACCES), a
511
+ * hung or disconnected network mount (EIO / ETIMEDOUT / ESTALE / EHOSTDOWN) and
512
+ * a genuinely deleted directory are indistinguishable through it. That
513
+ * distinction is the whole safety question for {@link reclaimGhostRepositories}:
514
+ * a repository on an unreachable volume must never be treated as gone.
515
+ *
516
+ * `lstatSync` keeps the errno, so the answer can be narrowed to the two codes
517
+ * that mean the kernel walked the path successfully and the entry was not
518
+ * there:
519
+ *
520
+ * - `ENOENT` — a component of the path does not exist;
521
+ * - `ENOTDIR` — a component that must be a directory is a file, so no such
522
+ * entry can exist under it either.
523
+ *
524
+ * Every other outcome — the path resolved, or the lookup failed for any other
525
+ * reason — answers `false`, i.e. "not confirmed absent, leave it alone".
526
+ * `lstat` rather than `stat` so a dangling symlink is reported as present: the
527
+ * link is a real entry that the user still has to remove.
528
+ *
529
+ * @param repoPath - Absolute path to test
530
+ * @returns `true` only when the path is confirmed to be absent
531
+ */
532
+ function directoryIsConfirmedAbsent(repoPath) {
533
+ if (!repoPath)
534
+ return false;
535
+ try {
536
+ fs_1.default.lstatSync(repoPath);
537
+ return false;
538
+ }
539
+ catch (error) {
540
+ const code = error.code;
541
+ return code === 'ENOENT' || code === 'ENOTDIR';
542
+ }
543
+ }
544
+ /**
545
+ * Take ghost `repositories` rows out of the scan set (Issue #2165).
546
+ *
547
+ * A row whose directory has been deleted stays `enabled = 1` forever: nothing
548
+ * removes it, so every server start and every sync re-derives the scan set from
549
+ * it, spawns a shell into a `cwd` that does not exist and logs an ERROR. Rows
550
+ * registered under `/tmp` were still doing this seven months after the
551
+ * directory they name was collected by the OS.
552
+ *
553
+ * {@link pruneStaleRepositoryWorktrees} cannot reach them. It deletes *worktree*
554
+ * rows, and it iterates {@link getRepositories}, which is a `GROUP BY` over the
555
+ * `worktrees` table — a repository with no worktree rows is not in its result
556
+ * at all, and its `ids.length === 0` early-continue would skip it even if it
557
+ * were. This function is the missing half: it works the `repositories` table.
558
+ *
559
+ * ## What it does — demote, not delete
560
+ *
561
+ * The row is set to `enabled = 0`, exactly as the Repositories screen's Scan
562
+ * toggle does (#1658). It is NOT deleted. `enabled` is the flag that decides
563
+ * what gets scanned, so demotion is sufficient — the row leaves `allPaths` at
564
+ * the next startup and sync, and the ERROR stops for good. Choosing it over
565
+ * `deleteRepository()` buys three things:
566
+ *
567
+ * 1. **Reversibility.** No filesystem test can prove a directory is gone
568
+ * *forever* — an unmounted volume looks exactly like a deleted one from
569
+ * userspace. A demoted row keeps its id, display name, `visible` flag and
570
+ * clone URL, is listed on the Repositories screen with a Disabled badge, and
571
+ * is one click from coming back. A wrong delete is unrecoverable.
572
+ * 2. **Agreement with #1666.** That Issue settled that exclusion is where the
573
+ * app *stops*, not where it deletes; startup used to purge excluded
574
+ * repositories and that was the bug. Reclaiming by deletion would re-open
575
+ * the same argument from the other end.
576
+ * 3. **No dangling references.** `clone_jobs.repository_id` points at this row.
577
+ *
578
+ * ## The line — what is NOT reclaimed
579
+ *
580
+ * Every guard fails toward keeping the row enabled:
581
+ *
582
+ * - **Already disabled** — nothing to fix; it is out of the scan set already,
583
+ * and touching it would rewrite state the user owns.
584
+ * - **Still listed in `WORKTREE_REPOS`** — the environment is a live
585
+ * declaration that the operator wants this path scanned. Same reasoning as
586
+ * migration v43's guard 2 (#1339): never overrule a path the env still asks
587
+ * for. Such a path is re-registered on every boot anyway.
588
+ * - **Not confirmed absent** — see {@link directoryIsConfirmedAbsent}. This is
589
+ * the "temporarily invisible" line: a repository under an unreachable network
590
+ * mount answers EIO / ETIMEDOUT / ESTALE / EACCES, not ENOENT, and is kept.
591
+ * - **Owns worktree rows** — the condition the Issue names, and the one that
592
+ * makes this provably lossless. Chat history, memos, todos, timers,
593
+ * schedules, tasks and verification runs all hang off `worktrees`, so a
594
+ * repository with zero worktree rows has no history to lose by definition.
595
+ * It is also good evidence that the directory was never successfully scanned:
596
+ * a scan of a present repository always yields at least its main worktree.
597
+ *
598
+ * @param db - Database instance
599
+ * @param envRepositoryPaths - Paths the environment still declares
600
+ * (`getRepositoryPaths()`); rows at these paths are never demoted
601
+ * @returns The rows that were demoted, in `getAllRepositories` order
602
+ */
603
+ function reclaimGhostRepositories(db, envRepositoryPaths = []) {
604
+ const envPaths = new Set(envRepositoryPaths.filter(p => !!p).map(p => path_1.default.resolve(p)));
605
+ const reclaimed = [];
606
+ for (const repo of (0, db_1.getAllRepositories)(db)) {
607
+ if (!repo.path)
608
+ continue;
609
+ if (!repo.enabled)
610
+ continue;
611
+ if (envPaths.has(repo.path))
612
+ continue;
613
+ if (!directoryIsConfirmedAbsent(repo.path))
614
+ continue;
615
+ if ((0, db_1.countWorktreesByRepositoryPath)(db, repo.path) > 0)
616
+ continue;
617
+ try {
618
+ (0, db_1.setRepositoryEnabled)(db, repo.id, false);
619
+ }
620
+ catch (error) {
621
+ // SEC-SF-004's disabled-row ceiling is the only expected failure. It
622
+ // guards against unbounded *growth* of the table, which this pass cannot
623
+ // cause — it creates no rows — so a refusal here just means one ghost
624
+ // keeps logging. Report it and move on rather than aborting startup.
625
+ logger.warn('repository:ghost-row-reclaim-failed', {
626
+ repoPath: repo.path,
627
+ error: error instanceof Error ? error.message : String(error),
628
+ });
629
+ continue;
630
+ }
631
+ reclaimed.push({ id: repo.id, path: repo.path });
632
+ logger.info('repository:ghost-row-reclaimed', { repoPath: repo.path });
633
+ }
634
+ return reclaimed;
635
+ }
482
636
  /**
483
637
  * Prune DB worktree rows for repositories that have vanished from disk.
484
638
  *
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /**
3
+ * Reading the end of an agent's own transcript file (Issue #2197).
4
+ *
5
+ * The second half of the pull-mode reader that is the same whatever the agent
6
+ * is, alongside `./user-turn-recorder`: every one of them keeps a file that
7
+ * grows for the life of a session, and every one of them only ever needs its
8
+ * newest turn.
9
+ *
10
+ * The shape is `lib/hooks/sources/claude/history`'s, which #2121 wrote inline
11
+ * because it was the only reader. It is here rather than there because #2197
12
+ * added the second and #2198 adds the third, and three private copies of "read
13
+ * the last 4 MiB and drop the partial first line" is how the bound and the
14
+ * partial-line rule quietly stop agreeing with each other.
15
+ *
16
+ * @module lib/history/transcript-tail
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.TRANSCRIPT_TAIL_BYTES = void 0;
20
+ exports.readTranscriptTail = readTranscriptTail;
21
+ const promises_1 = require("fs/promises");
22
+ const logger_1 = require("../../lib/logger");
23
+ const logger = (0, logger_1.createLogger)('lib/history/transcript-tail');
24
+ /**
25
+ * How much of a transcript's tail is read.
26
+ *
27
+ * These files grow for the life of a session and a long one is tens of
28
+ * megabytes — the largest claude transcript on this machine was 23 MB on
29
+ * 2026-08-31, and the largest codex rollout was **273 MB** on 2026-09-01 — so
30
+ * reading one whole on every finished turn would be the most expensive thing the
31
+ * poller does. Only the newest turn is ever written, so only the newest turn has
32
+ * to be in the window.
33
+ *
34
+ * 4 MiB is roughly two orders of magnitude above the measured size of a single
35
+ * turn and still small enough to read and parse in one tick. A turn that
36
+ * genuinely does not fit produces a turn with no prompt in it, which each reader
37
+ * detects and reports rather than writing as a headless reply.
38
+ */
39
+ exports.TRANSCRIPT_TAIL_BYTES = 4 * 1024 * 1024;
40
+ /**
41
+ * The last {@link TRANSCRIPT_TAIL_BYTES} of a file, as UTF-8.
42
+ *
43
+ * Read at an offset rather than whole, and the first line of a windowed read is
44
+ * dropped: starting mid-line would hand the caller's parser a fragment that it
45
+ * would count as malformed anyway, and dropping it deliberately keeps that
46
+ * counter meaning "the writer was mid-append", which is the thing worth seeing.
47
+ *
48
+ * Never throws.
49
+ *
50
+ * @param path - An absolute path the caller has already validated
51
+ * @returns The text, or null when the file could not be read
52
+ */
53
+ async function readTranscriptTail(path) {
54
+ let handle;
55
+ try {
56
+ handle = await (0, promises_1.open)(path, 'r');
57
+ const { size } = await handle.stat();
58
+ const offset = Math.max(0, size - exports.TRANSCRIPT_TAIL_BYTES);
59
+ const length = size - offset;
60
+ if (length <= 0)
61
+ return '';
62
+ const buffer = Buffer.alloc(length);
63
+ const { bytesRead } = await handle.read(buffer, 0, length, offset);
64
+ const text = buffer.subarray(0, bytesRead).toString('utf8');
65
+ if (offset === 0)
66
+ return text;
67
+ const firstBreak = text.indexOf('\n');
68
+ return firstBreak === -1 ? '' : text.slice(firstBreak + 1);
69
+ }
70
+ catch (error) {
71
+ logger.warn('transcript-tail-read-failed', {
72
+ path,
73
+ error: error instanceof Error ? error.message : String(error),
74
+ });
75
+ return null;
76
+ }
77
+ finally {
78
+ await handle?.close().catch(() => { });
79
+ }
80
+ }