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,773 @@
1
+ import * as TestingLibraryReact from '@testing-library/react';
2
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
3
+ import '@testing-library/jest-dom';
4
+ import { ProjectCard } from './ProjectCard';
5
+ import { KanbanCard } from '@/types';
6
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
7
+
8
+ type RenderFn = (ui: React.ReactElement) => { rerender: (ui: React.ReactElement) => void };
9
+ type Screen = {
10
+ getByText: (text: string | RegExp) => HTMLElement;
11
+ getByTitle: (title: string | RegExp) => HTMLElement;
12
+ queryByTitle: (title: string | RegExp) => HTMLElement | null;
13
+ };
14
+
15
+ const tlReact = TestingLibraryReact as unknown as {
16
+ render: RenderFn,
17
+ screen: Screen
18
+ };
19
+ const { render, screen } = tlReact;
20
+
21
+ const createQueryClient = () => new QueryClient({
22
+ defaultOptions: {
23
+ queries: { retry: false },
24
+ },
25
+ });
26
+
27
+ function renderWithProviders(ui: React.ReactElement) {
28
+ const queryClient = createQueryClient();
29
+ return render(
30
+ <QueryClientProvider client={queryClient}>
31
+ {ui}
32
+ </QueryClientProvider>
33
+ );
34
+ }
35
+
36
+ describe('ProjectCard', () => {
37
+ const mockCard: KanbanCard = {
38
+ id: 'local:123',
39
+ sessionSlug: 'session_123_abc',
40
+ title: 'Test Session',
41
+ directory: '/path/to/project',
42
+ projectName: 'TestProject',
43
+ agents: ['agent1'],
44
+ messageCount: 5,
45
+ status: 'idle',
46
+ opencodeStatus: 'idle',
47
+ waitingForUser: false,
48
+ todosTotal: 0,
49
+ todosCompleted: 0,
50
+ createdAt: 1000,
51
+ updatedAt: 2000,
52
+ sortOrder: 0,
53
+ hostId: 'local',
54
+ hostLabel: 'Local',
55
+ hostKind: 'local',
56
+ rawSessionId: '123',
57
+ readOnly: false
58
+ };
59
+
60
+ beforeEach(() => {
61
+ vi.clearAllMocks();
62
+ window.localStorage.clear();
63
+ const mockFetch = vi.fn(() => Promise.resolve({ ok: true } as Response)) as unknown as typeof fetch;
64
+ Object.defineProperty(globalThis, 'fetch', { value: mockFetch, configurable: true });
65
+ Object.defineProperty(window, 'location', {
66
+ value: {
67
+ assign: vi.fn(),
68
+ hostname: 'localhost',
69
+ },
70
+ configurable: true,
71
+ writable: true,
72
+ });
73
+
74
+ const mockConfirm = vi.fn(() => true) as unknown as typeof window.confirm;
75
+ Object.defineProperty(window, 'confirm', { value: mockConfirm, configurable: true });
76
+ });
77
+
78
+ it('renders local project card normally', () => {
79
+ renderWithProviders(
80
+ <ProjectCard projectName="TestProject" cards={[mockCard]} />
81
+ );
82
+
83
+ expect(screen.getByText('TestProject')).toBeTruthy();
84
+ expect(screen.getByText('Test Session')).toBeTruthy();
85
+ expect(screen.getByTitle('Open project')).toBeTruthy();
86
+ expect(screen.queryByTitle('Source: Local')).toBeNull();
87
+ });
88
+
89
+ it('exposes grouped action surfaces for writable projects', () => {
90
+ renderWithProviders(
91
+ <ProjectCard projectName="TestProject" cards={[mockCard]} />
92
+ );
93
+
94
+ expect(screen.getByTitle('Batch actions')).toBeTruthy();
95
+ expect(screen.getByTitle('Actions')).toBeTruthy();
96
+ });
97
+
98
+ it('shows archive-all and delete-all menu items for writable projects', () => {
99
+ const { fireEvent } = TestingLibraryReact;
100
+
101
+ renderWithProviders(
102
+ <ProjectCard projectName="TestProject" cards={[mockCard]} />
103
+ );
104
+
105
+ fireEvent.click(screen.getByTitle('Batch actions'));
106
+
107
+ expect(screen.getByText('Archive all')).toBeTruthy();
108
+ expect(screen.getByText('Delete all')).toBeTruthy();
109
+ });
110
+
111
+ it('calls the hub open-editor route for remote-mode project opens', async () => {
112
+ const remoteCard: KanbanCard = {
113
+ ...mockCard,
114
+ id: 'node-1:123',
115
+ hostId: 'node-1',
116
+ hostLabel: 'Node 1',
117
+ hostKind: 'remote',
118
+ hostBaseUrl: 'https://node-1.test',
119
+ };
120
+ const queryClient = createQueryClient();
121
+ queryClient.setQueryData(['opencode-config'], { vibepulse: { openEditorTargetMode: 'remote' } });
122
+ const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
123
+ return new Response(JSON.stringify({ success: true }), {
124
+ status: 200,
125
+ headers: { 'Content-Type': 'application/json' },
126
+ });
127
+ });
128
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
129
+
130
+ render(
131
+ <QueryClientProvider client={queryClient}>
132
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
133
+ </QueryClientProvider>
134
+ );
135
+
136
+ const { fireEvent } = TestingLibraryReact;
137
+ await TestingLibraryReact.waitFor(() => {
138
+ expect(screen.getByTitle('Open project')).not.toBeDisabled();
139
+ });
140
+ fireEvent.click(screen.getByTitle('Open project'));
141
+
142
+ await TestingLibraryReact.waitFor(() => {
143
+ expect(fetchMock).toHaveBeenCalledWith('/api/sessions/node-1:123/open-editor', expect.objectContaining({
144
+ method: 'POST',
145
+ }));
146
+ });
147
+ });
148
+
149
+ it('shows an explicit loading state while a remote project open request is in flight', async () => {
150
+ const remoteCard: KanbanCard = {
151
+ ...mockCard,
152
+ id: 'node-1:123',
153
+ hostId: 'node-1',
154
+ hostLabel: 'Node 1',
155
+ hostKind: 'remote',
156
+ hostBaseUrl: 'https://node-1.test',
157
+ };
158
+ const queryClient = createQueryClient();
159
+ queryClient.setQueryData(['opencode-config'], { vibepulse: { openEditorTargetMode: 'remote' } });
160
+ const deferred: { resolve: null | (() => void) } = { resolve: null };
161
+ const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
162
+ await new Promise<void>((resolve) => {
163
+ deferred.resolve = resolve;
164
+ });
165
+
166
+ return new Response(JSON.stringify({ success: true }), {
167
+ status: 200,
168
+ headers: { 'Content-Type': 'application/json' },
169
+ });
170
+ });
171
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
172
+
173
+ render(
174
+ <QueryClientProvider client={queryClient}>
175
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
176
+ </QueryClientProvider>
177
+ );
178
+
179
+ const { fireEvent } = TestingLibraryReact;
180
+ await TestingLibraryReact.waitFor(() => {
181
+ expect(screen.getByTitle('Open project')).not.toBeDisabled();
182
+ });
183
+ fireEvent.click(screen.getByTitle('Open project'));
184
+
185
+ expect(await TestingLibraryReact.screen.findByText('Opening…')).toBeTruthy();
186
+ if (deferred.resolve) {
187
+ deferred.resolve();
188
+ }
189
+ await TestingLibraryReact.waitFor(() => {
190
+ expect(TestingLibraryReact.screen.queryByText('Opening…')).toBeNull();
191
+ });
192
+ });
193
+
194
+ it('keeps URI-based hub-mode open behavior for remote projects', async () => {
195
+ const remoteCard: KanbanCard = {
196
+ ...mockCard,
197
+ id: 'node-1:123',
198
+ hostId: 'node-1',
199
+ hostLabel: 'Node 1',
200
+ hostKind: 'remote',
201
+ hostBaseUrl: 'https://node-1.test',
202
+ };
203
+ const queryClient = createQueryClient();
204
+ queryClient.setQueryData(['opencode-config'], { vibepulse: { openEditorTargetMode: 'hub' } });
205
+ const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
206
+ if (!init?.method || init.method === 'GET') {
207
+ return new Response(JSON.stringify({ vibepulse: { openEditorTargetMode: 'hub' } }), {
208
+ status: 200,
209
+ headers: { 'Content-Type': 'application/json' },
210
+ });
211
+ }
212
+
213
+ return new Response(JSON.stringify({ success: true }), {
214
+ status: 200,
215
+ headers: { 'Content-Type': 'application/json' },
216
+ });
217
+ });
218
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
219
+
220
+ render(
221
+ <QueryClientProvider client={queryClient}>
222
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
223
+ </QueryClientProvider>
224
+ );
225
+
226
+ const { fireEvent } = TestingLibraryReact;
227
+ await TestingLibraryReact.screen.findByText('TestProject');
228
+ fireEvent.click(screen.getByTitle('Open project'));
229
+
230
+ expect(window.location.assign).toHaveBeenCalledWith('vscode://vscode-remote/ssh-remote+node-1.test/path/to/project');
231
+ expect(fetchMock).not.toHaveBeenCalled();
232
+ });
233
+
234
+ it('prefers stored SSH host overrides for remote hub-mode project opens', async () => {
235
+ window.localStorage.setItem('vibepulse:ssh-host', 'override-host.test');
236
+ const remoteCard: KanbanCard = {
237
+ ...mockCard,
238
+ id: 'node-1:123',
239
+ hostId: 'node-1',
240
+ hostLabel: 'Node 1',
241
+ hostKind: 'remote',
242
+ hostBaseUrl: 'https://node-1.test',
243
+ };
244
+ const queryClient = createQueryClient();
245
+ queryClient.setQueryData(['opencode-config'], { vibepulse: { openEditorTargetMode: 'hub' } });
246
+ const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
247
+ if (!init?.method || init.method === 'GET') {
248
+ return new Response(JSON.stringify({ vibepulse: { openEditorTargetMode: 'hub' } }), {
249
+ status: 200,
250
+ headers: { 'Content-Type': 'application/json' },
251
+ });
252
+ }
253
+
254
+ return new Response(JSON.stringify({ success: true }), {
255
+ status: 200,
256
+ headers: { 'Content-Type': 'application/json' },
257
+ });
258
+ });
259
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
260
+
261
+ render(
262
+ <QueryClientProvider client={queryClient}>
263
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
264
+ </QueryClientProvider>
265
+ );
266
+
267
+ const { fireEvent } = TestingLibraryReact;
268
+ await TestingLibraryReact.screen.findByText('TestProject');
269
+ fireEvent.click(screen.getByTitle('Open project'));
270
+
271
+ expect(window.location.assign).toHaveBeenCalledWith('vscode://vscode-remote/ssh-remote+override-host.test/path/to/project');
272
+ expect(fetchMock).not.toHaveBeenCalled();
273
+ });
274
+
275
+ it('shows an explicit error for remote hub-mode Antigravity project opens', async () => {
276
+ window.localStorage.setItem('vibepulse:open-tool', 'antigravity');
277
+ const remoteCard: KanbanCard = {
278
+ ...mockCard,
279
+ id: 'node-1:123',
280
+ hostId: 'node-1',
281
+ hostLabel: 'Node 1',
282
+ hostKind: 'remote',
283
+ hostBaseUrl: 'https://node-1.test',
284
+ };
285
+ const queryClient = createQueryClient();
286
+ queryClient.setQueryData(['opencode-config'], { vibepulse: { openEditorTargetMode: 'hub' } });
287
+ const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
288
+ if (!init?.method || init.method === 'GET') {
289
+ return new Response(JSON.stringify({ vibepulse: { openEditorTargetMode: 'hub' } }), {
290
+ status: 200,
291
+ headers: { 'Content-Type': 'application/json' },
292
+ });
293
+ }
294
+
295
+ return new Response(JSON.stringify({ success: true }), {
296
+ status: 200,
297
+ headers: { 'Content-Type': 'application/json' },
298
+ });
299
+ });
300
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
301
+
302
+ render(
303
+ <QueryClientProvider client={queryClient}>
304
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
305
+ </QueryClientProvider>
306
+ );
307
+
308
+ const { fireEvent } = TestingLibraryReact;
309
+ await TestingLibraryReact.screen.findByText('TestProject');
310
+ fireEvent.click(screen.getByTitle('Open project'));
311
+
312
+ expect(await TestingLibraryReact.screen.findByText('Antigravity does not support hub-mode remote opens. Use VS Code or switch target mode to Remote node.')).toBeTruthy();
313
+ expect(window.location.assign).not.toHaveBeenCalled();
314
+ expect(fetchMock).not.toHaveBeenCalled();
315
+ });
316
+
317
+ it('keeps local project opens on the file-based URI flow', async () => {
318
+ window.localStorage.setItem('vibepulse:ssh-host', 'node-1.test');
319
+ const fetchMock = vi.fn(async () => new Response(JSON.stringify({ vibepulse: { openEditorTargetMode: 'remote' } }), {
320
+ status: 200,
321
+ headers: { 'Content-Type': 'application/json' },
322
+ }));
323
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
324
+
325
+ renderWithProviders(
326
+ <ProjectCard projectName="TestProject" cards={[mockCard]} />
327
+ );
328
+
329
+ const { fireEvent } = TestingLibraryReact;
330
+ fireEvent.click(screen.getByTitle('Open project'));
331
+
332
+ expect(window.location.assign).toHaveBeenCalledWith('vscode://file/path/to/project');
333
+ });
334
+
335
+ it('blocks mixed-host destructive batch actions without calling mutation APIs', async () => {
336
+ const mixedCards: KanbanCard[] = [
337
+ mockCard,
338
+ {
339
+ ...mockCard,
340
+ id: 'node-1:456',
341
+ hostId: 'node-1',
342
+ hostLabel: 'Node 1',
343
+ hostKind: 'remote',
344
+ rawSessionId: '456',
345
+ },
346
+ ];
347
+
348
+ renderWithProviders(
349
+ <ProjectCard projectName="TestProject" cards={mixedCards} />
350
+ );
351
+
352
+ const { fireEvent } = TestingLibraryReact;
353
+ fireEvent.click(screen.getByTitle('Batch actions'));
354
+ fireEvent.click(screen.getByText('Archive all'));
355
+
356
+ expect(screen.getByText('Mixed-host archive is not supported')).toBeTruthy();
357
+ expect(globalThis.fetch).toHaveBeenCalledTimes(1);
358
+ });
359
+
360
+ it('archives a single-host remote project and invalidates the sessions query', async () => {
361
+ const remoteCard: KanbanCard = {
362
+ ...mockCard,
363
+ id: 'node-1:123',
364
+ hostId: 'node-1',
365
+ hostLabel: 'Node 1',
366
+ hostKind: 'remote',
367
+ hostBaseUrl: 'https://node-1.test',
368
+ };
369
+ const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
370
+ if (!init?.method || init.method === 'GET') {
371
+ return new Response(JSON.stringify({ vibepulse: { openEditorTargetMode: 'remote' } }), {
372
+ status: 200,
373
+ headers: { 'Content-Type': 'application/json' },
374
+ });
375
+ }
376
+
377
+ return new Response(JSON.stringify({ success: true }), {
378
+ status: 200,
379
+ headers: { 'Content-Type': 'application/json' },
380
+ });
381
+ });
382
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
383
+
384
+ const queryClient = createQueryClient();
385
+ const invalidateQueriesSpy = vi.spyOn(queryClient, 'invalidateQueries');
386
+
387
+ render(
388
+ <QueryClientProvider client={queryClient}>
389
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
390
+ </QueryClientProvider>
391
+ );
392
+
393
+ const { fireEvent, waitFor } = TestingLibraryReact;
394
+ fireEvent.click(screen.getByTitle('Batch actions'));
395
+ fireEvent.click(screen.getByText('Archive all'));
396
+
397
+ await waitFor(() => {
398
+ expect(fetchMock).toHaveBeenCalledWith('/api/sessions/node-1:123/archive', expect.objectContaining({
399
+ method: 'POST',
400
+ }));
401
+ expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: ['sessions'] });
402
+ });
403
+ });
404
+
405
+ it('deletes a single-host remote project and invalidates the sessions query', async () => {
406
+ const remoteCard: KanbanCard = {
407
+ ...mockCard,
408
+ id: 'node-1:123',
409
+ hostId: 'node-1',
410
+ hostLabel: 'Node 1',
411
+ hostKind: 'remote',
412
+ hostBaseUrl: 'https://node-1.test',
413
+ };
414
+ const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
415
+ if (!init?.method || init.method === 'GET') {
416
+ return new Response(JSON.stringify({ vibepulse: { openEditorTargetMode: 'remote' } }), {
417
+ status: 200,
418
+ headers: { 'Content-Type': 'application/json' },
419
+ });
420
+ }
421
+
422
+ return new Response(JSON.stringify({ success: true }), {
423
+ status: 200,
424
+ headers: { 'Content-Type': 'application/json' },
425
+ });
426
+ });
427
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
428
+
429
+ const queryClient = createQueryClient();
430
+ const invalidateQueriesSpy = vi.spyOn(queryClient, 'invalidateQueries');
431
+
432
+ render(
433
+ <QueryClientProvider client={queryClient}>
434
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
435
+ </QueryClientProvider>
436
+ );
437
+
438
+ const { fireEvent, waitFor } = TestingLibraryReact;
439
+ fireEvent.click(screen.getByTitle('Batch actions'));
440
+ fireEvent.click(screen.getByText('Delete all'));
441
+
442
+ await waitFor(() => {
443
+ expect(fetchMock).toHaveBeenCalledWith('/api/sessions/node-1:123/delete', expect.objectContaining({
444
+ method: 'POST',
445
+ }));
446
+ expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: ['sessions'] });
447
+ });
448
+ });
449
+
450
+ it('blocks mixed-host delete actions without calling mutation APIs', async () => {
451
+ const mixedCards: KanbanCard[] = [
452
+ mockCard,
453
+ {
454
+ ...mockCard,
455
+ id: 'node-1:456',
456
+ hostId: 'node-1',
457
+ hostLabel: 'Node 1',
458
+ hostKind: 'remote',
459
+ rawSessionId: '456',
460
+ },
461
+ ];
462
+
463
+ renderWithProviders(
464
+ <ProjectCard projectName="TestProject" cards={mixedCards} />
465
+ );
466
+
467
+ const { fireEvent } = TestingLibraryReact;
468
+ fireEvent.click(screen.getByTitle('Batch actions'));
469
+ fireEvent.click(screen.getByText('Delete all'));
470
+
471
+ expect(screen.getByText('Mixed-host delete is not supported')).toBeTruthy();
472
+ expect(globalThis.fetch).toHaveBeenCalledTimes(1);
473
+ });
474
+
475
+ it('shows explicit delete failure feedback for remote project batch actions', async () => {
476
+ const remoteCard: KanbanCard = {
477
+ ...mockCard,
478
+ id: 'node-1:123',
479
+ hostId: 'node-1',
480
+ hostLabel: 'Node 1',
481
+ hostKind: 'remote',
482
+ hostBaseUrl: 'https://node-1.test',
483
+ };
484
+ const fetchMock = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => {
485
+ const url = String(input);
486
+ if (!init?.method || init.method === 'GET') {
487
+ return new Response(JSON.stringify({ vibepulse: { openEditorTargetMode: 'remote' } }), {
488
+ status: 200,
489
+ headers: { 'Content-Type': 'application/json' },
490
+ });
491
+ }
492
+
493
+ if (url === '/api/sessions/node-1:123/delete') {
494
+ return new Response(JSON.stringify({ reason: 'unauthorized' }), {
495
+ status: 401,
496
+ headers: { 'Content-Type': 'application/json' },
497
+ });
498
+ }
499
+
500
+ return new Response(JSON.stringify({ success: true }), {
501
+ status: 200,
502
+ headers: { 'Content-Type': 'application/json' },
503
+ });
504
+ });
505
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
506
+
507
+ renderWithProviders(
508
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
509
+ );
510
+
511
+ const { fireEvent } = TestingLibraryReact;
512
+ fireEvent.click(screen.getByTitle('Batch actions'));
513
+ fireEvent.click(screen.getByText('Delete all'));
514
+
515
+ expect(await TestingLibraryReact.screen.findByText('Remote node rejected the request. Check node access token settings.')).toBeTruthy();
516
+ });
517
+
518
+ it('shows explicit archive failure feedback for forbidden remote project batch actions', async () => {
519
+ const remoteCard: KanbanCard = {
520
+ ...mockCard,
521
+ id: 'node-1:123',
522
+ hostId: 'node-1',
523
+ hostLabel: 'Node 1',
524
+ hostKind: 'remote',
525
+ hostBaseUrl: 'https://node-1.test',
526
+ };
527
+ const fetchMock = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => {
528
+ const url = String(input);
529
+ if (!init?.method || init.method === 'GET') {
530
+ return new Response(JSON.stringify({ vibepulse: { openEditorTargetMode: 'remote' } }), {
531
+ status: 200,
532
+ headers: { 'Content-Type': 'application/json' },
533
+ });
534
+ }
535
+
536
+ if (url === '/api/sessions/node-1:123/archive') {
537
+ return new Response(JSON.stringify({ reason: 'node_request_failed_403' }), {
538
+ status: 403,
539
+ headers: { 'Content-Type': 'application/json' },
540
+ });
541
+ }
542
+
543
+ return new Response(JSON.stringify({ success: true }), {
544
+ status: 200,
545
+ headers: { 'Content-Type': 'application/json' },
546
+ });
547
+ });
548
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
549
+
550
+ renderWithProviders(
551
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
552
+ );
553
+
554
+ const { fireEvent } = TestingLibraryReact;
555
+ fireEvent.click(screen.getByTitle('Batch actions'));
556
+ fireEvent.click(screen.getByText('Archive all'));
557
+
558
+ expect(await TestingLibraryReact.screen.findByText('Remote node denied the request.')).toBeTruthy();
559
+ });
560
+
561
+ it('shows explicit offline feedback when project open fetch rejects', async () => {
562
+ const remoteCard: KanbanCard = {
563
+ ...mockCard,
564
+ id: 'node-1:123',
565
+ hostId: 'node-1',
566
+ hostLabel: 'Node 1',
567
+ hostKind: 'remote',
568
+ hostBaseUrl: 'https://node-1.test',
569
+ };
570
+ const queryClient = createQueryClient();
571
+ queryClient.setQueryData(['opencode-config'], { vibepulse: { openEditorTargetMode: 'remote' } });
572
+ const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
573
+ throw new Error('network failed');
574
+ });
575
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
576
+
577
+ render(
578
+ <QueryClientProvider client={queryClient}>
579
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
580
+ </QueryClientProvider>
581
+ );
582
+
583
+ const { fireEvent } = TestingLibraryReact;
584
+ await TestingLibraryReact.waitFor(() => {
585
+ expect(screen.getByTitle('Open project')).not.toBeDisabled();
586
+ });
587
+ fireEvent.click(screen.getByTitle('Open project'));
588
+
589
+ expect(await TestingLibraryReact.screen.findByText('Remote node is offline or unreachable.')).toBeTruthy();
590
+ });
591
+
592
+ it('shows the session-not-found message when the remote project open target is gone', async () => {
593
+ const remoteCard: KanbanCard = {
594
+ ...mockCard,
595
+ id: 'node-1:123',
596
+ hostId: 'node-1',
597
+ hostLabel: 'Node 1',
598
+ hostKind: 'remote',
599
+ hostBaseUrl: 'https://node-1.test',
600
+ };
601
+ const queryClient = createQueryClient();
602
+ queryClient.setQueryData(['opencode-config'], { vibepulse: { openEditorTargetMode: 'remote' } });
603
+ const fetchMock = vi.fn(async (_input: RequestInfo | URL, init?: RequestInit) => {
604
+ return new Response(JSON.stringify({
605
+ error: 'Session not found',
606
+ reason: 'session_not_found',
607
+ }), {
608
+ status: 404,
609
+ headers: { 'Content-Type': 'application/json' },
610
+ });
611
+ });
612
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
613
+
614
+ render(
615
+ <QueryClientProvider client={queryClient}>
616
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
617
+ </QueryClientProvider>
618
+ );
619
+
620
+ const { fireEvent } = TestingLibraryReact;
621
+ await TestingLibraryReact.waitFor(() => {
622
+ expect(screen.getByTitle('Open project')).not.toBeDisabled();
623
+ });
624
+ fireEvent.click(screen.getByTitle('Open project'));
625
+
626
+ expect(await TestingLibraryReact.screen.findByText('Session was not found.')).toBeTruthy();
627
+ });
628
+
629
+ it('shows a loading-settings state before remote project open mode is hydrated', async () => {
630
+ const remoteCard: KanbanCard = {
631
+ ...mockCard,
632
+ id: 'node-1:123',
633
+ hostId: 'node-1',
634
+ hostLabel: 'Node 1',
635
+ hostKind: 'remote',
636
+ hostBaseUrl: 'https://node-1.test',
637
+ };
638
+ const fetchMock = vi.fn(async () => new Promise<Response>(() => {}));
639
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
640
+
641
+ renderWithProviders(
642
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
643
+ );
644
+
645
+ expect(await TestingLibraryReact.screen.findByText('Loading open settings…')).toBeTruthy();
646
+ expect(screen.getByTitle('Open project')).toBeDisabled();
647
+ });
648
+
649
+ it('shows an error and keeps remote project open disabled when config loading fails', async () => {
650
+ const remoteCard: KanbanCard = {
651
+ ...mockCard,
652
+ id: 'node-1:123',
653
+ hostId: 'node-1',
654
+ hostLabel: 'Node 1',
655
+ hostKind: 'remote',
656
+ hostBaseUrl: 'https://node-1.test',
657
+ };
658
+ const fetchMock = vi.fn(async () => {
659
+ throw new Error('config failed');
660
+ });
661
+ Object.defineProperty(globalThis, 'fetch', { value: fetchMock, configurable: true });
662
+
663
+ renderWithProviders(
664
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
665
+ );
666
+
667
+ expect(await TestingLibraryReact.screen.findByText('Failed to load open settings. Remote open is unavailable until configuration loads.')).toBeTruthy();
668
+ expect(screen.getByTitle('Open project')).toBeDisabled();
669
+ });
670
+
671
+ it('renders remote read-only project card correctly', () => {
672
+ const remoteCard: KanbanCard = {
673
+ ...mockCard,
674
+ id: 'remote1:456',
675
+ hostId: 'remote1',
676
+ hostLabel: 'Remote 1',
677
+ hostKind: 'remote',
678
+ readOnly: true
679
+ };
680
+
681
+ renderWithProviders(
682
+ <ProjectCard projectName="TestProject" cards={[remoteCard]} />
683
+ );
684
+
685
+ expect(screen.getByText('TestProject')).toBeTruthy();
686
+ expect(screen.getByTitle('Source: Remote 1')).toBeTruthy();
687
+ expect(screen.queryByTitle('Open project')).toBeNull();
688
+ });
689
+
690
+ it('respects readOnly prop when explicitly passed', () => {
691
+ renderWithProviders(
692
+ <ProjectCard projectName="TestProject" cards={[mockCard]} readOnly={true} />
693
+ );
694
+ expect(screen.queryByTitle('Open project')).toBeNull();
695
+ });
696
+
697
+ it('distinguishes same project name on different hosts via badges', () => {
698
+ const remoteCardA: KanbanCard = {
699
+ ...mockCard,
700
+ id: 'hostA:123',
701
+ hostId: 'hostA',
702
+ hostLabel: 'Workspace A',
703
+ hostKind: 'remote',
704
+ };
705
+
706
+ const remoteCardB: KanbanCard = {
707
+ ...mockCard,
708
+ id: 'hostB:123',
709
+ hostId: 'hostB',
710
+ hostLabel: 'Workspace B',
711
+ hostKind: 'remote',
712
+ };
713
+
714
+ const { rerender } = renderWithProviders(
715
+ <ProjectCard projectName="TestProject" cards={[remoteCardA]} />
716
+ );
717
+ expect(screen.getByTitle('Source: Workspace A')).toBeTruthy();
718
+
719
+ rerender(
720
+ <QueryClientProvider client={createQueryClient()}>
721
+ <ProjectCard projectName="TestProject" cards={[remoteCardB]} />
722
+ </QueryClientProvider>
723
+ );
724
+ expect(screen.getByTitle('Source: Workspace B')).toBeTruthy();
725
+ });
726
+ });
727
+
728
+ describe('ProjectCard Host Badges', () => {
729
+ const mockCard: KanbanCard = {
730
+ id: 'local:123',
731
+ sessionSlug: 'session_123_abc',
732
+ title: 'Test Session',
733
+ directory: '/path/to/project',
734
+ projectName: 'TestProject',
735
+ agents: ['agent1'],
736
+ messageCount: 5,
737
+ status: 'idle',
738
+ opencodeStatus: 'idle',
739
+ waitingForUser: false,
740
+ todosTotal: 0,
741
+ todosCompleted: 0,
742
+ createdAt: 1000,
743
+ updatedAt: 2000,
744
+ sortOrder: 0,
745
+ hostId: 'local',
746
+ hostLabel: 'Local',
747
+ hostKind: 'local',
748
+ rawSessionId: '123',
749
+ readOnly: false
750
+ };
751
+
752
+ it('shows Local badge when multipleHostsEnabled is true', () => {
753
+ renderWithProviders(
754
+ <ProjectCard projectName="TestProject" cards={[mockCard]} multipleHostsEnabled={true} />
755
+ );
756
+ expect(screen.getByTitle('Source: Local')).toBeTruthy();
757
+ });
758
+
759
+ it('renders branch metadata in the footer area', () => {
760
+ renderWithProviders(
761
+ <ProjectCard projectName="TestProject" branch="main" cards={[mockCard]} />
762
+ );
763
+
764
+ expect(screen.getByTitle('main')).toBeTruthy();
765
+ });
766
+
767
+ it('hides Local badge when multipleHostsEnabled is false', () => {
768
+ renderWithProviders(
769
+ <ProjectCard projectName="TestProject" cards={[mockCard]} multipleHostsEnabled={false} />
770
+ );
771
+ expect(screen.queryByTitle('Source: Local')).toBeNull();
772
+ });
773
+ });