vibepulse 0.2.2 → 0.3.1-beta

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 (424) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +1 -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 +8 -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 +2 -2
  32. package/.next/server/app/api/node/events/route.js.nft.json +1 -1
  33. package/.next/server/app/api/node/sessions/[id]/delete/route.js +2 -2
  34. package/.next/server/app/api/node/sessions/[id]/delete/route.js.nft.json +1 -1
  35. package/.next/server/app/api/node/sessions/[id]/open-editor/route.js +2 -2
  36. package/.next/server/app/api/node/sessions/[id]/open-editor/route.js.nft.json +1 -1
  37. package/.next/server/app/api/node/sessions/route.js +6 -4
  38. package/.next/server/app/api/node/sessions/route.js.nft.json +1 -1
  39. package/.next/server/app/api/nodes/route.js +2 -2
  40. package/.next/server/app/api/nodes/route.js.nft.json +1 -1
  41. package/.next/server/app/api/opencode-config/route.js +2 -2
  42. package/.next/server/app/api/opencode-config/route.js.nft.json +1 -1
  43. package/.next/server/app/api/opencode-config/status/route.js +2 -2
  44. package/.next/server/app/api/opencode-config/status/route.js.nft.json +1 -1
  45. package/.next/server/app/api/opencode-events/route.js +3 -3
  46. package/.next/server/app/api/opencode-events/route.js.nft.json +1 -1
  47. package/.next/server/app/api/profiles/[id]/apply/route.js +2 -2
  48. package/.next/server/app/api/profiles/[id]/apply/route.js.nft.json +1 -1
  49. package/.next/server/app/api/profiles/[id]/export/route.js +2 -2
  50. package/.next/server/app/api/profiles/[id]/export/route.js.nft.json +1 -1
  51. package/.next/server/app/api/profiles/[id]/route.js +2 -2
  52. package/.next/server/app/api/profiles/[id]/route.js.nft.json +1 -1
  53. package/.next/server/app/api/profiles/import/route.js +2 -2
  54. package/.next/server/app/api/profiles/import/route.js.nft.json +1 -1
  55. package/.next/server/app/api/profiles/route.js +2 -2
  56. package/.next/server/app/api/profiles/route.js.nft.json +1 -1
  57. package/.next/server/app/api/sessions/[id]/archive/route.js +3 -2
  58. package/.next/server/app/api/sessions/[id]/archive/route.js.nft.json +1 -1
  59. package/.next/server/app/api/sessions/[id]/delete/route.js +4 -3
  60. package/.next/server/app/api/sessions/[id]/delete/route.js.nft.json +1 -1
  61. package/.next/server/app/api/sessions/[id]/open-editor/route.js +2 -2
  62. package/.next/server/app/api/sessions/[id]/open-editor/route.js.nft.json +1 -1
  63. package/.next/server/app/api/sessions/[id]/restore/route/app-paths-manifest.json +3 -0
  64. package/.next/server/app/api/sessions/[id]/restore/route/build-manifest.json +11 -0
  65. package/.next/server/app/api/sessions/[id]/restore/route/server-reference-manifest.json +4 -0
  66. package/.next/server/app/api/sessions/[id]/restore/route.js +8 -0
  67. package/.next/server/app/api/sessions/[id]/restore/route.js.map +5 -0
  68. package/.next/server/app/api/sessions/[id]/restore/route.js.nft.json +1 -0
  69. package/.next/server/app/api/sessions/[id]/restore/route_client-reference-manifest.js +2 -0
  70. package/.next/server/app/api/sessions/[id]/route.js +2 -2
  71. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  72. package/.next/server/app/api/sessions/route.js +5 -3
  73. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  74. package/.next/server/app/index.html +1 -1
  75. package/.next/server/app/index.rsc +3 -3
  76. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  77. package/.next/server/app/index.segments/_full.segment.rsc +3 -3
  78. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  79. package/.next/server/app/index.segments/_index.segment.rsc +2 -2
  80. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  81. package/.next/server/app/page_client-reference-manifest.js +1 -1
  82. package/.next/server/app-paths-manifest.json +1 -0
  83. package/.next/server/chunks/[root-of-the-server]__005eb0c5._.js +3 -0
  84. package/.next/server/chunks/[root-of-the-server]__005eb0c5._.js.map +1 -0
  85. package/.next/server/chunks/[root-of-the-server]__09e90d57._.js +3 -0
  86. package/.next/server/chunks/[root-of-the-server]__09e90d57._.js.map +1 -0
  87. package/.next/server/chunks/[root-of-the-server]__18dd0ce9._.js +3 -0
  88. package/.next/server/chunks/[root-of-the-server]__18dd0ce9._.js.map +1 -0
  89. package/.next/server/chunks/[root-of-the-server]__19468536._.js +3 -0
  90. package/.next/server/chunks/[root-of-the-server]__19468536._.js.map +1 -0
  91. package/.next/server/chunks/[root-of-the-server]__1b87ec42._.js +1 -1
  92. package/.next/server/chunks/[root-of-the-server]__1b87ec42._.js.map +1 -1
  93. package/.next/server/chunks/[root-of-the-server]__2b912935._.js +3 -0
  94. package/.next/server/chunks/[root-of-the-server]__2b912935._.js.map +1 -0
  95. package/.next/server/chunks/[root-of-the-server]__303d3bac._.js +3 -0
  96. package/.next/server/chunks/[root-of-the-server]__303d3bac._.js.map +1 -0
  97. package/.next/server/chunks/[root-of-the-server]__3fac2b91._.js +5 -0
  98. package/.next/server/chunks/[root-of-the-server]__3fac2b91._.js.map +1 -0
  99. package/.next/server/chunks/[root-of-the-server]__43440b8d._.js +3 -0
  100. package/.next/server/chunks/[root-of-the-server]__43440b8d._.js.map +1 -0
  101. package/.next/server/chunks/[root-of-the-server]__438f8bbe._.js +3 -0
  102. package/.next/server/chunks/[root-of-the-server]__438f8bbe._.js.map +1 -0
  103. package/.next/server/chunks/[root-of-the-server]__4a0bfb55._.js +3 -0
  104. package/.next/server/chunks/[root-of-the-server]__4a0bfb55._.js.map +1 -0
  105. package/.next/server/chunks/[root-of-the-server]__534c3949._.js +3 -0
  106. package/.next/server/chunks/[root-of-the-server]__534c3949._.js.map +1 -0
  107. package/.next/server/chunks/[root-of-the-server]__59160266._.js +1 -1
  108. package/.next/server/chunks/[root-of-the-server]__59160266._.js.map +1 -1
  109. package/.next/server/chunks/[root-of-the-server]__6f812da0._.js +3 -0
  110. package/.next/server/chunks/[root-of-the-server]__6f812da0._.js.map +1 -0
  111. package/.next/server/chunks/[root-of-the-server]__71aac504._.js +3 -0
  112. package/.next/server/chunks/[root-of-the-server]__71aac504._.js.map +1 -0
  113. package/.next/server/chunks/[root-of-the-server]__907a8bf2._.js +3 -0
  114. package/.next/server/chunks/[root-of-the-server]__907a8bf2._.js.map +1 -0
  115. package/.next/server/chunks/[root-of-the-server]__92089220._.js +3 -0
  116. package/.next/server/chunks/[root-of-the-server]__92089220._.js.map +1 -0
  117. package/.next/server/chunks/[root-of-the-server]__9b7bc2d0._.js +3 -0
  118. package/.next/server/chunks/[root-of-the-server]__9b7bc2d0._.js.map +1 -0
  119. package/.next/server/chunks/[root-of-the-server]__b2640944._.js +3 -0
  120. package/.next/server/chunks/[root-of-the-server]__b2640944._.js.map +1 -0
  121. package/.next/server/chunks/[root-of-the-server]__c2267cf1._.js +3 -0
  122. package/.next/server/chunks/[root-of-the-server]__c2267cf1._.js.map +1 -0
  123. package/.next/server/chunks/[root-of-the-server]__d7f7e6dd._.js +3 -0
  124. package/.next/server/chunks/{[root-of-the-server]__6924c09d._.js.map → [root-of-the-server]__d7f7e6dd._.js.map} +1 -1
  125. package/.next/server/chunks/[root-of-the-server]__d8e61048._.js +1 -1
  126. package/.next/server/chunks/[root-of-the-server]__d8e61048._.js.map +1 -1
  127. package/.next/server/chunks/[root-of-the-server]__f6d0d488._.js +3 -0
  128. package/.next/server/chunks/{[root-of-the-server]__192ed2f4._.js.map → [root-of-the-server]__f6d0d488._.js.map} +1 -1
  129. package/.next/server/chunks/[root-of-the-server]__fa559e1e._.js +3 -0
  130. package/.next/server/chunks/[root-of-the-server]__fa559e1e._.js.map +1 -0
  131. package/.next/server/chunks/_next-internal_server_app_api_sessions_[id]_restore_route_actions_af7d6b6c.js +3 -0
  132. package/.next/server/chunks/_next-internal_server_app_api_sessions_[id]_restore_route_actions_af7d6b6c.js.map +1 -0
  133. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_7e181e75.js +1 -1
  134. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_7e181e75.js.map +1 -1
  135. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_aca45402.js +1 -1
  136. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_aca45402.js.map +1 -1
  137. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_b054aff3.js +1 -1
  138. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_b054aff3.js.map +1 -1
  139. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_fa835ac3.js +2 -2
  140. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_fa835ac3.js.map +1 -1
  141. package/.next/server/chunks/src_lib_opencodeConfig_ts_8e209941._.js +3 -0
  142. package/.next/server/chunks/src_lib_opencodeConfig_ts_8e209941._.js.map +1 -0
  143. package/.next/server/chunks/src_lib_session-providers_claudeCode_ts_0f9590ed._.js +3 -0
  144. package/.next/server/chunks/src_lib_session-providers_claudeCode_ts_0f9590ed._.js.map +1 -0
  145. package/.next/server/chunks/ssr/{[root-of-the-server]__631e12d0._.js → [root-of-the-server]__c91a8380._.js} +2 -2
  146. package/.next/server/chunks/ssr/{[root-of-the-server]__631e12d0._.js.map → [root-of-the-server]__c91a8380._.js.map} +1 -1
  147. package/.next/server/chunks/ssr/src_app_page_tsx_a7111f3e._.js +3 -3
  148. package/.next/server/chunks/ssr/src_app_page_tsx_a7111f3e._.js.map +1 -1
  149. package/.next/server/pages/404.html +1 -1
  150. package/.next/server/pages/500.html +2 -2
  151. package/.next/server/server-reference-manifest.js +1 -1
  152. package/.next/server/server-reference-manifest.json +1 -1
  153. package/.next/standalone/.next/BUILD_ID +1 -1
  154. package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
  155. package/.next/standalone/.next/build-manifest.json +2 -2
  156. package/.next/standalone/.next/prerender-manifest.json +3 -3
  157. package/.next/standalone/.next/routes-manifest.json +8 -0
  158. package/.next/standalone/.next/server/app/_global-error/page.js +1 -1
  159. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  161. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  162. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  163. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  164. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  165. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  166. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  167. package/.next/standalone/.next/server/app/_not-found/page.js +1 -1
  168. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  169. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  170. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  171. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  172. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  173. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  174. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  175. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  176. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  177. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  178. package/.next/standalone/.next/server/app/api/node/events/route.js +2 -2
  179. package/.next/standalone/.next/server/app/api/node/events/route.js.nft.json +1 -1
  180. package/.next/standalone/.next/server/app/api/node/sessions/[id]/delete/route.js +2 -2
  181. package/.next/standalone/.next/server/app/api/node/sessions/[id]/delete/route.js.nft.json +1 -1
  182. package/.next/standalone/.next/server/app/api/node/sessions/[id]/open-editor/route.js +2 -2
  183. package/.next/standalone/.next/server/app/api/node/sessions/[id]/open-editor/route.js.nft.json +1 -1
  184. package/.next/standalone/.next/server/app/api/node/sessions/route.js +6 -4
  185. package/.next/standalone/.next/server/app/api/node/sessions/route.js.nft.json +1 -1
  186. package/.next/standalone/.next/server/app/api/nodes/route.js +2 -2
  187. package/.next/standalone/.next/server/app/api/nodes/route.js.nft.json +1 -1
  188. package/.next/standalone/.next/server/app/api/opencode-config/route.js +2 -2
  189. package/.next/standalone/.next/server/app/api/opencode-config/route.js.nft.json +1 -1
  190. package/.next/standalone/.next/server/app/api/opencode-config/status/route.js +2 -2
  191. package/.next/standalone/.next/server/app/api/opencode-config/status/route.js.nft.json +1 -1
  192. package/.next/standalone/.next/server/app/api/opencode-events/route.js +3 -3
  193. package/.next/standalone/.next/server/app/api/opencode-events/route.js.nft.json +1 -1
  194. package/.next/standalone/.next/server/app/api/profiles/[id]/apply/route.js +2 -2
  195. package/.next/standalone/.next/server/app/api/profiles/[id]/apply/route.js.nft.json +1 -1
  196. package/.next/standalone/.next/server/app/api/profiles/[id]/export/route.js +2 -2
  197. package/.next/standalone/.next/server/app/api/profiles/[id]/export/route.js.nft.json +1 -1
  198. package/.next/standalone/.next/server/app/api/profiles/[id]/route.js +2 -2
  199. package/.next/standalone/.next/server/app/api/profiles/[id]/route.js.nft.json +1 -1
  200. package/.next/standalone/.next/server/app/api/profiles/import/route.js +2 -2
  201. package/.next/standalone/.next/server/app/api/profiles/import/route.js.nft.json +1 -1
  202. package/.next/standalone/.next/server/app/api/profiles/route.js +2 -2
  203. package/.next/standalone/.next/server/app/api/profiles/route.js.nft.json +1 -1
  204. package/.next/standalone/.next/server/app/api/sessions/[id]/archive/route.js +3 -2
  205. package/.next/standalone/.next/server/app/api/sessions/[id]/archive/route.js.nft.json +1 -1
  206. package/.next/standalone/.next/server/app/api/sessions/[id]/delete/route.js +4 -3
  207. package/.next/standalone/.next/server/app/api/sessions/[id]/delete/route.js.nft.json +1 -1
  208. package/.next/standalone/.next/server/app/api/sessions/[id]/open-editor/route.js +2 -2
  209. package/.next/standalone/.next/server/app/api/sessions/[id]/open-editor/route.js.nft.json +1 -1
  210. package/.next/standalone/.next/server/app/api/sessions/[id]/restore/route/app-paths-manifest.json +3 -0
  211. package/.next/standalone/.next/server/app/api/sessions/[id]/restore/route/build-manifest.json +11 -0
  212. package/.next/standalone/.next/server/app/api/sessions/[id]/restore/route/server-reference-manifest.json +4 -0
  213. package/.next/standalone/.next/server/app/api/sessions/[id]/restore/route.js +8 -0
  214. package/.next/standalone/.next/server/app/api/sessions/[id]/restore/route.js.map +5 -0
  215. package/.next/standalone/.next/server/app/api/sessions/[id]/restore/route.js.nft.json +1 -0
  216. package/.next/standalone/.next/server/app/api/sessions/[id]/restore/route_client-reference-manifest.js +2 -0
  217. package/.next/standalone/.next/server/app/api/sessions/[id]/route.js +2 -2
  218. package/.next/standalone/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  219. package/.next/standalone/.next/server/app/api/sessions/route.js +5 -3
  220. package/.next/standalone/.next/server/app/api/sessions/route.js.nft.json +1 -1
  221. package/.next/standalone/.next/server/app/index.html +1 -1
  222. package/.next/standalone/.next/server/app/index.rsc +3 -3
  223. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  224. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  225. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  226. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  227. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  228. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  229. package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
  230. package/.next/standalone/.next/server/chunks/[root-of-the-server]__005eb0c5._.js +3 -0
  231. package/.next/standalone/.next/server/chunks/[root-of-the-server]__09e90d57._.js +3 -0
  232. package/.next/standalone/.next/server/chunks/[root-of-the-server]__18dd0ce9._.js +3 -0
  233. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19468536._.js +3 -0
  234. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1b87ec42._.js +1 -1
  235. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2b912935._.js +3 -0
  236. package/.next/standalone/.next/server/chunks/[root-of-the-server]__303d3bac._.js +3 -0
  237. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3fac2b91._.js +5 -0
  238. package/.next/standalone/.next/server/chunks/[root-of-the-server]__43440b8d._.js +3 -0
  239. package/.next/standalone/.next/server/chunks/[root-of-the-server]__438f8bbe._.js +3 -0
  240. package/.next/standalone/.next/server/chunks/[root-of-the-server]__4a0bfb55._.js +3 -0
  241. package/.next/standalone/.next/server/chunks/[root-of-the-server]__534c3949._.js +3 -0
  242. package/.next/standalone/.next/server/chunks/[root-of-the-server]__59160266._.js +1 -1
  243. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6f812da0._.js +3 -0
  244. package/.next/standalone/.next/server/chunks/[root-of-the-server]__71aac504._.js +3 -0
  245. package/.next/standalone/.next/server/chunks/[root-of-the-server]__907a8bf2._.js +3 -0
  246. package/.next/standalone/.next/server/chunks/[root-of-the-server]__92089220._.js +3 -0
  247. package/.next/standalone/.next/server/chunks/[root-of-the-server]__9b7bc2d0._.js +3 -0
  248. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b2640944._.js +3 -0
  249. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c2267cf1._.js +3 -0
  250. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d7f7e6dd._.js +3 -0
  251. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d8e61048._.js +1 -1
  252. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f6d0d488._.js +3 -0
  253. package/.next/standalone/.next/server/chunks/[root-of-the-server]__fa559e1e._.js +3 -0
  254. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_sessions_[id]_restore_route_actions_af7d6b6c.js +3 -0
  255. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_7e181e75.js +1 -1
  256. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_aca45402.js +1 -1
  257. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_b054aff3.js +1 -1
  258. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_fa835ac3.js +2 -2
  259. package/.next/standalone/.next/server/chunks/src_lib_opencodeConfig_ts_8e209941._.js +3 -0
  260. package/.next/standalone/.next/server/chunks/src_lib_session-providers_claudeCode_ts_0f9590ed._.js +3 -0
  261. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__631e12d0._.js → [root-of-the-server]__c91a8380._.js} +2 -2
  262. package/.next/standalone/.next/server/chunks/ssr/src_app_page_tsx_a7111f3e._.js +3 -3
  263. package/.next/standalone/.next/server/pages/404.html +1 -1
  264. package/.next/standalone/.next/server/pages/500.html +2 -2
  265. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  266. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  267. package/.next/standalone/.next/static/chunks/9e790b67c80f853c.js +13 -0
  268. package/.next/standalone/.next/static/chunks/c3dc8cd80979c971.css +3 -0
  269. package/.next/standalone/AGENTS.md +4 -0
  270. package/.next/standalone/README.md +54 -5
  271. package/.next/standalone/check-hsql.mjs +1 -1
  272. package/.next/standalone/docs/session-status-detection.md +36 -0
  273. package/.next/standalone/docs/superpowers/specs/2026-04-09-claude-capability-alignment-design.md +39 -0
  274. package/.next/standalone/eslint.config.mjs +1 -0
  275. package/.next/standalone/package-lock.json +74 -13
  276. package/.next/standalone/package.json +2 -2
  277. package/.next/standalone/src/app/api/node/events/route.ts +3 -3
  278. package/.next/standalone/src/app/api/node/sessions/[id]/archive/route.test.ts +60 -1
  279. package/.next/standalone/src/app/api/node/sessions/[id]/archive/route.ts +77 -22
  280. package/.next/standalone/src/app/api/node/sessions/[id]/delete/route.ts +6 -5
  281. package/.next/standalone/src/app/api/node/sessions/[id]/open-editor/route.ts +6 -5
  282. package/.next/standalone/src/app/api/node/sessions/route.test.ts +282 -0
  283. package/.next/standalone/src/app/api/node/sessions/route.ts +156 -30
  284. package/.next/standalone/src/app/api/opencode-config/route.test.ts +613 -0
  285. package/.next/standalone/src/app/api/opencode-config/route.ts +336 -185
  286. package/.next/standalone/src/app/api/opencode-events/route.test.ts +77 -1
  287. package/.next/standalone/src/app/api/opencode-events/route.ts +3 -3
  288. package/.next/standalone/src/app/api/opencode-models/route.test.ts +19 -0
  289. package/.next/standalone/src/app/api/opencode-models/route.ts +4 -1
  290. package/.next/standalone/src/app/api/profiles/[id]/apply/route.test.ts +227 -0
  291. package/.next/standalone/src/app/api/profiles/[id]/apply/route.ts +13 -9
  292. package/.next/standalone/src/app/api/sessions/[id]/archive/route.test.ts +126 -0
  293. package/.next/standalone/src/app/api/sessions/[id]/archive/route.ts +47 -12
  294. package/.next/standalone/src/app/api/sessions/[id]/delete/route.test.ts +140 -0
  295. package/.next/standalone/src/app/api/sessions/[id]/delete/route.ts +51 -16
  296. package/.next/standalone/src/app/api/sessions/[id]/open-editor/route.test.ts +74 -0
  297. package/.next/standalone/src/app/api/sessions/[id]/open-editor/route.ts +22 -2
  298. package/.next/standalone/src/app/api/sessions/[id]/restore/route.test.ts +186 -0
  299. package/.next/standalone/src/app/api/sessions/[id]/restore/route.ts +184 -0
  300. package/.next/standalone/src/app/api/sessions/[id]/route.ts +3 -3
  301. package/.next/standalone/src/app/api/sessions/route.test.ts +1955 -100
  302. package/.next/standalone/src/app/api/sessions/route.ts +361 -986
  303. package/.next/standalone/src/components/KanbanBoard.test.tsx +307 -1
  304. package/.next/standalone/src/components/KanbanBoard.tsx +106 -19
  305. package/.next/standalone/src/components/ProjectCard.test.tsx +420 -6
  306. package/.next/standalone/src/components/ProjectCard.tsx +238 -86
  307. package/.next/standalone/src/components/SessionCard.test.tsx +259 -8
  308. package/.next/standalone/src/components/SessionCard.tsx +182 -76
  309. package/.next/standalone/src/components/opencode-config/AgentConfigForm.test.tsx +141 -1
  310. package/.next/standalone/src/components/opencode-config/AgentConfigForm.tsx +99 -7
  311. package/.next/standalone/src/components/opencode-config/GeneralSettingsForm.test.tsx +11 -0
  312. package/.next/standalone/src/components/opencode-config/GeneralSettingsForm.tsx +41 -2
  313. package/.next/standalone/src/components/opencode-config/categories/CategoriesManager.tsx +3 -1
  314. package/.next/standalone/src/components/opencode-config/categories/CategoryConfigForm.test.tsx +106 -8
  315. package/.next/standalone/src/components/opencode-config/categories/CategoryConfigForm.tsx +82 -5
  316. package/.next/standalone/src/hooks/useHostSources.test.ts +0 -41
  317. package/.next/standalone/src/hooks/useOpencodeSync.test.ts +321 -1
  318. package/.next/standalone/src/hooks/useOpencodeSync.ts +16 -12
  319. package/.next/standalone/src/lib/claudeSessionOverrides.test.ts +75 -0
  320. package/.next/standalone/src/lib/claudeSessionOverrides.ts +169 -0
  321. package/.next/standalone/src/lib/fixtures/opencode-config/oh-my-openagent.v4.jsonc +70 -0
  322. package/.next/standalone/src/lib/fixtures/opencode-config/oh-my-openagent.v4.secret-like.jsonc +21 -0
  323. package/.next/standalone/src/lib/fixtures/opencode-config/oh-my-opencode.v3.jsonc +17 -0
  324. package/.next/standalone/src/lib/opencodeConfig.test.ts +430 -3
  325. package/.next/standalone/src/lib/opencodeConfig.ts +157 -4
  326. package/.next/standalone/src/lib/opencodeDiscovery.test.ts +241 -0
  327. package/.next/standalone/src/lib/opencodeDiscovery.ts +164 -9
  328. package/.next/standalone/src/lib/profiles/share.test.ts +92 -0
  329. package/.next/standalone/src/lib/profiles/share.ts +1 -0
  330. package/.next/standalone/src/lib/profiles/storage.test.ts +77 -1
  331. package/.next/standalone/src/lib/profiles/storage.ts +10 -9
  332. package/.next/standalone/src/lib/session-providers/claudeCode.test.ts +2288 -0
  333. package/.next/standalone/src/lib/session-providers/claudeCode.ts +1083 -0
  334. package/.next/standalone/src/lib/session-providers/localAggregator.test.ts +322 -0
  335. package/.next/standalone/src/lib/session-providers/localAggregator.ts +302 -0
  336. package/.next/standalone/src/lib/session-providers/opencodeProvider.test.ts +170 -0
  337. package/.next/standalone/src/lib/session-providers/opencodeProvider.ts +721 -0
  338. package/.next/standalone/src/lib/session-providers/opencodeSdkCompat.ts +92 -0
  339. package/.next/standalone/src/lib/session-providers/providerIds.test.ts +337 -0
  340. package/.next/standalone/src/lib/session-providers/providerIds.ts +176 -0
  341. package/.next/standalone/src/lib/session-providers/types.ts +131 -0
  342. package/.next/standalone/src/lib/transform.test.ts +253 -0
  343. package/.next/standalone/src/lib/transform.ts +96 -37
  344. package/.next/standalone/src/types/index.ts +23 -17
  345. package/.next/standalone/src/types/opencodeConfig.ts +55 -0
  346. package/.next/static/chunks/9e790b67c80f853c.js +13 -0
  347. package/.next/static/chunks/c3dc8cd80979c971.css +3 -0
  348. package/.next/trace +1 -1
  349. package/.next/trace-build +1 -1
  350. package/.next/types/routes.d.ts +2 -1
  351. package/.next/types/validator.ts +9 -0
  352. package/README.md +54 -5
  353. package/package.json +2 -2
  354. package/.next/server/chunks/[root-of-the-server]__1211da38._.js +0 -3
  355. package/.next/server/chunks/[root-of-the-server]__1211da38._.js.map +0 -1
  356. package/.next/server/chunks/[root-of-the-server]__192ed2f4._.js +0 -3
  357. package/.next/server/chunks/[root-of-the-server]__2b526e7a._.js +0 -3
  358. package/.next/server/chunks/[root-of-the-server]__2b526e7a._.js.map +0 -1
  359. package/.next/server/chunks/[root-of-the-server]__2f981540._.js +0 -3
  360. package/.next/server/chunks/[root-of-the-server]__2f981540._.js.map +0 -1
  361. package/.next/server/chunks/[root-of-the-server]__3745b314._.js +0 -3
  362. package/.next/server/chunks/[root-of-the-server]__3745b314._.js.map +0 -1
  363. package/.next/server/chunks/[root-of-the-server]__56690af0._.js +0 -3
  364. package/.next/server/chunks/[root-of-the-server]__56690af0._.js.map +0 -1
  365. package/.next/server/chunks/[root-of-the-server]__56f5f249._.js +0 -3
  366. package/.next/server/chunks/[root-of-the-server]__56f5f249._.js.map +0 -1
  367. package/.next/server/chunks/[root-of-the-server]__59175de4._.js +0 -3
  368. package/.next/server/chunks/[root-of-the-server]__59175de4._.js.map +0 -1
  369. package/.next/server/chunks/[root-of-the-server]__64fffc02._.js +0 -3
  370. package/.next/server/chunks/[root-of-the-server]__64fffc02._.js.map +0 -1
  371. package/.next/server/chunks/[root-of-the-server]__6924c09d._.js +0 -3
  372. package/.next/server/chunks/[root-of-the-server]__6c428a24._.js +0 -3
  373. package/.next/server/chunks/[root-of-the-server]__6c428a24._.js.map +0 -1
  374. package/.next/server/chunks/[root-of-the-server]__73a00b88._.js +0 -3
  375. package/.next/server/chunks/[root-of-the-server]__73a00b88._.js.map +0 -1
  376. package/.next/server/chunks/[root-of-the-server]__7e757f50._.js +0 -3
  377. package/.next/server/chunks/[root-of-the-server]__7e757f50._.js.map +0 -1
  378. package/.next/server/chunks/[root-of-the-server]__89c5eeab._.js +0 -3
  379. package/.next/server/chunks/[root-of-the-server]__89c5eeab._.js.map +0 -1
  380. package/.next/server/chunks/[root-of-the-server]__8da6c5a8._.js +0 -3
  381. package/.next/server/chunks/[root-of-the-server]__8da6c5a8._.js.map +0 -1
  382. package/.next/server/chunks/[root-of-the-server]__b796d06c._.js +0 -3
  383. package/.next/server/chunks/[root-of-the-server]__b796d06c._.js.map +0 -1
  384. package/.next/server/chunks/[root-of-the-server]__c2ce5c0f._.js +0 -3
  385. package/.next/server/chunks/[root-of-the-server]__c2ce5c0f._.js.map +0 -1
  386. package/.next/server/chunks/[root-of-the-server]__db285678._.js +0 -3
  387. package/.next/server/chunks/[root-of-the-server]__db285678._.js.map +0 -1
  388. package/.next/server/chunks/[root-of-the-server]__e00a9200._.js +0 -5
  389. package/.next/server/chunks/[root-of-the-server]__e00a9200._.js.map +0 -1
  390. package/.next/server/chunks/[root-of-the-server]__e5df5e5f._.js +0 -3
  391. package/.next/server/chunks/[root-of-the-server]__e5df5e5f._.js.map +0 -1
  392. package/.next/server/chunks/[root-of-the-server]__edbc8d9e._.js +0 -3
  393. package/.next/server/chunks/[root-of-the-server]__edbc8d9e._.js.map +0 -1
  394. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1211da38._.js +0 -3
  395. package/.next/standalone/.next/server/chunks/[root-of-the-server]__192ed2f4._.js +0 -3
  396. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2b526e7a._.js +0 -3
  397. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2f981540._.js +0 -3
  398. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3745b314._.js +0 -3
  399. package/.next/standalone/.next/server/chunks/[root-of-the-server]__56690af0._.js +0 -3
  400. package/.next/standalone/.next/server/chunks/[root-of-the-server]__56f5f249._.js +0 -3
  401. package/.next/standalone/.next/server/chunks/[root-of-the-server]__59175de4._.js +0 -3
  402. package/.next/standalone/.next/server/chunks/[root-of-the-server]__64fffc02._.js +0 -3
  403. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6924c09d._.js +0 -3
  404. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6c428a24._.js +0 -3
  405. package/.next/standalone/.next/server/chunks/[root-of-the-server]__73a00b88._.js +0 -3
  406. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7e757f50._.js +0 -3
  407. package/.next/standalone/.next/server/chunks/[root-of-the-server]__89c5eeab._.js +0 -3
  408. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8da6c5a8._.js +0 -3
  409. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b796d06c._.js +0 -3
  410. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c2ce5c0f._.js +0 -3
  411. package/.next/standalone/.next/server/chunks/[root-of-the-server]__db285678._.js +0 -3
  412. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e00a9200._.js +0 -5
  413. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e5df5e5f._.js +0 -3
  414. package/.next/standalone/.next/server/chunks/[root-of-the-server]__edbc8d9e._.js +0 -3
  415. package/.next/standalone/.next/static/chunks/65d5354ba0add961.js +0 -13
  416. package/.next/standalone/.next/static/chunks/f42202943f6742e5.css +0 -3
  417. package/.next/static/chunks/65d5354ba0add961.js +0 -13
  418. package/.next/static/chunks/f42202943f6742e5.css +0 -3
  419. /package/.next/standalone/.next/static/{5kq9DtuBFVxu4jsgmL5Q- → 0WaQ6UjiNBgvh531pJVh0}/_buildManifest.js +0 -0
  420. /package/.next/standalone/.next/static/{5kq9DtuBFVxu4jsgmL5Q- → 0WaQ6UjiNBgvh531pJVh0}/_clientMiddlewareManifest.json +0 -0
  421. /package/.next/standalone/.next/static/{5kq9DtuBFVxu4jsgmL5Q- → 0WaQ6UjiNBgvh531pJVh0}/_ssgManifest.js +0 -0
  422. /package/.next/static/{5kq9DtuBFVxu4jsgmL5Q- → 0WaQ6UjiNBgvh531pJVh0}/_buildManifest.js +0 -0
  423. /package/.next/static/{5kq9DtuBFVxu4jsgmL5Q- → 0WaQ6UjiNBgvh531pJVh0}/_clientMiddlewareManifest.json +0 -0
  424. /package/.next/static/{5kq9DtuBFVxu4jsgmL5Q- → 0WaQ6UjiNBgvh531pJVh0}/_ssgManifest.js +0 -0
@@ -17,6 +17,16 @@ interface SessionCardProps {
17
17
  card: KanbanCard;
18
18
  }
19
19
 
20
+ const RECENT_IDLE_CHILD_VISIBILITY_WINDOW_MS = 60_000;
21
+
22
+ function shouldShowChildSession(child: { realTimeStatus: string; waitingForUser: boolean; updatedAt: number }): boolean {
23
+ if (child.realTimeStatus !== 'idle' || child.waitingForUser) {
24
+ return true;
25
+ }
26
+
27
+ return Date.now() - child.updatedAt <= RECENT_IDLE_CHILD_VISIBILITY_WINDOW_MS;
28
+ }
29
+
20
30
  function formatRelativeTime(timestamp: number): string {
21
31
  const diffMs = Date.now() - timestamp;
22
32
  const diffMins = Math.floor(diffMs / (1000 * 60));
@@ -30,13 +40,16 @@ function formatRelativeTime(timestamp: number): string {
30
40
  }
31
41
 
32
42
  // Status indicator component
33
- function StatusIndicator({ status, waitingForUser }: { status: string; waitingForUser: boolean }) {
43
+ function StatusIndicator({ status, waitingForUser, provider }: { status: string; waitingForUser: boolean; provider?: string }) {
44
+ const isClaudeProvider = provider === 'claude-code';
45
+ const shapeClass = isClaudeProvider ? 'rotate-45 rounded-[1px]' : 'rounded-full';
46
+ const dotSizeClass = isClaudeProvider ? 'h-[9px] w-[9px]' : 'h-2.5 w-2.5';
34
47
  if (waitingForUser) {
35
48
  return (
36
49
  <div className="flex items-center gap-1.5 text-amber-600 dark:text-amber-400">
37
- <span className="relative flex h-2.5 w-2.5">
38
- <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-amber-400 opacity-75"></span>
39
- <span className="relative inline-flex rounded-full h-2.5 w-2.5 bg-amber-500"></span>
50
+ <span className={`relative flex ${dotSizeClass}`}>
51
+ <span className={`animate-ping absolute inline-flex h-full w-full ${shapeClass} bg-amber-400 opacity-75`} title="Waiting"></span>
52
+ <span className={`relative inline-flex ${dotSizeClass} ${shapeClass} bg-amber-500`}></span>
40
53
  </span>
41
54
  <span className="text-xs font-medium">Waiting</span>
42
55
  </div>
@@ -46,9 +59,9 @@ function StatusIndicator({ status, waitingForUser }: { status: string; waitingFo
46
59
  case 'busy':
47
60
  return (
48
61
  <div className="flex items-center gap-1.5 text-emerald-600 dark:text-emerald-400">
49
- <span className="relative flex h-2.5 w-2.5">
50
- <span className="animate-pulse absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
51
- <span className="relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500"></span>
62
+ <span className={`relative flex ${dotSizeClass}`}>
63
+ <span className={`animate-pulse absolute inline-flex h-full w-full ${shapeClass} bg-emerald-400 opacity-75`} title="Running"></span>
64
+ <span className={`relative inline-flex ${dotSizeClass} ${shapeClass} bg-emerald-500`}></span>
52
65
  </span>
53
66
  <span className="text-xs font-medium">Running</span>
54
67
  </div>
@@ -56,9 +69,9 @@ function StatusIndicator({ status, waitingForUser }: { status: string; waitingFo
56
69
  case 'retry':
57
70
  return (
58
71
  <div className="flex items-center gap-1.5 text-red-600 dark:text-red-400">
59
- <span className="relative flex h-2.5 w-2.5">
60
- <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
61
- <span className="relative inline-flex rounded-full h-2.5 w-2.5 bg-red-500"></span>
72
+ <span className={`relative flex ${dotSizeClass}`}>
73
+ <span className={`animate-ping absolute inline-flex h-full w-full ${shapeClass} bg-red-400 opacity-75`} title="Retrying"></span>
74
+ <span className={`relative inline-flex ${dotSizeClass} ${shapeClass} bg-red-500`}></span>
62
75
  </span>
63
76
  <span className="text-xs font-medium">Retrying</span>
64
77
  </div>
@@ -67,7 +80,7 @@ function StatusIndicator({ status, waitingForUser }: { status: string; waitingFo
67
80
  default:
68
81
  return (
69
82
  <div className="flex items-center gap-1.5 text-gray-500 dark:text-gray-400">
70
- <span className="inline-flex rounded-full h-2.5 w-2.5 bg-gray-400"></span>
83
+ <span className={`inline-flex ${dotSizeClass} bg-gray-400 ${shapeClass}`} title="Idle"></span>
71
84
  <span className="text-xs font-medium">Idle</span>
72
85
  </div>
73
86
  );
@@ -80,7 +93,7 @@ export function SessionCard({ card }: SessionCardProps) {
80
93
  const [remoteSshHost, setRemoteSshHost] = useState('');
81
94
  const [actionOpen, setActionOpen] = useState(false);
82
95
  const [actionError, setActionError] = useState<string | null>(null);
83
- const [pendingAction, setPendingAction] = useState<'open' | 'archive' | 'delete' | null>(null);
96
+ const [pendingAction, setPendingAction] = useState<'open' | 'archive' | 'restore' | 'delete' | null>(null);
84
97
  const actionMenuRef = useRef<HTMLDivElement>(null);
85
98
  const { data: config, isLoading: isConfigLoading, isError: isConfigError } = useQuery<ConfigResponse>({
86
99
  queryKey: ['opencode-config'],
@@ -108,9 +121,11 @@ export function SessionCard({ card }: SessionCardProps) {
108
121
  ? 'Opening…'
109
122
  : pendingAction === 'archive'
110
123
  ? 'Archiving…'
111
- : pendingAction === 'delete'
112
- ? 'Deleting…'
113
- : null;
124
+ : pendingAction === 'restore'
125
+ ? 'Restoring…'
126
+ : pendingAction === 'delete'
127
+ ? 'Deleting…'
128
+ : null;
114
129
 
115
130
  useEffect(() => {
116
131
  const storedTool = window.localStorage.getItem('vibepulse:open-tool');
@@ -181,12 +196,24 @@ export function SessionCard({ card }: SessionCardProps) {
181
196
  return;
182
197
  }
183
198
 
184
- const useRemoteSshTarget = isRemoteCard && openEditorTargetMode === 'hub' && openTool === 'vscode';
199
+ const canOpenEditor = card.capabilities ? card.capabilities.openEditor : true;
200
+ if (isRemoteCard && openEditorTargetMode === 'remote' && !canOpenEditor && openTool === 'antigravity') {
201
+ setActionError('Antigravity cannot open remote sessions without remote editor support. Use VS Code.');
202
+ return;
203
+ }
204
+
205
+ const useRemoteSshTarget =
206
+ isRemoteCard
207
+ && openTool === 'vscode'
208
+ && (
209
+ openEditorTargetMode === 'hub'
210
+ || (openEditorTargetMode === 'remote' && !canOpenEditor)
211
+ );
185
212
  const target = buildEditorUri(openTool === 'antigravity' ? 'antigravity' : 'vscode', card.directory, {
186
213
  remoteSshHost: useRemoteSshTarget ? remoteSshHost : null,
187
214
  });
188
215
 
189
- if (isRemoteCard && openEditorTargetMode === 'remote') {
216
+ if (isRemoteCard && openEditorTargetMode === 'remote' && canOpenEditor) {
190
217
  setPendingAction('open');
191
218
  try {
192
219
  const response = await fetch(`/api/sessions/${card.id}/open-editor`, {
@@ -216,6 +243,9 @@ export function SessionCard({ card }: SessionCardProps) {
216
243
  return;
217
244
  }
218
245
 
246
+ const canArchive = card.capabilities ? card.capabilities.archive : !card.readOnly;
247
+ if (!canArchive) return;
248
+
219
249
  setActionError(null);
220
250
  setPendingAction('archive');
221
251
  try {
@@ -233,11 +263,39 @@ export function SessionCard({ card }: SessionCardProps) {
233
263
  }
234
264
  };
235
265
 
266
+ const handleRestore = async () => {
267
+ if (isActionPending) {
268
+ return;
269
+ }
270
+
271
+ const canArchive = card.capabilities ? card.capabilities.archive : !card.readOnly;
272
+ if (!canArchive) return;
273
+
274
+ setActionError(null);
275
+ setPendingAction('restore');
276
+ try {
277
+ const response = await fetch(`/api/sessions/${card.id}/restore`, { method: 'POST' });
278
+ if (!response.ok) {
279
+ const errorBody = await response.json().catch(() => null);
280
+ setActionError(mapSessionActionError(errorBody, 'Failed to restore session'));
281
+ }
282
+ } catch {
283
+ setActionError('Remote node is offline or unreachable.');
284
+ } finally {
285
+ setPendingAction(null);
286
+ setActionOpen(false);
287
+ await queryClient.invalidateQueries({ queryKey: ['sessions'] });
288
+ }
289
+ };
290
+
236
291
  const handleDelete = async () => {
237
292
  if (isActionPending) {
238
293
  return;
239
294
  }
240
295
 
296
+ const canDelete = card.capabilities ? card.capabilities.delete : !card.readOnly;
297
+ if (!canDelete) return;
298
+
241
299
  setActionError(null);
242
300
  setPendingAction('delete');
243
301
  try {
@@ -255,6 +313,10 @@ export function SessionCard({ card }: SessionCardProps) {
255
313
  }
256
314
  };
257
315
 
316
+ const canArchive = card.capabilities ? card.capabilities.archive : !card.readOnly;
317
+ const canDelete = card.capabilities ? card.capabilities.delete : !card.readOnly;
318
+ const showActionsMenu = canArchive || canDelete;
319
+
258
320
  return (
259
321
  <article
260
322
  className="relative w-full text-left p-4 bg-white dark:bg-zinc-800 rounded-xl shadow-sm border border-gray-200 dark:border-zinc-700 hover:shadow-lg hover:border-gray-300 dark:hover:border-zinc-600 transition-all duration-200"
@@ -269,7 +331,7 @@ export function SessionCard({ card }: SessionCardProps) {
269
331
  >
270
332
  {/* Top: Status indicator */}
271
333
  <div className="flex items-center justify-between mb-2">
272
- <StatusIndicator status={card.opencodeStatus} waitingForUser={card.waitingForUser} />
334
+ <StatusIndicator status={card.opencodeStatus} waitingForUser={card.waitingForUser} provider={card.provider} />
273
335
  </div>
274
336
  <h3
275
337
  className="font-semibold text-gray-900 dark:text-gray-100 text-base line-clamp-2"
@@ -278,18 +340,17 @@ export function SessionCard({ card }: SessionCardProps) {
278
340
  {card.title || 'Untitled Session'}
279
341
  </h3>
280
342
 
281
- {card.agents.length > 0 && (
282
- <div className="flex flex-wrap gap-1 mt-2">
283
- {card.agents.map((agent) => (
284
- <span
285
- key={agent}
286
- className="px-2 py-0.5 bg-indigo-50 text-indigo-700 text-sm rounded-full font-medium"
287
- >
288
- {agent}
289
- </span>
290
- ))}
291
- </div>
292
- )}
343
+ <div className="flex flex-wrap gap-1 mt-2">
344
+ {card.agents.map((agent) => (
345
+ <span
346
+ key={agent}
347
+ className="px-2 py-0.5 bg-indigo-50 text-indigo-700 dark:bg-indigo-900/20 dark:text-indigo-400 text-xs rounded-full font-medium"
348
+ >
349
+ {agent}
350
+ </span>
351
+ ))}
352
+ </div>
353
+
293
354
  {card.projectName && (
294
355
  <div className="mt-2 flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400">
295
356
  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" role="img" aria-hidden="true">
@@ -338,7 +399,33 @@ export function SessionCard({ card }: SessionCardProps) {
338
399
  </div>
339
400
  </div>
340
401
  )}
402
+ {(() => {
403
+ const visibleChildren = (card.children || []).filter(
404
+ shouldShowChildSession
405
+ );
406
+ if (visibleChildren.length === 0) return null;
407
+ return (
408
+ <div className="mt-3 bg-gray-50/50 dark:bg-zinc-900/30 -mx-4 px-4 py-2 border-y border-gray-100 dark:border-zinc-700/50">
409
+ {visibleChildren.map((child, i) => (
410
+ <div
411
+ key={child.id}
412
+ className="flex items-center gap-2 pl-2 pr-3 py-1.5"
413
+ title={child.debugReason ? `Reason: ${child.debugReason}` : 'Subagent'}
414
+ >
415
+ <span className="text-gray-300 dark:text-zinc-600 text-xs flex-shrink-0 font-mono leading-none">
416
+ {i === visibleChildren.length - 1 ? '└' : '├'}
417
+ </span>
418
+ <StatusIndicator status={child.realTimeStatus} waitingForUser={child.waitingForUser} provider={card.provider} />
419
+ <span className="text-xs text-gray-500 dark:text-gray-400 truncate flex-1 min-w-0">
420
+ {child.title || 'Subagent'}
421
+ </span>
422
+ </div>
423
+ ))}
424
+ </div>
425
+ );
426
+ })()}
341
427
  {isConfigPendingForRemoteOpen ? (
428
+
342
429
  <div className="mt-3 rounded-md border border-blue-200 bg-blue-50 px-2 py-1 text-xs text-blue-700 dark:border-blue-900/40 dark:bg-blue-900/20 dark:text-blue-300">
343
430
  Loading open settings…
344
431
  </div>
@@ -382,52 +469,71 @@ export function SessionCard({ card }: SessionCardProps) {
382
469
  SSH: {remoteSshHost}
383
470
  </span>
384
471
  )}
385
- <div className="relative" ref={actionMenuRef}>
386
- <button
387
- type="button"
388
- className="inline-flex items-center justify-center w-6 h-6 rounded-md text-gray-400 hover:text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:text-gray-500 dark:hover:text-gray-200 dark:hover:bg-zinc-700"
389
- onClick={(e) => {
390
- e.stopPropagation();
391
- if (!isActionPending) {
392
- setActionOpen((prev) => !prev);
393
- }
394
- }}
395
- onDoubleClick={(e) => e.stopPropagation()}
396
- aria-label="Actions"
397
- title="Actions"
398
- disabled={isActionPending}
399
- >
400
- <svg className="w-4 h-4" viewBox="0 0 24 24" fill="currentColor" role="img" aria-hidden="true">
401
- <path d="M5 10a2 2 0 110 4 2 2 0 010-4zm7 0a2 2 0 110 4 2 2 0 010-4zm7 0a2 2 0 110 4 2 2 0 010-4z" />
402
- </svg>
403
- </button>
404
- {actionOpen && (
405
- <div className="absolute right-0 mt-1 w-36 rounded-md border border-gray-200 bg-white shadow-lg dark:border-zinc-700 dark:bg-zinc-900 z-10">
406
- <button
407
- type="button"
408
- className="w-full text-left px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:text-gray-200 dark:hover:bg-zinc-800"
409
- onClick={(e) => {
410
- e.stopPropagation();
411
- handleArchive();
412
- }}
413
- disabled={isActionPending}
414
- >
415
- Archive
416
- </button>
417
- <button
418
- type="button"
419
- className="w-full text-left px-3 py-2 text-sm text-red-600 hover:bg-red-50 disabled:cursor-not-allowed disabled:opacity-50 dark:text-red-400 dark:hover:bg-red-900/20"
420
- onClick={(e) => {
421
- e.stopPropagation();
422
- handleDelete();
423
- }}
424
- disabled={isActionPending}
425
- >
426
- Delete
427
- </button>
428
- </div>
429
- )}
430
- </div>
472
+ {showActionsMenu && (
473
+ <div className="relative" ref={actionMenuRef}>
474
+ <button
475
+ type="button"
476
+ className="inline-flex items-center justify-center w-6 h-6 rounded-md text-gray-400 hover:text-gray-700 hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 dark:text-gray-500 dark:hover:text-gray-200 dark:hover:bg-zinc-700"
477
+ onClick={(e) => {
478
+ e.stopPropagation();
479
+ if (!isActionPending) {
480
+ setActionOpen((prev) => !prev);
481
+ }
482
+ }}
483
+ onDoubleClick={(e) => e.stopPropagation()}
484
+ aria-label="Actions"
485
+ title="Actions"
486
+ disabled={isActionPending}
487
+ >
488
+ <svg className="w-4 h-4" viewBox="0 0 24 24" fill="currentColor" role="img" aria-hidden="true">
489
+ <path d="M5 10a2 2 0 110 4 2 2 0 010-4zm7 0a2 2 0 110 4 2 2 0 010-4zm7 0a2 2 0 110 4 2 2 0 010-4z" />
490
+ </svg>
491
+ </button>
492
+ {actionOpen && (
493
+ <div className="absolute right-0 mt-1 w-36 rounded-md border border-gray-200 bg-white shadow-lg dark:border-zinc-700 dark:bg-zinc-900 z-10">
494
+ {(card.status !== 'done' && canArchive) && (
495
+ <button
496
+ type="button"
497
+ className="w-full text-left px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:text-gray-200 dark:hover:bg-zinc-800"
498
+ onClick={(e) => {
499
+ e.stopPropagation();
500
+ handleArchive();
501
+ }}
502
+ disabled={isActionPending}
503
+ >
504
+ Archive
505
+ </button>
506
+ )}
507
+ {(card.status === 'done' && canArchive) && (
508
+ <button
509
+ type="button"
510
+ className="w-full text-left px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:text-gray-200 dark:hover:bg-zinc-800"
511
+ onClick={(e) => {
512
+ e.stopPropagation();
513
+ handleRestore();
514
+ }}
515
+ disabled={isActionPending}
516
+ >
517
+ Restore
518
+ </button>
519
+ )}
520
+ {canDelete && (
521
+ <button
522
+ type="button"
523
+ className="w-full text-left px-3 py-2 text-sm text-red-600 hover:bg-red-50 disabled:cursor-not-allowed disabled:opacity-50 dark:text-red-400 dark:hover:bg-red-900/20"
524
+ onClick={(e) => {
525
+ e.stopPropagation();
526
+ handleDelete();
527
+ }}
528
+ disabled={isActionPending}
529
+ >
530
+ Delete
531
+ </button>
532
+ )}
533
+ </div>
534
+ )}
535
+ </div>
536
+ )}
431
537
  </div>
432
538
  </article>
433
539
  );
@@ -1,4 +1,4 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
1
+ import { describe, it, expect, vi, beforeEach, beforeAll, afterAll } from 'vitest';
2
2
  import { render, screen, waitFor } from '@testing-library/react';
3
3
  import userEvent from '@testing-library/user-event';
4
4
  import { AgentConfigForm } from './AgentConfigForm';
@@ -15,6 +15,16 @@ function jsonResponse(data: unknown): Response {
15
15
  } as Response;
16
16
  }
17
17
 
18
+ beforeAll(() => {
19
+ window.HTMLElement.prototype.hasPointerCapture = vi.fn();
20
+ window.HTMLElement.prototype.scrollIntoView = vi.fn();
21
+ });
22
+
23
+ afterAll(() => {
24
+ delete (window.HTMLElement.prototype as any).hasPointerCapture;
25
+ delete (window.HTMLElement.prototype as any).scrollIntoView;
26
+ });
27
+
18
28
  describe('AgentConfigForm - echo bug fix', () => {
19
29
  let queryClient: QueryClient;
20
30
 
@@ -69,6 +79,136 @@ describe('AgentConfigForm - echo bug fix', () => {
69
79
  });
70
80
  });
71
81
 
82
+ it('preserves rich fallback_models structure on submit and updates reasoningEffort', async () => {
83
+ const user = userEvent.setup();
84
+
85
+ mockFetch.mockImplementation(async (url: RequestInfo | URL, init?: RequestInit) => {
86
+ if (url === '/api/opencode-config' && (!init?.method || init.method === 'GET')) {
87
+ return jsonResponse({
88
+ agents: {
89
+ sisyphus: {
90
+ model: 'openai/gpt-4o',
91
+ temperature: 0.5,
92
+ fallback_models: [{ model: 'claude-3-5-sonnet-20240620', maxTokens: 4000 }]
93
+ }
94
+ },
95
+ categories: {},
96
+ });
97
+ }
98
+ if (url === '/api/opencode-models') {
99
+ return jsonResponse({ models: ['openai/gpt-4o'], source: 'test' });
100
+ }
101
+ if (url === '/api/opencode-config' && init?.method === 'POST') {
102
+ return jsonResponse({ success: true });
103
+ }
104
+ return jsonResponse({});
105
+ });
106
+
107
+ render(
108
+ <QueryClientProvider client={queryClient}>
109
+ <AgentConfigForm agentName="sisyphus" />
110
+ </QueryClientProvider>
111
+ );
112
+
113
+ await waitFor(() => {
114
+ const fallbackInput = screen.getByLabelText(/fallback models \(json\)/i);
115
+ expect(fallbackInput).toHaveValue(JSON.stringify([{ model: 'claude-3-5-sonnet-20240620', maxTokens: 4000 }], null, 2));
116
+ });
117
+
118
+ const reasoningSelector = screen.getByLabelText(/reasoning effort/i);
119
+ await user.selectOptions(reasoningSelector, 'max');
120
+
121
+ const modelTrigger = screen.getAllByRole('combobox')[0];
122
+ await user.click(modelTrigger);
123
+ await waitFor(() => {
124
+ expect(screen.getByRole('option', { name: 'gpt-4o' })).toBeInTheDocument();
125
+ });
126
+ await user.click(screen.getByRole('option', { name: 'gpt-4o' }));
127
+
128
+ await user.click(screen.getByRole('button', { name: /save changes/i }));
129
+
130
+ await waitFor(() => {
131
+ const postCall = mockFetch.mock.calls.find((call) => call[0] === '/api/opencode-config' && call[1]?.method === 'POST');
132
+ expect(postCall).toBeTruthy();
133
+ });
134
+
135
+ const postCall = mockFetch.mock.calls.find((call) => call[0] === '/api/opencode-config' && call[1]?.method === 'POST');
136
+ const requestBody = JSON.parse(String(postCall?.[1]?.body));
137
+ expect(requestBody).toEqual({
138
+ agents: {
139
+ sisyphus: {
140
+ model: 'openai/gpt-4o',
141
+ temperature: 0.5,
142
+ top_p: 1,
143
+ variant: '',
144
+ prompt_append: '',
145
+ reasoningEffort: 'max',
146
+ fallback_models: [{ model: 'claude-3-5-sonnet-20240620', maxTokens: 4000 }],
147
+ }
148
+ }
149
+ });
150
+ });
151
+
152
+ it('sends explicit null when fallback_models is cleared and reasoningEffort is not set', async () => {
153
+ const user = userEvent.setup();
154
+
155
+ mockFetch.mockImplementation(async (url: RequestInfo | URL, init?: RequestInit) => {
156
+ if (url === '/api/opencode-config' && (!init?.method || init.method === 'GET')) {
157
+ return jsonResponse({
158
+ agents: {
159
+ sisyphus: {
160
+ model: 'openai/gpt-4o',
161
+ temperature: 0.5,
162
+ reasoningEffort: 'max',
163
+ fallback_models: [{ model: 'claude-3-5-sonnet-20240620', maxTokens: 4000 }]
164
+ }
165
+ },
166
+ categories: {},
167
+ });
168
+ }
169
+ if (url === '/api/opencode-models') {
170
+ return jsonResponse({ models: ['openai/gpt-4o'], source: 'test' });
171
+ }
172
+ if (url === '/api/opencode-config' && init?.method === 'POST') {
173
+ return jsonResponse({ success: true });
174
+ }
175
+ return jsonResponse({});
176
+ });
177
+
178
+ render(
179
+ <QueryClientProvider client={queryClient}>
180
+ <AgentConfigForm agentName="sisyphus" />
181
+ </QueryClientProvider>
182
+ );
183
+
184
+ await waitFor(() => {
185
+ expect(screen.getByLabelText(/fallback models \(json\)/i)).toHaveValue(JSON.stringify([{ model: 'claude-3-5-sonnet-20240620', maxTokens: 4000 }], null, 2));
186
+ });
187
+ const fallbackInput = screen.getByLabelText(/fallback models \(json\)/i);
188
+ await user.clear(fallbackInput);
189
+
190
+ const reasoningSelector = screen.getByLabelText(/reasoning effort/i);
191
+ await user.selectOptions(reasoningSelector, '');
192
+
193
+ const modelTrigger = screen.getAllByRole('combobox')[0];
194
+ await user.click(modelTrigger);
195
+ await waitFor(() => {
196
+ expect(screen.getByRole('option', { name: 'gpt-4o' })).toBeInTheDocument();
197
+ });
198
+ await user.click(screen.getByRole('option', { name: 'gpt-4o' }));
199
+
200
+ await user.click(screen.getByRole('button', { name: /save changes/i }));
201
+
202
+ await waitFor(() => {
203
+ const postCall = mockFetch.mock.calls.find((call) => call[0] === '/api/opencode-config' && call[1]?.method === 'POST');
204
+ expect(postCall).toBeTruthy();
205
+ });
206
+
207
+ const postCall = mockFetch.mock.calls.find((call) => call[0] === '/api/opencode-config' && call[1]?.method === 'POST');
208
+ const requestBody = JSON.parse(String(postCall?.[1]?.body));
209
+ expect(requestBody.agents.sisyphus.fallback_models).toBeNull();
210
+ expect(requestBody.agents.sisyphus.reasoningEffort).toBeNull();
211
+ });
72
212
  it('shows the upstream hephaestus fallback chain when no model is configured', async () => {
73
213
  mockFetch
74
214
  .mockResolvedValueOnce(