commandmate 0.10.3 → 0.10.4

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 (383) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +135 -135
  3. package/.next/app-path-routes-manifest.json +28 -28
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/prerender-manifest.json +15 -15
  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/app/update/route.js +3 -3
  9. package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
  10. package/.next/server/app/api/app/update-check/route.js +1 -1
  11. package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/assistant/conversation/route.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 +1 -1
  16. package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
  17. package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
  18. package/.next/server/app/api/assistant/messages/route.js +1 -1
  19. package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
  20. package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/assistant/session/route.js +1 -1
  22. package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
  23. package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/assistant/start/route.js +1 -1
  25. package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
  26. package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/assistant/terminal/route.js +3 -2
  28. package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
  29. package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/assistant/tools/route.js +1 -1
  31. package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
  32. package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/daily-summary/route.js +1 -1
  37. package/.next/server/app/api/daily-summary/route.js.nft.json +1 -1
  38. package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/api/daily-summary/status/route.js +1 -1
  40. package/.next/server/app/api/daily-summary/status/route.js.nft.json +1 -1
  41. package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
  43. package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
  45. package/.next/server/app/api/hooks/claude-done/route.js +1 -1
  46. package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
  47. package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
  49. package/.next/server/app/api/push/subscriptions/route.js +1 -1
  50. package/.next/server/app/api/push/subscriptions/route.js.nft.json +1 -1
  51. package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/repositories/[id]/route.js +1 -47
  54. package/.next/server/app/api/repositories/[id]/route.js.nft.json +1 -1
  55. package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js +1 -1
  57. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js.nft.json +1 -1
  58. package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
  60. package/.next/server/app/api/repositories/[id]/todos/route.js.nft.json +1 -1
  61. package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
  63. package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
  64. package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/repositories/clone/route.js +1 -1
  66. package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
  67. package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/repositories/excluded/route.js +1 -47
  69. package/.next/server/app/api/repositories/excluded/route.js.nft.json +1 -1
  70. package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/repositories/restore/route.js +1 -1
  72. package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
  73. package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/repositories/route.js +1 -1
  75. package/.next/server/app/api/repositories/route.js.nft.json +1 -1
  76. package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/repositories/scan/route.js +1 -1
  78. package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
  79. package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/repositories/sync/route.js +1 -1
  81. package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
  82. package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
  84. package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/todos/route.js +1 -1
  88. package/.next/server/app/api/todos/route.js.nft.json +1 -1
  89. package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
  90. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
  91. package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
  92. package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
  94. package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
  95. package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
  96. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
  97. package/.next/server/app/api/worktrees/[id]/cli-tool/route.js.nft.json +1 -1
  98. package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
  99. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +1 -1
  100. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +1 -1
  101. package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
  103. package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
  104. package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
  106. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js.nft.json +1 -1
  107. package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +2 -2
  109. package/.next/server/app/api/worktrees/[id]/execution-logs/route.js.nft.json +1 -1
  110. package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
  111. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
  112. package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +1 -1
  113. package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
  114. package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js +1 -1
  115. package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js.nft.json +1 -1
  116. package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
  117. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js +1 -1
  118. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js.nft.json +1 -1
  119. package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
  120. package/.next/server/app/api/worktrees/[id]/git/branches/route.js +1 -1
  121. package/.next/server/app/api/worktrees/[id]/git/branches/route.js.nft.json +1 -1
  122. package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
  123. package/.next/server/app/api/worktrees/[id]/git/checkout/route.js +1 -1
  124. package/.next/server/app/api/worktrees/[id]/git/checkout/route.js.nft.json +1 -1
  125. package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
  126. package/.next/server/app/api/worktrees/[id]/git/commit/route.js +1 -1
  127. package/.next/server/app/api/worktrees/[id]/git/commit/route.js.nft.json +1 -1
  128. package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/worktrees/[id]/git/diff/route.js +1 -1
  130. package/.next/server/app/api/worktrees/[id]/git/diff/route.js.nft.json +1 -1
  131. package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
  132. package/.next/server/app/api/worktrees/[id]/git/fetch/route.js +1 -1
  133. package/.next/server/app/api/worktrees/[id]/git/fetch/route.js.nft.json +1 -1
  134. package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/worktrees/[id]/git/log/route.js +1 -1
  136. package/.next/server/app/api/worktrees/[id]/git/log/route.js.nft.json +1 -1
  137. package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
  138. package/.next/server/app/api/worktrees/[id]/git/pull/route.js +1 -1
  139. package/.next/server/app/api/worktrees/[id]/git/pull/route.js.nft.json +1 -1
  140. package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
  141. package/.next/server/app/api/worktrees/[id]/git/push/route.js +1 -1
  142. package/.next/server/app/api/worktrees/[id]/git/push/route.js.nft.json +1 -1
  143. package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
  144. package/.next/server/app/api/worktrees/[id]/git/reset/route.js +1 -1
  145. package/.next/server/app/api/worktrees/[id]/git/reset/route.js.nft.json +1 -1
  146. package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
  147. package/.next/server/app/api/worktrees/[id]/git/revert/route.js +1 -1
  148. package/.next/server/app/api/worktrees/[id]/git/revert/route.js.nft.json +1 -1
  149. package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js +1 -1
  151. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js.nft.json +1 -1
  152. package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
  153. package/.next/server/app/api/worktrees/[id]/git/stage/route.js +1 -1
  154. package/.next/server/app/api/worktrees/[id]/git/stage/route.js.nft.json +1 -1
  155. package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/worktrees/[id]/git/staged/route.js +1 -1
  157. package/.next/server/app/api/worktrees/[id]/git/staged/route.js.nft.json +1 -1
  158. package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
  159. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js +1 -1
  160. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js.nft.json +1 -1
  161. package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
  162. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js +1 -1
  163. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js.nft.json +1 -1
  164. package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js +1 -1
  166. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js.nft.json +1 -1
  167. package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js +1 -1
  169. package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js.nft.json +1 -1
  170. package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
  171. package/.next/server/app/api/worktrees/[id]/git/stash/route.js +1 -1
  172. package/.next/server/app/api/worktrees/[id]/git/stash/route.js.nft.json +1 -1
  173. package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/worktrees/[id]/git/status/route.js +1 -1
  175. package/.next/server/app/api/worktrees/[id]/git/status/route.js.nft.json +1 -1
  176. package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
  177. package/.next/server/app/api/worktrees/[id]/git/unstage/route.js +1 -1
  178. package/.next/server/app/api/worktrees/[id]/git/unstage/route.js.nft.json +1 -1
  179. package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js +1 -1
  181. package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js.nft.json +1 -1
  182. package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
  183. package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
  184. package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
  185. package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
  186. package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
  187. package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
  188. package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
  189. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js +1 -1
  190. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +1 -1
  191. package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
  192. package/.next/server/app/api/worktrees/[id]/logs/route.js +1 -1
  193. package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +1 -1
  194. package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
  195. package/.next/server/app/api/worktrees/[id]/marp-render/route.js +2 -2
  196. package/.next/server/app/api/worktrees/[id]/marp-render/route.js.nft.json +1 -1
  197. package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
  198. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -1
  199. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js.nft.json +1 -1
  200. package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
  201. package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -1
  202. package/.next/server/app/api/worktrees/[id]/memos/route.js.nft.json +1 -1
  203. package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
  204. package/.next/server/app/api/worktrees/[id]/messages/route.js +1 -1
  205. package/.next/server/app/api/worktrees/[id]/messages/route.js.nft.json +1 -1
  206. package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
  207. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
  208. package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
  209. package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
  210. package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
  211. package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
  212. package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
  213. package/.next/server/app/api/worktrees/[id]/route.js +1 -1
  214. package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
  215. package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
  216. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +1 -1
  217. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js.nft.json +1 -1
  218. package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
  219. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +1 -1
  220. package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
  221. package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
  222. package/.next/server/app/api/worktrees/[id]/schedules/route.js +2 -2
  223. package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +1 -1
  224. package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
  225. package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
  226. package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +1 -1
  227. package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
  228. package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
  229. package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
  230. package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
  231. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
  232. package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +1 -1
  233. package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
  234. package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
  235. package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
  236. package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
  237. package/.next/server/app/api/worktrees/[id]/start-polling/route.js +1 -1
  238. package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
  239. package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
  240. package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
  241. package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
  242. package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
  243. package/.next/server/app/api/worktrees/[id]/timers/history/route.js +1 -1
  244. package/.next/server/app/api/worktrees/[id]/timers/history/route.js.nft.json +1 -1
  245. package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
  246. package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
  247. package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
  248. package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
  249. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js +1 -1
  250. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js.nft.json +1 -1
  251. package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
  252. package/.next/server/app/api/worktrees/[id]/todos/route.js +1 -1
  253. package/.next/server/app/api/worktrees/[id]/todos/route.js.nft.json +1 -1
  254. package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
  255. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js +1 -1
  256. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +1 -1
  257. package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
  258. package/.next/server/app/api/worktrees/[id]/tree/route.js +1 -1
  259. package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +1 -1
  260. package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
  261. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js +1 -1
  262. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +1 -1
  263. package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
  264. package/.next/server/app/api/worktrees/[id]/viewed/route.js +1 -1
  265. package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +1 -1
  266. package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
  267. package/.next/server/app/api/worktrees/route.js +1 -1
  268. package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
  269. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  270. package/.next/server/app/chat/page.js +1 -1
  271. package/.next/server/app/chat/page.js.nft.json +1 -1
  272. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  273. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  274. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  275. package/.next/server/app/more/page.js +2 -2
  276. package/.next/server/app/more/page.js.nft.json +1 -1
  277. package/.next/server/app/more/page_client-reference-manifest.js +1 -1
  278. package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
  279. package/.next/server/app/page.js +1 -1
  280. package/.next/server/app/page.js.nft.json +1 -1
  281. package/.next/server/app/page_client-reference-manifest.js +1 -1
  282. package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
  283. package/.next/server/app/repositories/page.js +1 -1
  284. package/.next/server/app/repositories/page.js.nft.json +1 -1
  285. package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
  286. package/.next/server/app/review/page.js +1 -1
  287. package/.next/server/app/review/page.js.nft.json +1 -1
  288. package/.next/server/app/review/page_client-reference-manifest.js +1 -1
  289. package/.next/server/app/sessions/page.js +1 -1
  290. package/.next/server/app/sessions/page.js.nft.json +1 -1
  291. package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  292. package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
  293. package/.next/server/app/worktrees/[id]/page.js +8 -8
  294. package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
  295. package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
  296. package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
  297. package/.next/server/app-paths-manifest.json +28 -28
  298. package/.next/server/chunks/1068.js +1 -1
  299. package/.next/server/chunks/1117.js +1 -0
  300. package/.next/server/chunks/233.js +1 -1
  301. package/.next/server/chunks/2404.js +1 -1
  302. package/.next/server/chunks/3270.js +1 -1
  303. package/.next/server/chunks/3480.js +2 -2
  304. package/.next/server/chunks/3543.js +1 -1
  305. package/.next/server/chunks/3945.js +1 -1
  306. package/.next/server/chunks/406.js +47 -0
  307. package/.next/server/chunks/4444.js +1 -1
  308. package/.next/server/chunks/5381.js +1 -47
  309. package/.next/server/chunks/5959.js +2 -2
  310. package/.next/server/chunks/646.js +33 -0
  311. package/.next/server/chunks/8681.js +1 -0
  312. package/.next/server/chunks/8807.js +305 -300
  313. package/.next/server/chunks/9355.js +1 -1
  314. package/.next/server/chunks/9687.js +1 -1
  315. package/.next/server/middleware-manifest.json +5 -5
  316. package/.next/server/pages/500.html +1 -1
  317. package/.next/server/pages-manifest.json +1 -1
  318. package/.next/server/server-reference-manifest.json +1 -1
  319. package/.next/static/chunks/4560-2bf9cb6504cc4425.js +1 -0
  320. package/.next/static/chunks/7347-a013a163a75030ec.js +1 -0
  321. package/.next/static/chunks/app/chat/page-5d20240f98c07cee.js +1 -0
  322. package/.next/static/chunks/app/layout-fe5857360dfba2b9.js +1 -0
  323. package/.next/static/chunks/app/more/page-af1d2af13ea901d2.js +1 -0
  324. package/.next/static/chunks/app/page-3bbe737ec910d1fb.js +1 -0
  325. package/.next/static/chunks/app/repositories/page-ace9134ac165a6de.js +1 -0
  326. package/.next/static/chunks/app/review/page-331b80f4f58582bc.js +1 -0
  327. package/.next/static/chunks/app/sessions/page-d694149a7e8649b6.js +1 -0
  328. package/.next/static/chunks/app/worktrees/[id]/page-932a52f8d11971f7.js +1 -0
  329. package/.next/static/css/d7e2e8d1b8d69d36.css +1 -0
  330. package/.next/trace +10 -10
  331. package/dist/cli/commands/quickstart.d.ts.map +1 -1
  332. package/dist/cli/commands/quickstart.js +27 -0
  333. package/dist/cli/commands/status.d.ts.map +1 -1
  334. package/dist/cli/commands/status.js +19 -0
  335. package/dist/cli/types/index.d.ts +6 -0
  336. package/dist/cli/types/index.d.ts.map +1 -1
  337. package/dist/cli/utils/agent-instances.d.ts +1 -1
  338. package/dist/cli/utils/agent-instances.d.ts.map +1 -1
  339. package/dist/cli/utils/agent-instances.js +8 -1
  340. package/dist/cli/utils/api-client.d.ts +36 -0
  341. package/dist/cli/utils/api-client.d.ts.map +1 -1
  342. package/dist/cli/utils/api-client.js +82 -0
  343. package/dist/cli/utils/daemon.d.ts.map +1 -1
  344. package/dist/cli/utils/daemon.js +44 -9
  345. package/dist/cli/utils/package-info.d.ts +17 -0
  346. package/dist/cli/utils/package-info.d.ts.map +1 -0
  347. package/dist/cli/utils/package-info.js +31 -0
  348. package/dist/cli/utils/pid-manager.d.ts +65 -9
  349. package/dist/cli/utils/pid-manager.d.ts.map +1 -1
  350. package/dist/cli/utils/pid-manager.js +81 -21
  351. package/dist/cli/utils/process-inspector.d.ts +27 -0
  352. package/dist/cli/utils/process-inspector.d.ts.map +1 -0
  353. package/dist/cli/utils/process-inspector.js +37 -0
  354. package/dist/server/src/config/github-links.js +22 -0
  355. package/dist/server/src/lib/db/db-instance.js +22 -3
  356. package/dist/server/src/lib/db/db-repository.js +107 -19
  357. package/dist/server/src/lib/db/db.js +3 -2
  358. package/dist/server/src/lib/db/memo-db.js +32 -1
  359. package/dist/server/src/lib/db/migrations/index.js +2 -0
  360. package/dist/server/src/lib/db/migrations/runner.js +11 -1
  361. package/dist/server/src/lib/db/migrations/v43-remove-cm-root-dir-ghost-repository.js +126 -0
  362. package/dist/server/src/lib/git/worktrees.js +90 -0
  363. package/dist/server/src/lib/job-executor.js +8 -2
  364. package/dist/server/src/lib/realtime/types.js +76 -0
  365. package/dist/server/src/lib/schedule-manager.js +9 -1
  366. package/dist/server/src/lib/version-checker.js +297 -0
  367. package/dist/server/src/lib/ws-server.js +37 -0
  368. package/package.json +1 -1
  369. package/.next/server/chunks/2464.js +0 -33
  370. package/.next/server/chunks/6791.js +0 -47
  371. package/.next/static/chunks/7347-4a031aecf4664a6d.js +0 -1
  372. package/.next/static/chunks/8954-ce15ee4d0423f1b1.js +0 -1
  373. package/.next/static/chunks/app/chat/page-dee86bdf87516e40.js +0 -1
  374. package/.next/static/chunks/app/layout-d02f4691a4eff86b.js +0 -1
  375. package/.next/static/chunks/app/more/page-39ec8b5f27cf52e7.js +0 -1
  376. package/.next/static/chunks/app/page-ebf1db9826b4065d.js +0 -1
  377. package/.next/static/chunks/app/repositories/page-2be54cae5fcc1f7a.js +0 -1
  378. package/.next/static/chunks/app/review/page-ac4efe6857a0f3bf.js +0 -1
  379. package/.next/static/chunks/app/sessions/page-dc545a3d45374187.js +0 -1
  380. package/.next/static/chunks/app/worktrees/[id]/page-9eb2f37809919531.js +0 -1
  381. package/.next/static/css/eabd34bf2ab147a4.css +0 -1
  382. /package/.next/static/{Ndx_NzkoP54cD0UCmjUlu → uBCIYS1Hth7V4unroKqGu}/_buildManifest.js +0 -0
  383. /package/.next/static/{Ndx_NzkoP54cD0UCmjUlu → uBCIYS1Hth7V4unroKqGu}/_ssgManifest.js +0 -0
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ /**
3
+ * Migration v43: delete the CM_ROOT_DIR ghost repository row (Issue #1339).
4
+ *
5
+ * Before #1328, `getRepositoryPaths()` returned CM_ROOT_DIR as if it were a
6
+ * single repository path, and the sync route handed it to
7
+ * `ensureEnvRepositoriesRegistered()`, which wrote it to `repositories` with
8
+ * `is_env_managed = 1`. But CM_ROOT_DIR is the *container* of repositories, not
9
+ * a repository: `git worktree list` run there returns nothing, so no `worktrees`
10
+ * row was ever created for it. The result is a repository row with no worktrees
11
+ * under it — visible in the repository management screen, absent from the
12
+ * sidebar (which is driven by `worktrees`), and impossible for the user to tell
13
+ * apart from a real entry.
14
+ *
15
+ * #1328 removed the discovery that created these rows but deliberately left the
16
+ * existing rows alone. This migration is that clean-up.
17
+ *
18
+ * SCOPE: only the `is_env_managed = 1` row whose path is exactly CM_ROOT_DIR.
19
+ * The `is_env_managed = 0` ghosts written by `disableRepository()` are a
20
+ * different defect (#1346) and are not touched here.
21
+ *
22
+ * The three guards below exist because deleting a *legitimate* env-managed row
23
+ * is not a harmless mistake: `ensureEnvRepositoriesRegistered()` recreates a
24
+ * missing row with `enabled: true` (db-repository.ts:469), so a wrong delete
25
+ * silently re-enables a repository the user had switched off, and drops their
26
+ * `visible` / `display_name` alongside it. Every guard fails toward keeping the
27
+ * row.
28
+ *
29
+ * Backward compatibility: a DB with no ghost row (the normal case for anyone who
30
+ * never ran a pre-#1328 build) matches nothing and the migration is a no-op.
31
+ */
32
+ var __importDefault = (this && this.__importDefault) || function (mod) {
33
+ return (mod && mod.__esModule) ? mod : { "default": mod };
34
+ };
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.v43_migrations = void 0;
37
+ const path_1 = __importDefault(require("path"));
38
+ /**
39
+ * The configured CM_ROOT_DIR, resolved the same way the ghost row's path was
40
+ * written: `path.resolve()` over the raw env value (`resolveRepositoryPath()`).
41
+ *
42
+ * Deliberately NOT `getEnv()`: that falls back to `process.cwd()` when
43
+ * CM_ROOT_DIR is unset (env.ts:218), which would aim this DELETE at whatever
44
+ * directory the server happened to start in — quite plausibly a real repository.
45
+ * An unset CM_ROOT_DIR must mean "skip", never "target cwd".
46
+ *
47
+ * Read straight from process.env rather than through env.ts so the migration
48
+ * stays frozen: it must keep deleting exactly what the pre-#1328 code wrote,
49
+ * whatever env.ts grows into later.
50
+ *
51
+ * @returns Resolved CM_ROOT_DIR, or null when it is not configured
52
+ */
53
+ function getConfiguredRootDir() {
54
+ // MCBD_ROOT_DIR is the pre-#76 name and still supported (env.ts ENV_MAPPING).
55
+ const raw = process.env.CM_ROOT_DIR ?? process.env.MCBD_ROOT_DIR;
56
+ if (!raw || !raw.trim()) {
57
+ return null;
58
+ }
59
+ return path_1.default.resolve(raw.trim());
60
+ }
61
+ /**
62
+ * WORKTREE_REPOS entries, resolved. These are the *legitimate* `is_env_managed`
63
+ * rows: post-#1328 `getRepositoryPaths()` returns this list and nothing else.
64
+ *
65
+ * Parsed inline, mirroring `getRepositoryPaths()` (git/worktrees.ts:144), rather
66
+ * than imported: worktrees.ts pulls in `@/lib/db`, whose barrel re-exports this
67
+ * very migration list.
68
+ *
69
+ * @returns Resolved WORKTREE_REPOS paths (empty when unset)
70
+ */
71
+ function getWorktreeRepoPaths() {
72
+ const raw = process.env.WORKTREE_REPOS;
73
+ if (!raw || !raw.trim()) {
74
+ return [];
75
+ }
76
+ return raw
77
+ .split(',')
78
+ .map((p) => p.trim())
79
+ .filter((p) => p.length > 0)
80
+ .map((p) => path_1.default.resolve(p));
81
+ }
82
+ exports.v43_migrations = [
83
+ {
84
+ version: 43,
85
+ name: 'remove-cm-root-dir-ghost-repository',
86
+ up: (db) => {
87
+ // Guard 1: no CM_ROOT_DIR, no target. See getConfiguredRootDir().
88
+ const rootDir = getConfiguredRootDir();
89
+ if (!rootDir) {
90
+ console.log('Migration 43: CM_ROOT_DIR is not set; no ghost row to remove');
91
+ return;
92
+ }
93
+ // Guard 2: CM_ROOT_DIR may legitimately also be listed in WORKTREE_REPOS,
94
+ // which makes its is_env_managed row real and its absence self-healing at
95
+ // enabled=true. Never delete a row the env still asks for.
96
+ if (getWorktreeRepoPaths().includes(rootDir)) {
97
+ console.log(`Migration 43: ${rootDir} is a WORKTREE_REPOS entry; keeping its repository row`);
98
+ return;
99
+ }
100
+ // Guard 3 (the NOT EXISTS): a row with worktrees under it is not a ghost,
101
+ // whatever the env says. This is the condition the issue names, and it is
102
+ // what makes the delete provably lossless — nothing references the row.
103
+ const result = db
104
+ .prepare(`DELETE FROM repositories
105
+ WHERE path = ?
106
+ AND is_env_managed = 1
107
+ AND NOT EXISTS (
108
+ SELECT 1 FROM worktrees WHERE worktrees.repository_path = ?
109
+ )`)
110
+ .run(rootDir, rootDir);
111
+ if (result.changes > 0) {
112
+ console.log(`Migration 43: removed CM_ROOT_DIR ghost repository row (${rootDir})`);
113
+ }
114
+ else {
115
+ console.log(`Migration 43: no ghost repository row at ${rootDir}`);
116
+ }
117
+ },
118
+ down: () => {
119
+ // The deleted row carried no user data — an env-managed ghost with no
120
+ // worktrees, no clone URL, and default flags — and re-inserting it would
121
+ // restore the very defect this migration fixes. No-op rollback (mirrors
122
+ // v35/v40).
123
+ console.log('No rollback for the CM_ROOT_DIR ghost row removal');
124
+ },
125
+ },
126
+ ];
@@ -13,8 +13,11 @@ exports.getRepositoryPaths = getRepositoryPaths;
13
13
  exports.scanWorktrees = scanWorktrees;
14
14
  exports.scanMultipleRepositories = scanMultipleRepositories;
15
15
  exports.syncWorktreesToDB = syncWorktreesToDB;
16
+ exports.repositoryExistsOnDisk = repositoryExistsOnDisk;
17
+ exports.pruneStaleRepositoryWorktrees = pruneStaleRepositoryWorktrees;
16
18
  const child_process_1 = require("child_process");
17
19
  const util_1 = require("util");
20
+ const fs_1 = __importDefault(require("fs"));
18
21
  const path_1 = __importDefault(require("path"));
19
22
  const db_1 = require("../../lib/db");
20
23
  const logger_1 = require("../../lib/logger");
@@ -293,3 +296,90 @@ function syncWorktreesToDB(db, worktrees) {
293
296
  }
294
297
  return { deletedIds: allDeletedIds, upsertedCount };
295
298
  }
299
+ /**
300
+ * Whether a repository still exists on disk as a git working tree.
301
+ *
302
+ * Returns `false` only when the directory itself is gone OR its `.git` entry is
303
+ * missing (a de-gitified directory). Every other state — including a present
304
+ * directory whose `.git` is intact — is reported as "still there", so a
305
+ * transient git failure (a locked index, a momentarily-unavailable network
306
+ * drive whose mount point is still present, …) never satisfies the prune
307
+ * condition. Issue #1349: fall on the side of NOT pruning whenever the on-disk
308
+ * state is inconclusive.
309
+ *
310
+ * @param repoPath - Canonical repository path (as stored in
311
+ * `worktrees.repository_path`, i.e. already `path.resolve()`d by
312
+ * {@link scanWorktrees}; see #1347)
313
+ * @returns `true` if the repository still looks present on disk
314
+ */
315
+ function repositoryExistsOnDisk(repoPath) {
316
+ if (!repoPath)
317
+ return false;
318
+ try {
319
+ return fs_1.default.existsSync(repoPath) && fs_1.default.existsSync(path_1.default.join(repoPath, '.git'));
320
+ }
321
+ catch {
322
+ // Inconclusive filesystem read (e.g. EACCES): be conservative and keep rows.
323
+ return true;
324
+ }
325
+ }
326
+ /**
327
+ * Prune DB worktree rows for repositories that have vanished from disk.
328
+ *
329
+ * Issue #1349: when a repository directory is deleted or de-gitified,
330
+ * {@link scanWorktrees} returns `[]` (git exit 128), so the repository silently
331
+ * drops out of the scan and {@link syncWorktreesToDB} never reaches its per-repo
332
+ * prune for it — the rows linger as ghost entries in the sidebar. The global
333
+ * early-return in `syncWorktreesToDB` only fires when *every* repository is
334
+ * empty, so a single vanished repository among healthy ones is never cleaned up.
335
+ *
336
+ * This runs as the global-sync reconciliation step: it enumerates every
337
+ * `repository_path` that still owns worktree rows and, for those that produced
338
+ * no worktrees in the current scan, deletes the rows **only when the repository
339
+ * directory (or its `.git`) is genuinely gone** (see
340
+ * {@link repositoryExistsOnDisk}). A repository that still exists but merely
341
+ * errored in git is left untouched, so a transient failure — a network drive
342
+ * blip, a locked repo — never destroys history.
343
+ *
344
+ * Intended for the full-scan endpoint (`POST /api/repositories/sync`) only.
345
+ * Single-repository callers (scan/restore) must NOT run this: they hold no
346
+ * authority over repositories outside their own scan, and running it there would
347
+ * prune repositories that merely weren't part of that request.
348
+ *
349
+ * Row keys stay consistent with #1347: {@link getRepositories} returns the
350
+ * stored (already `path.resolve()`d) `repository_path`, and every subsequent DB
351
+ * and filesystem lookup uses that same canonical value.
352
+ *
353
+ * @param db - Database instance
354
+ * @param liveWorktrees - Worktrees produced by the current scan; their
355
+ * repositories are known-present and therefore skipped
356
+ * @returns IDs of worktrees deleted for vanished repositories
357
+ */
358
+ function pruneStaleRepositoryWorktrees(db, liveWorktrees) {
359
+ // Repositories that produced at least one worktree this scan are alive by
360
+ // definition (git listed them), so they are never candidates for pruning.
361
+ const liveRepoPaths = new Set(liveWorktrees
362
+ .map(wt => wt.repositoryPath)
363
+ .filter((p) => !!p));
364
+ const deletedIds = [];
365
+ for (const repo of (0, db_1.getRepositories)(db)) {
366
+ const repoPath = repo.path;
367
+ if (!repoPath)
368
+ continue;
369
+ if (liveRepoPaths.has(repoPath))
370
+ continue;
371
+ // Conservative guard: keep rows unless the directory/.git is truly gone.
372
+ if (repositoryExistsOnDisk(repoPath))
373
+ continue;
374
+ const ids = (0, db_1.getWorktreesByRepository)(db, repoPath).map(row => row.id);
375
+ if (ids.length === 0)
376
+ continue;
377
+ const result = (0, db_1.deleteWorktreesByIds)(db, ids);
378
+ deletedIds.push(...ids);
379
+ logger.info('worktree:stale-repo-pruned', {
380
+ repoPath,
381
+ deletedCount: result.deletedCount,
382
+ });
383
+ }
384
+ return deletedIds;
385
+ }
@@ -136,8 +136,12 @@ async function executeSchedule(state) {
136
136
  return;
137
137
  }
138
138
  state.isExecuting = true;
139
- const logId = createExecutionLog(state.scheduleId, state.worktreeId, state.entry.message);
139
+ // Issue #1343: createExecutionLog() must stay inside the try so that a DB
140
+ // failure still reaches the finally that resets isExecuting. Otherwise the
141
+ // schedule is skipped by the guard above until the server restarts.
142
+ let logId;
140
143
  try {
144
+ logId = createExecutionLog(state.scheduleId, state.worktreeId, state.entry.message);
141
145
  const db = getLazyDbInstance();
142
146
  const worktree = db.prepare('SELECT path, vibe_local_model FROM worktrees WHERE id = ?').get(state.worktreeId);
143
147
  if (!worktree) {
@@ -153,7 +157,9 @@ async function executeSchedule(state) {
153
157
  }
154
158
  catch (error) {
155
159
  const errorMessage = error instanceof Error ? error.message : String(error);
156
- updateExecutionLog(logId, 'failed', errorMessage, null);
160
+ if (logId !== undefined) {
161
+ updateExecutionLog(logId, 'failed', errorMessage, null);
162
+ }
157
163
  logger.error('execution:failed', { name: state.entry.name, error: errorMessage });
158
164
  }
159
165
  finally {
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ /**
3
+ * Realtime (WebSocket) message contracts shared by the server broadcasters and
4
+ * the client consumers. Issue #1120.
5
+ *
6
+ * Server broadcasts are double-wrapped by `handleBroadcast` into an envelope:
7
+ * { type: 'broadcast', worktreeId, data: { type: '<realType>', ...payload } }
8
+ * `parseRealtimeEvent` unwraps that envelope and returns the inner payload as
9
+ * the canonical {@link RealtimeEvent}.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.VERSION_MISMATCH_EVENT_TYPE = exports.CLIENT_VERSION_MESSAGE_TYPE = void 0;
13
+ exports.isVersionMismatch = isVersionMismatch;
14
+ exports.parseRealtimeEvent = parseRealtimeEvent;
15
+ /**
16
+ * Client → server hello carrying the client bundle version, sent on every
17
+ * (re)connect so the server can detect a version drift (#1356). Kept as a shared
18
+ * constant so the client sender and the server handler cannot drift apart.
19
+ */
20
+ exports.CLIENT_VERSION_MESSAGE_TYPE = 'client_version';
21
+ /**
22
+ * Server → client notice that the running server version differs from this
23
+ * tab's bundle version (#1338/#1356). Drives the reload banner.
24
+ */
25
+ exports.VERSION_MISMATCH_EVENT_TYPE = 'version_mismatch';
26
+ /**
27
+ * Whether the running server version and this tab's bundle version have drifted
28
+ * apart and the user should be nudged to reload (#1338/#1356).
29
+ *
30
+ * Conservative on purpose (受入条件: 版が一致している間は誤検知しない): an empty or
31
+ * `'0.0.0'` fallback on either side means "version unknown" and is never treated
32
+ * as a mismatch, so a server that cannot resolve its own version stays silent.
33
+ */
34
+ function isVersionMismatch(serverVersion, clientVersion) {
35
+ if (!serverVersion || !clientVersion)
36
+ return false;
37
+ if (serverVersion === '0.0.0' || clientVersion === '0.0.0')
38
+ return false;
39
+ return serverVersion !== clientVersion;
40
+ }
41
+ /**
42
+ * Parse a raw WebSocket frame into the inner realtime event.
43
+ *
44
+ * Handles both the room broadcast envelope ({ type:'broadcast', data:{...} })
45
+ * and (defensively) already-unwrapped frames. Returns null on malformed input
46
+ * or frames without a usable inner `type`.
47
+ */
48
+ function parseRealtimeEvent(raw) {
49
+ let parsed;
50
+ try {
51
+ parsed = JSON.parse(raw);
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ if (!parsed || typeof parsed !== 'object')
57
+ return null;
58
+ const env = parsed;
59
+ if (env.type === 'broadcast') {
60
+ const inner = env.data;
61
+ if (!inner || typeof inner !== 'object')
62
+ return null;
63
+ const innerObj = inner;
64
+ if (typeof innerObj.type !== 'string')
65
+ return null;
66
+ // Ensure worktreeId is present even if the payload omitted it.
67
+ if (innerObj.worktreeId === undefined && typeof env.worktreeId === 'string') {
68
+ innerObj.worktreeId = env.worktreeId;
69
+ }
70
+ return innerObj;
71
+ }
72
+ if (typeof env.type === 'string') {
73
+ return env;
74
+ }
75
+ return null;
76
+ }
@@ -71,7 +71,15 @@ function createScheduleState(worktreeId, scheduleId, entry) {
71
71
  entry,
72
72
  };
73
73
  cronJob.schedule(() => {
74
- void (0, job_executor_1.executeSchedule)(state);
74
+ // Issue #1343: executeSchedule() rejects if its own error handling fails
75
+ // (e.g. the DB is still down when writing the 'failed' log). Without this
76
+ // catch the rejection is silently unhandled.
77
+ void (0, job_executor_1.executeSchedule)(state).catch((error) => {
78
+ logger.error('execution:unhandled', {
79
+ name: entry.name,
80
+ error: error instanceof Error ? error.message : String(error),
81
+ });
82
+ });
75
83
  });
76
84
  return state;
77
85
  }
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ /**
3
+ * Version Checker Module
4
+ * Issue #257: Version update notification feature
5
+ *
6
+ * Checks GitHub Releases API for newer versions of CommandMate.
7
+ * Uses globalThis cache pattern (auto-yes-manager.ts reference) for
8
+ * hot-reload persistence.
9
+ *
10
+ * Security:
11
+ * - [SEC-001] GITHUB_API_URL is hardcoded (SSRF prevention, OWASP A10:2021)
12
+ * - [SEC-SF-001] Response validation (validateReleaseUrl, sanitizeReleaseName)
13
+ * - [SEC-SF-002] User-Agent header for GitHub API compliance (OWASP A07:2021)
14
+ *
15
+ * @module version-checker
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.GITHUB_RELEASE_URL_PREFIX = exports.GITHUB_API_URL = void 0;
19
+ exports.isNewerVersion = isNewerVersion;
20
+ exports.getClientVersion = getClientVersion;
21
+ exports.getServerVersion = getServerVersion;
22
+ exports.getCurrentVersion = getCurrentVersion;
23
+ exports.validateReleaseUrl = validateReleaseUrl;
24
+ exports.sanitizeReleaseName = sanitizeReleaseName;
25
+ exports.checkForUpdate = checkForUpdate;
26
+ exports.resetCacheForTesting = resetCacheForTesting;
27
+ const fs_1 = require("fs");
28
+ const path_1 = require("path");
29
+ // =============================================================================
30
+ // Constants
31
+ // =============================================================================
32
+ /**
33
+ * [SEC-001] SSRF Prevention: GitHub API URL is a hardcoded constant.
34
+ * This value MUST NOT be derived from environment variables, config files,
35
+ * or user input. Changing this value requires security review.
36
+ * OWASP A10:2021 - Server-Side Request Forgery
37
+ */
38
+ exports.GITHUB_API_URL = 'https://api.github.com/repos/Kewton/CommandMate/releases/latest';
39
+ /**
40
+ * [SEC-SF-001] GitHub Releases URL allowed prefix for validation.
41
+ * Used to verify html_url from API responses.
42
+ * Imported from github-links.ts (Issue #264 DRY) and re-exported for backward compatibility.
43
+ */
44
+ const github_links_1 = require("../config/github-links");
45
+ Object.defineProperty(exports, "GITHUB_RELEASE_URL_PREFIX", { enumerable: true, get: function () { return github_links_1.GITHUB_RELEASE_URL_PREFIX; } });
46
+ /** Semver pattern: optional v-prefix followed by major.minor.patch */
47
+ const SEMVER_PATTERN = /^v?\d+\.\d+\.\d+$/;
48
+ /** [SEC-SF-001] Release name allowed characters pattern */
49
+ const RELEASE_NAME_PATTERN = /^[a-zA-Z0-9.\-\s_v]+$/;
50
+ /** Maximum allowed release name length */
51
+ const RELEASE_NAME_MAX_LENGTH = 128;
52
+ /** Cache TTL: 1 hour (matches GitHub API unauthenticated rate limit of 60 req/h) */
53
+ const CACHE_TTL_MS = 60 * 60 * 1000;
54
+ /** Fetch timeout: 5 seconds */
55
+ const FETCH_TIMEOUT_MS = 5000;
56
+ /**
57
+ * npm package name. [Issue #1359] Used to verify that a package.json resolved at
58
+ * runtime is CommandMate's own manifest and not an unrelated project's — a guard
59
+ * against an unexpected process.cwd() (e.g. a dev run started from a user's
60
+ * project directory) leaking a foreign version.
61
+ */
62
+ const PACKAGE_NAME = 'commandmate';
63
+ const cache = globalThis.__versionCheckCache ??
64
+ (globalThis.__versionCheckCache = {
65
+ result: null,
66
+ fetchedAt: 0,
67
+ rateLimitResetAt: null,
68
+ });
69
+ // =============================================================================
70
+ // Public Functions
71
+ // =============================================================================
72
+ /**
73
+ * Compare two semver version strings.
74
+ * [SF-003] Includes built-in validation - returns false for invalid formats.
75
+ *
76
+ * @param current - Current version (e.g., "0.2.3", "v0.2.3")
77
+ * @param latest - Latest version (e.g., "0.3.0", "v0.3.0")
78
+ * @returns true if latest is newer than current, false for invalid formats
79
+ */
80
+ function isNewerVersion(current, latest) {
81
+ // [SF-003] Defensive validation: reject invalid formats immediately
82
+ if (!SEMVER_PATTERN.test(current) || !SEMVER_PATTERN.test(latest)) {
83
+ return false;
84
+ }
85
+ const parse = (v) => v.replace(/^v/, '').split('.').map(Number);
86
+ const [cMajor, cMinor, cPatch] = parse(current);
87
+ const [lMajor, lMinor, lPatch] = parse(latest);
88
+ if (lMajor !== cMajor)
89
+ return lMajor > cMajor;
90
+ if (lMinor !== cMinor)
91
+ return lMinor > cMinor;
92
+ return lPatch > cPatch;
93
+ }
94
+ /**
95
+ * Read CommandMate's version from the installed package.json at runtime.
96
+ *
97
+ * [Issue #1359] `NEXT_PUBLIC_APP_VERSION` is baked into the bundle at
98
+ * `next build` time, so it reflects "the version present when the client bundle
99
+ * was last built", not the version of the server code actually running. Reading
100
+ * package.json on each call reflects the real installed version, which is what
101
+ * the update-check API must report as `currentVersion`.
102
+ *
103
+ * The server is spawned with cwd = package root (start.ts), so
104
+ * `process.cwd()/package.json` is the installed manifest. We verify
105
+ * `name === 'commandmate'` so an unexpected cwd can never leak an unrelated
106
+ * project's version; on any mismatch or read failure the caller falls back to
107
+ * the baked value.
108
+ *
109
+ * @returns Runtime version string, or null when unreadable / not CommandMate's package.json
110
+ */
111
+ function readRuntimeServerVersion() {
112
+ try {
113
+ const raw = (0, fs_1.readFileSync)((0, path_1.join)(process.cwd(), 'package.json'), 'utf-8');
114
+ const parsed = JSON.parse(raw);
115
+ if (parsed.name === PACKAGE_NAME &&
116
+ typeof parsed.version === 'string' &&
117
+ parsed.version.length > 0) {
118
+ return parsed.version;
119
+ }
120
+ return null;
121
+ }
122
+ catch {
123
+ // Unreadable / malformed package.json: fall back to the baked value.
124
+ return null;
125
+ }
126
+ }
127
+ /**
128
+ * Get the client bundle version (baked at build time).
129
+ * [CONS-002] `NEXT_PUBLIC_APP_VERSION` is injected by next.config.js from
130
+ * package.json at `next build` time. This is the correct value to describe
131
+ * "the version of the bundle this page was served from" and is intentionally
132
+ * left build-time baked (Issue #1359).
133
+ *
134
+ * @returns Client bundle version string (e.g., "0.2.3"), or "0.0.0" as fallback
135
+ */
136
+ function getClientVersion() {
137
+ return process.env.NEXT_PUBLIC_APP_VERSION ?? '0.0.0';
138
+ }
139
+ /**
140
+ * Get the server's actually-running version, resolved at runtime.
141
+ * [Issue #1359] Prefers the installed package.json (runtime truth) over the
142
+ * build-time baked `NEXT_PUBLIC_APP_VERSION`, so update-check reports the version
143
+ * of the server code that is really running. Separating this from
144
+ * getClientVersion() is the basis for version-mismatch detection (#1338/#1356).
145
+ *
146
+ * Resolution order:
147
+ * 1. Runtime package.json (name === "commandmate")
148
+ * 2. Baked NEXT_PUBLIC_APP_VERSION
149
+ * 3. "0.0.0"
150
+ *
151
+ * @returns Server runtime version string (e.g., "0.2.3"), or "0.0.0" as fallback
152
+ */
153
+ function getServerVersion() {
154
+ return readRuntimeServerVersion() ?? getClientVersion();
155
+ }
156
+ /**
157
+ * Get the current application version (server runtime version).
158
+ * Retained for backward compatibility; delegates to getServerVersion().
159
+ *
160
+ * @returns Current version string (e.g., "0.2.3"), or "0.0.0" as fallback
161
+ */
162
+ function getCurrentVersion() {
163
+ return getServerVersion();
164
+ }
165
+ /**
166
+ * Validate that a URL is a legitimate GitHub Releases URL.
167
+ * [SEC-SF-001] OWASP A03:2021 - Prevents injection via DNS pollution/MITM.
168
+ *
169
+ * @param url - URL to validate
170
+ * @returns Validated URL, or null if invalid
171
+ */
172
+ function validateReleaseUrl(url) {
173
+ if (!url.startsWith(github_links_1.GITHUB_RELEASE_URL_PREFIX)) {
174
+ return null;
175
+ }
176
+ return url;
177
+ }
178
+ /**
179
+ * Sanitize a release name to safe character set.
180
+ * [SEC-SF-001] Restricts to alphanumeric, dots, hyphens, spaces, underscores, v-prefix.
181
+ *
182
+ * @param name - Release name to sanitize
183
+ * @param tagName - Fallback value (semver-validated tag_name)
184
+ * @returns Sanitized name, or tagName if the name is invalid
185
+ */
186
+ function sanitizeReleaseName(name, tagName) {
187
+ if (RELEASE_NAME_PATTERN.test(name) && name.length <= RELEASE_NAME_MAX_LENGTH) {
188
+ return name;
189
+ }
190
+ // Fallback to tag_name (already validated by SEMVER_PATTERN)
191
+ return tagName;
192
+ }
193
+ /**
194
+ * Check GitHub Releases for newer versions.
195
+ * Uses in-memory cache (globalThis.__versionCheckCache) with 1-hour TTL.
196
+ * Silently fails on network errors, timeouts, or API issues.
197
+ *
198
+ * [SF-002] Multiple calls within the same process are safe: the globalThis cache
199
+ * (1-hour TTL) ensures that only the first call triggers a network request.
200
+ * Subsequent calls within the TTL window return the cached result without
201
+ * network overhead. The cache is stored in globalThis.__versionCheckCache
202
+ * and automatically invalidated after CACHE_TTL_MS (1 hour).
203
+ *
204
+ * @returns Update check result, or null on failure
205
+ */
206
+ async function checkForUpdate() {
207
+ try {
208
+ // Check cache validity
209
+ if (isCacheValid()) {
210
+ return cache.result;
211
+ }
212
+ // Check rate limit
213
+ if (isRateLimited()) {
214
+ return cache.result;
215
+ }
216
+ const response = await fetch(exports.GITHUB_API_URL, {
217
+ headers: {
218
+ 'Accept': 'application/vnd.github+json',
219
+ 'User-Agent': `CommandMate/${getCurrentVersion()}`, // [SEC-SF-002]
220
+ },
221
+ cache: 'no-store', // Issue #278: Prevent Next.js Data Cache from caching GitHub API responses
222
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
223
+ });
224
+ // Handle rate limit (403)
225
+ if (response.status === 403) {
226
+ handleRateLimit(response);
227
+ return cache.result;
228
+ }
229
+ if (!response.ok) {
230
+ return cache.result;
231
+ }
232
+ const data = (await response.json());
233
+ const currentVersion = getCurrentVersion();
234
+ const latestVersion = data.tag_name.replace(/^v/, '');
235
+ const hasUpdate = isNewerVersion(currentVersion, data.tag_name);
236
+ const result = {
237
+ hasUpdate,
238
+ currentVersion,
239
+ latestVersion,
240
+ releaseUrl: validateReleaseUrl(data.html_url),
241
+ releaseName: sanitizeReleaseName(data.name, data.tag_name),
242
+ publishedAt: data.published_at,
243
+ };
244
+ // Update cache
245
+ cache.result = result;
246
+ cache.fetchedAt = Date.now();
247
+ return result;
248
+ }
249
+ catch {
250
+ // Silent failure: network errors, timeouts, parse errors
251
+ return cache.result;
252
+ }
253
+ }
254
+ /**
255
+ * Reset cache for testing purposes only.
256
+ * @internal
257
+ */
258
+ function resetCacheForTesting() {
259
+ cache.result = null;
260
+ cache.fetchedAt = 0;
261
+ cache.rateLimitResetAt = null;
262
+ }
263
+ // =============================================================================
264
+ // Internal Functions
265
+ // =============================================================================
266
+ /** Check if cache is valid (within TTL) */
267
+ function isCacheValid() {
268
+ return cache.result !== null && (Date.now() - cache.fetchedAt) < CACHE_TTL_MS;
269
+ }
270
+ /**
271
+ * Check if currently rate-limited.
272
+ * [C-001] Simplified rate limit handling: uses rateLimitResetAt from 403 response.
273
+ */
274
+ function isRateLimited() {
275
+ if (!cache.rateLimitResetAt)
276
+ return false;
277
+ if (Date.now() >= cache.rateLimitResetAt) {
278
+ cache.rateLimitResetAt = null;
279
+ return false;
280
+ }
281
+ return true;
282
+ }
283
+ /**
284
+ * Handle 403 rate limit response.
285
+ * Extracts X-RateLimit-Reset header for precise retry timing,
286
+ * or falls back to CACHE_TTL_MS extension.
287
+ */
288
+ function handleRateLimit(response) {
289
+ const resetTimestamp = response.headers.get('X-RateLimit-Reset');
290
+ if (resetTimestamp) {
291
+ cache.rateLimitResetAt = parseInt(resetTimestamp, 10) * 1000;
292
+ }
293
+ else {
294
+ // Reset time unknown: retry after 1 hour
295
+ cache.rateLimitResetAt = Date.now() + CACHE_TTL_MS;
296
+ }
297
+ }