@leanspec/ui 0.2.5-dev.20251120070726 → 0.2.5-dev.20251120093243

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 (361) hide show
  1. package/.next/standalone/packages/ui/.next/BUILD_ID +1 -1
  2. package/.next/standalone/packages/ui/.next/app-path-routes-manifest.json +12 -0
  3. package/.next/standalone/packages/ui/.next/build-manifest.json +7 -6
  4. package/.next/standalone/packages/ui/.next/prerender-manifest.json +28 -3
  5. package/.next/standalone/packages/ui/.next/routes-manifest.json +91 -0
  6. package/.next/standalone/packages/ui/.next/server/app/_global-error/page/build-manifest.json +5 -4
  7. package/.next/standalone/packages/ui/.next/server/app/_global-error/page.js +1 -1
  8. package/.next/standalone/packages/ui/.next/server/app/_global-error/page.js.nft.json +1 -1
  9. package/.next/standalone/packages/ui/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/packages/ui/.next/server/app/_global-error.html +2 -2
  11. package/.next/standalone/packages/ui/.next/server/app/_global-error.rsc +1 -1
  12. package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  13. package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  14. package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/standalone/packages/ui/.next/server/app/_not-found/page/build-manifest.json +5 -4
  17. package/.next/standalone/packages/ui/.next/server/app/_not-found/page.js +2 -2
  18. package/.next/standalone/packages/ui/.next/server/app/_not-found/page.js.nft.json +1 -1
  19. package/.next/standalone/packages/ui/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/packages/ui/.next/server/app/_not-found.html +2 -2
  21. package/.next/standalone/packages/ui/.next/server/app/_not-found.rsc +20 -19
  22. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_full.segment.rsc +20 -19
  23. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_index.segment.rsc +26 -25
  24. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +3 -3
  25. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  26. package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_tree.segment.rsc +5 -5
  27. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/[id]/route/app-paths-manifest.json +3 -0
  28. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/[id]/route/build-manifest.json +11 -0
  29. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/[id]/route/server-reference-manifest.json +4 -0
  30. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/[id]/route.js +6 -0
  31. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/[id]/route.js.map +5 -0
  32. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/[id]/route.js.nft.json +1 -0
  33. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/[id]/route_client-reference-manifest.js +2 -0
  34. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/discover/route/app-paths-manifest.json +3 -0
  35. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/discover/route/build-manifest.json +11 -0
  36. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/discover/route/server-reference-manifest.json +4 -0
  37. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/discover/route.js +6 -0
  38. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/discover/route.js.map +5 -0
  39. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/discover/route.js.nft.json +1 -0
  40. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/discover/route_client-reference-manifest.js +2 -0
  41. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/list-directory/route/app-paths-manifest.json +3 -0
  42. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/list-directory/route/build-manifest.json +11 -0
  43. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/list-directory/route/server-reference-manifest.json +4 -0
  44. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/list-directory/route.js +6 -0
  45. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/list-directory/route.js.map +5 -0
  46. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/list-directory/route.js.nft.json +1 -0
  47. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/list-directory/route_client-reference-manifest.js +2 -0
  48. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/route/app-paths-manifest.json +3 -0
  49. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/route/build-manifest.json +11 -0
  50. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/route/server-reference-manifest.json +4 -0
  51. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/route.js +6 -0
  52. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/route.js.map +5 -0
  53. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/route.js.nft.json +1 -0
  54. package/.next/standalone/packages/ui/.next/server/app/api/local-projects/route_client-reference-manifest.js +2 -0
  55. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/route/app-paths-manifest.json +3 -0
  56. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/route/build-manifest.json +11 -0
  57. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/route/server-reference-manifest.json +4 -0
  58. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/route.js +8 -0
  59. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/route.js.map +5 -0
  60. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/route.js.nft.json +1 -0
  61. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/route_client-reference-manifest.js +2 -0
  62. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/route/app-paths-manifest.json +3 -0
  63. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/route/build-manifest.json +11 -0
  64. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/route/server-reference-manifest.json +4 -0
  65. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/route.js +9 -0
  66. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/route.js.map +5 -0
  67. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/route.js.nft.json +1 -0
  68. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/route_client-reference-manifest.js +2 -0
  69. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/status/route/app-paths-manifest.json +3 -0
  70. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/status/route/build-manifest.json +11 -0
  71. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/status/route/server-reference-manifest.json +4 -0
  72. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/status/route.js +8 -0
  73. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/status/route.js.map +5 -0
  74. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/status/route.js.nft.json +1 -0
  75. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/status/route_client-reference-manifest.js +2 -0
  76. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/route.js +4 -2
  77. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/route.js.nft.json +1 -1
  78. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/stats/route/app-paths-manifest.json +3 -0
  79. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/stats/route/build-manifest.json +11 -0
  80. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/stats/route/server-reference-manifest.json +4 -0
  81. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/stats/route.js +8 -0
  82. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/stats/route.js.map +5 -0
  83. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/stats/route.js.nft.json +1 -0
  84. package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/stats/route_client-reference-manifest.js +2 -0
  85. package/.next/standalone/packages/ui/.next/server/app/api/projects/route.js +3 -2
  86. package/.next/standalone/packages/ui/.next/server/app/api/projects/route.js.nft.json +1 -1
  87. package/.next/standalone/packages/ui/.next/server/app/api/revalidate/route.js +4 -2
  88. package/.next/standalone/packages/ui/.next/server/app/api/revalidate/route.js.nft.json +1 -1
  89. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/dependency-graph/route.js +4 -2
  90. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/dependency-graph/route.js.nft.json +1 -1
  91. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/route.js +4 -2
  92. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/route.js.nft.json +1 -1
  93. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/status/route.js +4 -3
  94. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/status/route.js.nft.json +1 -1
  95. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/subspecs/[file]/route.js +4 -2
  96. package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/subspecs/[file]/route.js.nft.json +1 -1
  97. package/.next/standalone/packages/ui/.next/server/app/api/stats/route.js +4 -2
  98. package/.next/standalone/packages/ui/.next/server/app/api/stats/route.js.nft.json +1 -1
  99. package/.next/standalone/packages/ui/.next/server/app/page/build-manifest.json +5 -4
  100. package/.next/standalone/packages/ui/.next/server/app/page.js +2 -2
  101. package/.next/standalone/packages/ui/.next/server/app/page.js.nft.json +1 -1
  102. package/.next/standalone/packages/ui/.next/server/app/page_client-reference-manifest.js +1 -1
  103. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page/app-paths-manifest.json +3 -0
  104. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page/build-manifest.json +18 -0
  105. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page/next-font-manifest.json +6 -0
  106. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page/react-loadable-manifest.json +1 -0
  107. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page/server-reference-manifest.json +4 -0
  108. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page.js +21 -0
  109. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page.js.map +5 -0
  110. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page.js.nft.json +1 -0
  111. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page_client-reference-manifest.js +2 -0
  112. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page/app-paths-manifest.json +3 -0
  113. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page/build-manifest.json +18 -0
  114. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page/next-font-manifest.json +6 -0
  115. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page/react-loadable-manifest.json +1 -0
  116. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page/server-reference-manifest.json +4 -0
  117. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page.js +21 -0
  118. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page.js.map +5 -0
  119. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page.js.nft.json +1 -0
  120. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page_client-reference-manifest.js +2 -0
  121. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page/app-paths-manifest.json +3 -0
  122. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page/build-manifest.json +18 -0
  123. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page/next-font-manifest.json +6 -0
  124. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page/react-loadable-manifest.json +1 -0
  125. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page/server-reference-manifest.json +4 -0
  126. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page.js +20 -0
  127. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page.js.map +5 -0
  128. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page.js.nft.json +1 -0
  129. package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page_client-reference-manifest.js +2 -0
  130. package/.next/standalone/packages/ui/.next/server/app/projects/page/app-paths-manifest.json +3 -0
  131. package/.next/standalone/packages/ui/.next/server/app/projects/page/build-manifest.json +18 -0
  132. package/.next/standalone/packages/ui/.next/server/app/projects/page/next-font-manifest.json +6 -0
  133. package/.next/standalone/packages/ui/.next/server/app/projects/page/react-loadable-manifest.json +1 -0
  134. package/.next/standalone/packages/ui/.next/server/app/projects/page/server-reference-manifest.json +4 -0
  135. package/.next/standalone/packages/ui/.next/server/app/projects/page.js +19 -0
  136. package/.next/standalone/packages/ui/.next/server/app/projects/page.js.map +5 -0
  137. package/.next/standalone/packages/ui/.next/server/app/projects/page.js.nft.json +1 -0
  138. package/.next/standalone/packages/ui/.next/server/app/projects/page_client-reference-manifest.js +2 -0
  139. package/.next/standalone/packages/ui/.next/server/app/projects.html +2 -0
  140. package/.next/standalone/packages/ui/.next/server/app/projects.meta +14 -0
  141. package/.next/standalone/packages/ui/.next/server/app/projects.rsc +34 -0
  142. package/.next/standalone/packages/ui/.next/server/app/projects.segments/_full.segment.rsc +34 -0
  143. package/.next/standalone/packages/ui/.next/server/app/projects.segments/_index.segment.rsc +27 -0
  144. package/.next/standalone/packages/ui/.next/server/app/projects.segments/_tree.segment.rsc +9 -0
  145. package/.next/standalone/packages/ui/.next/server/app/projects.segments/projects/__PAGE__.segment.rsc +9 -0
  146. package/.next/standalone/packages/ui/.next/server/app/projects.segments/projects.segment.rsc +4 -0
  147. package/.next/standalone/packages/ui/.next/server/app/specs/[id]/page/build-manifest.json +5 -4
  148. package/.next/standalone/packages/ui/.next/server/app/specs/[id]/page.js +4 -4
  149. package/.next/standalone/packages/ui/.next/server/app/specs/[id]/page.js.nft.json +1 -1
  150. package/.next/standalone/packages/ui/.next/server/app/specs/[id]/page_client-reference-manifest.js +1 -1
  151. package/.next/standalone/packages/ui/.next/server/app/specs/page/build-manifest.json +5 -4
  152. package/.next/standalone/packages/ui/.next/server/app/specs/page.js +2 -2
  153. package/.next/standalone/packages/ui/.next/server/app/specs/page.js.nft.json +1 -1
  154. package/.next/standalone/packages/ui/.next/server/app/specs/page_client-reference-manifest.js +1 -1
  155. package/.next/standalone/packages/ui/.next/server/app/stats/page/build-manifest.json +5 -4
  156. package/.next/standalone/packages/ui/.next/server/app/stats/page.js +2 -2
  157. package/.next/standalone/packages/ui/.next/server/app/stats/page.js.nft.json +1 -1
  158. package/.next/standalone/packages/ui/.next/server/app/stats/page_client-reference-manifest.js +1 -1
  159. package/.next/standalone/packages/ui/.next/server/app-paths-manifest.json +12 -0
  160. package/.next/standalone/packages/ui/.next/server/chunks/6681a__next-internal_server_app_api_projects_[id]_specs_[spec]_route_actions_d018d9e0.js +3 -0
  161. package/.next/standalone/packages/ui/.next/server/chunks/730ea_ui__next-internal_server_app_api_local-projects_[id]_route_actions_664abe9c.js +3 -0
  162. package/.next/standalone/packages/ui/.next/server/chunks/730ea_ui__next-internal_server_app_api_local-projects_discover_route_actions_e6ec3fa7.js +3 -0
  163. package/.next/standalone/packages/ui/.next/server/chunks/730ea_ui__next-internal_server_app_api_projects_[id]_stats_route_actions_a0bb04a8.js +3 -0
  164. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__0fbfea15._.js +3 -0
  165. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__126dea7b._.js +3 -0
  166. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__1f037512._.js +3 -0
  167. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__3559376c._.js +21 -0
  168. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__548e27d4._.js +3 -0
  169. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__65667b70._.js +3 -0
  170. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__675a763e._.js +3 -0
  171. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__803d07f0._.js +3 -0
  172. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__8075fe29._.js +3 -0
  173. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__8233e09b._.js +3 -0
  174. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__84cdc14a._.js +3 -0
  175. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__9ce722b4._.js +3 -0
  176. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__a2d7cbed._.js +3 -0
  177. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__aa677b0d._.js +3 -0
  178. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__ac744182._.js +3 -0
  179. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__bb9fca84._.js +4 -0
  180. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__bdc3963a._.js +3 -0
  181. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__f5c6d6b8._.js +3 -0
  182. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__fb91986f._.js +3 -0
  183. package/.next/standalone/packages/ui/.next/server/chunks/f825c_server_app_api_local-projects_list-directory_route_actions_d620ec1a.js +3 -0
  184. package/.next/standalone/packages/ui/.next/server/chunks/f825c_server_app_api_projects_[id]_specs_[spec]_status_route_actions_e9f1bdc5.js +3 -0
  185. package/.next/standalone/packages/ui/.next/server/chunks/node_modules__pnpm_731b55aa._.js +3 -0
  186. package/.next/standalone/packages/ui/.next/server/chunks/packages_ui__next-internal_server_app_api_local-projects_route_actions_9142d5ad.js +3 -0
  187. package/.next/standalone/packages/ui/.next/server/chunks/packages_ui__next-internal_server_app_api_projects_[id]_route_actions_bff49675.js +3 -0
  188. package/.next/standalone/packages/ui/.next/server/chunks/packages_ui_src_lib_db_index_ts_556307fa._.js +64 -5
  189. package/.next/standalone/packages/ui/.next/server/chunks/packages_ui_src_lib_specs_sources_database-source_ts_0bd881ee._.js +3 -0
  190. package/.next/standalone/packages/ui/.next/server/chunks/packages_ui_src_lib_specs_sources_database-source_ts_baa0160d._.js +3 -0
  191. package/.next/standalone/packages/ui/.next/server/chunks/ssr/38a22_sonner_dist_index_mjs_207730fe._.js +3 -0
  192. package/.next/standalone/packages/ui/.next/server/chunks/ssr/6e9bd_next_dist_7af75658._.js +3 -0
  193. package/.next/standalone/packages/ui/.next/server/chunks/ssr/{_a5b58449._.js → 6e9bd_next_dist_df5dcbe9._.js} +2 -2
  194. package/.next/standalone/packages/ui/.next/server/chunks/ssr/730ea_ui__next-internal_server_app_projects_[projectId]_specs_page_actions_82e32fe4.js +3 -0
  195. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__01bfc8ff._.js +3 -0
  196. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__1d0c2012._.js +1 -1
  197. package/.next/standalone/packages/ui/.next/server/chunks/ssr/{[root-of-the-server]__41f5b5c0._.js → [root-of-the-server]__4ec37765._.js} +2 -2
  198. package/.next/standalone/packages/ui/.next/server/chunks/ssr/{[root-of-the-server]__1af33d49._.js → [root-of-the-server]__50122e7e._.js} +2 -2
  199. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__5382b397._.js +3 -0
  200. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__73f60f12._.js +7 -0
  201. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__88a691ee._.js +3 -0
  202. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__a7ae8552._.js +7 -0
  203. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__bdbbba01._.js +3 -0
  204. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__c592f5d1._.js +3 -0
  205. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__cc589a54._.js +3 -0
  206. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__ec5b96a5._.js +3 -0
  207. package/.next/standalone/packages/ui/.next/server/chunks/ssr/{[root-of-the-server]__cbbbfb5d._.js → [root-of-the-server]__fd80e4dd._.js} +2 -2
  208. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_000dd317._.js +1 -1
  209. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_196b5a83._.js +3 -0
  210. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_39562b2a._.js +4 -0
  211. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_3b617676._.js +1 -1
  212. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_4129cc0f._.js +3 -0
  213. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_6174313a._.js +3 -0
  214. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_6e4dd8b6._.js +3 -0
  215. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_85effc18._.js +4 -0
  216. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_ad8c1e99._.js +1 -1
  217. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_bae6d2b8._.js +4 -0
  218. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_c2f54661._.js +5 -0
  219. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_fdd7780b._.js +4 -0
  220. package/.next/standalone/packages/ui/.next/server/chunks/ssr/f825c_server_app_projects_[projectId]_specs_[specId]_page_actions_22d9c35e.js +3 -0
  221. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_af9d3830._.js +3 -0
  222. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui__next-internal_server_app_projects_[projectId]_page_actions_f2986585.js +3 -0
  223. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui__next-internal_server_app_projects_page_actions_715940ea.js +3 -0
  224. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_app_projects_[projectId]_be242d6c._.js +3 -0
  225. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_app_projects_[projectId]_project-context-syncer_tsx_7954ea3b._.js +3 -0
  226. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_app_projects_page_tsx_6e166c8e._.js +3 -0
  227. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_app_specs_specs-client_tsx_0bb8f8f8._.js +1 -1
  228. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_components_ui_select_tsx_7e21d40f._.js +3 -0
  229. package/.next/standalone/packages/ui/.next/server/chunks/ssr/packages_ui_src_lib_specs_sources_database-source_ts_f7186c2a._.js +60 -1
  230. package/.next/standalone/packages/ui/.next/server/middleware-build-manifest.js +5 -4
  231. package/.next/standalone/packages/ui/.next/server/pages/404.html +2 -2
  232. package/.next/standalone/packages/ui/.next/server/pages/500.html +2 -2
  233. package/.next/standalone/packages/ui/.next/server/server-reference-manifest.js +1 -1
  234. package/.next/standalone/packages/ui/.next/server/server-reference-manifest.json +1 -1
  235. package/.next/standalone/packages/ui/.next/static/chunks/07f48b316e895080.js +1 -0
  236. package/.next/standalone/packages/ui/.next/static/chunks/0a7be410b438418a.js +1 -0
  237. package/.next/standalone/packages/ui/.next/static/chunks/1089ca88f6bef846.js +1 -0
  238. package/.next/standalone/packages/ui/.next/static/chunks/17471c87082c392c.js +5 -0
  239. package/.next/standalone/packages/ui/.next/static/chunks/220ba5cb8fe4dd69.js +1 -0
  240. package/.next/standalone/packages/ui/.next/static/chunks/35ccd3286e538bd2.js +1 -0
  241. package/.next/standalone/packages/ui/.next/static/chunks/571033caca823138.js +1 -0
  242. package/.next/standalone/packages/ui/.next/static/chunks/5a6fc30cd64085b4.css +1 -0
  243. package/.next/standalone/packages/ui/.next/static/chunks/5c2072ad938de8ed.js +1 -0
  244. package/.next/standalone/packages/ui/.next/static/chunks/843e1dfdc28e1385.js +1 -0
  245. package/.next/standalone/packages/ui/.next/static/chunks/9dad7fd31627df80.js +1 -0
  246. package/.next/standalone/packages/ui/.next/static/chunks/{c3d4d07de959ecf1.js → a055d4b2866ff8d4.js} +1 -1
  247. package/.next/standalone/packages/ui/.next/static/chunks/afb7c5a4255f4081.js +3 -0
  248. package/.next/{static/chunks/c557ac675be79771.js → standalone/packages/ui/.next/static/chunks/b760a3a9c2c8be28.js} +1 -1
  249. package/.next/standalone/packages/ui/.next/static/chunks/dcdd95180149fa10.js +1 -0
  250. package/.next/standalone/packages/ui/.next/static/chunks/ebd89051637b9a47.js +4 -0
  251. package/.next/standalone/packages/ui/.next/static/chunks/f9db24028d8c058e.js +1 -0
  252. package/.next/standalone/packages/ui/.next/static/chunks/fb640f50455ba34f.js +1 -0
  253. package/.next/standalone/packages/ui/.next/static/chunks/turbopack-b9690cacbf9fe48c.js +3 -0
  254. package/.next/standalone/packages/ui/bin/ui.js +17 -7
  255. package/.next/standalone/packages/ui/package.json +3 -1
  256. package/.next/standalone/packages/ui/src/app/api/local-projects/[id]/route.ts +117 -0
  257. package/.next/standalone/packages/ui/src/app/api/local-projects/discover/route.ts +41 -0
  258. package/.next/standalone/packages/ui/src/app/api/local-projects/list-directory/route.ts +38 -0
  259. package/.next/standalone/packages/ui/src/app/api/local-projects/route.ts +63 -0
  260. package/.next/standalone/packages/ui/src/app/api/projects/[id]/route.ts +97 -0
  261. package/.next/standalone/packages/ui/src/app/api/projects/[id]/specs/[spec]/route.ts +38 -0
  262. package/.next/standalone/packages/ui/src/app/api/projects/[id]/specs/[spec]/status/route.ts +97 -0
  263. package/.next/standalone/packages/ui/src/app/api/projects/[id]/specs/route.ts +7 -0
  264. package/.next/standalone/packages/ui/src/app/api/projects/[id]/stats/route.ts +19 -0
  265. package/.next/standalone/packages/ui/src/app/api/projects/route.ts +48 -1
  266. package/.next/standalone/packages/ui/src/app/dashboard-client.tsx +67 -6
  267. package/.next/standalone/packages/ui/src/app/layout.tsx +11 -8
  268. package/.next/standalone/packages/ui/src/app/not-found.tsx +1 -1
  269. package/.next/standalone/packages/ui/src/app/projects/[projectId]/layout.tsx +18 -0
  270. package/.next/standalone/packages/ui/src/app/projects/[projectId]/page.tsx +10 -0
  271. package/.next/standalone/packages/ui/src/app/projects/[projectId]/project-context-syncer.tsx +16 -0
  272. package/.next/standalone/packages/ui/src/app/projects/[projectId]/specs/[specId]/page.tsx +34 -0
  273. package/.next/standalone/packages/ui/src/app/projects/[projectId]/specs/page.tsx +20 -0
  274. package/.next/standalone/packages/ui/src/app/projects/page.tsx +156 -0
  275. package/.next/standalone/packages/ui/src/app/specs/specs-client.tsx +7 -2
  276. package/.next/standalone/packages/ui/src/components/create-project-dialog.tsx +139 -0
  277. package/.next/standalone/packages/ui/src/components/directory-picker.tsx +191 -0
  278. package/.next/standalone/packages/ui/src/components/main-sidebar.tsx +4 -0
  279. package/.next/standalone/packages/ui/src/components/project-switcher.tsx +139 -0
  280. package/.next/standalone/packages/ui/src/components/ui/dropdown-menu.tsx +200 -0
  281. package/.next/standalone/packages/ui/src/components/ui/popover.tsx +31 -0
  282. package/.next/standalone/packages/ui/src/contexts/project-context.tsx +229 -0
  283. package/.next/standalone/packages/ui/src/lib/db/index.ts +100 -0
  284. package/.next/standalone/packages/ui/src/lib/projects/index.ts +7 -0
  285. package/.next/standalone/packages/ui/src/lib/projects/registry.ts +467 -0
  286. package/.next/standalone/packages/ui/src/lib/projects/types.ts +37 -0
  287. package/.next/standalone/packages/ui/src/lib/specs/service.ts +13 -1
  288. package/.next/standalone/packages/ui/src/lib/specs/sources/multi-project-source.ts +258 -0
  289. package/.next/standalone/packages/ui/tsconfig.tsbuildinfo +1 -1
  290. package/.next/static/chunks/07f48b316e895080.js +1 -0
  291. package/.next/static/chunks/0a7be410b438418a.js +1 -0
  292. package/.next/static/chunks/1089ca88f6bef846.js +1 -0
  293. package/.next/static/chunks/17471c87082c392c.js +5 -0
  294. package/.next/static/chunks/220ba5cb8fe4dd69.js +1 -0
  295. package/.next/static/chunks/35ccd3286e538bd2.js +1 -0
  296. package/.next/static/chunks/571033caca823138.js +1 -0
  297. package/.next/static/chunks/5a6fc30cd64085b4.css +1 -0
  298. package/.next/static/chunks/5c2072ad938de8ed.js +1 -0
  299. package/.next/static/chunks/843e1dfdc28e1385.js +1 -0
  300. package/.next/static/chunks/9dad7fd31627df80.js +1 -0
  301. package/.next/static/chunks/{c3d4d07de959ecf1.js → a055d4b2866ff8d4.js} +1 -1
  302. package/.next/static/chunks/afb7c5a4255f4081.js +3 -0
  303. package/.next/{standalone/packages/ui/.next/static/chunks/c557ac675be79771.js → static/chunks/b760a3a9c2c8be28.js} +1 -1
  304. package/.next/static/chunks/dcdd95180149fa10.js +1 -0
  305. package/.next/static/chunks/ebd89051637b9a47.js +4 -0
  306. package/.next/static/chunks/f9db24028d8c058e.js +1 -0
  307. package/.next/static/chunks/fb640f50455ba34f.js +1 -0
  308. package/.next/static/chunks/turbopack-b9690cacbf9fe48c.js +3 -0
  309. package/bin/ui.js +17 -7
  310. package/package.json +3 -1
  311. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__175bef84._.js +0 -3
  312. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__3971eae5._.js +0 -3
  313. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__482b093a._.js +0 -21
  314. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__6bca1621._.js +0 -3
  315. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__87a3475a._.js +0 -3
  316. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__9f0f4c0b._.js +0 -3
  317. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__c1c9f5f5._.js +0 -3
  318. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__c6689757._.js +0 -3
  319. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__cd1fb0a2._.js +0 -4
  320. package/.next/standalone/packages/ui/.next/server/chunks/[root-of-the-server]__e2071b2e._.js +0 -3
  321. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__299c81cc._.js +0 -3
  322. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__5ca2e973._.js +0 -3
  323. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__b2fe773d._.js +0 -3
  324. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__e79a982a._.js +0 -7
  325. package/.next/standalone/packages/ui/.next/server/chunks/ssr/[root-of-the-server]__ff03fc1e._.js +0 -7
  326. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_66209e84._.js +0 -3
  327. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_6cd9a5e0._.js +0 -3
  328. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_b483c9fe._.js +0 -3
  329. package/.next/standalone/packages/ui/.next/server/chunks/ssr/_b5040d31._.js +0 -5
  330. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_9710705b._.js +0 -3
  331. package/.next/standalone/packages/ui/.next/server/chunks/ssr/node_modules__pnpm_b8ff10b9._.js +0 -3
  332. package/.next/standalone/packages/ui/.next/static/chunks/093ea4b175adb770.js +0 -1
  333. package/.next/standalone/packages/ui/.next/static/chunks/5f97d665a4d9dc62.js +0 -3
  334. package/.next/standalone/packages/ui/.next/static/chunks/9a80c22382ddcfaf.css +0 -1
  335. package/.next/standalone/packages/ui/.next/static/chunks/9b7b7024c39c5f99.js +0 -1
  336. package/.next/standalone/packages/ui/.next/static/chunks/aa47b212786d8695.js +0 -1
  337. package/.next/standalone/packages/ui/.next/static/chunks/ae04dcd433be6dab.js +0 -1
  338. package/.next/standalone/packages/ui/.next/static/chunks/c0fe4c94c7282ac0.js +0 -4
  339. package/.next/standalone/packages/ui/.next/static/chunks/c61cbb6a0ba3b6ab.js +0 -1
  340. package/.next/standalone/packages/ui/.next/static/chunks/d79bf953f0dfb650.js +0 -1
  341. package/.next/standalone/packages/ui/.next/static/chunks/e50fb8d0b728cd35.js +0 -5
  342. package/.next/standalone/packages/ui/.next/static/chunks/e6e238dbf1d3e740.js +0 -1
  343. package/.next/standalone/packages/ui/.next/static/chunks/turbopack-9cc79aa1b34ffcbe.js +0 -3
  344. package/.next/static/chunks/093ea4b175adb770.js +0 -1
  345. package/.next/static/chunks/5f97d665a4d9dc62.js +0 -3
  346. package/.next/static/chunks/9a80c22382ddcfaf.css +0 -1
  347. package/.next/static/chunks/9b7b7024c39c5f99.js +0 -1
  348. package/.next/static/chunks/aa47b212786d8695.js +0 -1
  349. package/.next/static/chunks/ae04dcd433be6dab.js +0 -1
  350. package/.next/static/chunks/c0fe4c94c7282ac0.js +0 -4
  351. package/.next/static/chunks/c61cbb6a0ba3b6ab.js +0 -1
  352. package/.next/static/chunks/d79bf953f0dfb650.js +0 -1
  353. package/.next/static/chunks/e50fb8d0b728cd35.js +0 -5
  354. package/.next/static/chunks/e6e238dbf1d3e740.js +0 -1
  355. package/.next/static/chunks/turbopack-9cc79aa1b34ffcbe.js +0 -3
  356. /package/.next/standalone/packages/ui/.next/static/{C8sZuJV5DQETshOIgjsmH → T1wNN9JmkdwBabQsqL-tC}/_buildManifest.js +0 -0
  357. /package/.next/standalone/packages/ui/.next/static/{C8sZuJV5DQETshOIgjsmH → T1wNN9JmkdwBabQsqL-tC}/_clientMiddlewareManifest.json +0 -0
  358. /package/.next/standalone/packages/ui/.next/static/{C8sZuJV5DQETshOIgjsmH → T1wNN9JmkdwBabQsqL-tC}/_ssgManifest.js +0 -0
  359. /package/.next/static/{C8sZuJV5DQETshOIgjsmH → T1wNN9JmkdwBabQsqL-tC}/_buildManifest.js +0 -0
  360. /package/.next/static/{C8sZuJV5DQETshOIgjsmH → T1wNN9JmkdwBabQsqL-tC}/_clientMiddlewareManifest.json +0 -0
  361. /package/.next/static/{C8sZuJV5DQETshOIgjsmH → T1wNN9JmkdwBabQsqL-tC}/_ssgManifest.js +0 -0
@@ -0,0 +1,139 @@
1
+ 'use client';
2
+
3
+ import { useState, useEffect } from 'react';
4
+ import { useRouter } from 'next/navigation';
5
+ import { useProject } from '@/contexts/project-context';
6
+ import { Button } from '@/components/ui/button';
7
+ import { Input } from '@/components/ui/input';
8
+ import { DirectoryPicker } from './directory-picker';
9
+ import { FolderOpen } from 'lucide-react';
10
+ import {
11
+ Dialog,
12
+ DialogContent,
13
+ DialogDescription,
14
+ DialogFooter,
15
+ DialogHeader,
16
+ DialogTitle,
17
+ } from '@/components/ui/dialog';
18
+ import { toast } from 'sonner';
19
+
20
+ interface CreateProjectDialogProps {
21
+ open: boolean;
22
+ onOpenChange: (open: boolean) => void;
23
+ }
24
+
25
+ export function CreateProjectDialog({ open, onOpenChange }: CreateProjectDialogProps) {
26
+ const { addProject, switchProject } = useProject();
27
+ const [path, setPath] = useState('');
28
+ const [isLoading, setIsLoading] = useState(false);
29
+ const [mode, setMode] = useState<'picker' | 'manual'>('picker');
30
+ const router = useRouter();
31
+
32
+ useEffect(() => {
33
+ if (open) {
34
+ setMode('picker');
35
+ setPath('');
36
+ }
37
+ }, [open]);
38
+
39
+ const handleAddProject = async (projectPath: string) => {
40
+ try {
41
+ setIsLoading(true);
42
+ const project = await addProject(projectPath);
43
+ await switchProject(project.id);
44
+ toast.success('Project added successfully');
45
+ onOpenChange(false);
46
+ router.push('/'); // Navigate to dashboard
47
+ } catch (error) {
48
+ const message = error instanceof Error ? error.message : 'Failed to add project';
49
+ toast.error(message);
50
+ } finally {
51
+ setIsLoading(false);
52
+ }
53
+ };
54
+
55
+ const handleSubmit = (e: React.FormEvent) => {
56
+ e.preventDefault();
57
+ if (!path) return;
58
+ handleAddProject(path);
59
+ };
60
+
61
+ return (
62
+ <Dialog open={open} onOpenChange={onOpenChange}>
63
+ <DialogContent className="sm:max-w-[600px]">
64
+ <DialogHeader>
65
+ <DialogTitle>Add Project</DialogTitle>
66
+ <DialogDescription>
67
+ {mode === 'picker'
68
+ ? 'Browse and select the project directory.'
69
+ : 'Enter the absolute path to your local project directory.'}
70
+ </DialogDescription>
71
+ </DialogHeader>
72
+
73
+ {mode === 'picker' ? (
74
+ <div className="space-y-2">
75
+ <DirectoryPicker
76
+ onSelect={handleAddProject}
77
+ onCancel={() => onOpenChange(false)}
78
+ initialPath={path}
79
+ actionLabel={isLoading ? "Adding..." : "Add Project"}
80
+ isLoading={isLoading}
81
+ />
82
+ <div className="flex justify-center">
83
+ <Button
84
+ variant="link"
85
+ size="sm"
86
+ onClick={() => setMode('manual')}
87
+ className="text-muted-foreground"
88
+ >
89
+ Enter path manually
90
+ </Button>
91
+ </div>
92
+ </div>
93
+ ) : (
94
+ <form onSubmit={handleSubmit}>
95
+ <div className="grid gap-4 py-4">
96
+ <div className="grid gap-2">
97
+ <label htmlFor="path" className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
98
+ Project Path
99
+ </label>
100
+ <div className="flex gap-2">
101
+ <Input
102
+ id="path"
103
+ value={path}
104
+ onChange={(e) => setPath(e.target.value)}
105
+ placeholder="/path/to/your/project"
106
+ className="flex-1"
107
+ disabled={isLoading}
108
+ />
109
+ </div>
110
+ <p className="text-xs text-muted-foreground">
111
+ Select the root directory of your project.
112
+ </p>
113
+ </div>
114
+ </div>
115
+ <DialogFooter className="flex-col sm:flex-row gap-2">
116
+ <div className="flex-1 flex justify-start">
117
+ <Button
118
+ type="button"
119
+ variant="ghost"
120
+ size="sm"
121
+ onClick={() => setMode('picker')}
122
+ >
123
+ <FolderOpen className="h-4 w-4 mr-2" />
124
+ Browse folders
125
+ </Button>
126
+ </div>
127
+ <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={isLoading}>
128
+ Cancel
129
+ </Button>
130
+ <Button type="submit" disabled={isLoading || !path}>
131
+ {isLoading ? 'Adding...' : 'Add Project'}
132
+ </Button>
133
+ </DialogFooter>
134
+ </form>
135
+ )}
136
+ </DialogContent>
137
+ </Dialog>
138
+ );
139
+ }
@@ -0,0 +1,191 @@
1
+ 'use client';
2
+
3
+ import { useState, useEffect, useRef } from 'react';
4
+ import { Button } from '@/components/ui/button';
5
+ import { Folder, ChevronUp, Loader2, ArrowLeft, Home, ChevronRight } from 'lucide-react';
6
+ import { cn } from '@/lib/utils';
7
+
8
+ interface DirectoryItem {
9
+ name: string;
10
+ path: string;
11
+ isDirectory: boolean;
12
+ }
13
+
14
+ interface DirectoryPickerProps {
15
+ onSelect: (path: string) => void;
16
+ onCancel: () => void;
17
+ initialPath?: string;
18
+ actionLabel?: string;
19
+ isLoading?: boolean;
20
+ }
21
+
22
+ export function DirectoryPicker({ onSelect, onCancel, initialPath, actionLabel = "Select This Folder", isLoading: externalLoading }: DirectoryPickerProps) {
23
+ const [currentPath, setCurrentPath] = useState(initialPath || '');
24
+ const [items, setItems] = useState<DirectoryItem[]>([]);
25
+ const [internalLoading, setInternalLoading] = useState(false);
26
+ const [error, setError] = useState<string | null>(null);
27
+ const scrollContainerRef = useRef<HTMLDivElement>(null);
28
+
29
+ const isLoading = externalLoading || internalLoading;
30
+
31
+ useEffect(() => {
32
+ fetchDirectory(currentPath);
33
+ }, [currentPath]);
34
+
35
+ // Auto-scroll breadcrumbs to end when path changes
36
+ useEffect(() => {
37
+ if (scrollContainerRef.current) {
38
+ scrollContainerRef.current.scrollLeft = scrollContainerRef.current.scrollWidth;
39
+ }
40
+ }, [currentPath]);
41
+
42
+ const fetchDirectory = async (path: string) => {
43
+ try {
44
+ setInternalLoading(true);
45
+ setError(null);
46
+ const response = await fetch('/api/local-projects/list-directory', {
47
+ method: 'POST',
48
+ headers: { 'Content-Type': 'application/json' },
49
+ body: JSON.stringify({ path }),
50
+ });
51
+
52
+ if (!response.ok) {
53
+ throw new Error('Failed to list directory');
54
+ }
55
+
56
+ const data = await response.json();
57
+ setItems(data.items);
58
+ // Update current path to the resolved path from server
59
+ if (!path) {
60
+ setCurrentPath(data.path);
61
+ }
62
+ } catch (err) {
63
+ setError(err instanceof Error ? err.message : String(err));
64
+ } finally {
65
+ setInternalLoading(false);
66
+ }
67
+ };
68
+
69
+ const handleNavigate = (path: string) => {
70
+ setCurrentPath(path);
71
+ };
72
+
73
+ const parentItem = items.find(item => item.name === '..');
74
+ const displayItems = items.filter(item => item.name !== '..');
75
+
76
+ // Parse path segments for breadcrumbs
77
+ const getPathSegments = (path: string) => {
78
+ if (!path) return [];
79
+ // Handle both Unix and Windows separators
80
+ const separator = path.includes('\\') ? '\\' : '/';
81
+ const parts = path.split(separator).filter(Boolean);
82
+
83
+ // If path starts with separator (Unix root), add it back
84
+ const isUnixRoot = path.startsWith('/');
85
+
86
+ return parts.map((part, index) => {
87
+ let segmentPath = parts.slice(0, index + 1).join(separator);
88
+ if (isUnixRoot) segmentPath = '/' + segmentPath;
89
+ // On Windows, the first part (C:) doesn't need a leading separator
90
+
91
+ return { name: part, path: segmentPath };
92
+ });
93
+ };
94
+
95
+ const segments = getPathSegments(currentPath);
96
+
97
+ return (
98
+ <div className="flex flex-col h-[400px] gap-4 min-w-0">
99
+ {/* Navigation Bar */}
100
+ <div className="flex items-center border rounded-md p-1 gap-1 bg-muted/30">
101
+ <Button
102
+ variant="ghost"
103
+ size="icon"
104
+ className="h-8 w-8 shrink-0"
105
+ disabled={!parentItem || isLoading}
106
+ onClick={() => parentItem && handleNavigate(parentItem.path)}
107
+ title="Go to parent directory"
108
+ >
109
+ <ArrowLeft className="h-4 w-4" />
110
+ </Button>
111
+
112
+ <div className="w-px h-5 bg-border mx-1" />
113
+
114
+ <div
115
+ ref={scrollContainerRef}
116
+ className="flex-1 overflow-x-auto whitespace-nowrap flex items-center scrollbar-hide px-1 min-w-0"
117
+ >
118
+ <button
119
+ onClick={() => handleNavigate('/')}
120
+ className="hover:bg-accent p-1 rounded-sm transition-colors shrink-0"
121
+ title="Go to root"
122
+ >
123
+ <Home className="h-4 w-4 text-muted-foreground" />
124
+ </button>
125
+
126
+ {segments.map((segment, i) => (
127
+ <div key={segment.path} className="flex items-center shrink-0">
128
+ <ChevronRight className="h-3 w-3 text-muted-foreground mx-0.5 shrink-0" />
129
+ <button
130
+ onClick={() => handleNavigate(segment.path)}
131
+ className={cn(
132
+ "px-1.5 py-0.5 rounded-sm transition-colors text-sm hover:bg-accent hover:text-accent-foreground",
133
+ i === segments.length - 1 ? "font-medium text-foreground" : "text-muted-foreground"
134
+ )}
135
+ >
136
+ {segment.name}
137
+ </button>
138
+ </div>
139
+ ))}
140
+ </div>
141
+ </div>
142
+
143
+ <div className="flex-1 border rounded-md overflow-hidden relative bg-background min-h-0">
144
+ {isLoading && (
145
+ <div className="absolute inset-0 bg-background/50 flex items-center justify-center z-10">
146
+ <Loader2 className="h-6 w-6 animate-spin" />
147
+ </div>
148
+ )}
149
+
150
+ {error ? (
151
+ <div className="p-4 text-destructive text-sm text-center">
152
+ {error}
153
+ <Button variant="link" onClick={() => fetchDirectory(currentPath)} className="block mx-auto mt-2">
154
+ Retry
155
+ </Button>
156
+ </div>
157
+ ) : (
158
+ <div className="h-full overflow-auto">
159
+ <div className="p-1">
160
+ {displayItems.length === 0 && !isLoading ? (
161
+ <div className="p-4 text-center text-sm text-muted-foreground">
162
+ Empty directory
163
+ </div>
164
+ ) : (
165
+ displayItems.map((item) => (
166
+ <button
167
+ key={item.path}
168
+ onClick={() => handleNavigate(item.path)}
169
+ className="flex items-center gap-3 w-full px-3 py-2 text-sm rounded-sm hover:bg-accent hover:text-accent-foreground text-left group transition-colors"
170
+ >
171
+ <Folder className="h-4 w-4 text-blue-500 fill-blue-500/20 group-hover:fill-blue-500/30 transition-colors shrink-0" />
172
+ <span className="truncate">{item.name}</span>
173
+ </button>
174
+ ))
175
+ )}
176
+ </div>
177
+ </div>
178
+ )}
179
+ </div>
180
+
181
+ <div className="flex justify-end gap-2">
182
+ <Button variant="outline" onClick={onCancel} disabled={isLoading}>
183
+ Cancel
184
+ </Button>
185
+ <Button onClick={() => onSelect(currentPath)} disabled={isLoading || !currentPath}>
186
+ {actionLabel}
187
+ </Button>
188
+ </div>
189
+ </div>
190
+ );
191
+ }
@@ -3,6 +3,7 @@
3
3
  import Link from 'next/link';
4
4
  import { usePathname } from 'next/navigation';
5
5
  import { Home, FileText, BarChart3, ChevronLeft, ChevronRight, X } from 'lucide-react';
6
+ import { ProjectSwitcher } from '@/components/project-switcher';
6
7
  import { Button } from '@/components/ui/button';
7
8
  import { cn } from '@/lib/utils';
8
9
  import * as React from 'react';
@@ -121,6 +122,9 @@ export function MainSidebar() {
121
122
 
122
123
  {/* Navigation */}
123
124
  {mounted && <nav className="flex-1 px-2 py-4 space-y-1">
125
+ <div className="mb-4">
126
+ <ProjectSwitcher collapsed={isCollapsed && !mobileOpen} />
127
+ </div>
124
128
  <SidebarLink
125
129
  href="/"
126
130
  icon={Home}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Project Switcher Component
3
+ * Dropdown/expandable project selector for the sidebar
4
+ */
5
+
6
+ 'use client';
7
+
8
+ import React, { useState } from 'react';
9
+ import { Check, ChevronsUpDown, Plus, FolderOpen, Star } from 'lucide-react';
10
+ import { cn } from '@/lib/utils';
11
+ import { Button } from '@/components/ui/button';
12
+ import {
13
+ Command,
14
+ CommandEmpty,
15
+ CommandGroup,
16
+ CommandInput,
17
+ CommandItem,
18
+ CommandList,
19
+ CommandSeparator,
20
+ } from '@/components/ui/command';
21
+ import {
22
+ Popover,
23
+ PopoverContent,
24
+ PopoverTrigger,
25
+ } from '@/components/ui/popover';
26
+ import { useProject } from '@/contexts/project-context';
27
+ import { CreateProjectDialog } from '@/components/create-project-dialog';
28
+
29
+ interface ProjectSwitcherProps {
30
+ collapsed?: boolean;
31
+ onAddProject?: () => void; // Kept for compatibility, but we'll use internal dialog
32
+ }
33
+
34
+ export function ProjectSwitcher({ collapsed }: ProjectSwitcherProps) {
35
+ const {
36
+ mode,
37
+ currentProject,
38
+ projects,
39
+ switchProject,
40
+ } = useProject();
41
+
42
+ const [open, setOpen] = useState(false);
43
+ const [showNewProjectDialog, setShowNewProjectDialog] = useState(false);
44
+
45
+ if (mode !== 'multi-project') {
46
+ return null;
47
+ }
48
+
49
+ const handleProjectSelect = async (projectId: string) => {
50
+ await switchProject(projectId);
51
+ setOpen(false);
52
+ };
53
+
54
+ const sortedProjects = [...projects].sort((a, b) => {
55
+ if (a.favorite === b.favorite) return 0;
56
+ return a.favorite ? -1 : 1;
57
+ });
58
+
59
+ return (
60
+ <>
61
+ <CreateProjectDialog
62
+ open={showNewProjectDialog}
63
+ onOpenChange={setShowNewProjectDialog}
64
+ />
65
+ <Popover open={open} onOpenChange={setOpen}>
66
+ <PopoverTrigger asChild>
67
+ <Button
68
+ variant="outline"
69
+ role="combobox"
70
+ aria-expanded={open}
71
+ className={cn(
72
+ "w-full justify-between",
73
+ collapsed ? "h-9 w-9 p-0 justify-center" : "px-3"
74
+ )}
75
+ >
76
+ {collapsed ? (
77
+ <FolderOpen className="h-4 w-4" />
78
+ ) : (
79
+ <>
80
+ <div className="flex items-center gap-2 truncate">
81
+ <FolderOpen className="h-4 w-4 shrink-0 opacity-50" />
82
+ <span className="truncate">
83
+ {currentProject?.name || "Select project..."}
84
+ </span>
85
+ </div>
86
+ <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
87
+ </>
88
+ )}
89
+ </Button>
90
+ </PopoverTrigger>
91
+ <PopoverContent className="w-[200px] p-0" align="start">
92
+ <Command>
93
+ <CommandInput placeholder="Search projects..." />
94
+ <CommandList>
95
+ <CommandEmpty>No project found.</CommandEmpty>
96
+ <CommandGroup heading="Projects">
97
+ {sortedProjects.map((project) => (
98
+ <CommandItem
99
+ key={project.id}
100
+ onSelect={() => handleProjectSelect(project.id)}
101
+ className="text-sm"
102
+ >
103
+ <div className="flex items-center gap-2 w-full">
104
+ <Check
105
+ className={cn(
106
+ "mr-2 h-4 w-4",
107
+ currentProject?.id === project.id
108
+ ? "opacity-100"
109
+ : "opacity-0"
110
+ )}
111
+ />
112
+ <span className="truncate flex-1">{project.name}</span>
113
+ {project.favorite && (
114
+ <Star className="h-3 w-3 fill-yellow-500 text-yellow-500" />
115
+ )}
116
+ </div>
117
+ </CommandItem>
118
+ ))}
119
+ </CommandGroup>
120
+ <CommandSeparator />
121
+ <CommandGroup>
122
+ <CommandItem
123
+ className="cursor-pointer"
124
+ onSelect={() => {
125
+ setOpen(false);
126
+ setShowNewProjectDialog(true);
127
+ }}
128
+ >
129
+ <Plus className="mr-2 h-4 w-4" />
130
+ Create Project
131
+ </CommandItem>
132
+ </CommandGroup>
133
+ </CommandList>
134
+ </Command>
135
+ </PopoverContent>
136
+ </Popover>
137
+ </>
138
+ );
139
+ }
@@ -0,0 +1,200 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
5
+ import { Check, ChevronRight, Circle } from "lucide-react"
6
+
7
+ import { cn } from "@/lib/utils"
8
+
9
+ const DropdownMenu = DropdownMenuPrimitive.Root
10
+
11
+ const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
12
+
13
+ const DropdownMenuGroup = DropdownMenuPrimitive.Group
14
+
15
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal
16
+
17
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub
18
+
19
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
20
+
21
+ const DropdownMenuSubTrigger = React.forwardRef<
22
+ React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
23
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
24
+ inset?: boolean
25
+ }
26
+ >(({ className, inset, children, ...props }, ref) => (
27
+ <DropdownMenuPrimitive.SubTrigger
28
+ ref={ref}
29
+ className={cn(
30
+ "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
31
+ inset && "pl-8",
32
+ className
33
+ )}
34
+ {...props}
35
+ >
36
+ {children}
37
+ <ChevronRight className="ml-auto h-4 w-4" />
38
+ </DropdownMenuPrimitive.SubTrigger>
39
+ ))
40
+ DropdownMenuSubTrigger.displayName =
41
+ DropdownMenuPrimitive.SubTrigger.displayName
42
+
43
+ const DropdownMenuSubContent = React.forwardRef<
44
+ React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
45
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
46
+ >(({ className, ...props }, ref) => (
47
+ <DropdownMenuPrimitive.SubContent
48
+ ref={ref}
49
+ className={cn(
50
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
51
+ className
52
+ )}
53
+ {...props}
54
+ />
55
+ ))
56
+ DropdownMenuSubContent.displayName =
57
+ DropdownMenuPrimitive.SubContent.displayName
58
+
59
+ const DropdownMenuContent = React.forwardRef<
60
+ React.ElementRef<typeof DropdownMenuPrimitive.Content>,
61
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
62
+ >(({ className, sideOffset = 4, ...props }, ref) => (
63
+ <DropdownMenuPrimitive.Portal>
64
+ <DropdownMenuPrimitive.Content
65
+ ref={ref}
66
+ sideOffset={sideOffset}
67
+ className={cn(
68
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
69
+ className
70
+ )}
71
+ {...props}
72
+ />
73
+ </DropdownMenuPrimitive.Portal>
74
+ ))
75
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
76
+
77
+ const DropdownMenuItem = React.forwardRef<
78
+ React.ElementRef<typeof DropdownMenuPrimitive.Item>,
79
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
80
+ inset?: boolean
81
+ }
82
+ >(({ className, inset, ...props }, ref) => (
83
+ <DropdownMenuPrimitive.Item
84
+ ref={ref}
85
+ className={cn(
86
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
87
+ inset && "pl-8",
88
+ className
89
+ )}
90
+ {...props}
91
+ />
92
+ ))
93
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
94
+
95
+ const DropdownMenuCheckboxItem = React.forwardRef<
96
+ React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
97
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
98
+ >(({ className, children, checked, ...props }, ref) => (
99
+ <DropdownMenuPrimitive.CheckboxItem
100
+ ref={ref}
101
+ className={cn(
102
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
103
+ className
104
+ )}
105
+ checked={checked}
106
+ {...props}
107
+ >
108
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
109
+ <DropdownMenuPrimitive.ItemIndicator>
110
+ <Check className="h-4 w-4" />
111
+ </DropdownMenuPrimitive.ItemIndicator>
112
+ </span>
113
+ {children}
114
+ </DropdownMenuPrimitive.CheckboxItem>
115
+ ))
116
+ DropdownMenuCheckboxItem.displayName =
117
+ DropdownMenuPrimitive.CheckboxItem.displayName
118
+
119
+ const DropdownMenuRadioItem = React.forwardRef<
120
+ React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
121
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
122
+ >(({ className, children, ...props }, ref) => (
123
+ <DropdownMenuPrimitive.RadioItem
124
+ ref={ref}
125
+ className={cn(
126
+ "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
127
+ className
128
+ )}
129
+ {...props}
130
+ >
131
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
132
+ <DropdownMenuPrimitive.ItemIndicator>
133
+ <Circle className="h-2 w-2 fill-current" />
134
+ </DropdownMenuPrimitive.ItemIndicator>
135
+ </span>
136
+ {children}
137
+ </DropdownMenuPrimitive.RadioItem>
138
+ ))
139
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
140
+
141
+ const DropdownMenuLabel = React.forwardRef<
142
+ React.ElementRef<typeof DropdownMenuPrimitive.Label>,
143
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
144
+ inset?: boolean
145
+ }
146
+ >(({ className, inset, ...props }, ref) => (
147
+ <DropdownMenuPrimitive.Label
148
+ ref={ref}
149
+ className={cn(
150
+ "px-2 py-1.5 text-sm font-semibold",
151
+ inset && "pl-8",
152
+ className
153
+ )}
154
+ {...props}
155
+ />
156
+ ))
157
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
158
+
159
+ const DropdownMenuSeparator = React.forwardRef<
160
+ React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
161
+ React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
162
+ >(({ className, ...props }, ref) => (
163
+ <DropdownMenuPrimitive.Separator
164
+ ref={ref}
165
+ className={cn("-mx-1 my-1 h-px bg-muted", className)}
166
+ {...props}
167
+ />
168
+ ))
169
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
170
+
171
+ const DropdownMenuShortcut = ({
172
+ className,
173
+ ...props
174
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
175
+ return (
176
+ <span
177
+ className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
178
+ {...props}
179
+ />
180
+ )
181
+ }
182
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
183
+
184
+ export {
185
+ DropdownMenu,
186
+ DropdownMenuTrigger,
187
+ DropdownMenuContent,
188
+ DropdownMenuItem,
189
+ DropdownMenuCheckboxItem,
190
+ DropdownMenuRadioItem,
191
+ DropdownMenuLabel,
192
+ DropdownMenuSeparator,
193
+ DropdownMenuShortcut,
194
+ DropdownMenuGroup,
195
+ DropdownMenuPortal,
196
+ DropdownMenuSub,
197
+ DropdownMenuSubContent,
198
+ DropdownMenuSubTrigger,
199
+ DropdownMenuRadioGroup,
200
+ }