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,476 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { X, Server, Globe, Plus, Trash2, Edit2, Check, AlertCircle, Key } from 'lucide-react';
3
+ import { useHostSources } from '@/hooks/useHostSources';
4
+ import { validateNodeUrl } from '@/lib/hostSourcesStorage';
5
+ import type { RemoteHostConfig } from '@/types';
6
+
7
+ interface HostManagerDialogProps {
8
+ open: boolean;
9
+ onClose: () => void;
10
+ hostSources: ReturnType<typeof useHostSources>;
11
+ isNodeMode?: boolean;
12
+ }
13
+
14
+ export function HostManagerDialog({ open, onClose, hostSources, isNodeMode = false }: HostManagerDialogProps) {
15
+ const { remoteHosts, addRemoteHost, editRemoteHost, deleteRemoteHost, toggleRemoteHost } = hostSources;
16
+ const [editingId, setEditingId] = useState<string | null>(null);
17
+ const [isAdding, setIsAdding] = useState(false);
18
+ const [formData, setFormData] = useState({ hostLabel: '', baseUrl: '', token: '' });
19
+ const [clearTokenOnSave, setClearTokenOnSave] = useState(false);
20
+ const [error, setError] = useState<string | null>(null);
21
+ const [isSubmitting, setIsSubmitting] = useState(false);
22
+
23
+ const executeNodeMutation = async (action: () => Promise<unknown>, fallbackMessage: string) => {
24
+ setError(null);
25
+ try {
26
+ await action();
27
+ } catch (err) {
28
+ setError(err instanceof Error ? err.message : fallbackMessage);
29
+ }
30
+ };
31
+
32
+ useEffect(() => {
33
+ if (open) {
34
+ const originalStyle = window.getComputedStyle(document.body).overflow;
35
+ document.body.style.overflow = 'hidden';
36
+ return () => {
37
+ document.body.style.overflow = originalStyle;
38
+ };
39
+ } else {
40
+ setIsAdding(false);
41
+ setEditingId(null);
42
+ setError(null);
43
+ setFormData({ hostLabel: '', baseUrl: '', token: '' });
44
+ setClearTokenOnSave(false);
45
+ setIsSubmitting(false);
46
+ }
47
+ }, [open]);
48
+
49
+ useEffect(() => {
50
+ if (!open) return;
51
+
52
+ const handleKeyDown = (e: KeyboardEvent) => {
53
+ if (e.key === 'Escape') {
54
+ onClose();
55
+ }
56
+ };
57
+
58
+ document.addEventListener('keydown', handleKeyDown);
59
+ return () => document.removeEventListener('keydown', handleKeyDown);
60
+ }, [open, onClose]);
61
+
62
+ const getNodeUrlError = (url: string) => {
63
+ const result = validateNodeUrl(url);
64
+
65
+ if (result.ok) {
66
+ return null;
67
+ }
68
+
69
+ if (result.error === 'unsupported_protocol') {
70
+ return 'Node URL must use http:// or https://';
71
+ }
72
+
73
+ if (result.error === 'credentials_not_allowed') {
74
+ return 'Node URL must not include a username or password';
75
+ }
76
+
77
+ return 'A valid Node URL is required (e.g., http://localhost:3000)';
78
+ };
79
+
80
+ const handleSave = async () => {
81
+ setError(null);
82
+ const normalizedLabel = formData.hostLabel.trim();
83
+
84
+ if (!normalizedLabel) {
85
+ setError('Label is required');
86
+ return;
87
+ }
88
+
89
+ const nodeUrlError = getNodeUrlError(formData.baseUrl);
90
+ if (nodeUrlError) {
91
+ setError(nodeUrlError);
92
+ return;
93
+ }
94
+
95
+ setIsSubmitting(true);
96
+ try {
97
+ if (isAdding) {
98
+ await addRemoteHost({
99
+ hostId: '', // Handled by backend
100
+ hostLabel: normalizedLabel,
101
+ baseUrl: formData.baseUrl,
102
+ enabled: true,
103
+ token: formData.token.trim(),
104
+ });
105
+ setIsAdding(false);
106
+ } else if (editingId) {
107
+ const existingHost = remoteHosts.find((h) => h.hostId === editingId);
108
+ if (existingHost) {
109
+ const normalizedToken = formData.token.trim();
110
+ const token = clearTokenOnSave ? '' : normalizedToken || undefined;
111
+
112
+ await editRemoteHost(editingId, {
113
+ ...existingHost,
114
+ hostLabel: normalizedLabel,
115
+ baseUrl: formData.baseUrl,
116
+ token,
117
+ });
118
+ }
119
+ setEditingId(null);
120
+ }
121
+ setFormData({ hostLabel: '', baseUrl: '', token: '' });
122
+ setClearTokenOnSave(false);
123
+ } catch (err) {
124
+ setError(err instanceof Error ? err.message : 'An error occurred');
125
+ } finally {
126
+ setIsSubmitting(false);
127
+ }
128
+ };
129
+
130
+ const startEdit = (host: RemoteHostConfig) => {
131
+ setEditingId(host.hostId);
132
+ setFormData({ hostLabel: host.hostLabel, baseUrl: host.baseUrl, token: '' });
133
+ setClearTokenOnSave(false);
134
+ setIsAdding(false);
135
+ setError(null);
136
+ };
137
+
138
+ const startAdd = () => {
139
+ setIsAdding(true);
140
+ setEditingId(null);
141
+ setFormData({ hostLabel: '', baseUrl: '', token: '' });
142
+ setClearTokenOnSave(false);
143
+ setError(null);
144
+ };
145
+
146
+ const cancelForm = () => {
147
+ setIsAdding(false);
148
+ setEditingId(null);
149
+ setFormData({ hostLabel: '', baseUrl: '', token: '' });
150
+ setClearTokenOnSave(false);
151
+ setError(null);
152
+ };
153
+
154
+ if (!open) return null;
155
+
156
+ return (
157
+ <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4 backdrop-blur-sm" data-testid="host-manager">
158
+ <div className="flex max-h-[85vh] w-full max-w-lg flex-col overflow-hidden rounded-xl border border-zinc-200 bg-white shadow-2xl dark:border-zinc-800 dark:bg-zinc-950">
159
+ <header className="flex h-14 items-center justify-between border-b border-zinc-200 px-5 dark:border-zinc-800">
160
+ <div className="flex items-center gap-2.5">
161
+ <Server className="h-5 w-5 text-blue-600 dark:text-blue-500" />
162
+ <h2 className="text-base font-semibold text-zinc-900 dark:text-zinc-100">
163
+ Nodes
164
+ </h2>
165
+ </div>
166
+ <button
167
+ type="button"
168
+ onClick={onClose}
169
+ className="flex h-8 w-8 items-center justify-center rounded-lg text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200"
170
+ aria-label="Close node manager"
171
+ >
172
+ <X className="h-4 w-4" />
173
+ </button>
174
+ </header>
175
+
176
+ <main className="flex-1 overflow-y-auto p-5">
177
+ {isNodeMode ? (
178
+ <div className="rounded-lg border border-yellow-200 bg-yellow-50 p-4 dark:border-yellow-900/50 dark:bg-yellow-900/20">
179
+ <div className="flex items-start gap-3">
180
+ <AlertCircle className="mt-0.5 h-5 w-5 text-yellow-600 dark:text-yellow-500" />
181
+ <div>
182
+ <h3 className="text-sm font-medium text-yellow-800 dark:text-yellow-400">Node Mode Active</h3>
183
+ <p className="mt-1 text-sm text-yellow-700 dark:text-yellow-500">
184
+ Remote node configuration is disabled while running in node mode to prevent nested hub configurations.
185
+ </p>
186
+ </div>
187
+ </div>
188
+ </div>
189
+ ) : (
190
+ <div className="space-y-3">
191
+ {error && !isAdding && !editingId && (
192
+ <div className="flex items-center gap-1.5 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700 dark:border-red-900/50 dark:bg-red-900/20 dark:text-red-400">
193
+ <AlertCircle className="h-3.5 w-3.5" />
194
+ <span>{error}</span>
195
+ </div>
196
+ )}
197
+ <div
198
+ data-testid="host-row-local"
199
+ className="flex items-center justify-between rounded-lg border border-zinc-200 bg-zinc-50/50 p-3 dark:border-zinc-800 dark:bg-zinc-900/20"
200
+ >
201
+ <div className="flex items-center gap-3">
202
+ <div className="flex h-8 w-8 items-center justify-center rounded-md bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400">
203
+ <Server className="h-4 w-4" />
204
+ </div>
205
+ <div>
206
+ <div className="text-sm font-medium text-zinc-900 dark:text-zinc-100">Local</div>
207
+ <div className="text-xs text-zinc-500 dark:text-zinc-400">Auto-discovered processes</div>
208
+ </div>
209
+ </div>
210
+ <div className="flex items-center">
211
+ <span className="inline-flex items-center rounded-full bg-blue-50 px-2 py-0.5 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10 dark:bg-blue-400/10 dark:text-blue-400 dark:ring-blue-400/30">
212
+ Built-in
213
+ </span>
214
+ </div>
215
+ </div>
216
+
217
+ {remoteHosts.map((host) => {
218
+ const isEditingThis = editingId === host.hostId;
219
+ const testIdSuffix = host.hostId.replace(/[^a-zA-Z0-9-]/g, '-').toLowerCase();
220
+
221
+ return (
222
+ <div
223
+ key={host.hostId}
224
+ data-testid={`host-row-remote-${testIdSuffix}`}
225
+ className={`flex flex-col gap-3 rounded-lg border p-3 transition-colors ${
226
+ isEditingThis
227
+ ? 'border-blue-500 bg-blue-50/30 dark:border-blue-500/50 dark:bg-blue-900/10'
228
+ : 'border-zinc-200 bg-white hover:border-zinc-300 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:border-zinc-700'
229
+ }`}
230
+ >
231
+ {isEditingThis ? (
232
+ <div className="space-y-3">
233
+ <div className="space-y-2">
234
+ <label htmlFor="edit-hostLabel" className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
235
+ Node Label
236
+ </label>
237
+ <input
238
+ id="edit-hostLabel"
239
+ data-testid="host-form-label"
240
+ type="text"
241
+ value={formData.hostLabel}
242
+ onChange={(e) => setFormData({ ...formData, hostLabel: e.target.value })}
243
+ className="w-full rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100"
244
+ placeholder="e.g., Production Node"
245
+ disabled={isSubmitting}
246
+ />
247
+ </div>
248
+ <div className="space-y-2">
249
+ <label htmlFor="edit-baseUrl" className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
250
+ Node URL
251
+ </label>
252
+ <input
253
+ id="edit-baseUrl"
254
+ data-testid="host-form-base-url"
255
+ type="url"
256
+ value={formData.baseUrl}
257
+ onChange={(e) => setFormData({ ...formData, baseUrl: e.target.value })}
258
+ className="w-full rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100"
259
+ placeholder="https://node.example.com"
260
+ disabled={isSubmitting}
261
+ />
262
+ </div>
263
+ <div className="space-y-2">
264
+ <label htmlFor="edit-token" className="text-xs font-medium text-zinc-700 dark:text-zinc-300 flex items-center gap-1.5">
265
+ <Key className="h-3.5 w-3.5" />
266
+ Update Token (optional)
267
+ </label>
268
+ <input
269
+ id="edit-token"
270
+ data-testid="host-form-token"
271
+ type="password"
272
+ value={formData.token}
273
+ onChange={(e) => {
274
+ const value = e.target.value;
275
+ setFormData({ ...formData, token: value });
276
+ if (clearTokenOnSave && value.trim().length > 0) {
277
+ setClearTokenOnSave(false);
278
+ }
279
+ }}
280
+ className="w-full rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100"
281
+ placeholder="Leave blank to keep existing token"
282
+ disabled={isSubmitting || clearTokenOnSave}
283
+ />
284
+ <label htmlFor="edit-clear-token" className="flex items-center gap-2 text-xs text-zinc-600 dark:text-zinc-400">
285
+ <input
286
+ id="edit-clear-token"
287
+ type="checkbox"
288
+ checked={clearTokenOnSave}
289
+ onChange={(e) => setClearTokenOnSave(e.target.checked)}
290
+ disabled={isSubmitting}
291
+ className="h-3.5 w-3.5 rounded border-zinc-300 text-blue-600 focus:ring-blue-500"
292
+ />
293
+ Clear saved token on save
294
+ </label>
295
+ </div>
296
+ {error && (
297
+ <div className="flex items-center gap-1.5 text-xs text-red-600 dark:text-red-400">
298
+ <AlertCircle className="h-3.5 w-3.5" />
299
+ <span>{error}</span>
300
+ </div>
301
+ )}
302
+ <div className="flex justify-end gap-2 pt-1">
303
+ <button
304
+ type="button"
305
+ onClick={cancelForm}
306
+ disabled={isSubmitting}
307
+ className="rounded-md px-3 py-1.5 text-xs font-medium text-zinc-600 hover:bg-zinc-100 disabled:opacity-50 dark:text-zinc-400 dark:hover:bg-zinc-800"
308
+ >
309
+ Cancel
310
+ </button>
311
+ <button
312
+ type="button"
313
+ onClick={handleSave}
314
+ disabled={isSubmitting}
315
+ className="inline-flex items-center gap-1.5 rounded-md bg-blue-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-blue-700 disabled:opacity-50"
316
+ >
317
+ <Check className="h-3.5 w-3.5" />
318
+ {isSubmitting ? 'Saving...' : 'Save'}
319
+ </button>
320
+ </div>
321
+ </div>
322
+ ) : (
323
+ <div className="flex items-center justify-between">
324
+ <div className="flex items-center gap-3">
325
+ <div className={`flex h-8 w-8 items-center justify-center rounded-md ${host.enabled ? 'bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400' : 'bg-zinc-50 text-zinc-400 dark:bg-zinc-900 dark:text-zinc-600'}`}>
326
+ <Globe className="h-4 w-4" />
327
+ </div>
328
+ <div className={host.enabled ? '' : 'opacity-60'}>
329
+ <div className="flex items-center gap-2">
330
+ <div className="text-sm font-medium text-zinc-900 dark:text-zinc-100">{host.hostLabel}</div>
331
+ {host.tokenConfigured && (
332
+ <Key className="h-3 w-3 text-zinc-400" aria-label="Token configured" />
333
+ )}
334
+ </div>
335
+ <div className="text-xs text-zinc-500 dark:text-zinc-400">{host.baseUrl}</div>
336
+ </div>
337
+ </div>
338
+ <div className="flex items-center gap-1">
339
+ <button
340
+ type="button"
341
+ onClick={() => {
342
+ void executeNodeMutation(
343
+ () => toggleRemoteHost(host.hostId, !host.enabled),
344
+ 'Failed to toggle node'
345
+ );
346
+ }}
347
+ className={`rounded-md px-2.5 py-1 text-xs font-medium transition-colors ${
348
+ host.enabled
349
+ ? 'text-zinc-600 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:bg-zinc-800'
350
+ : 'text-blue-600 hover:bg-blue-50 dark:text-blue-400 dark:hover:bg-blue-900/20'
351
+ }`}
352
+ >
353
+ {host.enabled ? 'Disable' : 'Enable'}
354
+ </button>
355
+ <button
356
+ type="button"
357
+ onClick={() => startEdit(host)}
358
+ className="rounded-md p-1.5 text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:hover:bg-zinc-800 dark:hover:text-zinc-200"
359
+ aria-label="Edit node"
360
+ >
361
+ <Edit2 className="h-3.5 w-3.5" />
362
+ </button>
363
+ <button
364
+ type="button"
365
+ onClick={() => {
366
+ void executeNodeMutation(
367
+ () => deleteRemoteHost(host.hostId),
368
+ 'Failed to delete node'
369
+ );
370
+ }}
371
+ className="rounded-md p-1.5 text-zinc-400 transition-colors hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-900/20 dark:hover:text-red-400"
372
+ aria-label="Delete node"
373
+ >
374
+ <Trash2 className="h-3.5 w-3.5" />
375
+ </button>
376
+ </div>
377
+ </div>
378
+ )}
379
+ </div>
380
+ );
381
+ })}
382
+
383
+ {isAdding ? (
384
+ <div className="flex flex-col gap-3 rounded-lg border border-blue-500 bg-blue-50/30 p-3 dark:border-blue-500/50 dark:bg-blue-900/10">
385
+ <div className="space-y-2">
386
+ <label htmlFor="add-hostLabel" className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
387
+ Node Label
388
+ </label>
389
+ <input
390
+ id="add-hostLabel"
391
+ data-testid="host-form-label"
392
+ type="text"
393
+ value={formData.hostLabel}
394
+ onChange={(e) => setFormData({ ...formData, hostLabel: e.target.value })}
395
+ className="w-full rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100"
396
+ placeholder="e.g., Remote Node"
397
+ disabled={isSubmitting}
398
+ />
399
+ </div>
400
+ <div className="space-y-2">
401
+ <label htmlFor="add-baseUrl" className="text-xs font-medium text-zinc-700 dark:text-zinc-300">
402
+ Node URL
403
+ </label>
404
+ <input
405
+ id="add-baseUrl"
406
+ data-testid="host-form-base-url"
407
+ type="url"
408
+ value={formData.baseUrl}
409
+ onChange={(e) => setFormData({ ...formData, baseUrl: e.target.value })}
410
+ className="w-full rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100"
411
+ placeholder="https://node.example.com"
412
+ disabled={isSubmitting}
413
+ />
414
+ </div>
415
+ <div className="space-y-2">
416
+ <label htmlFor="add-token" className="text-xs font-medium text-zinc-700 dark:text-zinc-300 flex items-center gap-1.5">
417
+ <Key className="h-3.5 w-3.5" />
418
+ Access Token (optional)
419
+ </label>
420
+ <input
421
+ id="add-token"
422
+ data-testid="host-form-token"
423
+ type="password"
424
+ value={formData.token}
425
+ onChange={(e) => setFormData({ ...formData, token: e.target.value })}
426
+ className="w-full rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-sm text-zinc-900 placeholder:text-zinc-400 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100"
427
+ placeholder="Leave blank only on trusted networks"
428
+ disabled={isSubmitting}
429
+ />
430
+ <p className="text-xs text-amber-700 dark:text-amber-400">
431
+ Recommended: set a token unless this node is only reachable on a trusted private network.
432
+ </p>
433
+ </div>
434
+ {error && (
435
+ <div className="flex items-center gap-1.5 text-xs text-red-600 dark:text-red-400">
436
+ <AlertCircle className="h-3.5 w-3.5" />
437
+ <span>{error}</span>
438
+ </div>
439
+ )}
440
+ <div className="flex justify-end gap-2 pt-1">
441
+ <button
442
+ type="button"
443
+ onClick={cancelForm}
444
+ disabled={isSubmitting}
445
+ className="rounded-md px-3 py-1.5 text-xs font-medium text-zinc-600 hover:bg-zinc-100 disabled:opacity-50 dark:text-zinc-400 dark:hover:bg-zinc-800"
446
+ >
447
+ Cancel
448
+ </button>
449
+ <button
450
+ type="button"
451
+ onClick={handleSave}
452
+ disabled={isSubmitting}
453
+ className="inline-flex items-center gap-1.5 rounded-md bg-blue-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-blue-700 disabled:opacity-50"
454
+ >
455
+ <Check className="h-3.5 w-3.5" />
456
+ {isSubmitting ? 'Adding...' : 'Add Node'}
457
+ </button>
458
+ </div>
459
+ </div>
460
+ ) : (
461
+ <button
462
+ type="button"
463
+ onClick={startAdd}
464
+ className="flex w-full items-center justify-center gap-2 rounded-lg border border-dashed border-zinc-300 py-3 text-sm font-medium text-zinc-600 transition-colors hover:border-zinc-400 hover:bg-zinc-50 hover:text-zinc-900 dark:border-zinc-700 dark:text-zinc-400 dark:hover:border-zinc-600 dark:hover:bg-zinc-900/50 dark:hover:text-zinc-100"
465
+ >
466
+ <Plus className="h-4 w-4" />
467
+ Add Remote Node
468
+ </button>
469
+ )}
470
+ </div>
471
+ )}
472
+ </main>
473
+ </div>
474
+ </div>
475
+ );
476
+ }
@@ -0,0 +1,72 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { render, screen, waitFor } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { AgentConfigForm } from './AgentConfigForm';
5
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
6
+
7
+ const mockFetch = vi.fn<typeof fetch>();
8
+ global.fetch = mockFetch;
9
+
10
+ function jsonResponse(data: unknown): Response {
11
+ return {
12
+ ok: true,
13
+ status: 200,
14
+ json: async () => data,
15
+ } as Response;
16
+ }
17
+
18
+ describe('AgentConfigForm - echo bug fix', () => {
19
+ let queryClient: QueryClient;
20
+
21
+ beforeEach(() => {
22
+ queryClient = new QueryClient({
23
+ defaultOptions: {
24
+ queries: { staleTime: 0 },
25
+ },
26
+ });
27
+ queryClient.clear();
28
+ vi.clearAllMocks();
29
+ });
30
+
31
+ it('should display new value instead of cached value after saving', async () => {
32
+ const user = userEvent.setup();
33
+
34
+ mockFetch
35
+ .mockResolvedValueOnce(
36
+ jsonResponse({
37
+ agents: { sisyphus: { model: 'anthropic/claude-3.5-sonnet', temperature: 0.5 } },
38
+ categories: {},
39
+ })
40
+ )
41
+ .mockResolvedValueOnce(jsonResponse({ success: true }))
42
+ .mockResolvedValueOnce(
43
+ jsonResponse({
44
+ agents: { sisyphus: { model: 'openai/gpt-4o', temperature: 0.8 } },
45
+ categories: {},
46
+ })
47
+ );
48
+
49
+ render(
50
+ <QueryClientProvider client={queryClient}>
51
+ <AgentConfigForm agentName="sisyphus" />
52
+ </QueryClientProvider>
53
+ );
54
+
55
+ await waitFor(() => {
56
+ const tempInput = screen.getByLabelText(/temperature value/i);
57
+ expect(tempInput).toHaveValue(0.5);
58
+ });
59
+
60
+ const tempInput = screen.getByLabelText(/temperature value/i);
61
+ await user.clear(tempInput);
62
+ await user.type(tempInput, '0.8');
63
+
64
+ await user.click(screen.getByRole('button', { name: /save changes/i }));
65
+
66
+ await waitFor(() => {
67
+ const updatedTempInput = screen.getByLabelText(/temperature value/i);
68
+ expect(updatedTempInput).toHaveValue(0.8);
69
+ });
70
+ });
71
+
72
+ });