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
@@ -0,0 +1,721 @@
1
+ import { execSync } from 'child_process';
2
+ import path from 'path';
3
+ import {
4
+ discoverOpencodePortsWithMeta,
5
+ discoverOpencodeProcessCwdsWithoutPortWithMeta,
6
+ } from '@/lib/opencodeDiscovery';
7
+ import {
8
+ pruneSessionStickyStatusBlocked,
9
+ pruneSessionForceUnarchived,
10
+ shouldForceSessionUnarchived,
11
+ } from '@/lib/sessionArchiveOverrides';
12
+ import {
13
+ applyStickyStatusStabilization,
14
+ pruneStickyState,
15
+ shouldSkipSessionStatusStabilization,
16
+ } from './localAggregator';
17
+ import type {
18
+ ChildEntry,
19
+ EnrichedSession,
20
+ LocalSessionProvider,
21
+ MessagePart,
22
+ MessageStateStatus,
23
+ ProcessHint,
24
+ SessionLike,
25
+ SessionsRouteResult,
26
+ StableRealtimeStatus,
27
+ } from './types';
28
+ import {
29
+ createVibePulseOpencodeClient,
30
+ formatOpencodeSdkError,
31
+ getOpencodeSessionMessages,
32
+ getOpencodeSessionStatus,
33
+ listOpencodeSessions,
34
+ type OpencodeSdkClient,
35
+ } from './opencodeSdkCompat';
36
+
37
+ const CHILD_ACTIVE_WINDOW_MS = 30 * 60 * 1000;
38
+ const CHILD_UNKNOWN_STATE_BUSY_WINDOW_MS = 2 * 60 * 1000;
39
+ const CHILD_STATUS_MESSAGE_CHECK_LIMIT = 50;
40
+ const STALL_DETECTION_WINDOW_MS = 30 * 1000;
41
+ const GIT_COMMAND_TIMEOUT_MS = 1200;
42
+ const sessionListTimeoutMs = readPositiveTimeoutEnv('OPENCODE_SESSIONS_LIST_TIMEOUT_MS', 6000);
43
+ const sessionStatusTimeoutMs = readPositiveTimeoutEnv('OPENCODE_SESSIONS_STATUS_TIMEOUT_MS', 4000);
44
+ const sessionMessagesTimeoutMs = readPositiveTimeoutEnv('OPENCODE_SESSIONS_MESSAGES_TIMEOUT_MS', 2500);
45
+
46
+ const WAITING_PART_STATUSES = new Set<string>([
47
+ 'awaiting-input',
48
+ 'awaiting_input',
49
+ 'input-required',
50
+ 'input_required',
51
+ 'requires-input',
52
+ 'requires_input',
53
+ 'blocked',
54
+ 'paused',
55
+ ]);
56
+
57
+ function readPositiveTimeoutEnv(name: string, fallback: number): number {
58
+ const raw = process.env[name];
59
+ const parsed = Number(raw);
60
+ if (Number.isFinite(parsed) && parsed > 0) {
61
+ return Math.floor(parsed);
62
+ }
63
+ return fallback;
64
+ }
65
+
66
+ function withTimeout<T>(operation: (signal: AbortSignal) => Promise<T>, timeoutMs: number, label: string): Promise<T> {
67
+ const timeoutError = new Error(`${label} timed out after ${timeoutMs}ms`);
68
+ const timeoutController = new AbortController();
69
+ let timeoutHandle: NodeJS.Timeout | undefined;
70
+ const timeoutPromise = new Promise<never>((_, reject) => {
71
+ timeoutHandle = setTimeout(() => {
72
+ timeoutController.abort();
73
+ reject(timeoutError);
74
+ }, timeoutMs);
75
+ });
76
+
77
+ const operationPromise = operation(timeoutController.signal).catch((error) => {
78
+ if (timeoutController.signal.aborted) {
79
+ throw timeoutError;
80
+ }
81
+
82
+ throw error;
83
+ });
84
+
85
+ return Promise.race([operationPromise, timeoutPromise]).finally(() => {
86
+ if (timeoutHandle) {
87
+ clearTimeout(timeoutHandle);
88
+ }
89
+ });
90
+ }
91
+
92
+ function normalizePartStatus(status: string): string {
93
+ return status.trim().toLowerCase();
94
+ }
95
+
96
+ function isWaitingPartStatus(status: string): boolean {
97
+ return WAITING_PART_STATUSES.has(normalizePartStatus(status));
98
+ }
99
+
100
+ function collectPartStatuses(messages: Array<{ parts?: MessagePart[] }>): MessageStateStatus[] {
101
+ const partStatuses: MessageStateStatus[] = [];
102
+
103
+ for (const message of messages) {
104
+ for (const part of message.parts || []) {
105
+ const status = part?.state?.status;
106
+ if (typeof status === 'string') {
107
+ const normalized = normalizePartStatus(status);
108
+ if (normalized) {
109
+ partStatuses.push(normalized);
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ return partStatuses;
116
+ }
117
+
118
+ async function fetchPartStatuses(
119
+ client: OpencodeSdkClient,
120
+ sessionId: string,
121
+ timeoutMs: number
122
+ ): Promise<MessageStateStatus[]> {
123
+ const messagesResult = await withTimeout(
124
+ (signal) => getOpencodeSessionMessages(client, sessionId, 8, signal),
125
+ timeoutMs,
126
+ `session.messages(${sessionId})`
127
+ );
128
+ const messages = (messagesResult.data || []) as Array<{ parts?: MessagePart[] }>;
129
+ return collectPartStatuses(messages);
130
+ }
131
+
132
+ function getUpdatedAt(session: { time?: { updated?: number; created?: number } }): number {
133
+ return session.time?.updated || session.time?.created || 0;
134
+ }
135
+
136
+ function hasRecentActivity(session: { time?: { updated?: number } }, now: number): boolean {
137
+ const updatedAt = session.time?.updated;
138
+ if (!updatedAt) return false;
139
+ return now - updatedAt <= STALL_DETECTION_WINDOW_MS;
140
+ }
141
+
142
+ function toChildEntry(
143
+ child: SessionLike,
144
+ status: 'idle' | 'busy' | 'retry',
145
+ waitingForUser = false
146
+ ): ChildEntry {
147
+ return {
148
+ id: child.id,
149
+ slug: child.slug,
150
+ title: child.title,
151
+ directory: child.directory,
152
+ debugReason: child.debugReason,
153
+ parentID: child.parentID,
154
+ time: child.time,
155
+ realTimeStatus: status,
156
+ waitingForUser,
157
+ };
158
+ }
159
+
160
+ function getProjectName(directory: string): string {
161
+ return path.basename(directory);
162
+ }
163
+
164
+ function isGitRepo(directory: string): boolean {
165
+ try {
166
+ const result = execSync('git rev-parse --is-inside-work-tree', {
167
+ cwd: directory,
168
+ encoding: 'utf-8',
169
+ stdio: ['ignore', 'pipe', 'ignore'],
170
+ timeout: GIT_COMMAND_TIMEOUT_MS,
171
+ });
172
+ return result.trim() === 'true';
173
+ } catch {
174
+ return false;
175
+ }
176
+ }
177
+
178
+ function getGitBranch(directory: string): string | null {
179
+ if (!isGitRepo(directory)) return null;
180
+ try {
181
+ const branch = execSync('git branch --show-current', {
182
+ cwd: directory,
183
+ encoding: 'utf-8',
184
+ stdio: ['ignore', 'pipe', 'ignore'],
185
+ timeout: GIT_COMMAND_TIMEOUT_MS,
186
+ });
187
+ return branch.trim() || null;
188
+ } catch {
189
+ return null;
190
+ }
191
+ }
192
+
193
+ function sortChildEntries(children: ChildEntry[]): void {
194
+ children.sort((a, b) => {
195
+ const aActive = a.realTimeStatus === 'busy' || a.realTimeStatus === 'retry';
196
+ const bActive = b.realTimeStatus === 'busy' || b.realTimeStatus === 'retry';
197
+
198
+ if (aActive && !bActive) return -1;
199
+ if (!aActive && bActive) return 1;
200
+
201
+ const aTime = a.time?.updated || a.time?.created || 0;
202
+ const bTime = b.time?.updated || b.time?.created || 0;
203
+ return bTime - aTime;
204
+ });
205
+ }
206
+
207
+ export const opencodeLocalSessionProvider: LocalSessionProvider = {
208
+ id: 'opencode',
209
+ async getSessionsResult({ stickyBusyDelayMs }): Promise<SessionsRouteResult> {
210
+ const { processes: rawProcessHints, timedOut: processDiscoveryTimedOut } =
211
+ discoverOpencodeProcessCwdsWithoutPortWithMeta();
212
+ const processHintsByDirectory = new Map<string, ProcessHint>();
213
+ for (const process of rawProcessHints) {
214
+ if (!process.cwd || process.cwd.startsWith('/private/tmp/opencode')) {
215
+ continue;
216
+ }
217
+ if (processHintsByDirectory.has(process.cwd)) {
218
+ continue;
219
+ }
220
+ processHintsByDirectory.set(process.cwd, {
221
+ pid: process.pid,
222
+ directory: process.cwd,
223
+ projectName: getProjectName(process.cwd),
224
+ reason: 'process_without_api_port',
225
+ });
226
+ }
227
+
228
+ const { ports, timedOut: portDiscoveryTimedOut } = discoverOpencodePortsWithMeta();
229
+
230
+ if (!ports.length) {
231
+ const processHints = Array.from(processHintsByDirectory.values());
232
+
233
+ if (portDiscoveryTimedOut || processDiscoveryTimedOut) {
234
+ return {
235
+ payload: {
236
+ error: 'OpenCode discovery timed out',
237
+ hint: 'Host process discovery exceeded timeout. Retry shortly, or increase OPENCODE_DISCOVERY_TIMEOUT_MS.',
238
+ ...(processHints.length > 0 ? { processHints } : {}),
239
+ },
240
+ status: 503,
241
+ sourceMeta: {
242
+ online: false,
243
+ degraded: true,
244
+ reason: 'OpenCode discovery timed out',
245
+ },
246
+ };
247
+ }
248
+
249
+ if (processHints.length > 0) {
250
+ return {
251
+ payload: { sessions: [], processHints },
252
+ sourceMeta: {
253
+ online: false,
254
+ reason: 'OpenCode server not found',
255
+ },
256
+ };
257
+ }
258
+
259
+ return {
260
+ payload: {
261
+ error: 'OpenCode server not found',
262
+ hint: 'Make sure OpenCode is running with an exposed API port. Example: opencode --port <PORT> (VibePulse auto-detects active ports).',
263
+ },
264
+ status: 503,
265
+ sourceMeta: {
266
+ online: false,
267
+ reason: 'OpenCode server not found',
268
+ },
269
+ };
270
+ }
271
+
272
+ try {
273
+ const results = await Promise.allSettled(ports.map(async (port) => {
274
+ const client = createVibePulseOpencodeClient(`http://localhost:${port}`);
275
+ const sessionsResult = await withTimeout(
276
+ (signal) => listOpencodeSessions(client, signal),
277
+ sessionListTimeoutMs,
278
+ `session.list(${port})`
279
+ );
280
+ const statusResult = await withTimeout(
281
+ (signal) => getOpencodeSessionStatus(client, signal),
282
+ sessionStatusTimeoutMs,
283
+ `session.status(${port})`
284
+ ).catch(() => ({ data: {} }));
285
+ return { port, client, sessions: sessionsResult.data || [], status: statusResult.data || {} };
286
+ }));
287
+
288
+ const allSessions: SessionLike[] = [];
289
+ const statusMap: Record<string, { type: StableRealtimeStatus }> = {};
290
+ const clientByPort: Record<number, OpencodeSdkClient> = {};
291
+ const sessionPortMap: Record<string, number> = {};
292
+ const failedPorts: Array<{ port: number; reason: string }> = [];
293
+
294
+ for (let i = 0; i < results.length; i++) {
295
+ const result = results[i];
296
+ const port = ports[i];
297
+ if (result.status !== 'fulfilled') {
298
+ failedPorts.push({
299
+ port,
300
+ reason: formatOpencodeSdkError(result.reason),
301
+ });
302
+ continue;
303
+ }
304
+ allSessions.push(...(result.value.sessions as SessionLike[]));
305
+ Object.assign(statusMap, result.value.status);
306
+ clientByPort[result.value.port] = result.value.client;
307
+ for (const session of result.value.sessions as SessionLike[]) {
308
+ if (!(session.id in sessionPortMap)) {
309
+ sessionPortMap[session.id] = result.value.port;
310
+ }
311
+ }
312
+ }
313
+
314
+ const sessions: SessionLike[] = [];
315
+ const seen = new Set<string>();
316
+ for (const session of allSessions) {
317
+ if (seen.has(session.id)) {
318
+ continue;
319
+ }
320
+ seen.add(session.id);
321
+ sessions.push(session);
322
+ }
323
+
324
+ const parentSessions = sessions.filter((session) => !session.parentID);
325
+ const childSessions = sessions.filter((session) => !!session.parentID);
326
+
327
+ const lifecycleNow = Date.now();
328
+ pruneSessionForceUnarchived(lifecycleNow);
329
+ pruneSessionStickyStatusBlocked(lifecycleNow);
330
+
331
+ for (const session of parentSessions) {
332
+ if (session.time?.archived !== undefined && shouldForceSessionUnarchived(session.id, lifecycleNow)) {
333
+ session.time = {
334
+ ...session.time,
335
+ archived: undefined,
336
+ };
337
+ }
338
+ }
339
+
340
+ for (const child of childSessions) {
341
+ if (child.time?.archived !== undefined && shouldForceSessionUnarchived(child.id, lifecycleNow)) {
342
+ child.time = {
343
+ ...child.time,
344
+ archived: undefined,
345
+ };
346
+ }
347
+ }
348
+
349
+ if (results.length > 0 && failedPorts.length === results.length) {
350
+ pruneStickyState(Date.now(), new Set<string>());
351
+ return {
352
+ payload: {
353
+ error: 'Failed to fetch sessions from OpenCode ports',
354
+ hint: 'All discovered OpenCode API ports timed out or failed. Retry shortly or increase OPENCODE_SESSIONS_LIST_TIMEOUT_MS.',
355
+ failedPorts,
356
+ },
357
+ status: 503,
358
+ sourceMeta: {
359
+ online: false,
360
+ degraded: true,
361
+ reason: 'Failed to fetch sessions from OpenCode ports',
362
+ },
363
+ };
364
+ }
365
+
366
+ if (failedPorts.length > 0 && parentSessions.length === 0 && childSessions.length === 0) {
367
+ pruneStickyState(Date.now(), new Set<string>());
368
+ return {
369
+ payload: {
370
+ sessions: [],
371
+ processHints: Array.from(processHintsByDirectory.values()),
372
+ failedPorts,
373
+ degraded: true,
374
+ },
375
+ sourceMeta: {
376
+ online: true,
377
+ degraded: true,
378
+ },
379
+ };
380
+ }
381
+
382
+ const enrichedSessions: EnrichedSession[] = parentSessions.map((session) => ({
383
+ ...session,
384
+ projectName: getProjectName(session.directory),
385
+ branch: getGitBranch(session.directory),
386
+ realTimeStatus: statusMap[session.id]?.type || 'idle',
387
+ waitingForUser: false,
388
+ children: [],
389
+ }));
390
+
391
+ const parentById = new Map(enrichedSessions.map((session) => [session.id, session]));
392
+ const now = Date.now();
393
+ const unresolvedChildren: Array<{ parentId: string; child: SessionLike; childUpdatedAt: number }> = [];
394
+
395
+ for (const child of childSessions) {
396
+ let parent = child.parentID ? parentById.get(child.parentID) : undefined;
397
+
398
+ if (!parent) {
399
+ const candidates = enrichedSessions
400
+ .filter((session) => session.directory === child.directory)
401
+ .sort((a, b) => getUpdatedAt(b) - getUpdatedAt(a));
402
+
403
+ parent =
404
+ candidates.find((session) => session.realTimeStatus === 'busy' || session.realTimeStatus === 'retry') ||
405
+ candidates[0];
406
+ }
407
+
408
+ if (!parent) {
409
+ continue;
410
+ }
411
+
412
+ const statusFromMap = statusMap[child.id]?.type;
413
+ const childUpdatedAt = getUpdatedAt(child);
414
+ const isRecent = childUpdatedAt > 0 && now - childUpdatedAt <= CHILD_ACTIVE_WINDOW_MS;
415
+ const shouldSkipArchivedChild = !!child.time?.archived && !statusFromMap && !isRecent;
416
+
417
+ if (shouldSkipArchivedChild) {
418
+ continue;
419
+ }
420
+
421
+ if (statusFromMap && statusFromMap !== 'idle') {
422
+ parent.children.push(toChildEntry(child, statusFromMap));
423
+ } else if (isRecent) {
424
+ if (unresolvedChildren.length < CHILD_STATUS_MESSAGE_CHECK_LIMIT) {
425
+ unresolvedChildren.push({ parentId: parent.id, child, childUpdatedAt });
426
+ }
427
+ } else {
428
+ continue;
429
+ }
430
+ }
431
+
432
+ if (unresolvedChildren.length > 0) {
433
+ const unresolvedChecks = await Promise.allSettled(
434
+ unresolvedChildren.map(async ({ parentId, child, childUpdatedAt }) => {
435
+ const port = sessionPortMap[child.id] ?? sessionPortMap[parentId];
436
+ const client = port ? clientByPort[port] : undefined;
437
+ const assumeBusyForUnknown = childUpdatedAt > 0 && now - childUpdatedAt <= CHILD_UNKNOWN_STATE_BUSY_WINDOW_MS;
438
+ if (!client) {
439
+ return {
440
+ parentId,
441
+ child,
442
+ childStatus: assumeBusyForUnknown ? ('busy' as const) : ('idle' as const),
443
+ };
444
+ }
445
+
446
+ try {
447
+ const partStatuses = await fetchPartStatuses(client, child.id, sessionMessagesTimeoutMs);
448
+ const hasRunningState = partStatuses.some((status) => status === 'running');
449
+ const hasWaitingState = !hasRunningState && partStatuses.some(isWaitingPartStatus);
450
+ const hasActiveState = hasWaitingState || hasRunningState;
451
+ const recentlyActive = childUpdatedAt > 0 && now - childUpdatedAt <= 5 * 60 * 1000;
452
+
453
+ return {
454
+ parentId,
455
+ child,
456
+ childWaitingForUser: hasWaitingState,
457
+ childStatus: hasActiveState
458
+ ? ('busy' as const)
459
+ : recentlyActive || assumeBusyForUnknown
460
+ ? ('busy' as const)
461
+ : ('idle' as const),
462
+ };
463
+ } catch {
464
+ return {
465
+ parentId,
466
+ child,
467
+ childWaitingForUser: false,
468
+ childStatus: assumeBusyForUnknown ? ('busy' as const) : ('idle' as const),
469
+ };
470
+ }
471
+ })
472
+ );
473
+
474
+ for (const check of unresolvedChecks) {
475
+ if (check.status !== 'fulfilled') continue;
476
+ if (check.value.childStatus === 'idle') continue;
477
+ const parent = parentById.get(check.value.parentId);
478
+ if (!parent) continue;
479
+ parent.children.push(toChildEntry(check.value.child, check.value.childStatus, check.value.childWaitingForUser));
480
+ }
481
+ }
482
+
483
+ const parentStatusFallbackCandidates = enrichedSessions
484
+ .filter((session) => {
485
+ if (session.realTimeStatus !== 'idle') return false;
486
+ const updatedAt = getUpdatedAt(session);
487
+ if (updatedAt > 0 && now - updatedAt <= CHILD_ACTIVE_WINDOW_MS) return true;
488
+ return !!session.time?.archived;
489
+ })
490
+ .sort((a, b) => getUpdatedAt(b) - getUpdatedAt(a))
491
+ .slice(0, CHILD_STATUS_MESSAGE_CHECK_LIMIT);
492
+
493
+ if (parentStatusFallbackCandidates.length > 0) {
494
+ const parentFallbackChecks = await Promise.allSettled(
495
+ parentStatusFallbackCandidates.map(async (session) => {
496
+ const updatedAt = getUpdatedAt(session);
497
+ const assumeBusyForUnknown = updatedAt > 0 && now - updatedAt <= CHILD_UNKNOWN_STATE_BUSY_WINDOW_MS;
498
+ const port = sessionPortMap[session.id];
499
+ const client = port ? clientByPort[port] : undefined;
500
+
501
+ if (!client) {
502
+ return {
503
+ sessionId: session.id,
504
+ status: assumeBusyForUnknown ? ('busy' as const) : ('idle' as const),
505
+ waitingForUser: false,
506
+ };
507
+ }
508
+
509
+ try {
510
+ const partStatuses = await fetchPartStatuses(client, session.id, sessionMessagesTimeoutMs);
511
+ const hasRunningState = partStatuses.some((status) => status === 'running');
512
+ const hasWaitingState = !hasRunningState && partStatuses.some(isWaitingPartStatus);
513
+ const hasCompletedState =
514
+ partStatuses.length > 0 && partStatuses.every((status) => status === 'completed');
515
+ const recentlyActive = hasRecentActivity(session, now);
516
+
517
+ return {
518
+ sessionId: session.id,
519
+ status: hasRunningState || hasWaitingState
520
+ ? ('busy' as const)
521
+ : hasCompletedState && !recentlyActive
522
+ ? ('idle' as const)
523
+ : assumeBusyForUnknown || recentlyActive
524
+ ? ('busy' as const)
525
+ : ('idle' as const),
526
+ waitingForUser: hasWaitingState,
527
+ };
528
+ } catch {
529
+ return {
530
+ sessionId: session.id,
531
+ status: assumeBusyForUnknown ? ('busy' as const) : ('idle' as const),
532
+ waitingForUser: false,
533
+ };
534
+ }
535
+ })
536
+ );
537
+
538
+ for (const check of parentFallbackChecks) {
539
+ if (check.status !== 'fulfilled') continue;
540
+ if (check.value.status === 'idle') continue;
541
+ const session = parentById.get(check.value.sessionId);
542
+ if (!session) continue;
543
+ session.realTimeStatus = check.value.status;
544
+ if (check.value.waitingForUser) {
545
+ session.waitingForUser = true;
546
+ }
547
+ }
548
+ }
549
+
550
+ for (const session of enrichedSessions) {
551
+ if (session.children.length > 0) {
552
+ sortChildEntries(session.children);
553
+ }
554
+ }
555
+
556
+ const sessionsForInteractionChecks = enrichedSessions.filter(
557
+ (session) =>
558
+ session.realTimeStatus === 'busy' ||
559
+ !!session.time?.archived ||
560
+ session.children.some((child) => child.realTimeStatus === 'busy' || child.realTimeStatus === 'retry')
561
+ );
562
+ if (sessionsForInteractionChecks.length > 0) {
563
+ const pendingChecks = await Promise.allSettled(
564
+ sessionsForInteractionChecks.map(async (session) => {
565
+ const port = sessionPortMap[session.id];
566
+ const client = port ? clientByPort[port] : undefined;
567
+ if (!client) {
568
+ return {
569
+ sessionId: session.id,
570
+ parentWaiting: false,
571
+ waiting: false,
572
+ running: false,
573
+ waitingChildIds: new Set<string>(),
574
+ };
575
+ }
576
+
577
+ try {
578
+ const partStatuses = await fetchPartStatuses(client, session.id, sessionMessagesTimeoutMs);
579
+ const hasRunning = partStatuses.some((status) => status === 'running');
580
+ const hasInteractionWait = !hasRunning && partStatuses.some(isWaitingPartStatus);
581
+
582
+ const childStateChecks = await Promise.allSettled(
583
+ session.children
584
+ .filter((child) => child.realTimeStatus === 'busy' || child.realTimeStatus === 'retry')
585
+ .map(async (child) => {
586
+ const childPort = sessionPortMap[child.id] ?? sessionPortMap[session.id];
587
+ const childClient = childPort ? clientByPort[childPort] : undefined;
588
+ if (!childClient) {
589
+ return { childId: child.id, waiting: false };
590
+ }
591
+ try {
592
+ const childStatuses = await fetchPartStatuses(childClient, child.id, sessionMessagesTimeoutMs);
593
+ const childHasRunning = childStatuses.some((status) => status === 'running');
594
+ return {
595
+ childId: child.id,
596
+ waiting: !childHasRunning && childStatuses.some(isWaitingPartStatus),
597
+ };
598
+ } catch {
599
+ return { childId: child.id, waiting: false };
600
+ }
601
+ })
602
+ );
603
+
604
+ const waitingChildIds = new Set(
605
+ childStateChecks
606
+ .filter((result): result is PromiseFulfilledResult<{ childId: string; waiting: boolean }> => result.status === 'fulfilled')
607
+ .filter((result) => result.value.waiting)
608
+ .map((result) => result.value.childId)
609
+ );
610
+
611
+ const hasWaitingChildren =
612
+ waitingChildIds.size > 0 ||
613
+ session.children.some((child) => child.waitingForUser || child.realTimeStatus === 'retry');
614
+
615
+ return {
616
+ sessionId: session.id,
617
+ parentWaiting: hasInteractionWait,
618
+ waiting: hasInteractionWait || hasWaitingChildren,
619
+ running: hasRunning,
620
+ waitingChildIds,
621
+ };
622
+ } catch {
623
+ return {
624
+ sessionId: session.id,
625
+ parentWaiting: false,
626
+ waiting: false,
627
+ running: false,
628
+ waitingChildIds: new Set<string>(),
629
+ };
630
+ }
631
+ })
632
+ );
633
+
634
+ for (const result of pendingChecks) {
635
+ if (result.status === 'fulfilled') {
636
+ const session = enrichedSessions.find((candidate) => candidate.id === result.value.sessionId);
637
+ if (!session) continue;
638
+ for (const child of session.children) {
639
+ if (result.value.waitingChildIds.has(child.id)) {
640
+ child.waitingForUser = true;
641
+ }
642
+ }
643
+ if (result.value.running) {
644
+ session.realTimeStatus = 'busy';
645
+ }
646
+ if (result.value.parentWaiting) {
647
+ session.waitingForUser = true;
648
+ }
649
+ }
650
+ }
651
+ }
652
+
653
+ const stickyNow = Date.now();
654
+ const activeStickyIds = new Set<string>();
655
+
656
+ for (const session of enrichedSessions) {
657
+ activeStickyIds.add(session.id);
658
+ for (const child of session.children) {
659
+ activeStickyIds.add(`child:${child.id}`);
660
+ }
661
+ }
662
+
663
+ for (const session of enrichedSessions) {
664
+ if (shouldSkipSessionStatusStabilization(session, stickyNow)) {
665
+ continue;
666
+ }
667
+
668
+ applyStickyStatusStabilization(session, stickyNow, stickyBusyDelayMs);
669
+ }
670
+ pruneStickyState(stickyNow, activeStickyIds);
671
+
672
+ const knownDirectories = new Set<string>();
673
+ for (const session of sessions) {
674
+ if (session.directory) {
675
+ knownDirectories.add(session.directory);
676
+ }
677
+ }
678
+
679
+ const processHints = Array.from(processHintsByDirectory.values()).filter(
680
+ (hint) => !knownDirectories.has(hint.directory)
681
+ );
682
+
683
+ const payload = {
684
+ sessions: enrichedSessions,
685
+ processHints,
686
+ } as NonNullable<SessionsRouteResult['payload']>;
687
+
688
+ if (failedPorts.length > 0) {
689
+ payload.failedPorts = failedPorts;
690
+ payload.degraded = true;
691
+ }
692
+
693
+ return {
694
+ payload,
695
+ sourceMeta: {
696
+ online: true,
697
+ ...(failedPorts.length > 0 ? { degraded: true } : {}),
698
+ },
699
+ };
700
+ } catch (error) {
701
+ console.error('Error fetching sessions:', error);
702
+ return {
703
+ payload: {
704
+ error: 'Failed to fetch sessions',
705
+ details: error instanceof Error ? error.message : String(error),
706
+ hint: 'Make sure OpenCode is running with an exposed API port. Example: opencode --port <PORT> (VibePulse auto-detects active ports).',
707
+ },
708
+ status: 500,
709
+ sourceMeta: {
710
+ online: false,
711
+ degraded: true,
712
+ reason: 'Failed to fetch sessions',
713
+ },
714
+ };
715
+ }
716
+ },
717
+ };
718
+
719
+ export function createOpencodeLocalSessionProvider(): LocalSessionProvider {
720
+ return opencodeLocalSessionProvider;
721
+ }