vibepulse 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (420) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +4 -0
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/cache/.previewinfo +1 -1
  5. package/.next/cache/.rscinfo +1 -1
  6. package/.next/cache/.tsbuildinfo +1 -1
  7. package/.next/cache/config.json +3 -3
  8. package/.next/fallback-build-manifest.json +2 -2
  9. package/.next/prerender-manifest.json +3 -3
  10. package/.next/routes-manifest.json +32 -0
  11. package/.next/server/app/_global-error/page.js +1 -1
  12. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  13. package/.next/server/app/_global-error.html +2 -2
  14. package/.next/server/app/_global-error.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  16. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  17. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/.next/server/app/_not-found/page.js +1 -1
  21. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  22. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  23. package/.next/server/app/_not-found.html +1 -1
  24. package/.next/server/app/_not-found.rsc +2 -2
  25. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  26. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  27. package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  28. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  29. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  30. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  31. package/.next/server/app/api/node/events/route.js +1 -1
  32. package/.next/server/app/api/node/events/route.js.nft.json +1 -1
  33. package/.next/server/app/api/node/health/route.js +1 -1
  34. package/.next/server/app/api/node/health/route.js.nft.json +1 -1
  35. package/.next/server/app/api/node/sessions/[id]/archive/route/app-paths-manifest.json +3 -0
  36. package/.next/server/app/api/node/sessions/[id]/archive/route/build-manifest.json +11 -0
  37. package/.next/server/app/api/node/sessions/[id]/archive/route/server-reference-manifest.json +4 -0
  38. package/.next/server/app/api/node/sessions/[id]/archive/route.js +6 -0
  39. package/.next/server/app/api/node/sessions/[id]/archive/route.js.map +5 -0
  40. package/.next/server/app/api/node/sessions/[id]/archive/route.js.nft.json +1 -0
  41. package/.next/server/app/api/node/sessions/[id]/archive/route_client-reference-manifest.js +2 -0
  42. package/.next/server/app/api/node/sessions/[id]/delete/route/app-paths-manifest.json +3 -0
  43. package/.next/server/app/api/node/sessions/[id]/delete/route/build-manifest.json +11 -0
  44. package/.next/server/app/api/node/sessions/[id]/delete/route/server-reference-manifest.json +4 -0
  45. package/.next/server/app/api/node/sessions/[id]/delete/route.js +7 -0
  46. package/.next/server/app/api/node/sessions/[id]/delete/route.js.map +5 -0
  47. package/.next/server/app/api/node/sessions/[id]/delete/route.js.nft.json +1 -0
  48. package/.next/server/app/api/node/sessions/[id]/delete/route_client-reference-manifest.js +2 -0
  49. package/.next/server/app/api/node/sessions/[id]/open-editor/route/app-paths-manifest.json +3 -0
  50. package/.next/server/app/api/node/sessions/[id]/open-editor/route/build-manifest.json +11 -0
  51. package/.next/server/app/api/node/sessions/[id]/open-editor/route/server-reference-manifest.json +4 -0
  52. package/.next/server/app/api/node/sessions/[id]/open-editor/route.js +7 -0
  53. package/.next/server/app/api/node/sessions/[id]/open-editor/route.js.map +5 -0
  54. package/.next/server/app/api/node/sessions/[id]/open-editor/route.js.nft.json +1 -0
  55. package/.next/server/app/api/node/sessions/[id]/open-editor/route_client-reference-manifest.js +2 -0
  56. package/.next/server/app/api/node/sessions/route.js +1 -1
  57. package/.next/server/app/api/node/sessions/route.js.nft.json +1 -1
  58. package/.next/server/app/api/opencode-events/route.js +1 -1
  59. package/.next/server/app/api/opencode-events/route.js.nft.json +1 -1
  60. package/.next/server/app/api/sessions/[id]/archive/route.js +2 -1
  61. package/.next/server/app/api/sessions/[id]/archive/route.js.nft.json +1 -1
  62. package/.next/server/app/api/sessions/[id]/delete/route.js +3 -2
  63. package/.next/server/app/api/sessions/[id]/delete/route.js.nft.json +1 -1
  64. package/.next/server/app/api/sessions/[id]/open-editor/route/app-paths-manifest.json +3 -0
  65. package/.next/server/app/api/sessions/[id]/open-editor/route/build-manifest.json +11 -0
  66. package/.next/server/app/api/sessions/[id]/open-editor/route/server-reference-manifest.json +4 -0
  67. package/.next/server/app/api/sessions/[id]/open-editor/route.js +7 -0
  68. package/.next/server/app/api/sessions/[id]/open-editor/route.js.map +5 -0
  69. package/.next/server/app/api/sessions/[id]/open-editor/route.js.nft.json +1 -0
  70. package/.next/server/app/api/sessions/[id]/open-editor/route_client-reference-manifest.js +2 -0
  71. package/.next/server/app/api/sessions/route.js +1 -1
  72. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  73. package/.next/server/app/index.html +1 -1
  74. package/.next/server/app/index.rsc +3 -3
  75. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  76. package/.next/server/app/index.segments/_full.segment.rsc +3 -3
  77. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  78. package/.next/server/app/index.segments/_index.segment.rsc +2 -2
  79. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  80. package/.next/server/app/page.js +1 -1
  81. package/.next/server/app/page.js.nft.json +1 -1
  82. package/.next/server/app/page_client-reference-manifest.js +1 -1
  83. package/.next/server/app-paths-manifest.json +4 -0
  84. package/.next/server/chunks/[root-of-the-server]__1211da38._.js +3 -0
  85. package/.next/server/chunks/[root-of-the-server]__1211da38._.js.map +1 -0
  86. package/.next/{standalone/.next/server/chunks/[root-of-the-server]__b698889b._.js → server/chunks/[root-of-the-server]__1b87ec42._.js} +2 -2
  87. package/.next/server/chunks/[root-of-the-server]__1b87ec42._.js.map +1 -0
  88. package/.next/server/chunks/[root-of-the-server]__2b526e7a._.js +3 -0
  89. package/.next/server/chunks/[root-of-the-server]__2b526e7a._.js.map +1 -0
  90. package/.next/server/chunks/[root-of-the-server]__2f981540._.js +3 -0
  91. package/.next/server/chunks/[root-of-the-server]__2f981540._.js.map +1 -0
  92. package/.next/server/chunks/[root-of-the-server]__3745b314._.js +3 -0
  93. package/.next/server/chunks/[root-of-the-server]__3745b314._.js.map +1 -0
  94. package/.next/server/chunks/[root-of-the-server]__56690af0._.js +1 -1
  95. package/.next/server/chunks/[root-of-the-server]__56690af0._.js.map +1 -1
  96. package/.next/server/chunks/[root-of-the-server]__56f5f249._.js +1 -1
  97. package/.next/server/chunks/[root-of-the-server]__56f5f249._.js.map +1 -1
  98. package/.next/server/chunks/[root-of-the-server]__59175de4._.js +1 -1
  99. package/.next/server/chunks/[root-of-the-server]__59175de4._.js.map +1 -1
  100. package/.next/server/chunks/[root-of-the-server]__64fffc02._.js +1 -1
  101. package/.next/server/chunks/[root-of-the-server]__64fffc02._.js.map +1 -1
  102. package/.next/server/chunks/[root-of-the-server]__6c428a24._.js +3 -0
  103. package/.next/server/chunks/[root-of-the-server]__6c428a24._.js.map +1 -0
  104. package/.next/server/chunks/[root-of-the-server]__73a00b88._.js +3 -0
  105. package/.next/server/chunks/[root-of-the-server]__73a00b88._.js.map +1 -0
  106. package/.next/server/chunks/[root-of-the-server]__89c5eeab._.js +1 -1
  107. package/.next/server/chunks/[root-of-the-server]__89c5eeab._.js.map +1 -1
  108. package/.next/server/chunks/[root-of-the-server]__8da6c5a8._.js +1 -1
  109. package/.next/server/chunks/[root-of-the-server]__8da6c5a8._.js.map +1 -1
  110. package/.next/server/chunks/[root-of-the-server]__b796d06c._.js +1 -1
  111. package/.next/server/chunks/[root-of-the-server]__b796d06c._.js.map +1 -1
  112. package/.next/server/chunks/[root-of-the-server]__c2ce5c0f._.js +1 -1
  113. package/.next/server/chunks/[root-of-the-server]__c2ce5c0f._.js.map +1 -1
  114. package/.next/server/chunks/[root-of-the-server]__d8e61048._.js +3 -0
  115. package/.next/server/chunks/[root-of-the-server]__d8e61048._.js.map +1 -0
  116. package/.next/server/chunks/[root-of-the-server]__db285678._.js +3 -0
  117. package/.next/server/chunks/[root-of-the-server]__db285678._.js.map +1 -0
  118. package/.next/{standalone/.next/server/chunks/[root-of-the-server]__16a9eb0a._.js → server/chunks/[root-of-the-server]__e00a9200._.js} +2 -2
  119. package/.next/server/chunks/{[root-of-the-server]__16a9eb0a._.js.map → [root-of-the-server]__e00a9200._.js.map} +1 -1
  120. package/.next/server/chunks/[root-of-the-server]__e5df5e5f._.js +3 -0
  121. package/.next/server/chunks/[root-of-the-server]__e5df5e5f._.js.map +1 -0
  122. package/.next/server/chunks/_next-internal_server_app_api_node_sessions_[id]_archive_route_actions_237255a5.js +3 -0
  123. package/.next/server/chunks/_next-internal_server_app_api_node_sessions_[id]_archive_route_actions_237255a5.js.map +1 -0
  124. package/.next/server/chunks/_next-internal_server_app_api_node_sessions_[id]_delete_route_actions_e5d426f6.js +3 -0
  125. package/.next/server/chunks/_next-internal_server_app_api_node_sessions_[id]_delete_route_actions_e5d426f6.js.map +1 -0
  126. package/.next/server/chunks/_next-internal_server_app_api_sessions_[id]_open-editor_route_actions_eaebf476.js +3 -0
  127. package/.next/server/chunks/_next-internal_server_app_api_sessions_[id]_open-editor_route_actions_eaebf476.js.map +1 -0
  128. package/.next/server/chunks/ce889_server_app_api_node_sessions_[id]_open-editor_route_actions_791cdf5b.js +3 -0
  129. package/.next/server/chunks/ce889_server_app_api_node_sessions_[id]_open-editor_route_actions_791cdf5b.js.map +1 -0
  130. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_7e181e75.js +1 -1
  131. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_7e181e75.js.map +1 -1
  132. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_b054aff3.js +1 -1
  133. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_b054aff3.js.map +1 -1
  134. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_fa835ac3.js +2 -2
  135. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_fa835ac3.js.map +1 -1
  136. package/.next/server/chunks/ssr/{[root-of-the-server]__efc52f08._.js → [root-of-the-server]__631e12d0._.js} +2 -2
  137. package/.next/server/chunks/ssr/[root-of-the-server]__a8cd3911._.js +3 -0
  138. package/.next/server/chunks/ssr/src_app_page_tsx_a7111f3e._.js +3 -3
  139. package/.next/server/chunks/ssr/src_app_page_tsx_a7111f3e._.js.map +1 -1
  140. package/.next/server/pages/404.html +1 -1
  141. package/.next/server/pages/500.html +2 -2
  142. package/.next/server/server-reference-manifest.js +1 -1
  143. package/.next/server/server-reference-manifest.json +1 -1
  144. package/.next/standalone/.next/BUILD_ID +1 -1
  145. package/.next/standalone/.next/app-path-routes-manifest.json +4 -0
  146. package/.next/standalone/.next/build-manifest.json +2 -2
  147. package/.next/standalone/.next/prerender-manifest.json +3 -3
  148. package/.next/standalone/.next/routes-manifest.json +32 -0
  149. package/.next/standalone/.next/server/app/_global-error/page.js +1 -1
  150. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  151. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  152. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  153. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  154. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  155. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  156. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  157. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  158. package/.next/standalone/.next/server/app/_not-found/page.js +1 -1
  159. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  161. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  162. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  163. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  164. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  165. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  166. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  167. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  168. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  169. package/.next/standalone/.next/server/app/api/node/events/route.js +1 -1
  170. package/.next/standalone/.next/server/app/api/node/events/route.js.nft.json +1 -1
  171. package/.next/standalone/.next/server/app/api/node/health/route.js +1 -1
  172. package/.next/standalone/.next/server/app/api/node/health/route.js.nft.json +1 -1
  173. package/.next/standalone/.next/server/app/api/node/sessions/[id]/archive/route/app-paths-manifest.json +3 -0
  174. package/.next/standalone/.next/server/app/api/node/sessions/[id]/archive/route/build-manifest.json +11 -0
  175. package/.next/standalone/.next/server/app/api/node/sessions/[id]/archive/route/server-reference-manifest.json +4 -0
  176. package/.next/standalone/.next/server/app/api/node/sessions/[id]/archive/route.js +6 -0
  177. package/.next/standalone/.next/server/app/api/node/sessions/[id]/archive/route.js.map +5 -0
  178. package/.next/standalone/.next/server/app/api/node/sessions/[id]/archive/route.js.nft.json +1 -0
  179. package/.next/standalone/.next/server/app/api/node/sessions/[id]/archive/route_client-reference-manifest.js +2 -0
  180. package/.next/standalone/.next/server/app/api/node/sessions/[id]/delete/route/app-paths-manifest.json +3 -0
  181. package/.next/standalone/.next/server/app/api/node/sessions/[id]/delete/route/build-manifest.json +11 -0
  182. package/.next/standalone/.next/server/app/api/node/sessions/[id]/delete/route/server-reference-manifest.json +4 -0
  183. package/.next/standalone/.next/server/app/api/node/sessions/[id]/delete/route.js +7 -0
  184. package/.next/standalone/.next/server/app/api/node/sessions/[id]/delete/route.js.map +5 -0
  185. package/.next/standalone/.next/server/app/api/node/sessions/[id]/delete/route.js.nft.json +1 -0
  186. package/.next/standalone/.next/server/app/api/node/sessions/[id]/delete/route_client-reference-manifest.js +2 -0
  187. package/.next/standalone/.next/server/app/api/node/sessions/[id]/open-editor/route/app-paths-manifest.json +3 -0
  188. package/.next/standalone/.next/server/app/api/node/sessions/[id]/open-editor/route/build-manifest.json +11 -0
  189. package/.next/standalone/.next/server/app/api/node/sessions/[id]/open-editor/route/server-reference-manifest.json +4 -0
  190. package/.next/standalone/.next/server/app/api/node/sessions/[id]/open-editor/route.js +7 -0
  191. package/.next/standalone/.next/server/app/api/node/sessions/[id]/open-editor/route.js.map +5 -0
  192. package/.next/standalone/.next/server/app/api/node/sessions/[id]/open-editor/route.js.nft.json +1 -0
  193. package/.next/standalone/.next/server/app/api/node/sessions/[id]/open-editor/route_client-reference-manifest.js +2 -0
  194. package/.next/standalone/.next/server/app/api/node/sessions/route.js +1 -1
  195. package/.next/standalone/.next/server/app/api/node/sessions/route.js.nft.json +1 -1
  196. package/.next/standalone/.next/server/app/api/opencode-events/route.js +1 -1
  197. package/.next/standalone/.next/server/app/api/opencode-events/route.js.nft.json +1 -1
  198. package/.next/standalone/.next/server/app/api/sessions/[id]/archive/route.js +2 -1
  199. package/.next/standalone/.next/server/app/api/sessions/[id]/archive/route.js.nft.json +1 -1
  200. package/.next/standalone/.next/server/app/api/sessions/[id]/delete/route.js +3 -2
  201. package/.next/standalone/.next/server/app/api/sessions/[id]/delete/route.js.nft.json +1 -1
  202. package/.next/standalone/.next/server/app/api/sessions/[id]/open-editor/route/app-paths-manifest.json +3 -0
  203. package/.next/standalone/.next/server/app/api/sessions/[id]/open-editor/route/build-manifest.json +11 -0
  204. package/.next/standalone/.next/server/app/api/sessions/[id]/open-editor/route/server-reference-manifest.json +4 -0
  205. package/.next/standalone/.next/server/app/api/sessions/[id]/open-editor/route.js +7 -0
  206. package/.next/standalone/.next/server/app/api/sessions/[id]/open-editor/route.js.map +5 -0
  207. package/.next/standalone/.next/server/app/api/sessions/[id]/open-editor/route.js.nft.json +1 -0
  208. package/.next/standalone/.next/server/app/api/sessions/[id]/open-editor/route_client-reference-manifest.js +2 -0
  209. package/.next/standalone/.next/server/app/api/sessions/route.js +1 -1
  210. package/.next/standalone/.next/server/app/api/sessions/route.js.nft.json +1 -1
  211. package/.next/standalone/.next/server/app/index.html +1 -1
  212. package/.next/standalone/.next/server/app/index.rsc +3 -3
  213. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  214. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  215. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  216. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  217. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  218. package/.next/standalone/.next/server/app/page.js +1 -1
  219. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  220. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  221. package/.next/standalone/.next/server/app-paths-manifest.json +4 -0
  222. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1211da38._.js +3 -0
  223. package/.next/{server/chunks/[root-of-the-server]__b698889b._.js → standalone/.next/server/chunks/[root-of-the-server]__1b87ec42._.js} +2 -2
  224. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2b526e7a._.js +3 -0
  225. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2f981540._.js +3 -0
  226. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3745b314._.js +3 -0
  227. package/.next/standalone/.next/server/chunks/[root-of-the-server]__56690af0._.js +1 -1
  228. package/.next/standalone/.next/server/chunks/[root-of-the-server]__56f5f249._.js +1 -1
  229. package/.next/standalone/.next/server/chunks/[root-of-the-server]__59175de4._.js +1 -1
  230. package/.next/standalone/.next/server/chunks/[root-of-the-server]__64fffc02._.js +1 -1
  231. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6c428a24._.js +3 -0
  232. package/.next/standalone/.next/server/chunks/[root-of-the-server]__73a00b88._.js +3 -0
  233. package/.next/standalone/.next/server/chunks/[root-of-the-server]__89c5eeab._.js +1 -1
  234. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8da6c5a8._.js +1 -1
  235. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b796d06c._.js +1 -1
  236. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c2ce5c0f._.js +1 -1
  237. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d8e61048._.js +3 -0
  238. package/.next/standalone/.next/server/chunks/[root-of-the-server]__db285678._.js +3 -0
  239. package/.next/{server/chunks/[root-of-the-server]__16a9eb0a._.js → standalone/.next/server/chunks/[root-of-the-server]__e00a9200._.js} +2 -2
  240. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e5df5e5f._.js +3 -0
  241. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_node_sessions_[id]_archive_route_actions_237255a5.js +3 -0
  242. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_node_sessions_[id]_delete_route_actions_e5d426f6.js +3 -0
  243. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_sessions_[id]_open-editor_route_actions_eaebf476.js +3 -0
  244. package/.next/standalone/.next/server/chunks/ce889_server_app_api_node_sessions_[id]_open-editor_route_actions_791cdf5b.js +3 -0
  245. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_7e181e75.js +1 -1
  246. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_b054aff3.js +1 -1
  247. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_fa835ac3.js +2 -2
  248. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__efc52f08._.js → [root-of-the-server]__631e12d0._.js} +2 -2
  249. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__a8cd3911._.js +3 -0
  250. package/.next/standalone/.next/server/chunks/ssr/src_app_page_tsx_a7111f3e._.js +3 -3
  251. package/.next/standalone/.next/server/pages/404.html +1 -1
  252. package/.next/standalone/.next/server/pages/500.html +2 -2
  253. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  254. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  255. package/.next/standalone/.next/static/chunks/7ac19aaef01f4a03.js +13 -0
  256. package/.next/standalone/.next/static/chunks/f42202943f6742e5.css +3 -0
  257. package/.next/standalone/AGENTS.md +85 -0
  258. package/.next/standalone/README.md +76 -0
  259. package/.next/standalone/__mocks__/child_process.ts +4 -0
  260. package/.next/standalone/bin/dev-runtime.js +58 -0
  261. package/.next/standalone/bin/vibepulse.js +87 -0
  262. package/.next/standalone/check-hsql.mjs +71 -0
  263. package/.next/standalone/docs/session-status-detection.md +258 -0
  264. package/.next/standalone/eslint.config.mjs +31 -0
  265. package/.next/standalone/next.config.ts +8 -0
  266. package/.next/standalone/package-lock.json +10312 -0
  267. package/.next/standalone/package.json +1 -1
  268. package/.next/standalone/postcss.config.mjs +7 -0
  269. package/.next/standalone/src/AGENTS.md +41 -0
  270. package/.next/standalone/src/app/api/AGENTS.md +40 -0
  271. package/.next/standalone/src/app/api/node/events/route.test.ts +196 -0
  272. package/.next/standalone/src/app/api/node/events/route.ts +259 -0
  273. package/.next/standalone/src/app/api/node/health/route.test.ts +190 -0
  274. package/.next/standalone/src/app/api/node/health/route.ts +48 -0
  275. package/.next/standalone/src/app/api/node/sessions/[id]/archive/route.test.ts +128 -0
  276. package/.next/standalone/src/app/api/node/sessions/[id]/archive/route.ts +97 -0
  277. package/.next/standalone/src/app/api/node/sessions/[id]/delete/route.test.ts +113 -0
  278. package/.next/standalone/src/app/api/node/sessions/[id]/delete/route.ts +81 -0
  279. package/.next/standalone/src/app/api/node/sessions/[id]/open-editor/route.test.ts +206 -0
  280. package/.next/standalone/src/app/api/node/sessions/[id]/open-editor/route.ts +123 -0
  281. package/.next/standalone/src/app/api/node/sessions/route.test.ts +408 -0
  282. package/.next/standalone/src/app/api/node/sessions/route.ts +1094 -0
  283. package/.next/standalone/src/app/api/nodes/route.test.ts +237 -0
  284. package/.next/standalone/src/app/api/nodes/route.ts +176 -0
  285. package/.next/standalone/src/app/api/opencode-config/route.test.ts +86 -0
  286. package/.next/standalone/src/app/api/opencode-config/route.ts +376 -0
  287. package/.next/standalone/src/app/api/opencode-config/status/route.ts +31 -0
  288. package/.next/standalone/src/app/api/opencode-events/route.test.ts +624 -0
  289. package/.next/standalone/src/app/api/opencode-events/route.ts +508 -0
  290. package/.next/standalone/src/app/api/opencode-models/route.test.ts +167 -0
  291. package/.next/standalone/src/app/api/opencode-models/route.ts +76 -0
  292. package/.next/standalone/src/app/api/profiles/[id]/apply/route.ts +49 -0
  293. package/.next/standalone/src/app/api/profiles/[id]/export/route.ts +31 -0
  294. package/.next/standalone/src/app/api/profiles/[id]/route.ts +160 -0
  295. package/.next/standalone/src/app/api/profiles/import/route.test.js +107 -0
  296. package/.next/standalone/src/app/api/profiles/import/route.ts +65 -0
  297. package/.next/standalone/src/app/api/profiles/route.ts +107 -0
  298. package/.next/standalone/src/app/api/sessions/[id]/archive/route.test.ts +136 -0
  299. package/.next/standalone/src/app/api/sessions/[id]/archive/route.ts +170 -0
  300. package/.next/standalone/src/app/api/sessions/[id]/delete/route.test.ts +113 -0
  301. package/.next/standalone/src/app/api/sessions/[id]/delete/route.ts +137 -0
  302. package/.next/standalone/src/app/api/sessions/[id]/open-editor/route.test.ts +218 -0
  303. package/.next/standalone/src/app/api/sessions/[id]/open-editor/route.ts +85 -0
  304. package/.next/standalone/src/app/api/sessions/[id]/route.test.ts +531 -0
  305. package/.next/standalone/src/app/api/sessions/[id]/route.ts +75 -0
  306. package/.next/standalone/src/app/api/sessions/route.test.ts +1298 -0
  307. package/.next/standalone/src/app/api/sessions/route.ts +1695 -0
  308. package/.next/standalone/src/app/favicon.ico +0 -0
  309. package/.next/standalone/src/app/globals.css +66 -0
  310. package/.next/standalone/src/app/layout.tsx +37 -0
  311. package/.next/standalone/src/app/page.test.tsx +134 -0
  312. package/.next/standalone/src/app/page.tsx +358 -0
  313. package/.next/standalone/src/components/AGENTS.md +42 -0
  314. package/.next/standalone/src/components/ErrorBoundary.tsx +72 -0
  315. package/.next/standalone/src/components/KanbanBoard.test.tsx +704 -0
  316. package/.next/standalone/src/components/KanbanBoard.tsx +852 -0
  317. package/.next/standalone/src/components/LoadingState.tsx +37 -0
  318. package/.next/standalone/src/components/ProjectCard.test.tsx +773 -0
  319. package/.next/standalone/src/components/ProjectCard.tsx +595 -0
  320. package/.next/standalone/src/components/QueryProvider.tsx +25 -0
  321. package/.next/standalone/src/components/SessionCard.test.tsx +566 -0
  322. package/.next/standalone/src/components/SessionCard.tsx +434 -0
  323. package/.next/standalone/src/components/SessionList.tsx +60 -0
  324. package/.next/standalone/src/components/host-config/HostManagerDialog.test.tsx +252 -0
  325. package/.next/standalone/src/components/host-config/HostManagerDialog.tsx +476 -0
  326. package/.next/standalone/src/components/opencode-config/AgentConfigForm.test.tsx +72 -0
  327. package/.next/standalone/src/components/opencode-config/AgentConfigForm.tsx +483 -0
  328. package/.next/standalone/src/components/opencode-config/AgentModelSelector.tsx +284 -0
  329. package/.next/standalone/src/components/opencode-config/AgentsConfigPanel.tsx +162 -0
  330. package/.next/standalone/src/components/opencode-config/ConfigButton.tsx +43 -0
  331. package/.next/standalone/src/components/opencode-config/ConfigPanel.tsx +91 -0
  332. package/.next/standalone/src/components/opencode-config/FullscreenConfigPanel.tsx +435 -0
  333. package/.next/standalone/src/components/opencode-config/GeneralSettingsForm.test.tsx +91 -0
  334. package/.next/standalone/src/components/opencode-config/GeneralSettingsForm.tsx +288 -0
  335. package/.next/standalone/src/components/opencode-config/categories/CategoriesList.tsx +382 -0
  336. package/.next/standalone/src/components/opencode-config/categories/CategoriesManager.test.tsx +111 -0
  337. package/.next/standalone/src/components/opencode-config/categories/CategoriesManager.tsx +174 -0
  338. package/.next/standalone/src/components/opencode-config/categories/CategoryConfigForm.tsx +453 -0
  339. package/.next/standalone/src/components/opencode-config/profiles/ProfileCard.tsx +140 -0
  340. package/.next/standalone/src/components/opencode-config/profiles/ProfileEditor.tsx +446 -0
  341. package/.next/standalone/src/components/opencode-config/profiles/ProfileList.tsx +446 -0
  342. package/.next/standalone/src/components/opencode-config/profiles/ProfileManager.test.tsx +225 -0
  343. package/.next/standalone/src/components/opencode-config/profiles/ProfileManager.tsx +405 -0
  344. package/.next/standalone/src/components/ui/Tabs.tsx +59 -0
  345. package/.next/standalone/src/hooks/useHostSources.test.ts +509 -0
  346. package/.next/standalone/src/hooks/useHostSources.ts +299 -0
  347. package/.next/standalone/src/hooks/useOpencodeSync.test.ts +387 -0
  348. package/.next/standalone/src/hooks/useOpencodeSync.ts +571 -0
  349. package/.next/standalone/src/index.ts +2 -0
  350. package/.next/standalone/src/lib/editorLauncher.server.ts +36 -0
  351. package/.next/standalone/src/lib/editorLauncher.test.ts +35 -0
  352. package/.next/standalone/src/lib/editorLauncher.ts +25 -0
  353. package/.next/standalone/src/lib/hostAccent.test.ts +58 -0
  354. package/.next/standalone/src/lib/hostAccent.ts +46 -0
  355. package/.next/standalone/src/lib/hostIdentity.test.ts +187 -0
  356. package/.next/standalone/src/lib/hostIdentity.ts +122 -0
  357. package/.next/standalone/src/lib/hostSourcesStorage.test.ts +141 -0
  358. package/.next/standalone/src/lib/hostSourcesStorage.ts +72 -0
  359. package/.next/standalone/src/lib/nodeProtocol.test.ts +159 -0
  360. package/.next/standalone/src/lib/nodeProtocol.ts +142 -0
  361. package/.next/standalone/src/lib/nodeRegistry.test.ts +173 -0
  362. package/.next/standalone/src/lib/nodeRegistry.ts +398 -0
  363. package/.next/standalone/src/lib/notificationSound.ts +292 -0
  364. package/.next/standalone/src/lib/opencodeConfig.test.ts +100 -0
  365. package/.next/standalone/src/lib/opencodeConfig.ts +76 -0
  366. package/.next/standalone/src/lib/opencodeDiscovery.ts +275 -0
  367. package/.next/standalone/src/lib/profiles/share.test.ts +91 -0
  368. package/.next/standalone/src/lib/profiles/share.ts +93 -0
  369. package/.next/standalone/src/lib/profiles/storage.test.ts +108 -0
  370. package/.next/standalone/src/lib/profiles/storage.ts +370 -0
  371. package/.next/standalone/src/lib/runtimeMode.test.ts +29 -0
  372. package/.next/standalone/src/lib/runtimeMode.ts +29 -0
  373. package/.next/standalone/src/lib/sessionActionErrors.ts +37 -0
  374. package/.next/standalone/src/lib/sessionArchiveOverrides.test.ts +43 -0
  375. package/.next/standalone/src/lib/sessionArchiveOverrides.ts +116 -0
  376. package/.next/standalone/src/lib/transform.test.ts +121 -0
  377. package/.next/standalone/src/lib/transform.ts +193 -0
  378. package/.next/standalone/src/test/setup.ts +8 -0
  379. package/.next/standalone/src/types/index.ts +152 -0
  380. package/.next/standalone/src/types/opencodeConfig.ts +149 -0
  381. package/.next/standalone/tsconfig.json +34 -0
  382. package/.next/standalone/tsconfig.lib.json +17 -0
  383. package/.next/standalone/vitest.config.ts +16 -0
  384. package/.next/static/chunks/7ac19aaef01f4a03.js +13 -0
  385. package/.next/static/chunks/f42202943f6742e5.css +3 -0
  386. package/.next/trace +1 -1
  387. package/.next/trace-build +1 -1
  388. package/.next/types/routes.d.ts +5 -1
  389. package/.next/types/validator.ts +36 -0
  390. package/package.json +1 -1
  391. package/.next/server/chunks/[root-of-the-server]__0b017945._.js +0 -3
  392. package/.next/server/chunks/[root-of-the-server]__0b017945._.js.map +0 -1
  393. package/.next/server/chunks/[root-of-the-server]__1e118bd3._.js +0 -3
  394. package/.next/server/chunks/[root-of-the-server]__1e118bd3._.js.map +0 -1
  395. package/.next/server/chunks/[root-of-the-server]__6979e732._.js +0 -3
  396. package/.next/server/chunks/[root-of-the-server]__6979e732._.js.map +0 -1
  397. package/.next/server/chunks/[root-of-the-server]__a7b4d79d._.js +0 -3
  398. package/.next/server/chunks/[root-of-the-server]__a7b4d79d._.js.map +0 -1
  399. package/.next/server/chunks/[root-of-the-server]__b698889b._.js.map +0 -1
  400. package/.next/server/chunks/[root-of-the-server]__ddc251b7._.js +0 -3
  401. package/.next/server/chunks/[root-of-the-server]__ddc251b7._.js.map +0 -1
  402. package/.next/server/chunks/ssr/[root-of-the-server]__b0788643._.js +0 -3
  403. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0b017945._.js +0 -3
  404. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1e118bd3._.js +0 -3
  405. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6979e732._.js +0 -3
  406. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a7b4d79d._.js +0 -3
  407. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ddc251b7._.js +0 -3
  408. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__b0788643._.js +0 -3
  409. package/.next/standalone/.next/static/chunks/9f8c22002e7395e8.js +0 -13
  410. package/.next/standalone/.next/static/chunks/f1b55db60e7ed6f3.css +0 -3
  411. package/.next/static/chunks/9f8c22002e7395e8.js +0 -13
  412. package/.next/static/chunks/f1b55db60e7ed6f3.css +0 -3
  413. /package/.next/server/chunks/ssr/{[root-of-the-server]__efc52f08._.js.map → [root-of-the-server]__631e12d0._.js.map} +0 -0
  414. /package/.next/server/chunks/ssr/{[root-of-the-server]__b0788643._.js.map → [root-of-the-server]__a8cd3911._.js.map} +0 -0
  415. /package/.next/standalone/.next/static/{L_tmqf71LaeMzApO4SiU- → Fw2R3y-fHX4B2SWxNy_4X}/_buildManifest.js +0 -0
  416. /package/.next/standalone/.next/static/{L_tmqf71LaeMzApO4SiU- → Fw2R3y-fHX4B2SWxNy_4X}/_clientMiddlewareManifest.json +0 -0
  417. /package/.next/standalone/.next/static/{L_tmqf71LaeMzApO4SiU- → Fw2R3y-fHX4B2SWxNy_4X}/_ssgManifest.js +0 -0
  418. /package/.next/static/{L_tmqf71LaeMzApO4SiU- → Fw2R3y-fHX4B2SWxNy_4X}/_buildManifest.js +0 -0
  419. /package/.next/static/{L_tmqf71LaeMzApO4SiU- → Fw2R3y-fHX4B2SWxNy_4X}/_clientMiddlewareManifest.json +0 -0
  420. /package/.next/static/{L_tmqf71LaeMzApO4SiU- → Fw2R3y-fHX4B2SWxNy_4X}/_ssgManifest.js +0 -0
@@ -0,0 +1,531 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+
3
+ vi.mock('@opencode-ai/sdk', () => ({
4
+ createOpencodeClient: vi.fn(),
5
+ }));
6
+
7
+ vi.mock('@/lib/opencodeDiscovery', () => ({
8
+ discoverOpencodePortsWithMeta: vi.fn(),
9
+ }));
10
+
11
+ vi.mock('@/lib/sessionArchiveOverrides', () => ({
12
+ clearSessionForceUnarchived: vi.fn(),
13
+ clearSessionStickyStatusBlocked: vi.fn(),
14
+ markSessionStickyStatusBlocked: vi.fn(),
15
+ }));
16
+
17
+ vi.mock('@/lib/nodeRegistry', () => ({
18
+ listNodeRecords: vi.fn(),
19
+ }));
20
+
21
+ import { createOpencodeClient } from '@opencode-ai/sdk';
22
+ import { discoverOpencodePortsWithMeta } from '@/lib/opencodeDiscovery';
23
+ import {
24
+ clearSessionForceUnarchived,
25
+ clearSessionStickyStatusBlocked,
26
+ markSessionStickyStatusBlocked,
27
+ } from '@/lib/sessionArchiveOverrides';
28
+ import { listNodeRecords } from '@/lib/nodeRegistry';
29
+
30
+ import { GET } from './route';
31
+ import { POST as archiveSession } from './archive/route';
32
+ import { POST as deleteSession } from './delete/route';
33
+
34
+ type CreateOpencodeClientMock = {
35
+ mock: { calls: unknown[][] };
36
+ mockReturnValue: (value: unknown) => void;
37
+ };
38
+
39
+ type DiscoverPortsMock = {
40
+ mockReturnValue: (value: { ports: number[]; timedOut: boolean }) => void;
41
+ };
42
+
43
+ type SideEffectMock = {
44
+ mock: { calls: unknown[][] };
45
+ };
46
+
47
+ type SessionDeleteMock = {
48
+ mock: { calls: unknown[][] };
49
+ mockRejectedValueOnce: (error: Error) => void;
50
+ mockResolvedValueOnce: (value?: unknown) => void;
51
+ };
52
+
53
+ type FetchMock = {
54
+ (...args: unknown[]): Promise<Response>;
55
+ mock: { calls: unknown[][] };
56
+ };
57
+
58
+ const mockCreateOpencodeClient = createOpencodeClient as unknown as CreateOpencodeClientMock;
59
+ const mockDiscoverPortsWithMeta = discoverOpencodePortsWithMeta as unknown as DiscoverPortsMock;
60
+ const mockClearSessionForceUnarchived = clearSessionForceUnarchived as unknown as SideEffectMock;
61
+ const mockClearSessionStickyStatusBlocked = clearSessionStickyStatusBlocked as unknown as SideEffectMock;
62
+ const mockMarkSessionStickyStatusBlocked = markSessionStickyStatusBlocked as unknown as SideEffectMock;
63
+ const mockListNodeRecords = listNodeRecords as unknown as {
64
+ mockResolvedValue: (value: unknown) => void;
65
+ };
66
+
67
+ describe('/api/sessions/[id] composite id handling', () => {
68
+ beforeEach(() => {
69
+ vi.clearAllMocks();
70
+ vi.unstubAllGlobals();
71
+ mockDiscoverPortsWithMeta.mockReturnValue({ ports: [7777], timedOut: false });
72
+ mockListNodeRecords.mockResolvedValue([]);
73
+ });
74
+
75
+ afterEach(() => {
76
+ vi.unstubAllGlobals();
77
+ });
78
+
79
+ it('maps local composite ids to raw ids for session detail reads', async () => {
80
+ const sessionGet = vi.fn(async () => ({
81
+ data: {
82
+ id: 'abc',
83
+ title: 'Local Session',
84
+ },
85
+ }));
86
+
87
+ mockCreateOpencodeClient.mockReturnValue({
88
+ session: {
89
+ get: sessionGet,
90
+ },
91
+ } as never);
92
+
93
+ const response = await GET(new Request('http://localhost/api/sessions/local:abc'), {
94
+ params: Promise.resolve({ id: 'local:abc' }),
95
+ });
96
+ const data = await response.json();
97
+
98
+ expect(response.status).toBe(200);
99
+ expect(sessionGet).toHaveBeenCalledWith({ path: { id: 'abc' } });
100
+ expect(data).toEqual({
101
+ session: {
102
+ id: 'abc',
103
+ title: 'Local Session',
104
+ },
105
+ });
106
+ });
107
+
108
+ it('rejects non-local (remote node) composite ids for session detail reads', async () => {
109
+ const response = await GET(new Request('http://localhost/api/sessions/remote-a:abc'), {
110
+ params: Promise.resolve({ id: 'remote-a:abc' }),
111
+ });
112
+ const data = await response.json();
113
+
114
+ expect(response.status).toBe(404);
115
+ expect(data).toEqual({ error: 'Session not found' });
116
+ expect(mockCreateOpencodeClient.mock.calls).toHaveLength(0);
117
+ });
118
+
119
+ it('keeps remote node sessions read-only by rejecting node composite ids for detail reads', async () => {
120
+ const response = await GET(new Request('http://localhost/api/sessions/node-1:abc'), {
121
+ params: Promise.resolve({ id: 'node-1:abc' }),
122
+ });
123
+ const data = await response.json();
124
+
125
+ expect(response.status).toBe(404);
126
+ expect(data).toEqual({ error: 'Session not found' });
127
+ expect(mockCreateOpencodeClient.mock.calls).toHaveLength(0);
128
+ });
129
+
130
+ it('maps local composite ids to raw ids for local archive operations', async () => {
131
+ const mockFetch = vi.fn(async () => new Response('', { status: 200 })) as unknown as FetchMock;
132
+ vi.stubGlobal('fetch', mockFetch);
133
+
134
+ const response = await archiveSession(new Request('http://localhost/api/sessions/local:abc/archive', { method: 'POST' }), {
135
+ params: Promise.resolve({ id: 'local:abc' }),
136
+ });
137
+ const data = await response.json();
138
+
139
+ expect(response.status).toBe(200);
140
+ expect(mockFetch).toHaveBeenCalledTimes(1);
141
+ expect(mockFetch.mock.calls[0][0]).toBe('http://localhost:7777/session/abc');
142
+ expect(mockClearSessionForceUnarchived).toHaveBeenCalledWith('abc');
143
+ expect(mockMarkSessionStickyStatusBlocked).toHaveBeenCalledWith('abc');
144
+ expect(data).toEqual({ success: true });
145
+ });
146
+
147
+ it('rejects remote composite ids for local archive operations', async () => {
148
+ const mockFetch = vi.fn(async () => new Response('', { status: 200 })) as unknown as FetchMock;
149
+ vi.stubGlobal('fetch', mockFetch);
150
+
151
+ const response = await archiveSession(new Request('http://localhost/api/sessions/remote-a:abc/archive', { method: 'POST' }), {
152
+ params: Promise.resolve({ id: 'remote-a:abc' }),
153
+ });
154
+ const data = await response.json();
155
+
156
+ expect(response.status).toBe(404);
157
+ expect(data).toEqual({ error: 'Session not found', reason: 'session_not_found' });
158
+ expect(mockFetch.mock.calls).toHaveLength(0);
159
+ });
160
+
161
+ it('forwards remote archive operations to the matching node once', async () => {
162
+ mockListNodeRecords.mockResolvedValue([
163
+ {
164
+ nodeId: 'node-1',
165
+ nodeLabel: 'Node 1',
166
+ baseUrl: 'https://node-1.test',
167
+ enabled: true,
168
+ token: 'node-token',
169
+ createdAt: new Date().toISOString(),
170
+ updatedAt: new Date().toISOString(),
171
+ },
172
+ ]);
173
+ const mockFetch = vi.fn(async () => new Response(JSON.stringify({ success: true }), { status: 200 })) as unknown as FetchMock;
174
+ vi.stubGlobal('fetch', mockFetch);
175
+
176
+ const response = await archiveSession(new Request('http://localhost/api/sessions/node-1:abc/archive', { method: 'POST' }), {
177
+ params: Promise.resolve({ id: 'node-1:abc' }),
178
+ });
179
+ const data = await response.json();
180
+ const headers = new Headers((mockFetch.mock.calls[0][1] as RequestInit | undefined)?.headers);
181
+
182
+ expect(response.status).toBe(200);
183
+ expect(data).toEqual({ success: true });
184
+ expect(mockFetch).toHaveBeenCalledTimes(1);
185
+ expect(mockFetch.mock.calls[0][0]).toBe('https://node-1.test/api/node/sessions/abc/archive');
186
+ expect(headers.get('x-vibepulse-node-version')).toBe('1');
187
+ expect(headers.get('authorization')).toBe('Bearer node-token');
188
+ });
189
+
190
+ it('surfaces remote archive auth failures deterministically', async () => {
191
+ mockListNodeRecords.mockResolvedValue([
192
+ {
193
+ nodeId: 'node-1',
194
+ nodeLabel: 'Node 1',
195
+ baseUrl: 'https://node-1.test',
196
+ enabled: true,
197
+ token: 'node-token',
198
+ createdAt: new Date().toISOString(),
199
+ updatedAt: new Date().toISOString(),
200
+ },
201
+ ]);
202
+ const mockFetch = vi.fn(async () => new Response(JSON.stringify({ reason: 'unauthorized' }), { status: 401 })) as unknown as FetchMock;
203
+ vi.stubGlobal('fetch', mockFetch);
204
+
205
+ const response = await archiveSession(new Request('http://localhost/api/sessions/node-1:abc/archive', { method: 'POST' }), {
206
+ params: Promise.resolve({ id: 'node-1:abc' }),
207
+ });
208
+ const data = await response.json();
209
+
210
+ expect(response.status).toBe(401);
211
+ expect(data).toEqual({ error: 'Remote archive failed', reason: 'unauthorized' });
212
+ });
213
+
214
+ it('surfaces remote archive forbidden failures deterministically', async () => {
215
+ mockListNodeRecords.mockResolvedValue([
216
+ {
217
+ nodeId: 'node-1',
218
+ nodeLabel: 'Node 1',
219
+ baseUrl: 'https://node-1.test',
220
+ enabled: true,
221
+ token: 'node-token',
222
+ createdAt: new Date().toISOString(),
223
+ updatedAt: new Date().toISOString(),
224
+ },
225
+ ]);
226
+ const mockFetch = vi.fn(async () => new Response(JSON.stringify({ reason: 'node_request_failed_403' }), { status: 403 })) as unknown as FetchMock;
227
+ vi.stubGlobal('fetch', mockFetch);
228
+
229
+ const response = await archiveSession(new Request('http://localhost/api/sessions/node-1:abc/archive', { method: 'POST' }), {
230
+ params: Promise.resolve({ id: 'node-1:abc' }),
231
+ });
232
+ const data = await response.json();
233
+
234
+ expect(response.status).toBe(403);
235
+ expect(data).toEqual({ error: 'Remote archive failed', reason: 'node_request_failed_403' });
236
+ });
237
+
238
+ it('maps remote archive timeouts to upstream_timeout', async () => {
239
+ vi.useFakeTimers();
240
+ mockListNodeRecords.mockResolvedValue([
241
+ {
242
+ nodeId: 'node-1',
243
+ nodeLabel: 'Node 1',
244
+ baseUrl: 'https://node-1.test',
245
+ enabled: true,
246
+ token: 'node-token',
247
+ createdAt: new Date().toISOString(),
248
+ updatedAt: new Date().toISOString(),
249
+ },
250
+ ]);
251
+ const mockFetch = vi.fn((_url: unknown, init?: RequestInit) => new Promise<Response>((_, reject) => {
252
+ init?.signal?.addEventListener('abort', () => reject(new Error('aborted')), { once: true });
253
+ })) as unknown as FetchMock;
254
+ vi.stubGlobal('fetch', mockFetch);
255
+
256
+ const responsePromise = archiveSession(new Request('http://localhost/api/sessions/node-1:abc/archive', { method: 'POST' }), {
257
+ params: Promise.resolve({ id: 'node-1:abc' }),
258
+ });
259
+
260
+ await vi.advanceTimersByTimeAsync(5000);
261
+ const response = await responsePromise;
262
+ const data = await response.json();
263
+
264
+ expect(response.status).toBe(504);
265
+ expect(data).toEqual({ error: 'Remote node request timed out', reason: 'upstream_timeout' });
266
+ vi.useRealTimers();
267
+ });
268
+
269
+ it('surfaces unsupported remote archive routes deterministically', async () => {
270
+ mockListNodeRecords.mockResolvedValue([
271
+ {
272
+ nodeId: 'node-1',
273
+ nodeLabel: 'Node 1',
274
+ baseUrl: 'https://node-1.test',
275
+ enabled: true,
276
+ token: 'node-token',
277
+ createdAt: new Date().toISOString(),
278
+ updatedAt: new Date().toISOString(),
279
+ },
280
+ ]);
281
+ const mockFetch = vi.fn(async () => new Response(JSON.stringify({ reason: 'node_request_failed_501' }), { status: 501 })) as unknown as FetchMock;
282
+ vi.stubGlobal('fetch', mockFetch);
283
+
284
+ const response = await archiveSession(new Request('http://localhost/api/sessions/node-1:abc/archive', { method: 'POST' }), {
285
+ params: Promise.resolve({ id: 'node-1:abc' }),
286
+ });
287
+ const data = await response.json();
288
+
289
+ expect(response.status).toBe(501);
290
+ expect(data).toEqual({ error: 'Remote archive failed', reason: 'node_request_failed_501' });
291
+ });
292
+
293
+ it('surfaces missing remote archive routes deterministically', async () => {
294
+ mockListNodeRecords.mockResolvedValue([
295
+ {
296
+ nodeId: 'node-1',
297
+ nodeLabel: 'Node 1',
298
+ baseUrl: 'https://node-1.test',
299
+ enabled: true,
300
+ token: 'node-token',
301
+ createdAt: new Date().toISOString(),
302
+ updatedAt: new Date().toISOString(),
303
+ },
304
+ ]);
305
+ const mockFetch = vi.fn(async () => new Response(JSON.stringify({ reason: 'node_request_failed_404' }), { status: 404 })) as unknown as FetchMock;
306
+ vi.stubGlobal('fetch', mockFetch);
307
+
308
+ const response = await archiveSession(new Request('http://localhost/api/sessions/node-1:abc/archive', { method: 'POST' }), {
309
+ params: Promise.resolve({ id: 'node-1:abc' }),
310
+ });
311
+ const data = await response.json();
312
+
313
+ expect(response.status).toBe(404);
314
+ expect(data).toEqual({ error: 'Remote archive failed', reason: 'node_request_failed_404' });
315
+ });
316
+
317
+ it('maps local composite ids to raw ids for local delete operations', async () => {
318
+ const sessionDelete = vi.fn(async () => undefined);
319
+
320
+ mockCreateOpencodeClient.mockReturnValue({
321
+ session: {
322
+ delete: sessionDelete,
323
+ },
324
+ } as never);
325
+
326
+ const response = await deleteSession(new Request('http://localhost/api/sessions/local:abc/delete', { method: 'POST' }), {
327
+ params: Promise.resolve({ id: 'local:abc' }),
328
+ });
329
+ const data = await response.json();
330
+
331
+ expect(response.status).toBe(200);
332
+ expect(sessionDelete).toHaveBeenCalledWith({ path: { id: 'abc' } });
333
+ expect(mockClearSessionForceUnarchived).toHaveBeenCalledWith('abc');
334
+ expect(mockClearSessionStickyStatusBlocked).toHaveBeenCalledWith('abc');
335
+ expect(data).toEqual({ success: true });
336
+ });
337
+
338
+ it('rejects remote composite ids for local delete operations', async () => {
339
+ const response = await deleteSession(new Request('http://localhost/api/sessions/remote-a:abc/delete', { method: 'POST' }), {
340
+ params: Promise.resolve({ id: 'remote-a:abc' }),
341
+ });
342
+ const data = await response.json();
343
+
344
+ expect(response.status).toBe(404);
345
+ expect(data).toEqual({ error: 'Session not found', reason: 'session_not_found' });
346
+ expect(mockCreateOpencodeClient.mock.calls).toHaveLength(0);
347
+ });
348
+
349
+ it('forwards remote delete operations to the matching node once', async () => {
350
+ mockListNodeRecords.mockResolvedValue([
351
+ {
352
+ nodeId: 'node-1',
353
+ nodeLabel: 'Node 1',
354
+ baseUrl: 'https://node-1.test',
355
+ enabled: true,
356
+ token: 'node-token',
357
+ createdAt: new Date().toISOString(),
358
+ updatedAt: new Date().toISOString(),
359
+ },
360
+ ]);
361
+ const mockFetch = vi.fn(async () => new Response(JSON.stringify({ success: true }), { status: 200 })) as unknown as FetchMock;
362
+ vi.stubGlobal('fetch', mockFetch);
363
+
364
+ const response = await deleteSession(new Request('http://localhost/api/sessions/node-1:abc/delete', { method: 'POST' }), {
365
+ params: Promise.resolve({ id: 'node-1:abc' }),
366
+ });
367
+ const data = await response.json();
368
+ const headers = new Headers((mockFetch.mock.calls[0][1] as RequestInit | undefined)?.headers);
369
+
370
+ expect(response.status).toBe(200);
371
+ expect(data).toEqual({ success: true });
372
+ expect(mockFetch.mock.calls[0][0]).toBe('https://node-1.test/api/node/sessions/abc/delete');
373
+ expect(headers.get('x-vibepulse-node-version')).toBe('1');
374
+ expect(headers.get('authorization')).toBe('Bearer node-token');
375
+ expect(mockCreateOpencodeClient.mock.calls).toHaveLength(0);
376
+ });
377
+
378
+ it('surfaces unsupported remote delete routes deterministically', async () => {
379
+ mockListNodeRecords.mockResolvedValue([
380
+ {
381
+ nodeId: 'node-1',
382
+ nodeLabel: 'Node 1',
383
+ baseUrl: 'https://node-1.test',
384
+ enabled: true,
385
+ token: 'node-token',
386
+ createdAt: new Date().toISOString(),
387
+ updatedAt: new Date().toISOString(),
388
+ },
389
+ ]);
390
+ const mockFetch = vi.fn(async () => new Response(JSON.stringify({ reason: 'node_request_failed_501' }), { status: 501 })) as unknown as FetchMock;
391
+ vi.stubGlobal('fetch', mockFetch);
392
+
393
+ const response = await deleteSession(new Request('http://localhost/api/sessions/node-1:abc/delete', { method: 'POST' }), {
394
+ params: Promise.resolve({ id: 'node-1:abc' }),
395
+ });
396
+ const data = await response.json();
397
+
398
+ expect(response.status).toBe(501);
399
+ expect(data).toEqual({ error: 'Remote delete failed', reason: 'node_request_failed_501' });
400
+ });
401
+
402
+ it('surfaces missing remote delete routes deterministically', async () => {
403
+ mockListNodeRecords.mockResolvedValue([
404
+ {
405
+ nodeId: 'node-1',
406
+ nodeLabel: 'Node 1',
407
+ baseUrl: 'https://node-1.test',
408
+ enabled: true,
409
+ token: 'node-token',
410
+ createdAt: new Date().toISOString(),
411
+ updatedAt: new Date().toISOString(),
412
+ },
413
+ ]);
414
+ const mockFetch = vi.fn(async () => new Response(JSON.stringify({ reason: 'node_request_failed_404' }), { status: 404 })) as unknown as FetchMock;
415
+ vi.stubGlobal('fetch', mockFetch);
416
+
417
+ const response = await deleteSession(new Request('http://localhost/api/sessions/node-1:abc/delete', { method: 'POST' }), {
418
+ params: Promise.resolve({ id: 'node-1:abc' }),
419
+ });
420
+ const data = await response.json();
421
+
422
+ expect(response.status).toBe(404);
423
+ expect(data).toEqual({ error: 'Remote delete failed', reason: 'node_request_failed_404' });
424
+ });
425
+
426
+ it('maps remote delete timeouts to upstream_timeout', async () => {
427
+ vi.useFakeTimers();
428
+ mockListNodeRecords.mockResolvedValue([
429
+ {
430
+ nodeId: 'node-1',
431
+ nodeLabel: 'Node 1',
432
+ baseUrl: 'https://node-1.test',
433
+ enabled: true,
434
+ token: 'node-token',
435
+ createdAt: new Date().toISOString(),
436
+ updatedAt: new Date().toISOString(),
437
+ },
438
+ ]);
439
+ const mockFetch = vi.fn((_url: unknown, init?: RequestInit) => new Promise<Response>((_, reject) => {
440
+ init?.signal?.addEventListener('abort', () => reject(new Error('aborted')), { once: true });
441
+ })) as unknown as FetchMock;
442
+ vi.stubGlobal('fetch', mockFetch);
443
+
444
+ const responsePromise = deleteSession(new Request('http://localhost/api/sessions/node-1:abc/delete', { method: 'POST' }), {
445
+ params: Promise.resolve({ id: 'node-1:abc' }),
446
+ });
447
+
448
+ await vi.advanceTimersByTimeAsync(5000);
449
+ const response = await responsePromise;
450
+ const data = await response.json();
451
+
452
+ expect(response.status).toBe(504);
453
+ expect(data).toEqual({ error: 'Remote node request timed out', reason: 'upstream_timeout' });
454
+ vi.useRealTimers();
455
+ });
456
+
457
+ it('maps remote delete offline failures to upstream_unreachable', async () => {
458
+ mockListNodeRecords.mockResolvedValue([
459
+ {
460
+ nodeId: 'node-1',
461
+ nodeLabel: 'Node 1',
462
+ baseUrl: 'https://node-1.test',
463
+ enabled: true,
464
+ token: 'node-token',
465
+ createdAt: new Date().toISOString(),
466
+ updatedAt: new Date().toISOString(),
467
+ },
468
+ ]);
469
+ const mockFetch = vi.fn(async () => {
470
+ throw new Error('network failed');
471
+ }) as unknown as FetchMock;
472
+ vi.stubGlobal('fetch', mockFetch);
473
+
474
+ const response = await deleteSession(new Request('http://localhost/api/sessions/node-1:abc/delete', { method: 'POST' }), {
475
+ params: Promise.resolve({ id: 'node-1:abc' }),
476
+ });
477
+ const data = await response.json();
478
+
479
+ expect(response.status).toBe(503);
480
+ expect(data).toEqual({ error: 'Remote node request failed', reason: 'upstream_unreachable' });
481
+ });
482
+
483
+ it('falls back to next port when first port fails during delete', async () => {
484
+ mockDiscoverPortsWithMeta.mockReturnValue({ ports: [7777, 7778], timedOut: false });
485
+ const sessionDelete = vi.fn(async () => undefined) as unknown as SessionDeleteMock;
486
+ sessionDelete.mockRejectedValueOnce(new Error('Connection refused'));
487
+
488
+ mockCreateOpencodeClient.mockReturnValue({
489
+ session: {
490
+ delete: sessionDelete,
491
+ },
492
+ } as never);
493
+
494
+ const response = await deleteSession(new Request('http://localhost/api/sessions/local:abc/delete', { method: 'POST' }), {
495
+ params: Promise.resolve({ id: 'local:abc' }),
496
+ });
497
+
498
+ expect(response.status).toBe(200);
499
+ expect(sessionDelete.mock.calls).toHaveLength(2);
500
+ expect(sessionDelete.mock.calls[0]).toEqual([{ path: { id: 'abc' } }]);
501
+ expect(mockClearSessionForceUnarchived).toHaveBeenCalledWith('abc');
502
+ expect(mockClearSessionStickyStatusBlocked).toHaveBeenCalledWith('abc');
503
+ });
504
+
505
+ it('returns informed error when all ports fail during delete', async () => {
506
+ mockDiscoverPortsWithMeta.mockReturnValue({ ports: [7777, 7778], timedOut: false });
507
+ const sessionDelete = vi.fn(async () => undefined) as unknown as SessionDeleteMock;
508
+ sessionDelete.mockRejectedValueOnce(new Error('Connection refused'));
509
+ sessionDelete.mockRejectedValueOnce(new Error('Timeout'));
510
+
511
+ mockCreateOpencodeClient.mockReturnValue({
512
+ session: {
513
+ delete: sessionDelete,
514
+ },
515
+ } as never);
516
+
517
+ const response = await deleteSession(new Request('http://localhost/api/sessions/local:abc/delete', { method: 'POST' }), {
518
+ params: Promise.resolve({ id: 'local:abc' }),
519
+ });
520
+ const data = await response.json();
521
+
522
+ expect(response.status).toBe(500);
523
+ expect(data).toEqual({
524
+ error: 'Failed to delete session',
525
+ message: 'Timeout',
526
+ portsTried: 2,
527
+ });
528
+ expect(mockClearSessionForceUnarchived.mock.calls).toHaveLength(0);
529
+ expect(mockClearSessionStickyStatusBlocked.mock.calls).toHaveLength(0);
530
+ });
531
+ });
@@ -0,0 +1,75 @@
1
+ import { createOpencodeClient } from '@opencode-ai/sdk';
2
+ import { discoverOpencodePortsWithMeta } from '@/lib/opencodeDiscovery';
3
+ import { parseSourceKey } from '@/lib/hostIdentity';
4
+
5
+ function resolveLocalSessionId(id: string): string | null {
6
+ if (!id.includes(':')) {
7
+ return id;
8
+ }
9
+
10
+ try {
11
+ const { hostId, sessionId } = parseSourceKey(id);
12
+ return hostId === 'local' ? sessionId : null;
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+
18
+ export async function GET(
19
+ _: Request,
20
+ { params }: { params: Promise<{ id: string }> }
21
+ ) {
22
+ const { id } = await params;
23
+ const sessionId = resolveLocalSessionId(id);
24
+
25
+ if (!sessionId) {
26
+ return Response.json({ error: 'Session not found' }, { status: 404 });
27
+ }
28
+
29
+ const { ports, timedOut } = discoverOpencodePortsWithMeta();
30
+
31
+ if (!ports.length) {
32
+ if (timedOut) {
33
+ return Response.json(
34
+ {
35
+ error: 'OpenCode discovery timed out',
36
+ hint: 'Host process discovery exceeded timeout. Retry shortly, or increase OPENCODE_DISCOVERY_TIMEOUT_MS.'
37
+ },
38
+ { status: 503 }
39
+ );
40
+ }
41
+
42
+ return Response.json(
43
+ {
44
+ error: 'OpenCode server not found',
45
+ hint: 'Make sure OpenCode is running with an exposed API port. Example: opencode --port <PORT> (VibePulse auto-detects active ports).'
46
+ },
47
+ { status: 503 }
48
+ );
49
+ }
50
+
51
+ try {
52
+ for (const port of ports) {
53
+ try {
54
+ const client = createOpencodeClient({ baseUrl: `http://localhost:${port}` });
55
+ const result = await client.session.get({ path: { id: sessionId } });
56
+ if (result.data) {
57
+ return Response.json({ session: result.data });
58
+ }
59
+ } catch {
60
+ // Try next port
61
+ }
62
+ }
63
+ return Response.json({ error: 'Session not found' }, { status: 404 });
64
+ } catch (error) {
65
+ console.error('Error fetching session:', error);
66
+ return Response.json(
67
+ {
68
+ error: 'Failed to fetch session',
69
+ details: error instanceof Error ? error.message : String(error),
70
+ hint: 'Make sure OpenCode is running with an exposed API port. Example: opencode --port <PORT> (VibePulse auto-detects active ports).'
71
+ },
72
+ { status: 500 }
73
+ );
74
+ }
75
+ }