@jlongo78/agent-spaces 0.9.6 → 0.9.8

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 (917) hide show
  1. package/.next/standalone/.claude/settings.local.json +68 -0
  2. package/.next/standalone/.claude/spaces-env.json +1 -0
  3. package/.next/standalone/.next/BUILD_ID +1 -1
  4. package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
  5. package/.next/standalone/.next/build-manifest.json +2 -2
  6. package/.next/standalone/.next/prerender-manifest.json +3 -3
  7. package/.next/standalone/.next/required-server-files.json +19 -19
  8. package/.next/standalone/.next/routes-manifest.json +6 -0
  9. package/.next/standalone/.next/server/app/(desktop)/admin/analytics/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/(desktop)/admin/users/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/(desktop)/analytics/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/(desktop)/cortex/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/(desktop)/network/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/(desktop)/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/(desktop)/projects/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/(desktop)/sessions/[id]/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/(desktop)/sessions/[id]/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/(desktop)/sessions/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/(desktop)/settings/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/(desktop)/terminal/page.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/(desktop)/terminal/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/(desktop)/terminal/pane/[id]/page_client-reference-manifest.js +1 -1
  23. package/.next/standalone/.next/server/app/(desktop)/terminal/remote/[nodeId]/[workspaceId]/page_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/(desktop)/workspaces/page_client-reference-manifest.js +1 -1
  25. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  26. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  27. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  28. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  29. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  30. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  31. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  32. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  33. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  34. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  35. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  36. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  37. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  38. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  39. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  40. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/admin/analytics.html +1 -1
  42. package/.next/standalone/.next/server/app/admin/analytics.rsc +2 -2
  43. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics/__PAGE__.segment.rsc +1 -1
  44. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics.segment.rsc +1 -1
  45. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  46. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  47. package/.next/standalone/.next/server/app/admin/analytics.segments/_full.segment.rsc +2 -2
  48. package/.next/standalone/.next/server/app/admin/analytics.segments/_head.segment.rsc +1 -1
  49. package/.next/standalone/.next/server/app/admin/analytics.segments/_index.segment.rsc +2 -2
  50. package/.next/standalone/.next/server/app/admin/analytics.segments/_tree.segment.rsc +2 -2
  51. package/.next/standalone/.next/server/app/admin/users.html +1 -1
  52. package/.next/standalone/.next/server/app/admin/users.rsc +2 -2
  53. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users/__PAGE__.segment.rsc +1 -1
  54. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users.segment.rsc +1 -1
  55. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  56. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  57. package/.next/standalone/.next/server/app/admin/users.segments/_full.segment.rsc +2 -2
  58. package/.next/standalone/.next/server/app/admin/users.segments/_head.segment.rsc +1 -1
  59. package/.next/standalone/.next/server/app/admin/users.segments/_index.segment.rsc +2 -2
  60. package/.next/standalone/.next/server/app/admin/users.segments/_tree.segment.rsc +2 -2
  61. package/.next/standalone/.next/server/app/analytics.html +1 -1
  62. package/.next/standalone/.next/server/app/analytics.rsc +2 -2
  63. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics/__PAGE__.segment.rsc +1 -1
  64. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics.segment.rsc +1 -1
  65. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  66. package/.next/standalone/.next/server/app/analytics.segments/_full.segment.rsc +2 -2
  67. package/.next/standalone/.next/server/app/analytics.segments/_head.segment.rsc +1 -1
  68. package/.next/standalone/.next/server/app/analytics.segments/_index.segment.rsc +2 -2
  69. package/.next/standalone/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
  70. package/.next/standalone/.next/server/app/api/analytics/overview/route.js +1 -1
  71. package/.next/standalone/.next/server/app/api/analytics/overview/route.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/api/benchmark/lobes/route.js +1 -1
  73. package/.next/standalone/.next/server/app/api/benchmark/lobes/route.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/api/benchmark/run/route.js +1 -1
  75. package/.next/standalone/.next/server/app/api/benchmark/run/route.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route.js +1 -1
  77. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route.js.nft.json +1 -1
  78. package/.next/standalone/.next/server/app/api/benchmark/runs/route.js +1 -1
  79. package/.next/standalone/.next/server/app/api/benchmark/runs/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/api/benchmark/status/route.js +1 -1
  81. package/.next/standalone/.next/server/app/api/benchmark/status/route.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/api/bulk/route.js +1 -1
  83. package/.next/standalone/.next/server/app/api/bulk/route.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/api/config/route.js +1 -1
  85. package/.next/standalone/.next/server/app/api/config/route.js.nft.json +1 -1
  86. package/.next/standalone/.next/server/app/api/cortex/context/route.js +1 -1
  87. package/.next/standalone/.next/server/app/api/cortex/context/route.js.nft.json +1 -1
  88. package/.next/standalone/.next/server/app/api/cortex/curation/assess/route.js +1 -1
  89. package/.next/standalone/.next/server/app/api/cortex/curation/assess/route.js.nft.json +1 -1
  90. package/.next/standalone/.next/server/app/api/cortex/curation/publish/route.js +1 -1
  91. package/.next/standalone/.next/server/app/api/cortex/curation/publish/route.js.nft.json +1 -1
  92. package/.next/standalone/.next/server/app/api/cortex/curation/refine/route.js +1 -1
  93. package/.next/standalone/.next/server/app/api/cortex/curation/refine/route.js.nft.json +1 -1
  94. package/.next/standalone/.next/server/app/api/cortex/curation/review/route.js +1 -1
  95. package/.next/standalone/.next/server/app/api/cortex/curation/review/route.js.nft.json +1 -1
  96. package/.next/standalone/.next/server/app/api/cortex/curation/seed/route.js +1 -1
  97. package/.next/standalone/.next/server/app/api/cortex/curation/seed/route.js.nft.json +1 -1
  98. package/.next/standalone/.next/server/app/api/cortex/export/route.js +1 -1
  99. package/.next/standalone/.next/server/app/api/cortex/export/route.js.nft.json +1 -1
  100. package/.next/standalone/.next/server/app/api/cortex/federation/pending/route.js +1 -1
  101. package/.next/standalone/.next/server/app/api/cortex/federation/pending/route.js.nft.json +1 -1
  102. package/.next/standalone/.next/server/app/api/cortex/federation/resolve/route.js +1 -1
  103. package/.next/standalone/.next/server/app/api/cortex/federation/resolve/route.js.nft.json +1 -1
  104. package/.next/standalone/.next/server/app/api/cortex/federation/search/route.js +1 -1
  105. package/.next/standalone/.next/server/app/api/cortex/federation/search/route.js.nft.json +1 -1
  106. package/.next/standalone/.next/server/app/api/cortex/federation/teach/route.js +1 -1
  107. package/.next/standalone/.next/server/app/api/cortex/federation/teach/route.js.nft.json +1 -1
  108. package/.next/standalone/.next/server/app/api/cortex/graph/edges/route.js +1 -1
  109. package/.next/standalone/.next/server/app/api/cortex/graph/edges/route.js.nft.json +1 -1
  110. package/.next/standalone/.next/server/app/api/cortex/graph/entities/[id]/route.js +1 -1
  111. package/.next/standalone/.next/server/app/api/cortex/graph/entities/[id]/route.js.nft.json +1 -1
  112. package/.next/standalone/.next/server/app/api/cortex/graph/entities/route.js +1 -1
  113. package/.next/standalone/.next/server/app/api/cortex/graph/entities/route.js.nft.json +1 -1
  114. package/.next/standalone/.next/server/app/api/cortex/graph/populate/route.js +1 -1
  115. package/.next/standalone/.next/server/app/api/cortex/graph/populate/route.js.nft.json +1 -1
  116. package/.next/standalone/.next/server/app/api/cortex/import/route.js +1 -1
  117. package/.next/standalone/.next/server/app/api/cortex/import/route.js.nft.json +1 -1
  118. package/.next/standalone/.next/server/app/api/cortex/import/status/route.js +1 -1
  119. package/.next/standalone/.next/server/app/api/cortex/import/status/route.js.nft.json +1 -1
  120. package/.next/standalone/.next/server/app/api/cortex/ingest/bootstrap/route.js +1 -1
  121. package/.next/standalone/.next/server/app/api/cortex/ingest/bootstrap/route.js.nft.json +1 -1
  122. package/.next/standalone/.next/server/app/api/cortex/ingest/status/route.js +1 -1
  123. package/.next/standalone/.next/server/app/api/cortex/ingest/status/route.js.nft.json +1 -1
  124. package/.next/standalone/.next/server/app/api/cortex/knowledge/[id]/route.js +1 -1
  125. package/.next/standalone/.next/server/app/api/cortex/knowledge/[id]/route.js.nft.json +1 -1
  126. package/.next/standalone/.next/server/app/api/cortex/knowledge/route.js +1 -1
  127. package/.next/standalone/.next/server/app/api/cortex/knowledge/route.js.nft.json +1 -1
  128. package/.next/standalone/.next/server/app/api/cortex/lobes/[id]/route.js +1 -1
  129. package/.next/standalone/.next/server/app/api/cortex/lobes/[id]/route.js.nft.json +1 -1
  130. package/.next/standalone/.next/server/app/api/cortex/lobes/route.js +1 -1
  131. package/.next/standalone/.next/server/app/api/cortex/lobes/route.js.nft.json +1 -1
  132. package/.next/standalone/.next/server/app/api/cortex/lobes/share/route.js +1 -1
  133. package/.next/standalone/.next/server/app/api/cortex/lobes/share/route.js.nft.json +1 -1
  134. package/.next/standalone/.next/server/app/api/cortex/marketplace/browse/route.js +1 -1
  135. package/.next/standalone/.next/server/app/api/cortex/marketplace/browse/route.js.nft.json +1 -1
  136. package/.next/standalone/.next/server/app/api/cortex/marketplace/preview/route.js +1 -1
  137. package/.next/standalone/.next/server/app/api/cortex/marketplace/preview/route.js.nft.json +1 -1
  138. package/.next/standalone/.next/server/app/api/cortex/mcp/call/route.js +1 -1
  139. package/.next/standalone/.next/server/app/api/cortex/mcp/call/route.js.nft.json +1 -1
  140. package/.next/standalone/.next/server/app/api/cortex/mcp/tools/route.js +1 -1
  141. package/.next/standalone/.next/server/app/api/cortex/mcp/tools/route.js.nft.json +1 -1
  142. package/.next/standalone/.next/server/app/api/cortex/search/route.js +1 -1
  143. package/.next/standalone/.next/server/app/api/cortex/search/route.js.nft.json +1 -1
  144. package/.next/standalone/.next/server/app/api/cortex/settings/route.js +1 -1
  145. package/.next/standalone/.next/server/app/api/cortex/settings/route.js.nft.json +1 -1
  146. package/.next/standalone/.next/server/app/api/cortex/status/route.js +1 -1
  147. package/.next/standalone/.next/server/app/api/cortex/status/route.js.nft.json +1 -1
  148. package/.next/standalone/.next/server/app/api/cortex/timeline/route.js +1 -1
  149. package/.next/standalone/.next/server/app/api/cortex/timeline/route.js.nft.json +1 -1
  150. package/.next/standalone/.next/server/app/api/cortex/usage/route.js +1 -1
  151. package/.next/standalone/.next/server/app/api/cortex/usage/route.js.nft.json +1 -1
  152. package/.next/standalone/.next/server/app/api/cortex/workspace/[id]/context/route.js +1 -1
  153. package/.next/standalone/.next/server/app/api/cortex/workspace/[id]/context/route.js.nft.json +1 -1
  154. package/.next/standalone/.next/server/app/api/events/route.js +1 -1
  155. package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
  156. package/.next/standalone/.next/server/app/api/files/route.js +1 -1
  157. package/.next/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  158. package/.next/standalone/.next/server/app/api/folders/route.js +1 -1
  159. package/.next/standalone/.next/server/app/api/folders/route.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/api/network/handshake/route.js +1 -1
  161. package/.next/standalone/.next/server/app/api/network/handshake/route.js.nft.json +1 -1
  162. package/.next/standalone/.next/server/app/api/network/panes/[id]/route.js +1 -1
  163. package/.next/standalone/.next/server/app/api/network/panes/[id]/route.js.nft.json +1 -1
  164. package/.next/standalone/.next/server/app/api/network/panes/route.js +1 -1
  165. package/.next/standalone/.next/server/app/api/network/panes/route.js.nft.json +1 -1
  166. package/.next/standalone/.next/server/app/api/network/projects/route.js +1 -1
  167. package/.next/standalone/.next/server/app/api/network/projects/route.js.nft.json +1 -1
  168. package/.next/standalone/.next/server/app/api/network/search/route.js +1 -1
  169. package/.next/standalone/.next/server/app/api/network/search/route.js.nft.json +1 -1
  170. package/.next/standalone/.next/server/app/api/network/sessions/[id]/messages/route.js +1 -1
  171. package/.next/standalone/.next/server/app/api/network/sessions/[id]/messages/route.js.nft.json +1 -1
  172. package/.next/standalone/.next/server/app/api/network/sessions/[id]/route.js +1 -1
  173. package/.next/standalone/.next/server/app/api/network/sessions/[id]/route.js.nft.json +1 -1
  174. package/.next/standalone/.next/server/app/api/network/sessions/route.js +1 -1
  175. package/.next/standalone/.next/server/app/api/network/sessions/route.js.nft.json +1 -1
  176. package/.next/standalone/.next/server/app/api/network/workspaces/[id]/route.js +1 -1
  177. package/.next/standalone/.next/server/app/api/network/workspaces/[id]/route.js.nft.json +1 -1
  178. package/.next/standalone/.next/server/app/api/network/workspaces/route.js +1 -1
  179. package/.next/standalone/.next/server/app/api/network/workspaces/route.js.nft.json +1 -1
  180. package/.next/standalone/.next/server/app/api/panes/[id]/diff/route.js +1 -1
  181. package/.next/standalone/.next/server/app/api/panes/[id]/diff/route.js.nft.json +1 -1
  182. package/.next/standalone/.next/server/app/api/panes/[id]/route.js +1 -1
  183. package/.next/standalone/.next/server/app/api/panes/[id]/route.js.nft.json +1 -1
  184. package/.next/standalone/.next/server/app/api/panes/route.js +1 -1
  185. package/.next/standalone/.next/server/app/api/panes/route.js.nft.json +1 -1
  186. package/.next/standalone/.next/server/app/api/projects/route.js +1 -1
  187. package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  188. package/.next/standalone/.next/server/app/api/proxy/models/[modelId]/[...path]/route.js +1 -1
  189. package/.next/standalone/.next/server/app/api/proxy/models/[modelId]/[...path]/route.js.nft.json +1 -1
  190. package/.next/standalone/.next/server/app/api/proxy/models/[modelId]/status/route.js +1 -1
  191. package/.next/standalone/.next/server/app/api/proxy/models/[modelId]/status/route.js.nft.json +1 -1
  192. package/.next/standalone/.next/server/app/api/search/route.js +2 -2
  193. package/.next/standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  194. package/.next/standalone/.next/server/app/api/sessions/[id]/chat/route.js +1 -1
  195. package/.next/standalone/.next/server/app/api/sessions/[id]/chat/route.js.nft.json +1 -1
  196. package/.next/standalone/.next/server/app/api/sessions/[id]/messages/route.js +1 -1
  197. package/.next/standalone/.next/server/app/api/sessions/[id]/messages/route.js.nft.json +1 -1
  198. package/.next/standalone/.next/server/app/api/sessions/[id]/route.js +1 -1
  199. package/.next/standalone/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  200. package/.next/standalone/.next/server/app/api/sessions/route.js +2 -2
  201. package/.next/standalone/.next/server/app/api/sessions/route.js.nft.json +1 -1
  202. package/.next/standalone/.next/server/app/api/sync/route.js +1 -1
  203. package/.next/standalone/.next/server/app/api/sync/route.js.nft.json +1 -1
  204. package/.next/standalone/.next/server/app/api/tags/route.js +1 -1
  205. package/.next/standalone/.next/server/app/api/tags/route.js.nft.json +1 -1
  206. package/.next/standalone/.next/server/app/api/tier/route.js +1 -1
  207. package/.next/standalone/.next/server/app/api/tier/route.js.nft.json +1 -1
  208. package/.next/standalone/.next/server/app/api/whisper/config/route.js +1 -1
  209. package/.next/standalone/.next/server/app/api/whisper/config/route.js.nft.json +1 -1
  210. package/.next/standalone/.next/server/app/api/whisper/route.js.nft.json +1 -1
  211. package/.next/standalone/.next/server/app/api/wizard/chart/route/app-paths-manifest.json +3 -0
  212. package/.next/standalone/.next/server/app/api/wizard/chart/route/build-manifest.json +11 -0
  213. package/.next/standalone/.next/server/app/api/wizard/chart/route/server-reference-manifest.json +4 -0
  214. package/.next/standalone/.next/server/app/api/wizard/chart/route.js +7 -0
  215. package/.next/standalone/.next/server/app/api/wizard/chart/route.js.map +5 -0
  216. package/.next/standalone/.next/server/app/api/wizard/chart/route.js.nft.json +1 -0
  217. package/.next/standalone/.next/server/app/api/wizard/chart/route_client-reference-manifest.js +2 -0
  218. package/.next/standalone/.next/server/app/api/wizard/chat/route.js +1 -1
  219. package/.next/standalone/.next/server/app/api/wizard/chat/route.js.nft.json +1 -1
  220. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/[key]/route.js +1 -1
  221. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/[key]/route.js.nft.json +1 -1
  222. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/route.js +1 -1
  223. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/route.js.nft.json +1 -1
  224. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/[msgId]/route.js +1 -1
  225. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/[msgId]/route.js.nft.json +1 -1
  226. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/route.js +1 -1
  227. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/route.js.nft.json +1 -1
  228. package/.next/standalone/.next/server/app/api/workspaces/[id]/route.js +1 -1
  229. package/.next/standalone/.next/server/app/api/workspaces/[id]/route.js.nft.json +1 -1
  230. package/.next/standalone/.next/server/app/api/workspaces/[id]/sessions/route.js +1 -1
  231. package/.next/standalone/.next/server/app/api/workspaces/[id]/sessions/route.js.nft.json +1 -1
  232. package/.next/standalone/.next/server/app/api/workspaces/route.js +2 -2
  233. package/.next/standalone/.next/server/app/api/workspaces/route.js.nft.json +1 -1
  234. package/.next/standalone/.next/server/app/cortex.html +1 -1
  235. package/.next/standalone/.next/server/app/cortex.rsc +3 -3
  236. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap/cortex/__PAGE__.segment.rsc +2 -2
  237. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap/cortex.segment.rsc +1 -1
  238. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  239. package/.next/standalone/.next/server/app/cortex.segments/_full.segment.rsc +3 -3
  240. package/.next/standalone/.next/server/app/cortex.segments/_head.segment.rsc +1 -1
  241. package/.next/standalone/.next/server/app/cortex.segments/_index.segment.rsc +2 -2
  242. package/.next/standalone/.next/server/app/cortex.segments/_tree.segment.rsc +2 -2
  243. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  244. package/.next/standalone/.next/server/app/login.html +1 -1
  245. package/.next/standalone/.next/server/app/login.rsc +2 -2
  246. package/.next/standalone/.next/server/app/login.segments/_full.segment.rsc +2 -2
  247. package/.next/standalone/.next/server/app/login.segments/_head.segment.rsc +1 -1
  248. package/.next/standalone/.next/server/app/login.segments/_index.segment.rsc +2 -2
  249. package/.next/standalone/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  250. package/.next/standalone/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  251. package/.next/standalone/.next/server/app/login.segments/login.segment.rsc +1 -1
  252. package/.next/standalone/.next/server/app/m/page_client-reference-manifest.js +1 -1
  253. package/.next/standalone/.next/server/app/m/projects/page_client-reference-manifest.js +1 -1
  254. package/.next/standalone/.next/server/app/m/projects.html +1 -1
  255. package/.next/standalone/.next/server/app/m/projects.rsc +2 -2
  256. package/.next/standalone/.next/server/app/m/projects.segments/_full.segment.rsc +2 -2
  257. package/.next/standalone/.next/server/app/m/projects.segments/_head.segment.rsc +1 -1
  258. package/.next/standalone/.next/server/app/m/projects.segments/_index.segment.rsc +2 -2
  259. package/.next/standalone/.next/server/app/m/projects.segments/_tree.segment.rsc +2 -2
  260. package/.next/standalone/.next/server/app/m/projects.segments/m/projects/__PAGE__.segment.rsc +1 -1
  261. package/.next/standalone/.next/server/app/m/projects.segments/m/projects.segment.rsc +1 -1
  262. package/.next/standalone/.next/server/app/m/projects.segments/m.segment.rsc +1 -1
  263. package/.next/standalone/.next/server/app/m/sessions/[id]/page.js.nft.json +1 -1
  264. package/.next/standalone/.next/server/app/m/sessions/[id]/page_client-reference-manifest.js +1 -1
  265. package/.next/standalone/.next/server/app/m/sessions/page_client-reference-manifest.js +1 -1
  266. package/.next/standalone/.next/server/app/m/sessions.html +1 -1
  267. package/.next/standalone/.next/server/app/m/sessions.rsc +2 -2
  268. package/.next/standalone/.next/server/app/m/sessions.segments/_full.segment.rsc +2 -2
  269. package/.next/standalone/.next/server/app/m/sessions.segments/_head.segment.rsc +1 -1
  270. package/.next/standalone/.next/server/app/m/sessions.segments/_index.segment.rsc +2 -2
  271. package/.next/standalone/.next/server/app/m/sessions.segments/_tree.segment.rsc +2 -2
  272. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions/__PAGE__.segment.rsc +1 -1
  273. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions.segment.rsc +1 -1
  274. package/.next/standalone/.next/server/app/m/sessions.segments/m.segment.rsc +1 -1
  275. package/.next/standalone/.next/server/app/m/settings/page_client-reference-manifest.js +1 -1
  276. package/.next/standalone/.next/server/app/m/settings.html +1 -1
  277. package/.next/standalone/.next/server/app/m/settings.rsc +2 -2
  278. package/.next/standalone/.next/server/app/m/settings.segments/_full.segment.rsc +2 -2
  279. package/.next/standalone/.next/server/app/m/settings.segments/_head.segment.rsc +1 -1
  280. package/.next/standalone/.next/server/app/m/settings.segments/_index.segment.rsc +2 -2
  281. package/.next/standalone/.next/server/app/m/settings.segments/_tree.segment.rsc +2 -2
  282. package/.next/standalone/.next/server/app/m/settings.segments/m/settings/__PAGE__.segment.rsc +1 -1
  283. package/.next/standalone/.next/server/app/m/settings.segments/m/settings.segment.rsc +1 -1
  284. package/.next/standalone/.next/server/app/m/settings.segments/m.segment.rsc +1 -1
  285. package/.next/standalone/.next/server/app/m/terminal/page_client-reference-manifest.js +1 -1
  286. package/.next/standalone/.next/server/app/m/terminal.html +1 -1
  287. package/.next/standalone/.next/server/app/m/terminal.rsc +3 -3
  288. package/.next/standalone/.next/server/app/m/terminal.segments/_full.segment.rsc +3 -3
  289. package/.next/standalone/.next/server/app/m/terminal.segments/_head.segment.rsc +1 -1
  290. package/.next/standalone/.next/server/app/m/terminal.segments/_index.segment.rsc +2 -2
  291. package/.next/standalone/.next/server/app/m/terminal.segments/_tree.segment.rsc +2 -2
  292. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal/__PAGE__.segment.rsc +2 -2
  293. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal.segment.rsc +1 -1
  294. package/.next/standalone/.next/server/app/m/terminal.segments/m.segment.rsc +1 -1
  295. package/.next/standalone/.next/server/app/m.html +1 -1
  296. package/.next/standalone/.next/server/app/m.rsc +2 -2
  297. package/.next/standalone/.next/server/app/m.segments/_full.segment.rsc +2 -2
  298. package/.next/standalone/.next/server/app/m.segments/_head.segment.rsc +1 -1
  299. package/.next/standalone/.next/server/app/m.segments/_index.segment.rsc +2 -2
  300. package/.next/standalone/.next/server/app/m.segments/_tree.segment.rsc +2 -2
  301. package/.next/standalone/.next/server/app/m.segments/m/__PAGE__.segment.rsc +1 -1
  302. package/.next/standalone/.next/server/app/m.segments/m.segment.rsc +1 -1
  303. package/.next/standalone/.next/server/app/network.html +1 -1
  304. package/.next/standalone/.next/server/app/network.rsc +2 -2
  305. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network/__PAGE__.segment.rsc +1 -1
  306. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network.segment.rsc +1 -1
  307. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  308. package/.next/standalone/.next/server/app/network.segments/_full.segment.rsc +2 -2
  309. package/.next/standalone/.next/server/app/network.segments/_head.segment.rsc +1 -1
  310. package/.next/standalone/.next/server/app/network.segments/_index.segment.rsc +2 -2
  311. package/.next/standalone/.next/server/app/network.segments/_tree.segment.rsc +2 -2
  312. package/.next/standalone/.next/server/app/projects.html +1 -1
  313. package/.next/standalone/.next/server/app/projects.rsc +2 -2
  314. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects/__PAGE__.segment.rsc +1 -1
  315. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects.segment.rsc +1 -1
  316. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  317. package/.next/standalone/.next/server/app/projects.segments/_full.segment.rsc +2 -2
  318. package/.next/standalone/.next/server/app/projects.segments/_head.segment.rsc +1 -1
  319. package/.next/standalone/.next/server/app/projects.segments/_index.segment.rsc +2 -2
  320. package/.next/standalone/.next/server/app/projects.segments/_tree.segment.rsc +2 -2
  321. package/.next/standalone/.next/server/app/sessions.html +1 -1
  322. package/.next/standalone/.next/server/app/sessions.rsc +2 -2
  323. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions/__PAGE__.segment.rsc +1 -1
  324. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions.segment.rsc +1 -1
  325. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  326. package/.next/standalone/.next/server/app/sessions.segments/_full.segment.rsc +2 -2
  327. package/.next/standalone/.next/server/app/sessions.segments/_head.segment.rsc +1 -1
  328. package/.next/standalone/.next/server/app/sessions.segments/_index.segment.rsc +2 -2
  329. package/.next/standalone/.next/server/app/sessions.segments/_tree.segment.rsc +2 -2
  330. package/.next/standalone/.next/server/app/settings.html +1 -1
  331. package/.next/standalone/.next/server/app/settings.rsc +2 -2
  332. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings/__PAGE__.segment.rsc +1 -1
  333. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings.segment.rsc +1 -1
  334. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  335. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +2 -2
  336. package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  337. package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  338. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  339. package/.next/standalone/.next/server/app/terminal.html +1 -1
  340. package/.next/standalone/.next/server/app/terminal.rsc +3 -3
  341. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal/__PAGE__.segment.rsc +2 -2
  342. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal.segment.rsc +1 -1
  343. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  344. package/.next/standalone/.next/server/app/terminal.segments/_full.segment.rsc +3 -3
  345. package/.next/standalone/.next/server/app/terminal.segments/_head.segment.rsc +1 -1
  346. package/.next/standalone/.next/server/app/terminal.segments/_index.segment.rsc +2 -2
  347. package/.next/standalone/.next/server/app/terminal.segments/_tree.segment.rsc +2 -2
  348. package/.next/standalone/.next/server/app/vr/page/react-loadable-manifest.json +1 -1
  349. package/.next/standalone/.next/server/app/vr/page_client-reference-manifest.js +1 -1
  350. package/.next/standalone/.next/server/app/vr.html +1 -1
  351. package/.next/standalone/.next/server/app/vr.rsc +3 -3
  352. package/.next/standalone/.next/server/app/vr.segments/_full.segment.rsc +3 -3
  353. package/.next/standalone/.next/server/app/vr.segments/_head.segment.rsc +1 -1
  354. package/.next/standalone/.next/server/app/vr.segments/_index.segment.rsc +2 -2
  355. package/.next/standalone/.next/server/app/vr.segments/_tree.segment.rsc +2 -2
  356. package/.next/standalone/.next/server/app/vr.segments/vr/__PAGE__.segment.rsc +2 -2
  357. package/.next/standalone/.next/server/app/vr.segments/vr.segment.rsc +1 -1
  358. package/.next/standalone/.next/server/app/workspaces.html +1 -1
  359. package/.next/standalone/.next/server/app/workspaces.rsc +2 -2
  360. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces/__PAGE__.segment.rsc +1 -1
  361. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces.segment.rsc +1 -1
  362. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  363. package/.next/standalone/.next/server/app/workspaces.segments/_full.segment.rsc +2 -2
  364. package/.next/standalone/.next/server/app/workspaces.segments/_head.segment.rsc +1 -1
  365. package/.next/standalone/.next/server/app/workspaces.segments/_index.segment.rsc +2 -2
  366. package/.next/standalone/.next/server/app/workspaces.segments/_tree.segment.rsc +2 -2
  367. package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
  368. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00e90fc6._.js +98 -0
  369. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01ab8675._.js +98 -0
  370. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03974f05._.js +98 -0
  371. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__bb331da9._.js → [root-of-the-server]__046c9b91._.js} +3 -3
  372. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04ae6bf0._.js +98 -0
  373. package/.next/standalone/.next/server/chunks/[root-of-the-server]__056fa416._.js +1 -1
  374. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ac4ea3f._.js +3 -0
  375. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0b8e64cb._.js +98 -0
  376. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__d95165f0._.js → [root-of-the-server]__0facd39e._.js} +3 -3
  377. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10bc76a3._.js +3 -0
  378. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__9d68157b._.js → [root-of-the-server]__115f3934._.js} +3 -3
  379. package/.next/standalone/.next/server/chunks/[root-of-the-server]__11f155f1._.js +3 -0
  380. package/.next/standalone/.next/server/chunks/[root-of-the-server]__160e7c73._.js +22 -33
  381. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__91e23c96._.js → [root-of-the-server]__17a3b966._.js} +3 -3
  382. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__277d9445._.js → [root-of-the-server]__17d3a2b2._.js} +3 -3
  383. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a86c055._.js +98 -0
  384. package/.next/standalone/.next/server/chunks/[root-of-the-server]__20b5e9c4._.js +3 -0
  385. package/.next/standalone/.next/server/chunks/[root-of-the-server]__28d6fbd8._.js +98 -0
  386. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__04f04898._.js → [root-of-the-server]__2a3f866b._.js} +2 -2
  387. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__a95bb38b._.js → [root-of-the-server]__316617e7._.js} +2 -2
  388. package/.next/standalone/.next/server/chunks/[root-of-the-server]__32ad8f71._.js +98 -0
  389. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__6fe5e6c8._.js → [root-of-the-server]__35457394._.js} +2 -2
  390. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1f054c65._.js → [root-of-the-server]__35de78e6._.js} +3 -3
  391. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3685ffcb._.js +98 -0
  392. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__614458b7._.js → [root-of-the-server]__38954988._.js} +3 -3
  393. package/.next/standalone/.next/server/chunks/[root-of-the-server]__426ad936._.js +106 -0
  394. package/.next/standalone/.next/server/chunks/[root-of-the-server]__4985c034._.js +98 -0
  395. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5c6ce9ed._.js +98 -0
  396. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5cebe58a._.js +98 -0
  397. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5d5e4789._.js +98 -0
  398. package/.next/standalone/.next/server/chunks/[root-of-the-server]__65676930._.js +3 -0
  399. package/.next/standalone/.next/server/chunks/[root-of-the-server]__67cab326._.js +58 -0
  400. package/.next/standalone/.next/server/chunks/[root-of-the-server]__698c6f01._.js +98 -0
  401. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6c64af29._.js +131 -0
  402. package/.next/standalone/.next/server/chunks/[root-of-the-server]__73aed9f5._.js +98 -0
  403. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__ac84b704._.js → [root-of-the-server]__79b6a9bb._.js} +3 -3
  404. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__e56abacf._.js → [root-of-the-server]__7db704c6._.js} +4 -4
  405. package/.next/standalone/.next/server/chunks/[root-of-the-server]__812ca02b._.js +98 -0
  406. package/.next/standalone/.next/server/chunks/[root-of-the-server]__821f50fa._.js +98 -0
  407. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8716b86e._.js +98 -0
  408. package/.next/standalone/.next/server/chunks/[root-of-the-server]__884ef754._.js +98 -0
  409. package/.next/standalone/.next/server/chunks/[root-of-the-server]__88cdbd68._.js +98 -0
  410. package/.next/standalone/.next/server/chunks/[root-of-the-server]__89d9aba9._.js +98 -0
  411. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8d536cb5._.js +98 -0
  412. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8df8c5d1._.js +98 -0
  413. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__2d7a454e._.js → [root-of-the-server]__8f2ccc41._.js} +3 -3
  414. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__2a2c5fc5._.js → [root-of-the-server]__95c9d682._.js} +4 -4
  415. package/.next/standalone/.next/server/chunks/[root-of-the-server]__9e5d7774._.js +98 -0
  416. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__cc6e2885._.js → [root-of-the-server]__9edcff87._.js} +2 -2
  417. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a049dfc2._.js +98 -0
  418. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a5b4bb9a._.js +98 -0
  419. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__929ea03a._.js → [root-of-the-server]__a83262a1._.js} +2 -2
  420. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a9cd1240._.js +98 -0
  421. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a9d7f822._.js +98 -0
  422. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ad08c221._.js +98 -0
  423. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ad585f2f._.js +98 -0
  424. package/.next/standalone/.next/server/chunks/[root-of-the-server]__afcb8f7d._.js +98 -0
  425. package/.next/standalone/.next/server/chunks/[root-of-the-server]__bc250d43._.js +98 -0
  426. package/.next/standalone/.next/server/chunks/[root-of-the-server]__bce2a6e7._.js +98 -0
  427. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c011bf91._.js +98 -0
  428. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c0ac2895._.js +3 -0
  429. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c130a00c._.js +1 -1
  430. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c37d6380._.js +3 -0
  431. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cae392eb._.js +98 -0
  432. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cc2616bb._.js +3 -3
  433. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d501fa9b._.js +98 -0
  434. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d59c6c15._.js +98 -0
  435. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d5c1db32._.js +98 -0
  436. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d5d92527._.js +1 -1
  437. package/.next/standalone/.next/server/chunks/[root-of-the-server]__dba60c86._.js +98 -0
  438. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__2384f98e._.js → [root-of-the-server]__de14b9ae._.js} +3 -3
  439. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e10643d1._.js +98 -0
  440. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__00fdfbda._.js → [root-of-the-server]__e2a996e5._.js} +2 -2
  441. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__4d903941._.js → [root-of-the-server]__e3477417._.js} +3 -3
  442. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__32dc5513._.js → [root-of-the-server]__e4db362e._.js} +2 -2
  443. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__49e42a3a._.js → [root-of-the-server]__e4e70b86._.js} +3 -3
  444. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__ac39ecc7._.js → [root-of-the-server]__e54925af._.js} +3 -3
  445. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e8edc5b0._.js +98 -0
  446. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__eafd040b._.js → [root-of-the-server]__eab4d83b._.js} +2 -2
  447. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ead29015._.js +1 -1
  448. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__194955d4._.js → [root-of-the-server]__f056fd83._.js} +3 -3
  449. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f0e99572._.js +98 -0
  450. package/.next/standalone/.next/server/chunks/[root-of-the-server]__fe1e16d0._.js +98 -0
  451. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ff9cd277._.js +98 -0
  452. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ffaea2ce._.js +98 -0
  453. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_wizard_chart_route_actions_888e2ec1.js +3 -0
  454. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__2cffc362._.js +3 -0
  455. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__f1050870._.js → [root-of-the-server]__47c97637._.js} +2 -2
  456. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__66aca5d4._.js +1 -1
  457. package/.next/standalone/.next/server/chunks/ssr/_17b946fd._.js +3 -0
  458. package/.next/standalone/.next/server/chunks/ssr/_2a1d79e7._.js +1 -1
  459. package/.next/standalone/.next/server/chunks/ssr/_5c3c4cfa._.js +7 -5
  460. package/.next/standalone/.next/server/chunks/ssr/_ba432382._.js +7 -5
  461. package/.next/standalone/.next/server/chunks/ssr/src_app_(desktop)_cortex_page_tsx_0f33d8b3._.js +1 -1
  462. package/.next/standalone/.next/server/chunks/ssr/src_app_(desktop)_terminal_page_tsx_de5e8d85._.js +4 -4
  463. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__90eeddae._.js +1 -1
  464. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  465. package/.next/standalone/.next/server/pages/404.html +1 -1
  466. package/.next/standalone/.next/server/pages/500.html +2 -2
  467. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  468. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  469. package/.next/standalone/.next/static/chunks/0852575eb90c1e8d.js +85 -0
  470. package/.next/standalone/.next/static/chunks/{74d0ac0b1d0a1b79.js → 10b00b4f66102dcf.js} +1 -1
  471. package/.next/standalone/.next/static/chunks/{16eb77953dee9ea3.js → 19c71a8376c23c58.js} +1 -1
  472. package/.next/standalone/.next/static/chunks/2b769d1597e4fc1c.css +3 -0
  473. package/.next/standalone/.next/static/chunks/{3e91fc608659c524.js → 350271fe79509caf.js} +1 -1
  474. package/.next/standalone/.next/static/chunks/{70423c7afd8abf5f.js → 597847c22200c212.js} +1 -1
  475. package/.next/standalone/.next/static/chunks/{fb0abd1933b2b2e1.js → 7f6a14f1849fa94d.js} +1 -1
  476. package/.next/standalone/.next/static/chunks/{7ecd9bbb0ce4d68a.js → b7c8fe9b7275a84f.js} +1 -1
  477. package/.next/standalone/.next/static/chunks/{6245135a7afb8c7b.js → c9b10fc55516d142.js} +8 -6
  478. package/.next/standalone/.next/static/chunks/d0065f48eab94944.js +1 -0
  479. package/.next/standalone/.next/static/chunks/{180c1b9ff31b979f.js → f7b34c807badf95d.js} +8 -6
  480. package/.next/standalone/.spaces/cortex-context.md +50 -144
  481. package/.next/standalone/LICENSE +661 -661
  482. package/.next/standalone/NOTICE +5 -5
  483. package/.next/standalone/README.md +131 -131
  484. package/.next/standalone/bin/cortex-hook.js +79 -79
  485. package/.next/standalone/bin/cortex-hook.sh +62 -62
  486. package/.next/standalone/bin/cortex-learn-hook.js +138 -138
  487. package/.next/standalone/bin/cortex-mcp.js +60 -60
  488. package/.next/standalone/bin/cortex-pi-extension.ts +170 -170
  489. package/.next/standalone/bin/fix-standalone-externals.js +79 -79
  490. package/.next/standalone/bin/lib/auto-setup.js +110 -110
  491. package/.next/standalone/bin/mdns-service.js +171 -171
  492. package/.next/standalone/bin/postinstall.js +35 -35
  493. package/.next/standalone/bin/setup-admin.js +195 -195
  494. package/.next/standalone/bin/spaces-dev.js +247 -247
  495. package/.next/standalone/bin/spaces-install.js +660 -660
  496. package/.next/standalone/bin/spaces-postinstall.js +50 -50
  497. package/.next/standalone/bin/spaces-reset-totp.js +50 -50
  498. package/.next/standalone/bin/spaces-service.js +1046 -1046
  499. package/.next/standalone/bin/spaces-setup.js +253 -253
  500. package/.next/standalone/bin/spaces.js +808 -805
  501. package/.next/standalone/bin/ssh-auth-keys.sh +68 -68
  502. package/.next/standalone/bin/terminal-server.js +2819 -2781
  503. package/.next/standalone/cortex-hook-debug.log +57 -23
  504. package/.next/standalone/docker-compose.yml +28 -28
  505. package/.next/standalone/docs/architecture.md +387 -387
  506. package/.next/standalone/docs/cortex-integration-reference.md +268 -268
  507. package/.next/standalone/docs/cortex.md +293 -293
  508. package/.next/standalone/docs/getting-started.md +96 -96
  509. package/.next/standalone/docs/plans/2026-02-24-multi-agent-sessions-design.md +133 -133
  510. package/.next/standalone/docs/plans/2026-02-24-multi-agent-sessions-plan.md +959 -959
  511. package/.next/standalone/docs/plans/2026-03-02-security-audit.md +229 -229
  512. package/.next/standalone/docs/plans/2026-03-07-service-command-design.md +146 -146
  513. package/.next/standalone/docs/plans/2026-03-07-service-command-plan.md +254 -254
  514. package/.next/standalone/docs/server-install.md +564 -564
  515. package/.next/standalone/docs/social-card.html +150 -150
  516. package/.next/standalone/docs/superpowers/plans/2026-03-12-spaces-cortex.md +5270 -5270
  517. package/.next/standalone/docs/superpowers/plans/2026-03-13-cortex-wiring.md +1387 -1387
  518. package/.next/standalone/docs/superpowers/plans/2026-03-14-cortex-v2-entity-graph.md +1923 -1923
  519. package/.next/standalone/docs/superpowers/plans/2026-03-14-cortex-v2-knowledge-evolution.md +1113 -1113
  520. package/.next/standalone/docs/superpowers/plans/2026-03-15-cortex-v2-boundary-engine.md +853 -853
  521. package/.next/standalone/docs/superpowers/plans/2026-03-15-cortex-v2-context-engine.md +1274 -1274
  522. package/.next/standalone/docs/superpowers/plans/2026-03-15-cortex-v2-signal-ingestion.md +933 -933
  523. package/.next/standalone/docs/superpowers/plans/2026-03-16-cortex-lobes.md +1080 -1080
  524. package/.next/standalone/docs/superpowers/plans/2026-03-16-cortex-v2-gravity-system.md +768 -768
  525. package/.next/standalone/docs/superpowers/plans/2026-03-16-cortex-v2-ui.md +1108 -1108
  526. package/.next/standalone/docs/superpowers/plans/2026-03-18-cortex-ui-integration.md +1846 -1846
  527. package/.next/standalone/docs/superpowers/plans/2026-03-19-vr-phase1-shell.md +1639 -1639
  528. package/.next/standalone/docs/superpowers/plans/2026-03-27-dockview-pane-layout.md +98 -98
  529. package/.next/standalone/docs/superpowers/specs/2026-03-11-universe-view-design.md +320 -320
  530. package/.next/standalone/docs/superpowers/specs/2026-03-12-spaces-brain-design.md +720 -720
  531. package/.next/standalone/docs/superpowers/specs/2026-03-13-cortex-wiring-design.md +268 -268
  532. package/.next/standalone/docs/superpowers/specs/2026-03-14-cortex-v2-design.md +623 -623
  533. package/.next/standalone/docs/superpowers/specs/2026-03-16-cortex-lobes-design.md +263 -263
  534. package/.next/standalone/docs/superpowers/specs/2026-03-16-cortex-v2-ui-design.md +240 -240
  535. package/.next/standalone/docs/superpowers/specs/2026-03-16-pane-ux-design.md +77 -77
  536. package/.next/standalone/docs/superpowers/specs/2026-03-18-cortex-ui-integration-design.md +341 -341
  537. package/.next/standalone/docs/superpowers/specs/2026-03-19-vr-phase1-shell-design.md +288 -288
  538. package/.next/standalone/docs/superpowers/specs/2026-03-27-pane-diff-review-and-project-wizard-design.md +322 -322
  539. package/.next/standalone/docs/tiers.md +104 -104
  540. package/.next/standalone/eslint.config.mjs +18 -18
  541. package/.next/standalone/next.config.ts +20 -20
  542. package/.next/standalone/nginx.conf +53 -53
  543. package/.next/standalone/node_modules/@img/sharp-win32-x64/lib/sharp-win32-x64.node +0 -0
  544. package/.next/standalone/node_modules/@img/{sharp-linux-x64 → sharp-win32-x64}/package.json +39 -46
  545. package/.next/standalone/package-lock.json +14985 -14986
  546. package/.next/standalone/package.json +111 -111
  547. package/.next/standalone/postcss.config.mjs +7 -7
  548. package/.next/standalone/scripts/rebuild.cmd +65 -65
  549. package/.next/standalone/scripts/rebuild.sh +59 -59
  550. package/.next/standalone/server.js +1 -1
  551. package/.next/standalone/src/app/(desktop)/admin/analytics/page.tsx +266 -266
  552. package/.next/standalone/src/app/(desktop)/admin/users/page.tsx +399 -399
  553. package/.next/standalone/src/app/(desktop)/analytics/page.tsx +166 -166
  554. package/.next/standalone/src/app/(desktop)/cortex/page.tsx +81 -81
  555. package/.next/standalone/src/app/(desktop)/dashboard-client.tsx +56 -56
  556. package/.next/standalone/src/app/(desktop)/layout.tsx +18 -18
  557. package/.next/standalone/src/app/(desktop)/network/page.tsx +137 -137
  558. package/.next/standalone/src/app/(desktop)/page.tsx +17 -17
  559. package/.next/standalone/src/app/(desktop)/projects/page.tsx +68 -68
  560. package/.next/standalone/src/app/(desktop)/sessions/[id]/page.tsx +519 -519
  561. package/.next/standalone/src/app/(desktop)/sessions/page.tsx +145 -145
  562. package/.next/standalone/src/app/(desktop)/settings/page.tsx +446 -446
  563. package/.next/standalone/src/app/(desktop)/terminal/layout.tsx +7 -7
  564. package/.next/standalone/src/app/(desktop)/terminal/page.tsx +1330 -1291
  565. package/.next/standalone/src/app/(desktop)/terminal/pane/[id]/page.tsx +211 -211
  566. package/.next/standalone/src/app/(desktop)/terminal/remote/[nodeId]/[workspaceId]/page.tsx +252 -252
  567. package/.next/standalone/src/app/(desktop)/workspaces/page.tsx +12 -12
  568. package/.next/standalone/src/app/api/admin/analytics/route.ts +10 -10
  569. package/.next/standalone/src/app/api/admin/users/[id]/route.ts +20 -20
  570. package/.next/standalone/src/app/api/admin/users/route.ts +15 -15
  571. package/.next/standalone/src/app/api/analytics/overview/route.ts +80 -80
  572. package/.next/standalone/src/app/api/auth/login/route.ts +10 -10
  573. package/.next/standalone/src/app/api/auth/logout/route.ts +9 -9
  574. package/.next/standalone/src/app/api/auth/me/route.ts +22 -22
  575. package/.next/standalone/src/app/api/auth/totp/setup/route.ts +10 -10
  576. package/.next/standalone/src/app/api/auth/totp/status/route.ts +10 -10
  577. package/.next/standalone/src/app/api/auth/totp/verify/route.ts +10 -10
  578. package/.next/standalone/src/app/api/benchmark/lobes/route.ts +16 -16
  579. package/.next/standalone/src/app/api/benchmark/run/route.ts +113 -92
  580. package/.next/standalone/src/app/api/benchmark/runs/[id]/route.ts +26 -26
  581. package/.next/standalone/src/app/api/benchmark/runs/route.ts +16 -16
  582. package/.next/standalone/src/app/api/benchmark/status/route.ts +35 -35
  583. package/.next/standalone/src/app/api/bulk/route.ts +34 -34
  584. package/.next/standalone/src/app/api/chat/route.ts +85 -85
  585. package/.next/standalone/src/app/api/config/route.ts +30 -30
  586. package/.next/standalone/src/app/api/cortex/context/route.ts +78 -78
  587. package/.next/standalone/src/app/api/cortex/curation/assess/route.ts +27 -27
  588. package/.next/standalone/src/app/api/cortex/curation/publish/route.ts +23 -23
  589. package/.next/standalone/src/app/api/cortex/curation/refine/route.ts +23 -23
  590. package/.next/standalone/src/app/api/cortex/curation/review/route.ts +29 -29
  591. package/.next/standalone/src/app/api/cortex/curation/seed/route.ts +23 -23
  592. package/.next/standalone/src/app/api/cortex/export/route.ts +40 -40
  593. package/.next/standalone/src/app/api/cortex/federation/pending/route.ts +20 -20
  594. package/.next/standalone/src/app/api/cortex/federation/resolve/route.ts +43 -43
  595. package/.next/standalone/src/app/api/cortex/federation/search/route.ts +35 -35
  596. package/.next/standalone/src/app/api/cortex/federation/teach/route.ts +76 -76
  597. package/.next/standalone/src/app/api/cortex/graph/edges/route.ts +112 -112
  598. package/.next/standalone/src/app/api/cortex/graph/entities/[id]/route.ts +73 -73
  599. package/.next/standalone/src/app/api/cortex/graph/entities/route.ts +75 -75
  600. package/.next/standalone/src/app/api/cortex/graph/populate/route.ts +203 -203
  601. package/.next/standalone/src/app/api/cortex/import/route.ts +75 -75
  602. package/.next/standalone/src/app/api/cortex/import/status/route.ts +15 -15
  603. package/.next/standalone/src/app/api/cortex/ingest/bootstrap/route.ts +39 -39
  604. package/.next/standalone/src/app/api/cortex/ingest/status/route.ts +15 -15
  605. package/.next/standalone/src/app/api/cortex/knowledge/[id]/route.ts +91 -91
  606. package/.next/standalone/src/app/api/cortex/knowledge/route.ts +97 -97
  607. package/.next/standalone/src/app/api/cortex/lobes/[id]/route.ts +67 -67
  608. package/.next/standalone/src/app/api/cortex/lobes/route.ts +22 -22
  609. package/.next/standalone/src/app/api/cortex/lobes/share/route.ts +80 -80
  610. package/.next/standalone/src/app/api/cortex/marketplace/browse/route.ts +43 -43
  611. package/.next/standalone/src/app/api/cortex/marketplace/preview/route.ts +46 -46
  612. package/.next/standalone/src/app/api/cortex/mcp/call/route.ts +11 -11
  613. package/.next/standalone/src/app/api/cortex/mcp/tools/route.ts +8 -8
  614. package/.next/standalone/src/app/api/cortex/search/route.ts +57 -45
  615. package/.next/standalone/src/app/api/cortex/settings/route.ts +35 -35
  616. package/.next/standalone/src/app/api/cortex/status/route.ts +169 -169
  617. package/.next/standalone/src/app/api/cortex/timeline/route.ts +42 -42
  618. package/.next/standalone/src/app/api/cortex/usage/route.ts +31 -31
  619. package/.next/standalone/src/app/api/cortex/workspace/[id]/context/route.ts +41 -41
  620. package/.next/standalone/src/app/api/events/route.ts +40 -40
  621. package/.next/standalone/src/app/api/files/route.ts +187 -187
  622. package/.next/standalone/src/app/api/folders/route.ts +107 -97
  623. package/.next/standalone/src/app/api/network/connect-callback/route.ts +11 -11
  624. package/.next/standalone/src/app/api/network/connect-request/[id]/route.ts +11 -11
  625. package/.next/standalone/src/app/api/network/connect-request/route.ts +17 -17
  626. package/.next/standalone/src/app/api/network/discovered/route.ts +9 -9
  627. package/.next/standalone/src/app/api/network/handshake/route.ts +25 -25
  628. package/.next/standalone/src/app/api/network/health/route.ts +10 -10
  629. package/.next/standalone/src/app/api/network/identity/route.ts +15 -15
  630. package/.next/standalone/src/app/api/network/keys/[id]/route.ts +10 -10
  631. package/.next/standalone/src/app/api/network/keys/route.ts +15 -15
  632. package/.next/standalone/src/app/api/network/nodes/[id]/route.ts +15 -15
  633. package/.next/standalone/src/app/api/network/nodes/check/route.ts +9 -9
  634. package/.next/standalone/src/app/api/network/nodes/route.ts +15 -15
  635. package/.next/standalone/src/app/api/network/panes/[id]/route.ts +78 -62
  636. package/.next/standalone/src/app/api/network/panes/route.ts +61 -50
  637. package/.next/standalone/src/app/api/network/projects/route.ts +32 -25
  638. package/.next/standalone/src/app/api/network/proxy/[nodeId]/[...path]/route.ts +25 -25
  639. package/.next/standalone/src/app/api/network/search/route.ts +45 -38
  640. package/.next/standalone/src/app/api/network/sessions/[id]/messages/route.ts +43 -36
  641. package/.next/standalone/src/app/api/network/sessions/[id]/route.ts +41 -34
  642. package/.next/standalone/src/app/api/network/sessions/route.ts +50 -43
  643. package/.next/standalone/src/app/api/network/terminal/token/route.ts +10 -10
  644. package/.next/standalone/src/app/api/network/workspaces/[id]/route.ts +80 -71
  645. package/.next/standalone/src/app/api/network/workspaces/route.ts +87 -85
  646. package/.next/standalone/src/app/api/panes/[id]/diff/route.ts +121 -121
  647. package/.next/standalone/src/app/api/panes/[id]/route.ts +60 -60
  648. package/.next/standalone/src/app/api/panes/route.ts +39 -39
  649. package/.next/standalone/src/app/api/projects/route.ts +13 -13
  650. package/.next/standalone/src/app/api/proxy/models/[modelId]/[...path]/route.ts +80 -80
  651. package/.next/standalone/src/app/api/proxy/models/[modelId]/status/route.ts +33 -33
  652. package/.next/standalone/src/app/api/search/route.ts +47 -47
  653. package/.next/standalone/src/app/api/sessions/[id]/chat/route.ts +120 -120
  654. package/.next/standalone/src/app/api/sessions/[id]/messages/route.ts +34 -34
  655. package/.next/standalone/src/app/api/sessions/[id]/route.ts +73 -73
  656. package/.next/standalone/src/app/api/sessions/route.ts +64 -64
  657. package/.next/standalone/src/app/api/sync/route.ts +24 -24
  658. package/.next/standalone/src/app/api/tags/route.ts +35 -35
  659. package/.next/standalone/src/app/api/tier/route.ts +16 -16
  660. package/.next/standalone/src/app/api/updates/route.ts +65 -65
  661. package/.next/standalone/src/app/api/whisper/config/route.ts +50 -42
  662. package/.next/standalone/src/app/api/whisper/route.ts +91 -91
  663. package/.next/standalone/src/app/api/wizard/chart/route.ts +129 -0
  664. package/.next/standalone/src/app/api/wizard/chat/route.ts +113 -113
  665. package/.next/standalone/src/app/api/workspaces/[id]/context/[key]/route.ts +39 -39
  666. package/.next/standalone/src/app/api/workspaces/[id]/context/route.ts +28 -28
  667. package/.next/standalone/src/app/api/workspaces/[id]/messages/[msgId]/route.ts +17 -17
  668. package/.next/standalone/src/app/api/workspaces/[id]/messages/route.ts +39 -39
  669. package/.next/standalone/src/app/api/workspaces/[id]/route.ts +47 -47
  670. package/.next/standalone/src/app/api/workspaces/[id]/sessions/route.ts +62 -62
  671. package/.next/standalone/src/app/api/workspaces/route.ts +79 -79
  672. package/.next/standalone/src/app/globals.css +88 -88
  673. package/.next/standalone/src/app/layout.tsx +33 -33
  674. package/.next/standalone/src/app/login/layout.tsx +7 -7
  675. package/.next/standalone/src/app/login/page.tsx +315 -315
  676. package/.next/standalone/src/app/m/layout.tsx +16 -16
  677. package/.next/standalone/src/app/m/page.tsx +118 -118
  678. package/.next/standalone/src/app/m/projects/page.tsx +64 -64
  679. package/.next/standalone/src/app/m/sessions/[id]/page.tsx +168 -168
  680. package/.next/standalone/src/app/m/sessions/page.tsx +177 -177
  681. package/.next/standalone/src/app/m/settings/page.tsx +230 -230
  682. package/.next/standalone/src/app/m/terminal/page.tsx +413 -413
  683. package/.next/standalone/src/app/vr/page.tsx +21 -21
  684. package/.next/standalone/src/app/vr/vr-app.tsx +163 -163
  685. package/.next/standalone/src/app/vr/vr-controls.tsx +139 -139
  686. package/.next/standalone/src/app/vr/vr-door.tsx +82 -82
  687. package/.next/standalone/src/app/vr/vr-environment.tsx +71 -71
  688. package/.next/standalone/src/app/vr/vr-gaze.tsx +89 -89
  689. package/.next/standalone/src/app/vr/vr-layout.ts +49 -49
  690. package/.next/standalone/src/app/vr/vr-lobby.tsx +97 -97
  691. package/.next/standalone/src/app/vr/vr-pane.tsx +195 -195
  692. package/.next/standalone/src/app/vr/vr-room.tsx +79 -79
  693. package/.next/standalone/src/app/vr/vr-terminal.tsx +303 -303
  694. package/.next/standalone/src/components/auth/totp-gate.tsx +183 -183
  695. package/.next/standalone/src/components/bus/activity-panel.tsx +261 -261
  696. package/.next/standalone/src/components/common/color-picker.tsx +35 -35
  697. package/.next/standalone/src/components/common/dev-directory-picker.tsx +339 -339
  698. package/.next/standalone/src/components/common/folder-picker.tsx +200 -200
  699. package/.next/standalone/src/components/common/tag-picker.tsx +190 -190
  700. package/.next/standalone/src/components/common/workspace-picker.tsx +113 -113
  701. package/.next/standalone/src/components/cortex/benchmark-tab.tsx +894 -880
  702. package/.next/standalone/src/components/cortex/constants.ts +29 -29
  703. package/.next/standalone/src/components/cortex/cortex-dashboard.tsx +304 -304
  704. package/.next/standalone/src/components/cortex/cortex-indicator.tsx +44 -44
  705. package/.next/standalone/src/components/cortex/cortex-panel.tsx +140 -140
  706. package/.next/standalone/src/components/cortex/cortex-settings.tsx +280 -280
  707. package/.next/standalone/src/components/cortex/curation-tab.tsx +810 -810
  708. package/.next/standalone/src/components/cortex/entity-detail.tsx +101 -101
  709. package/.next/standalone/src/components/cortex/entity-graph.tsx +382 -382
  710. package/.next/standalone/src/components/cortex/import-dialog.tsx +212 -212
  711. package/.next/standalone/src/components/cortex/injection-badge.tsx +72 -72
  712. package/.next/standalone/src/components/cortex/knowledge-card.tsx +109 -109
  713. package/.next/standalone/src/components/cortex/knowledge-tab.tsx +158 -158
  714. package/.next/standalone/src/components/cortex/lobe-settings.tsx +215 -215
  715. package/.next/standalone/src/components/cortex/marketplace-card.tsx +126 -126
  716. package/.next/standalone/src/components/cortex/marketplace-tab.tsx +113 -113
  717. package/.next/standalone/src/components/dashboard/activity-chart.tsx +41 -41
  718. package/.next/standalone/src/components/dashboard/model-usage-chart.tsx +61 -61
  719. package/.next/standalone/src/components/dashboard/recent-sessions.tsx +68 -68
  720. package/.next/standalone/src/components/dashboard/stats-cards.tsx +36 -36
  721. package/.next/standalone/src/components/files/file-explorer.tsx +703 -703
  722. package/.next/standalone/src/components/layout/providers.tsx +38 -38
  723. package/.next/standalone/src/components/layout/sidebar.tsx +170 -170
  724. package/.next/standalone/src/components/layout/tier-provider.tsx +53 -53
  725. package/.next/standalone/src/components/layout/update-banner.tsx +92 -92
  726. package/.next/standalone/src/components/mobile/bottom-nav.tsx +46 -46
  727. package/.next/standalone/src/components/mobile/immersive-voice-button.tsx +123 -123
  728. package/.next/standalone/src/components/mobile/mobile-chat-input.tsx +244 -244
  729. package/.next/standalone/src/components/mobile/mobile-header.tsx +44 -44
  730. package/.next/standalone/src/components/mobile/mobile-session-card.tsx +56 -56
  731. package/.next/standalone/src/components/mobile/mobile-terminal-input.tsx +74 -74
  732. package/.next/standalone/src/components/mobile/mobile-terminal-pane.tsx +302 -302
  733. package/.next/standalone/src/components/mobile/mobile-terminal-toolbar.tsx +76 -76
  734. package/.next/standalone/src/components/mobile/pull-to-refresh.tsx +82 -82
  735. package/.next/standalone/src/components/mobile/voice-input.tsx +53 -53
  736. package/.next/standalone/src/components/network/api-key-list.tsx +190 -190
  737. package/.next/standalone/src/components/network/connection-requests.tsx +94 -94
  738. package/.next/standalone/src/components/network/node-add-dialog.tsx +131 -131
  739. package/.next/standalone/src/components/network/node-badge.tsx +26 -26
  740. package/.next/standalone/src/components/network/node-list.tsx +207 -207
  741. package/.next/standalone/src/components/network/node-selector.tsx +49 -49
  742. package/.next/standalone/src/components/sessions/session-filters.tsx +116 -116
  743. package/.next/standalone/src/components/sessions/session-list.tsx +485 -485
  744. package/.next/standalone/src/components/terminal/pane-diff-panel.tsx +179 -179
  745. package/.next/standalone/src/components/terminal/terminal-pane.tsx +1530 -1464
  746. package/.next/standalone/src/components/viewer/chat-input.tsx +275 -275
  747. package/.next/standalone/src/components/viewer/message-renderer.tsx +551 -551
  748. package/.next/standalone/src/components/wizard/chart-wizard.tsx +405 -0
  749. package/.next/standalone/src/components/wizard/project-wizard.tsx +153 -153
  750. package/.next/standalone/src/components/wizard/wizard-chat.tsx +99 -99
  751. package/.next/standalone/src/components/wizard/wizard-plan-summary.tsx +103 -103
  752. package/.next/standalone/src/components/wizard/wizard-review.tsx +225 -225
  753. package/.next/standalone/src/components/workspace/universe-cluster.tsx +131 -131
  754. package/.next/standalone/src/components/workspace/universe-orb.tsx +128 -128
  755. package/.next/standalone/src/components/workspace/universe-types.ts +22 -22
  756. package/.next/standalone/src/components/workspace/universe-utils.ts +11 -11
  757. package/.next/standalone/src/components/workspace/universe-view.tsx +397 -397
  758. package/.next/standalone/src/components/workspace/workspace-chooser.tsx +634 -634
  759. package/.next/standalone/src/hooks/use-benchmark.ts +72 -71
  760. package/.next/standalone/src/hooks/use-bus.ts +147 -147
  761. package/.next/standalone/src/hooks/use-idle-detection.ts +79 -79
  762. package/.next/standalone/src/hooks/use-network.ts +229 -229
  763. package/.next/standalone/src/hooks/use-sessions.ts +437 -437
  764. package/.next/standalone/src/hooks/use-speech-recognition.ts +114 -113
  765. package/.next/standalone/src/hooks/use-sse.ts +35 -35
  766. package/.next/standalone/src/hooks/use-tier.ts +39 -39
  767. package/.next/standalone/src/lib/agents.ts +97 -97
  768. package/.next/standalone/src/lib/aider/parser.ts +111 -111
  769. package/.next/standalone/src/lib/api.ts +19 -19
  770. package/.next/standalone/src/lib/auth.ts +47 -47
  771. package/.next/standalone/src/lib/claude/parser.ts +212 -212
  772. package/.next/standalone/src/lib/claude/stats.ts +204 -204
  773. package/.next/standalone/src/lib/codex/parser.test.ts +111 -111
  774. package/.next/standalone/src/lib/codex/parser.ts +287 -287
  775. package/.next/standalone/src/lib/config.ts +132 -132
  776. package/.next/standalone/src/lib/cortex/benchmark.ts +83 -67
  777. package/.next/standalone/src/lib/cortex/config.ts +42 -42
  778. package/.next/standalone/src/lib/cortex/debug.ts +10 -10
  779. package/.next/standalone/src/lib/cortex/distillation/usage-store.ts +18 -18
  780. package/.next/standalone/src/lib/cortex/graph/resolver.ts +10 -10
  781. package/.next/standalone/src/lib/cortex/graph/types.ts +22 -22
  782. package/.next/standalone/src/lib/cortex/index.ts +109 -56
  783. package/.next/standalone/src/lib/cortex/ingestion/bootstrap.ts +14 -14
  784. package/.next/standalone/src/lib/cortex/knowledge/compat.ts +14 -14
  785. package/.next/standalone/src/lib/cortex/knowledge/contradiction.ts +10 -10
  786. package/.next/standalone/src/lib/cortex/knowledge/types.ts +67 -67
  787. package/.next/standalone/src/lib/cortex/lobes/config.ts +16 -16
  788. package/.next/standalone/src/lib/cortex/lobes/resolver.ts +8 -8
  789. package/.next/standalone/src/lib/cortex/lobes/shares.ts +14 -14
  790. package/.next/standalone/src/lib/cortex/mcp/server.ts +12 -12
  791. package/.next/standalone/src/lib/cortex/portability/exporter.ts +6 -6
  792. package/.next/standalone/src/lib/cortex/portability/importer.ts +10 -10
  793. package/.next/standalone/src/lib/cortex/retrieval/context-engine.ts +10 -10
  794. package/.next/standalone/src/lib/cortex/types.ts +39 -39
  795. package/.next/standalone/src/lib/cost-calculator.ts +48 -48
  796. package/.next/standalone/src/lib/db/init.ts +71 -71
  797. package/.next/standalone/src/lib/db/queries.ts +740 -827
  798. package/.next/standalone/src/lib/db/schema.ts +206 -206
  799. package/.next/standalone/src/lib/events/sse.ts +36 -36
  800. package/.next/standalone/src/lib/forge/parser.ts +52 -52
  801. package/.next/standalone/src/lib/gemini/parser.ts +258 -258
  802. package/.next/standalone/src/lib/license.ts +56 -56
  803. package/.next/standalone/src/lib/pro.ts +31 -31
  804. package/.next/standalone/src/lib/shell-user.ts +101 -0
  805. package/.next/standalone/src/lib/sync/indexer.ts +504 -504
  806. package/.next/standalone/src/lib/sync/watcher.ts +64 -64
  807. package/.next/standalone/src/lib/teams.ts +31 -31
  808. package/.next/standalone/src/lib/telemetry.ts +75 -75
  809. package/.next/standalone/src/lib/terminal/server.ts +188 -188
  810. package/.next/standalone/src/lib/tier.ts +38 -38
  811. package/.next/standalone/src/lib/utils.ts +72 -72
  812. package/.next/standalone/src/lib/vms/manager.ts +121 -121
  813. package/.next/standalone/src/middleware.ts +133 -133
  814. package/.next/standalone/src/types/claude.ts +208 -208
  815. package/.next/standalone/src/types/network.ts +61 -61
  816. package/.next/standalone/tests/setup.ts +8 -8
  817. package/.next/standalone/tsconfig.json +34 -34
  818. package/.next/standalone/vitest.config.ts +24 -24
  819. package/LICENSE +661 -661
  820. package/README.md +131 -131
  821. package/bin/cortex-hook.js +79 -79
  822. package/bin/cortex-hook.sh +62 -62
  823. package/bin/cortex-learn-hook.js +138 -138
  824. package/bin/cortex-mcp.js +60 -60
  825. package/bin/cortex-pi-extension.ts +170 -170
  826. package/bin/fix-standalone-externals.js +79 -79
  827. package/bin/lib/auto-setup.js +110 -110
  828. package/bin/mdns-service.js +171 -171
  829. package/bin/postinstall.js +35 -35
  830. package/bin/setup-admin.js +195 -195
  831. package/bin/spaces-dev.js +247 -247
  832. package/bin/spaces-install.js +660 -660
  833. package/bin/spaces-postinstall.js +50 -50
  834. package/bin/spaces-reset-totp.js +50 -50
  835. package/bin/spaces-service.js +1046 -1046
  836. package/bin/spaces-setup.js +253 -253
  837. package/bin/spaces.js +808 -805
  838. package/bin/ssh-auth-keys.sh +68 -68
  839. package/bin/terminal-server.js +2819 -2781
  840. package/package.json +111 -111
  841. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0903a426._.js +0 -98
  842. package/.next/standalone/.next/server/chunks/[root-of-the-server]__09e8ccc9._.js +0 -98
  843. package/.next/standalone/.next/server/chunks/[root-of-the-server]__11c684b1._.js +0 -98
  844. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1572d4ef._.js +0 -98
  845. package/.next/standalone/.next/server/chunks/[root-of-the-server]__186cd0bb._.js +0 -3
  846. package/.next/standalone/.next/server/chunks/[root-of-the-server]__212760e6._.js +0 -98
  847. package/.next/standalone/.next/server/chunks/[root-of-the-server]__228595ec._.js +0 -98
  848. package/.next/standalone/.next/server/chunks/[root-of-the-server]__283c890f._.js +0 -3
  849. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2f300a68._.js +0 -98
  850. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2f452778._.js +0 -98
  851. package/.next/standalone/.next/server/chunks/[root-of-the-server]__35f8e77e._.js +0 -98
  852. package/.next/standalone/.next/server/chunks/[root-of-the-server]__379fc2e9._.js +0 -98
  853. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3b40d79f._.js +0 -98
  854. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3d3dca2b._.js +0 -98
  855. package/.next/standalone/.next/server/chunks/[root-of-the-server]__4d5b78d2._.js +0 -98
  856. package/.next/standalone/.next/server/chunks/[root-of-the-server]__54163e52._.js +0 -98
  857. package/.next/standalone/.next/server/chunks/[root-of-the-server]__563c0817._.js +0 -3
  858. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5812f90a._.js +0 -98
  859. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5c5e87f5._.js +0 -98
  860. package/.next/standalone/.next/server/chunks/[root-of-the-server]__60d15b16._.js +0 -98
  861. package/.next/standalone/.next/server/chunks/[root-of-the-server]__69d315e5._.js +0 -3
  862. package/.next/standalone/.next/server/chunks/[root-of-the-server]__71f29038._.js +0 -98
  863. package/.next/standalone/.next/server/chunks/[root-of-the-server]__74084e07._.js +0 -3
  864. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7921aa80._.js +0 -98
  865. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7e077dd8._.js +0 -98
  866. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7ebc4280._.js +0 -131
  867. package/.next/standalone/.next/server/chunks/[root-of-the-server]__857c60bb._.js +0 -98
  868. package/.next/standalone/.next/server/chunks/[root-of-the-server]__874fe565._.js +0 -98
  869. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8e2171f7._.js +0 -98
  870. package/.next/standalone/.next/server/chunks/[root-of-the-server]__95659b2d._.js +0 -98
  871. package/.next/standalone/.next/server/chunks/[root-of-the-server]__9679b91e._.js +0 -98
  872. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a90729a1._.js +0 -98
  873. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ad4346fa._.js +0 -98
  874. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b0862d69._.js +0 -98
  875. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b43306ee._.js +0 -98
  876. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b689ff5e._.js +0 -106
  877. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ba87daaa._.js +0 -98
  878. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c0461005._.js +0 -98
  879. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c1deb5f3._.js +0 -98
  880. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c8a62f42._.js +0 -98
  881. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cabaac2b._.js +0 -98
  882. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cb027619._.js +0 -98
  883. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cf608218._.js +0 -98
  884. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cfc1290d._.js +0 -98
  885. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d0109b9b._.js +0 -98
  886. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d0125483._.js +0 -3
  887. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d048ee6b._.js +0 -98
  888. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d12644e7._.js +0 -98
  889. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e3cc946c._.js +0 -98
  890. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e6fd27f8._.js +0 -98
  891. package/.next/standalone/.next/server/chunks/[root-of-the-server]__efb8251e._.js +0 -98
  892. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f44c6882._.js +0 -98
  893. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f85283de._.js +0 -98
  894. package/.next/standalone/.next/server/chunks/[root-of-the-server]__feceb3e4._.js +0 -98
  895. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__843070a6._.js +0 -3
  896. package/.next/standalone/.next/server/chunks/ssr/_e84a0c06._.js +0 -3
  897. package/.next/standalone/.next/static/chunks/470cade58d4eceeb.css +0 -3
  898. package/.next/standalone/.next/static/chunks/9d4164833c2c1fd6.js +0 -85
  899. package/.next/standalone/.next/static/chunks/f091f4bf8d80fd07.js +0 -1
  900. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/README.md +0 -46
  901. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h +0 -221
  902. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/index.js +0 -1
  903. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  904. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/package.json +0 -42
  905. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/README.md +0 -46
  906. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/glib-2.0/include/glibconfig.h +0 -221
  907. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/index.js +0 -1
  908. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  909. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +0 -42
  910. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/versions.json +0 -30
  911. package/.next/standalone/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node +0 -0
  912. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/lib/sharp-linuxmusl-x64.node +0 -0
  913. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/package.json +0 -46
  914. /package/.next/standalone/.next/static/{5S4TviTCiNiTjf6KjXjBo → u1pHON3drz1mBi7owkbBP}/_buildManifest.js +0 -0
  915. /package/.next/standalone/.next/static/{5S4TviTCiNiTjf6KjXjBo → u1pHON3drz1mBi7owkbBP}/_clientMiddlewareManifest.json +0 -0
  916. /package/.next/standalone/.next/static/{5S4TviTCiNiTjf6KjXjBo → u1pHON3drz1mBi7owkbBP}/_ssgManifest.js +0 -0
  917. /package/.next/standalone/node_modules/@img/{sharp-libvips-linux-x64 → sharp-win32-x64}/versions.json +0 -0
@@ -1,880 +1,894 @@
1
- 'use client';
2
-
3
- import { useState, useEffect, useRef } from 'react';
4
- import {
5
- BarChart,
6
- Bar,
7
- XAxis,
8
- YAxis,
9
- Tooltip,
10
- ResponsiveContainer,
11
- Cell,
12
- } from 'recharts';
13
- import { FlaskConical, ChevronDown, ChevronRight, Play, Loader2 } from 'lucide-react';
14
- import {
15
- useBenchmarkRuns,
16
- useBenchmarkRun,
17
- useBenchmarkLobes,
18
- useBenchmarkStatus,
19
- useStartBenchmark,
20
- } from '@/hooks/use-benchmark';
21
-
22
- interface BenchmarkRun {
23
- id: string;
24
- timestamp: string;
25
- model: string;
26
- preset: string;
27
- task_count: number;
28
- config: string;
29
- }
30
-
31
- interface BenchmarkRunSummary {
32
- runId: string;
33
- timestamp: string;
34
- model: string;
35
- preset: string;
36
- taskCount: number;
37
- avgTokenDelta: number;
38
- avgTokenDeltaPercent: number;
39
- avgQualityWithout: number;
40
- avgQualityWith: number;
41
- avgQualityImprovement: number;
42
- avgRetrievalRelevance: number;
43
- avgRetrievalLatencyMs: number;
44
- }
45
-
46
- interface CategoryBreakdown {
47
- category: string;
48
- taskCount: number;
49
- avgTokenDeltaPercent: number;
50
- avgQualityWithout: number;
51
- avgQualityWith: number;
52
- avgRetrievalRelevance: number;
53
- hitRate: number;
54
- }
55
-
56
- interface BenchmarkTaskResult {
57
- id: string;
58
- run_id: string;
59
- task_id: string;
60
- category: string;
61
- difficulty: string;
62
- status: string;
63
- tokens_without_input: number | null;
64
- tokens_without_output: number | null;
65
- tokens_with_input: number | null;
66
- tokens_with_output: number | null;
67
- tokens_delta: number | null;
68
- tokens_delta_percent: number | null;
69
- injection_tokens: number | null;
70
- quality_without: number | null;
71
- quality_with: number | null;
72
- quality_improvement: number | null;
73
- judge_confidence: number | null;
74
- retrieval_count: number | null;
75
- retrieval_avg_relevance: number | null;
76
- retrieval_latency_ms: number | null;
77
- duration_without_ms: number | null;
78
- duration_with_ms: number | null;
79
- }
80
-
81
- interface BenchmarkLobeScore {
82
- id: string;
83
- run_id: string;
84
- lobe_id: string;
85
- lobe_name: string;
86
- overall_score: number | null;
87
- token_savings: number | null;
88
- quality_improvement: number | null;
89
- coverage_score: number | null;
90
- category_strengths: string | null;
91
- badge_tier: string | null;
92
- marketplace_ready: number | null;
93
- }
94
-
95
- function StatCard({
96
- label,
97
- value,
98
- sub,
99
- color,
100
- }: {
101
- label: string;
102
- value: string;
103
- sub?: string;
104
- color?: string;
105
- }) {
106
- return (
107
- <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-3">
108
- <div className="text-[10px] text-gray-500 uppercase tracking-wider mb-1">{label}</div>
109
- <div className={`text-lg font-semibold tabular-nums ${color || 'text-white'}`}>{value}</div>
110
- {sub && <div className="text-[10px] text-gray-600 mt-0.5">{sub}</div>}
111
- </div>
112
- );
113
- }
114
-
115
- const CHART_TOOLTIP_STYLE = {
116
- background: '#0f0f11',
117
- border: '1px solid rgba(255,255,255,0.08)',
118
- borderRadius: '0.5rem',
119
- fontSize: '11px',
120
- color: '#d1d5db',
121
- };
122
-
123
- function deltaColor(pct: number): string {
124
- if (pct < -10) return '#22c55e';
125
- if (pct < 0) return '#86efac';
126
- if (pct < 5) return '#f59e0b';
127
- return '#ef4444';
128
- }
129
-
130
- function TaskRow({ result }: { result: BenchmarkTaskResult }) {
131
- const [open, setOpen] = useState(false);
132
- return (
133
- <div className="border border-white/[0.05] rounded-lg overflow-hidden">
134
- <button
135
- onClick={() => setOpen(v => !v)}
136
- className="w-full flex items-center gap-3 px-3 py-2 text-left hover:bg-white/[0.02] transition-colors"
137
- >
138
- <span className="text-gray-500">
139
- {open ? <ChevronDown className="w-3.5 h-3.5" /> : <ChevronRight className="w-3.5 h-3.5" />}
140
- </span>
141
- <span className="text-xs text-gray-300 font-mono flex-1 truncate" title={result.task_id}>
142
- {result.task_id}
143
- </span>
144
- <span className="text-[10px] text-gray-600 w-20">{result.category}</span>
145
- <span className="text-[10px] text-gray-600 w-12">{result.difficulty}</span>
146
- <span
147
- className="text-[10px] tabular-nums w-16 text-right"
148
- style={{ color: deltaColor(result.tokens_delta_percent ?? 0) }}
149
- >
150
- {result.tokens_delta_percent != null
151
- ? `${result.tokens_delta_percent > 0 ? '+' : ''}${result.tokens_delta_percent.toFixed(1)}%`
152
- : '—'}
153
- </span>
154
- <span className="text-[10px] text-gray-400 tabular-nums w-20 text-right">
155
- {result.quality_with != null ? result.quality_with.toFixed(2) : '—'}
156
- {' / '}
157
- {result.quality_without != null ? result.quality_without.toFixed(2) : '—'}
158
- </span>
159
- </button>
160
- {open && (
161
- <div className="px-8 pb-3 pt-1 grid grid-cols-2 md:grid-cols-4 gap-3 bg-white/[0.01] border-t border-white/[0.05]">
162
- <div>
163
- <div className="text-[9px] text-gray-600 uppercase mb-0.5">Tokens without</div>
164
- <div className="text-xs text-gray-300 tabular-nums">
165
- {result.tokens_without_input ?? '—'} in / {result.tokens_without_output ?? '—'} out
166
- </div>
167
- </div>
168
- <div>
169
- <div className="text-[9px] text-gray-600 uppercase mb-0.5">Tokens with</div>
170
- <div className="text-xs text-gray-300 tabular-nums">
171
- {result.tokens_with_input ?? '—'} in / {result.tokens_with_output ?? '—'} out
172
- </div>
173
- </div>
174
- <div>
175
- <div className="text-[9px] text-gray-600 uppercase mb-0.5">Injection</div>
176
- <div className="text-xs text-gray-300 tabular-nums">{result.injection_tokens ?? '—'} tokens</div>
177
- </div>
178
- <div>
179
- <div className="text-[9px] text-gray-600 uppercase mb-0.5">Retrieval</div>
180
- <div className="text-xs text-gray-300 tabular-nums">
181
- {result.retrieval_count ?? 0} hits
182
- {result.retrieval_avg_relevance != null
183
- ? ` · ${result.retrieval_avg_relevance.toFixed(3)} rel`
184
- : ''}
185
- {result.retrieval_latency_ms != null
186
- ? ` · ${result.retrieval_latency_ms.toFixed(0)}ms`
187
- : ''}
188
- </div>
189
- </div>
190
- <div>
191
- <div className="text-[9px] text-gray-600 uppercase mb-0.5">Quality improvement</div>
192
- <div
193
- className="text-xs tabular-nums"
194
- style={{
195
- color:
196
- (result.quality_improvement ?? 0) > 0
197
- ? '#22c55e'
198
- : (result.quality_improvement ?? 0) < 0
199
- ? '#ef4444'
200
- : '#6b7280',
201
- }}
202
- >
203
- {result.quality_improvement != null
204
- ? `${result.quality_improvement > 0 ? '+' : ''}${result.quality_improvement.toFixed(3)}`
205
- : '—'}
206
- </div>
207
- </div>
208
- <div>
209
- <div className="text-[9px] text-gray-600 uppercase mb-0.5">Judge confidence</div>
210
- <div className="text-xs text-gray-300 tabular-nums">
211
- {result.judge_confidence != null ? result.judge_confidence.toFixed(2) : '—'}
212
- </div>
213
- </div>
214
- <div>
215
- <div className="text-[9px] text-gray-600 uppercase mb-0.5">Duration without</div>
216
- <div className="text-xs text-gray-300 tabular-nums">
217
- {result.duration_without_ms != null ? `${result.duration_without_ms.toFixed(0)}ms` : '—'}
218
- </div>
219
- </div>
220
- <div>
221
- <div className="text-[9px] text-gray-600 uppercase mb-0.5">Duration with</div>
222
- <div className="text-xs text-gray-300 tabular-nums">
223
- {result.duration_with_ms != null ? `${result.duration_with_ms.toFixed(0)}ms` : '—'}
224
- </div>
225
- </div>
226
- </div>
227
- )}
228
- </div>
229
- );
230
- }
231
-
232
- function BadgePill({ tier }: { tier: string | null }) {
233
- if (!tier) return null;
234
- const colors: Record<string, string> = {
235
- gold: 'bg-yellow-500/20 text-yellow-300 border-yellow-500/30',
236
- silver: 'bg-gray-400/20 text-gray-300 border-gray-400/30',
237
- bronze: 'bg-orange-500/20 text-orange-300 border-orange-500/30',
238
- };
239
- const cls = colors[tier.toLowerCase()] || 'bg-purple-500/20 text-purple-300 border-purple-500/30';
240
- return (
241
- <span className={`text-[9px] px-1.5 py-0.5 rounded border font-medium uppercase ${cls}`}>
242
- {tier}
243
- </span>
244
- );
245
- }
246
-
247
- const BENCHMARK_CATEGORIES = [
248
- 'codebase-qa',
249
- 'bug-fixing',
250
- 'code-generation',
251
- 'refactoring',
252
- 'style-convention',
253
- 'decision-recall',
254
- 'cross-session',
255
- 'error-recovery',
256
- 'domain-knowledge',
257
- 'multi-layer',
258
- 'performance-optimization',
259
- 'api-integration',
260
- 'security-access',
261
- 'meta-self',
262
- 'lobe-specific',
263
- ];
264
-
265
- const PRESET_META: Record<string, { label: string; desc: string; tasks: string; time: string }> = {
266
- quick: {
267
- label: 'Quick Test',
268
- desc: 'Single task per category',
269
- tasks: '~15 tasks',
270
- time: '~3 min',
271
- },
272
- standard: {
273
- label: 'Standard',
274
- desc: '5 tasks per category',
275
- tasks: '~75 tasks',
276
- time: '~20 min',
277
- },
278
- full: {
279
- label: 'Comprehensive',
280
- desc: 'All tasks',
281
- tasks: '~156 tasks',
282
- time: '~1 hour',
283
- },
284
- };
285
-
286
- function ProgressBar({ current, total }: { current: number; total: number }) {
287
- const pct = total > 0 ? Math.round((current / total) * 100) : 0;
288
- return (
289
- <div className="w-full">
290
- <div className="flex items-center justify-between mb-1">
291
- <span className="text-[10px] text-gray-500 tabular-nums">
292
- {current} / {total > 0 ? total : '?'} tasks
293
- </span>
294
- <span className="text-[10px] text-gray-500 tabular-nums">{pct}%</span>
295
- </div>
296
- <div className="h-1.5 bg-white/[0.06] rounded-full overflow-hidden">
297
- <div
298
- className="h-full bg-purple-500 rounded-full transition-all duration-500"
299
- style={{ width: `${pct}%` }}
300
- />
301
- </div>
302
- </div>
303
- );
304
- }
305
-
306
- function RunLauncher({ onRunComplete }: { onRunComplete: () => void }) {
307
- const { data: status } = useBenchmarkStatus();
308
- const startBenchmark = useStartBenchmark();
309
-
310
- const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
311
- const [customModel, setCustomModel] = useState('claude-haiku-4-5');
312
- const [noJudge, setNoJudge] = useState(false);
313
- const [showCustom, setShowCustom] = useState(false);
314
-
315
- const isRunning = status?.running === true;
316
-
317
- // When a run transitions from running -> finished, trigger refresh of runs list
318
- const prevRunningRef = useRef<boolean | undefined>(undefined);
319
- useEffect(() => {
320
- if (prevRunningRef.current === true && !isRunning && status?.exitCode != null) {
321
- onRunComplete();
322
- }
323
- prevRunningRef.current = isRunning;
324
- }, [isRunning, status?.exitCode, onRunComplete]);
325
-
326
- function handlePreset(preset: string) {
327
- startBenchmark.mutate({ preset });
328
- }
329
-
330
- function handleCustomRun() {
331
- startBenchmark.mutate({
332
- preset: 'custom',
333
- categories: selectedCategories.length > 0 ? selectedCategories.join(',') : undefined,
334
- noJudge,
335
- model: customModel,
336
- });
337
- }
338
-
339
- function toggleCategory(cat: string) {
340
- setSelectedCategories(prev =>
341
- prev.includes(cat) ? prev.filter(c => c !== cat) : [...prev, cat],
342
- );
343
- }
344
-
345
- const lastLines = status?.output
346
- ? status.output
347
- .split('\n')
348
- .filter((l: string) => l.trim().length > 0)
349
- .slice(-6)
350
- : [];
351
-
352
- if (isRunning) {
353
- return (
354
- <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-4 space-y-3">
355
- <div className="flex items-center justify-between">
356
- <div className="flex items-center gap-2">
357
- <Loader2 className="w-3.5 h-3.5 text-purple-400 animate-spin" />
358
- <span className="text-xs font-medium text-gray-300">
359
- Benchmark running {status?.preset}
360
- {status?.categories && status.categories !== 'all' ? ` (${status.categories})` : ''}
361
- </span>
362
- </div>
363
- <span className="text-[10px] text-gray-600 font-mono">
364
- {status?.model}
365
- </span>
366
- </div>
367
-
368
- <ProgressBar
369
- current={status?.progress?.current ?? 0}
370
- total={status?.progress?.total ?? 0}
371
- />
372
-
373
- {lastLines.length > 0 && (
374
- <div className="bg-black/30 rounded-md p-3 font-mono text-[10px] text-gray-500 space-y-0.5 max-h-28 overflow-y-auto">
375
- {lastLines.map((line: string, i: number) => (
376
- <div key={i} className="leading-relaxed">{line}</div>
377
- ))}
378
- </div>
379
- )}
380
- </div>
381
- );
382
- }
383
-
384
- // Not running — show launcher
385
- const startError = (startBenchmark.data as any)?.error;
386
-
387
- return (
388
- <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg overflow-hidden">
389
- <div className="px-4 py-3 border-b border-white/[0.05]">
390
- <h3 className="text-xs font-medium text-gray-400">Run Benchmark</h3>
391
- </div>
392
-
393
- <div className="p-4 space-y-2">
394
- {/* Preset buttons */}
395
- {Object.entries(PRESET_META).map(([preset, meta]) => (
396
- <div
397
- key={preset}
398
- className="flex items-center justify-between px-3 py-2.5 rounded-lg border border-white/[0.05] hover:border-white/[0.10] hover:bg-white/[0.02] transition-colors"
399
- >
400
- <div className="min-w-0">
401
- <div className="flex items-center gap-2">
402
- <span className="text-xs font-medium text-gray-300">{meta.label}</span>
403
- <span className="text-[10px] text-gray-600">{meta.desc}</span>
404
- </div>
405
- <div className="text-[10px] text-gray-600 mt-0.5 tabular-nums">
406
- {meta.tasks} &middot; {meta.time}
407
- </div>
408
- </div>
409
- <button
410
- onClick={() => handlePreset(preset)}
411
- disabled={startBenchmark.isPending}
412
- className="ml-4 flex items-center gap-1.5 px-3 py-1 text-[11px] font-medium rounded-md bg-purple-600/20 text-purple-300 border border-purple-500/20 hover:bg-purple-600/30 hover:border-purple-500/40 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shrink-0"
413
- >
414
- <Play className="w-2.5 h-2.5" />
415
- Run
416
- </button>
417
- </div>
418
- ))}
419
-
420
- {/* Custom section toggle */}
421
- <div className="pt-1">
422
- <button
423
- onClick={() => setShowCustom(v => !v)}
424
- className="flex items-center gap-1.5 text-[11px] text-gray-500 hover:text-gray-400 transition-colors"
425
- >
426
- {showCustom ? <ChevronDown className="w-3 h-3" /> : <ChevronRight className="w-3 h-3" />}
427
- Custom
428
- </button>
429
-
430
- {showCustom && (
431
- <div className="mt-3 space-y-3 pl-1">
432
- {/* Category checkboxes */}
433
- <div>
434
- <div className="text-[10px] text-gray-600 uppercase tracking-wider mb-2">Categories</div>
435
- <div className="flex flex-wrap gap-1.5">
436
- {BENCHMARK_CATEGORIES.map(cat => {
437
- const active = selectedCategories.includes(cat);
438
- return (
439
- <button
440
- key={cat}
441
- onClick={() => toggleCategory(cat)}
442
- className={`px-2 py-0.5 text-[10px] rounded border transition-colors ${
443
- active
444
- ? 'bg-purple-500/20 text-purple-300 border-purple-500/30'
445
- : 'bg-white/[0.03] text-gray-500 border-white/[0.06] hover:text-gray-400 hover:border-white/[0.10]'
446
- }`}
447
- >
448
- {cat}
449
- </button>
450
- );
451
- })}
452
- </div>
453
- {selectedCategories.length === 0 && (
454
- <div className="text-[10px] text-gray-600 mt-1">None selected = all categories</div>
455
- )}
456
- </div>
457
-
458
- {/* Model + noJudge row */}
459
- <div className="flex items-center gap-4">
460
- <div>
461
- <div className="text-[10px] text-gray-600 uppercase tracking-wider mb-1">Model</div>
462
- <select
463
- value={customModel}
464
- onChange={e => setCustomModel(e.target.value)}
465
- className="px-2.5 py-1 text-xs bg-white/5 border border-white/10 rounded-md text-gray-300 focus:outline-none focus:border-purple-500/50"
466
- >
467
- <option value="claude-haiku-4-5">claude-haiku-4-5</option>
468
- <option value="claude-sonnet-4-5">claude-sonnet-4-5</option>
469
- <option value="claude-opus-4-5">claude-opus-4-5</option>
470
- </select>
471
- </div>
472
-
473
- <div className="flex items-center gap-2 mt-4">
474
- <input
475
- id="no-judge"
476
- type="checkbox"
477
- checked={noJudge}
478
- onChange={e => setNoJudge(e.target.checked)}
479
- className="w-3.5 h-3.5 rounded accent-purple-500"
480
- />
481
- <label htmlFor="no-judge" className="text-[11px] text-gray-400 cursor-pointer">
482
- Skip judge
483
- </label>
484
- </div>
485
- </div>
486
-
487
- {/* Run custom */}
488
- <button
489
- onClick={handleCustomRun}
490
- disabled={startBenchmark.isPending}
491
- className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md bg-purple-600/20 text-purple-300 border border-purple-500/20 hover:bg-purple-600/30 hover:border-purple-500/40 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
492
- >
493
- <Play className="w-3 h-3" />
494
- Run Custom
495
- </button>
496
- </div>
497
- )}
498
- </div>
499
-
500
- {startError && (
501
- <div className="text-[11px] text-red-400 bg-red-500/10 border border-red-500/20 rounded-md px-3 py-2">
502
- {startError}
503
- </div>
504
- )}
505
-
506
- {status && !isRunning && status.exitCode != null && (
507
- <div className="text-[11px] text-gray-500 bg-white/[0.02] border border-white/[0.05] rounded-md px-3 py-2">
508
- Last run finished — exit code {status.exitCode}
509
- {status.exitCode === 0 ? ' (success)' : ' (error)'}
510
- </div>
511
- )}
512
- </div>
513
- </div>
514
- );
515
- }
516
-
517
- export function BenchmarkTab() {
518
- const { data: runsData, isLoading: runsLoading, refetch: refetchRuns } = useBenchmarkRuns();
519
- const runs: BenchmarkRun[] = runsData?.runs ?? [];
520
- const [selectedRunId, setSelectedRunId] = useState<string | null>(null);
521
-
522
- // Default to latest run once loaded
523
- const effectiveRunId = selectedRunId ?? runs[0]?.id ?? null;
524
-
525
- const { data: runDetail, isLoading: detailLoading } = useBenchmarkRun(effectiveRunId);
526
- const { data: lobesData } = useBenchmarkLobes();
527
-
528
- const summary: BenchmarkRunSummary | null = runDetail?.summary ?? null;
529
- const categories: CategoryBreakdown[] = runDetail?.categories ?? [];
530
- const results: BenchmarkTaskResult[] = runDetail?.results ?? [];
531
- const lobes: BenchmarkLobeScore[] = lobesData?.lobes ?? [];
532
-
533
- const noData = !runsLoading && runs.length === 0;
534
-
535
- if (runsLoading) {
536
- return (
537
- <div className="p-6 max-w-5xl space-y-6">
538
- <RunLauncher onRunComplete={() => refetchRuns()} />
539
- <div className="text-sm text-gray-500">Loading benchmark data...</div>
540
- </div>
541
- );
542
- }
543
-
544
- if (noData) {
545
- return (
546
- <div className="p-6 max-w-5xl space-y-6">
547
- <RunLauncher onRunComplete={() => refetchRuns()} />
548
- <div className="flex flex-col items-center justify-center gap-4 py-16 text-gray-600">
549
- <FlaskConical className="w-10 h-10" />
550
- <p className="text-sm text-center max-w-xs">
551
- No benchmark data yet. Use the launcher above or run{' '}
552
- <span className="text-gray-500 font-mono text-xs">npm run benchmark</span>
553
- {' '}to generate results.
554
- </p>
555
- </div>
556
- </div>
557
- );
558
- }
559
-
560
- const tokenDeltaChartData = categories.map(c => ({
561
- name: c.category,
562
- delta: parseFloat(c.avgTokenDeltaPercent.toFixed(1)),
563
- }));
564
-
565
- const qualityChartData = categories.map(c => ({
566
- name: c.category,
567
- without: parseFloat(c.avgQualityWithout.toFixed(3)),
568
- with: parseFloat(c.avgQualityWith.toFixed(3)),
569
- }));
570
-
571
- const hitRateChartData = [...categories]
572
- .sort((a, b) => b.hitRate - a.hitRate)
573
- .map(c => ({
574
- name: c.category,
575
- hitRate: parseFloat((c.hitRate * 100).toFixed(1)),
576
- }));
577
-
578
- return (
579
- <div className="p-6 max-w-5xl space-y-6">
580
- {/* Run launcher */}
581
- <RunLauncher onRunComplete={() => refetchRuns()} />
582
-
583
- {/* Run selector */}
584
- <div className="flex items-center gap-3">
585
- <label className="text-[11px] text-gray-500 shrink-0">Run</label>
586
- <select
587
- value={effectiveRunId ?? ''}
588
- onChange={e => setSelectedRunId(e.target.value || null)}
589
- className="px-3 py-1.5 text-xs bg-white/5 border border-white/10 rounded-lg text-gray-300 focus:outline-none focus:border-purple-500/50"
590
- >
591
- {runs.map((r: BenchmarkRun) => (
592
- <option key={r.id} value={r.id}>
593
- {new Date(r.timestamp).toLocaleString()} {r.model} ({r.preset}, {r.task_count} tasks)
594
- </option>
595
- ))}
596
- </select>
597
- </div>
598
-
599
- {/* Overview stat cards */}
600
- {summary && (
601
- <div className="grid grid-cols-2 md:grid-cols-5 gap-3">
602
- <StatCard
603
- label="Avg Token Delta"
604
- value={
605
- summary.avgTokenDeltaPercent != null
606
- ? `${summary.avgTokenDeltaPercent > 0 ? '+' : ''}${summary.avgTokenDeltaPercent.toFixed(1)}%`
607
- : ''
608
- }
609
- sub="vs baseline"
610
- color={
611
- summary.avgTokenDeltaPercent < 0
612
- ? 'text-green-400'
613
- : summary.avgTokenDeltaPercent < 5
614
- ? 'text-amber-400'
615
- : 'text-red-400'
616
- }
617
- />
618
- <StatCard
619
- label="Quality (with)"
620
- value={summary.avgQualityWith.toFixed(2)}
621
- sub="avg LLM judge score"
622
- color="text-purple-400"
623
- />
624
- <StatCard
625
- label="Quality (without)"
626
- value={summary.avgQualityWithout.toFixed(2)}
627
- sub="baseline"
628
- />
629
- <StatCard
630
- label="Tasks"
631
- value={summary.taskCount.toString()}
632
- sub={`${categories.length} categories`}
633
- />
634
- <StatCard
635
- label="Avg Retrieval"
636
- value={
637
- summary.avgRetrievalLatencyMs
638
- ? `${summary.avgRetrievalLatencyMs.toFixed(0)}ms`
639
- : '—'
640
- }
641
- sub={
642
- summary.avgRetrievalRelevance
643
- ? `${summary.avgRetrievalRelevance.toFixed(3)} relevance`
644
- : 'relevance'
645
- }
646
- />
647
- </div>
648
- )}
649
-
650
- {detailLoading && (
651
- <div className="text-sm text-gray-500">Loading run details...</div>
652
- )}
653
-
654
- {/* Category breakdown table */}
655
- {categories.length > 0 && (
656
- <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg overflow-hidden">
657
- <div className="px-4 py-3 border-b border-white/[0.05]">
658
- <h3 className="text-xs font-medium text-gray-400">Category Breakdown</h3>
659
- </div>
660
- <div className="overflow-x-auto">
661
- <table className="w-full text-xs">
662
- <thead>
663
- <tr className="border-b border-white/[0.05]">
664
- <th className="px-4 py-2 text-left text-[10px] text-gray-500 uppercase tracking-wider">Category</th>
665
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Tasks</th>
666
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Token Delta</th>
667
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Quality w/o</th>
668
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Quality with</th>
669
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Hit Rate</th>
670
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Relevance</th>
671
- </tr>
672
- </thead>
673
- <tbody>
674
- {categories.map((cat, i) => (
675
- <tr
676
- key={cat.category}
677
- className={`border-b border-white/[0.03] ${i % 2 === 0 ? '' : 'bg-white/[0.01]'}`}
678
- >
679
- <td className="px-4 py-2 text-gray-300">{cat.category}</td>
680
- <td className="px-4 py-2 text-right text-gray-400 tabular-nums">{cat.taskCount}</td>
681
- <td
682
- className="px-4 py-2 text-right tabular-nums font-medium"
683
- style={{ color: deltaColor(cat.avgTokenDeltaPercent) }}
684
- >
685
- {cat.avgTokenDeltaPercent > 0 ? '+' : ''}
686
- {cat.avgTokenDeltaPercent.toFixed(1)}%
687
- </td>
688
- <td className="px-4 py-2 text-right text-gray-400 tabular-nums">
689
- {cat.avgQualityWithout.toFixed(2)}
690
- </td>
691
- <td className="px-4 py-2 text-right text-gray-300 tabular-nums font-medium">
692
- {cat.avgQualityWith.toFixed(2)}
693
- </td>
694
- <td className="px-4 py-2 text-right text-gray-400 tabular-nums">
695
- {(cat.hitRate * 100).toFixed(0)}%
696
- </td>
697
- <td className="px-4 py-2 text-right text-gray-400 tabular-nums">
698
- {cat.avgRetrievalRelevance.toFixed(3)}
699
- </td>
700
- </tr>
701
- ))}
702
- </tbody>
703
- </table>
704
- </div>
705
- </div>
706
- )}
707
-
708
- {/* Charts row */}
709
- {categories.length > 0 && (
710
- <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
711
- {/* Token delta by category */}
712
- <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-4">
713
- <h3 className="text-xs font-medium text-gray-400 mb-3">Token Delta % by Category</h3>
714
- <ResponsiveContainer width="100%" height={160}>
715
- <BarChart data={tokenDeltaChartData} margin={{ top: 4, right: 4, bottom: 4, left: 0 }}>
716
- <XAxis dataKey="name" tick={{ fontSize: 10, fill: '#6b7280' }} />
717
- <YAxis tick={{ fontSize: 10, fill: '#6b7280' }} />
718
- <Tooltip
719
- contentStyle={CHART_TOOLTIP_STYLE}
720
- formatter={(v: any) => [`${v > 0 ? '+' : ''}${v}%`, 'Token delta']}
721
- />
722
- <Bar dataKey="delta" radius={[2, 2, 0, 0]}>
723
- {tokenDeltaChartData.map((entry, i) => (
724
- <Cell key={i} fill={deltaColor(entry.delta)} />
725
- ))}
726
- </Bar>
727
- </BarChart>
728
- </ResponsiveContainer>
729
- </div>
730
-
731
- {/* Quality comparison */}
732
- <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-4">
733
- <h3 className="text-xs font-medium text-gray-400 mb-3">Quality Score by Category</h3>
734
- <div className="flex items-center gap-4 mb-2">
735
- <span className="flex items-center gap-1 text-[10px] text-gray-500">
736
- <span className="w-2 h-2 rounded-sm inline-block" style={{ background: '#6b7280' }} />
737
- Without
738
- </span>
739
- <span className="flex items-center gap-1 text-[10px] text-gray-500">
740
- <span className="w-2 h-2 rounded-sm inline-block" style={{ background: '#7c3aed' }} />
741
- With Cortex
742
- </span>
743
- </div>
744
- <ResponsiveContainer width="100%" height={160}>
745
- <BarChart data={qualityChartData} margin={{ top: 4, right: 4, bottom: 4, left: 0 }}>
746
- <XAxis dataKey="name" tick={{ fontSize: 10, fill: '#6b7280' }} />
747
- <YAxis domain={[0, 1]} tick={{ fontSize: 10, fill: '#6b7280' }} />
748
- <Tooltip contentStyle={CHART_TOOLTIP_STYLE} />
749
- <Bar dataKey="without" fill="#4b5563" radius={[2, 2, 0, 0]} />
750
- <Bar dataKey="with" fill="#7c3aed" radius={[2, 2, 0, 0]} />
751
- </BarChart>
752
- </ResponsiveContainer>
753
- </div>
754
-
755
- {/* Hit rate */}
756
- <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-4 md:col-span-2">
757
- <h3 className="text-xs font-medium text-gray-400 mb-3">Knowledge Retrieval Hit Rate %</h3>
758
- <ResponsiveContainer width="100%" height={120}>
759
- <BarChart
760
- data={hitRateChartData}
761
- layout="vertical"
762
- margin={{ top: 4, right: 4, bottom: 4, left: 60 }}
763
- >
764
- <XAxis type="number" domain={[0, 100]} tick={{ fontSize: 10, fill: '#6b7280' }} />
765
- <YAxis
766
- type="category"
767
- dataKey="name"
768
- tick={{ fontSize: 10, fill: '#6b7280' }}
769
- width={56}
770
- />
771
- <Tooltip
772
- contentStyle={CHART_TOOLTIP_STYLE}
773
- formatter={(v: any) => [`${v}%`, 'Hit rate']}
774
- />
775
- <Bar dataKey="hitRate" fill="#06b6d4" radius={[0, 2, 2, 0]} />
776
- </BarChart>
777
- </ResponsiveContainer>
778
- </div>
779
- </div>
780
- )}
781
-
782
- {/* Lobe scores */}
783
- {lobes.length > 0 && (
784
- <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg overflow-hidden">
785
- <div className="px-4 py-3 border-b border-white/[0.05]">
786
- <h3 className="text-xs font-medium text-gray-400">Lobe Scores</h3>
787
- </div>
788
- <div className="overflow-x-auto">
789
- <table className="w-full text-xs">
790
- <thead>
791
- <tr className="border-b border-white/[0.05]">
792
- <th className="px-4 py-2 text-left text-[10px] text-gray-500 uppercase tracking-wider">Lobe</th>
793
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Overall</th>
794
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Token Savings</th>
795
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Quality +</th>
796
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Coverage</th>
797
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Badge</th>
798
- <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Marketplace</th>
799
- </tr>
800
- </thead>
801
- <tbody>
802
- {lobes.map((lobe, i) => (
803
- <tr
804
- key={lobe.id}
805
- className={`border-b border-white/[0.03] ${i % 2 === 0 ? '' : 'bg-white/[0.01]'}`}
806
- >
807
- <td className="px-4 py-2">
808
- <div className="text-gray-300">{lobe.lobe_name}</div>
809
- <div className="text-[9px] text-gray-600 font-mono">{lobe.lobe_id}</div>
810
- </td>
811
- <td className="px-4 py-2 text-right text-purple-400 tabular-nums font-medium">
812
- {lobe.overall_score != null ? lobe.overall_score.toFixed(2) : '—'}
813
- </td>
814
- <td
815
- className="px-4 py-2 text-right tabular-nums"
816
- style={{ color: (lobe.token_savings ?? 0) > 0 ? '#22c55e' : '#6b7280' }}
817
- >
818
- {lobe.token_savings != null
819
- ? `${lobe.token_savings > 0 ? '+' : ''}${lobe.token_savings.toFixed(1)}%`
820
- : '—'}
821
- </td>
822
- <td
823
- className="px-4 py-2 text-right tabular-nums"
824
- style={{ color: (lobe.quality_improvement ?? 0) > 0 ? '#22c55e' : '#6b7280' }}
825
- >
826
- {lobe.quality_improvement != null
827
- ? `${lobe.quality_improvement > 0 ? '+' : ''}${lobe.quality_improvement.toFixed(3)}`
828
- : '—'}
829
- </td>
830
- <td className="px-4 py-2 text-right text-gray-400 tabular-nums">
831
- {lobe.coverage_score != null ? lobe.coverage_score.toFixed(2) : '—'}
832
- </td>
833
- <td className="px-4 py-2 text-right">
834
- <BadgePill tier={lobe.badge_tier} />
835
- </td>
836
- <td className="px-4 py-2 text-right">
837
- {lobe.marketplace_ready ? (
838
- <span className="text-[9px] px-1.5 py-0.5 rounded border bg-green-500/10 text-green-400 border-green-500/20">
839
- Ready
840
- </span>
841
- ) : (
842
- <span className="text-[9px] text-gray-600">—</span>
843
- )}
844
- </td>
845
- </tr>
846
- ))}
847
- </tbody>
848
- </table>
849
- </div>
850
- </div>
851
- )}
852
-
853
- {/* Task results */}
854
- {results.length > 0 && (
855
- <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg overflow-hidden">
856
- <div className="px-4 py-3 border-b border-white/[0.05] flex items-center justify-between">
857
- <h3 className="text-xs font-medium text-gray-400">Task Results</h3>
858
- <span className="text-[10px] text-gray-600">{results.length} tasks</span>
859
- </div>
860
- <div className="px-4 py-2">
861
- {/* Column headers */}
862
- <div className="flex items-center gap-3 px-3 py-1 mb-1">
863
- <span className="w-3.5" />
864
- <span className="text-[9px] text-gray-600 uppercase tracking-wider flex-1">Task ID</span>
865
- <span className="text-[9px] text-gray-600 uppercase tracking-wider w-20">Category</span>
866
- <span className="text-[9px] text-gray-600 uppercase tracking-wider w-12">Diff</span>
867
- <span className="text-[9px] text-gray-600 uppercase tracking-wider w-16 text-right">Token %</span>
868
- <span className="text-[9px] text-gray-600 uppercase tracking-wider w-20 text-right">Quality w/w</span>
869
- </div>
870
- <div className="space-y-1">
871
- {results.map(r => (
872
- <TaskRow key={r.id} result={r} />
873
- ))}
874
- </div>
875
- </div>
876
- </div>
877
- )}
878
- </div>
879
- );
880
- }
1
+ 'use client';
2
+
3
+ import { useState, useEffect, useRef } from 'react';
4
+ import {
5
+ BarChart,
6
+ Bar,
7
+ XAxis,
8
+ YAxis,
9
+ Tooltip,
10
+ ResponsiveContainer,
11
+ Cell,
12
+ } from 'recharts';
13
+ import { FlaskConical, ChevronDown, ChevronRight, Play, Loader2 } from 'lucide-react';
14
+ import {
15
+ useBenchmarkRuns,
16
+ useBenchmarkRun,
17
+ useBenchmarkLobes,
18
+ useBenchmarkStatus,
19
+ useStartBenchmark,
20
+ } from '@/hooks/use-benchmark';
21
+
22
+ interface BenchmarkRun {
23
+ id: string;
24
+ timestamp: string;
25
+ model: string;
26
+ preset: string;
27
+ task_count: number;
28
+ config: string;
29
+ }
30
+
31
+ interface BenchmarkRunSummary {
32
+ runId: string;
33
+ timestamp: string;
34
+ model: string;
35
+ preset: string;
36
+ taskCount: number;
37
+ avgTokenDelta: number;
38
+ avgTokenDeltaPercent: number;
39
+ avgQualityWithout: number;
40
+ avgQualityWith: number;
41
+ avgQualityImprovement: number;
42
+ avgRetrievalRelevance: number;
43
+ avgRetrievalLatencyMs: number;
44
+ }
45
+
46
+ interface CategoryBreakdown {
47
+ category: string;
48
+ taskCount: number;
49
+ avgTokenDeltaPercent: number;
50
+ avgQualityWithout: number;
51
+ avgQualityWith: number;
52
+ avgRetrievalRelevance: number;
53
+ hitRate: number;
54
+ }
55
+
56
+ interface BenchmarkTaskResult {
57
+ id: string;
58
+ run_id: string;
59
+ task_id: string;
60
+ category: string;
61
+ difficulty: string;
62
+ status: string;
63
+ tokens_without_input: number | null;
64
+ tokens_without_output: number | null;
65
+ tokens_with_input: number | null;
66
+ tokens_with_output: number | null;
67
+ tokens_delta: number | null;
68
+ tokens_delta_percent: number | null;
69
+ injection_tokens: number | null;
70
+ quality_without: number | null;
71
+ quality_with: number | null;
72
+ quality_improvement: number | null;
73
+ judge_confidence: number | null;
74
+ retrieval_count: number | null;
75
+ retrieval_avg_relevance: number | null;
76
+ retrieval_latency_ms: number | null;
77
+ duration_without_ms: number | null;
78
+ duration_with_ms: number | null;
79
+ }
80
+
81
+ interface BenchmarkLobeScore {
82
+ id: string;
83
+ run_id: string;
84
+ lobe_id: string;
85
+ lobe_name: string;
86
+ overall_score: number | null;
87
+ token_savings: number | null;
88
+ quality_improvement: number | null;
89
+ coverage_score: number | null;
90
+ category_strengths: string | null;
91
+ badge_tier: string | null;
92
+ marketplace_ready: number | null;
93
+ }
94
+
95
+ function StatCard({
96
+ label,
97
+ value,
98
+ sub,
99
+ color,
100
+ }: {
101
+ label: string;
102
+ value: string;
103
+ sub?: string;
104
+ color?: string;
105
+ }) {
106
+ return (
107
+ <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-3">
108
+ <div className="text-[10px] text-gray-500 uppercase tracking-wider mb-1">{label}</div>
109
+ <div className={`text-lg font-semibold tabular-nums ${color || 'text-white'}`}>{value}</div>
110
+ {sub && <div className="text-[10px] text-gray-600 mt-0.5">{sub}</div>}
111
+ </div>
112
+ );
113
+ }
114
+
115
+ const CHART_TOOLTIP_STYLE = {
116
+ background: '#0f0f11',
117
+ border: '1px solid rgba(255,255,255,0.08)',
118
+ borderRadius: '0.5rem',
119
+ fontSize: '11px',
120
+ color: '#d1d5db',
121
+ };
122
+
123
+ function deltaColor(pct: number): string {
124
+ if (pct < -10) return '#22c55e';
125
+ if (pct < 0) return '#86efac';
126
+ if (pct < 5) return '#f59e0b';
127
+ return '#ef4444';
128
+ }
129
+
130
+ function TaskRow({ result }: { result: BenchmarkTaskResult }) {
131
+ const [open, setOpen] = useState(false);
132
+ return (
133
+ <div className="border border-white/[0.05] rounded-lg overflow-hidden">
134
+ <button
135
+ onClick={() => setOpen(v => !v)}
136
+ className="w-full flex items-center gap-3 px-3 py-2 text-left hover:bg-white/[0.02] transition-colors"
137
+ >
138
+ <span className="text-gray-500">
139
+ {open ? <ChevronDown className="w-3.5 h-3.5" /> : <ChevronRight className="w-3.5 h-3.5" />}
140
+ </span>
141
+ <span className="text-xs text-gray-300 font-mono flex-1 truncate" title={result.task_id}>
142
+ {result.task_id}
143
+ </span>
144
+ <span className="text-[10px] text-gray-600 w-20">{result.category}</span>
145
+ <span className="text-[10px] text-gray-600 w-12">{result.difficulty}</span>
146
+ <span
147
+ className="text-[10px] tabular-nums w-16 text-right"
148
+ style={{ color: deltaColor(result.tokens_delta_percent ?? 0) }}
149
+ >
150
+ {result.tokens_delta_percent != null
151
+ ? `${result.tokens_delta_percent > 0 ? '+' : ''}${result.tokens_delta_percent.toFixed(1)}%`
152
+ : '—'}
153
+ </span>
154
+ <span className="text-[10px] text-gray-400 tabular-nums w-20 text-right">
155
+ {result.quality_with != null ? result.quality_with.toFixed(2) : '—'}
156
+ {' / '}
157
+ {result.quality_without != null ? result.quality_without.toFixed(2) : '—'}
158
+ </span>
159
+ </button>
160
+ {open && (
161
+ <div className="px-8 pb-3 pt-1 grid grid-cols-2 md:grid-cols-4 gap-3 bg-white/[0.01] border-t border-white/[0.05]">
162
+ <div>
163
+ <div className="text-[9px] text-gray-600 uppercase mb-0.5">Tokens without</div>
164
+ <div className="text-xs text-gray-300 tabular-nums">
165
+ {result.tokens_without_input ?? '—'} in / {result.tokens_without_output ?? '—'} out
166
+ </div>
167
+ </div>
168
+ <div>
169
+ <div className="text-[9px] text-gray-600 uppercase mb-0.5">Tokens with</div>
170
+ <div className="text-xs text-gray-300 tabular-nums">
171
+ {result.tokens_with_input ?? '—'} in / {result.tokens_with_output ?? '—'} out
172
+ </div>
173
+ </div>
174
+ <div>
175
+ <div className="text-[9px] text-gray-600 uppercase mb-0.5">Injection</div>
176
+ <div className="text-xs text-gray-300 tabular-nums">{result.injection_tokens ?? '—'} tokens</div>
177
+ </div>
178
+ <div>
179
+ <div className="text-[9px] text-gray-600 uppercase mb-0.5">Retrieval</div>
180
+ <div className="text-xs text-gray-300 tabular-nums">
181
+ {result.retrieval_count ?? 0} hits
182
+ {result.retrieval_avg_relevance != null
183
+ ? ` · ${result.retrieval_avg_relevance.toFixed(3)} rel`
184
+ : ''}
185
+ {result.retrieval_latency_ms != null
186
+ ? ` · ${result.retrieval_latency_ms.toFixed(0)}ms`
187
+ : ''}
188
+ </div>
189
+ </div>
190
+ <div>
191
+ <div className="text-[9px] text-gray-600 uppercase mb-0.5">Quality improvement</div>
192
+ <div
193
+ className="text-xs tabular-nums"
194
+ style={{
195
+ color:
196
+ (result.quality_improvement ?? 0) > 0
197
+ ? '#22c55e'
198
+ : (result.quality_improvement ?? 0) < 0
199
+ ? '#ef4444'
200
+ : '#6b7280',
201
+ }}
202
+ >
203
+ {result.quality_improvement != null
204
+ ? `${result.quality_improvement > 0 ? '+' : ''}${result.quality_improvement.toFixed(3)}`
205
+ : '—'}
206
+ </div>
207
+ </div>
208
+ <div>
209
+ <div className="text-[9px] text-gray-600 uppercase mb-0.5">Judge confidence</div>
210
+ <div className="text-xs text-gray-300 tabular-nums">
211
+ {result.judge_confidence != null ? result.judge_confidence.toFixed(2) : '—'}
212
+ </div>
213
+ </div>
214
+ <div>
215
+ <div className="text-[9px] text-gray-600 uppercase mb-0.5">Duration without</div>
216
+ <div className="text-xs text-gray-300 tabular-nums">
217
+ {result.duration_without_ms != null ? `${result.duration_without_ms.toFixed(0)}ms` : '—'}
218
+ </div>
219
+ </div>
220
+ <div>
221
+ <div className="text-[9px] text-gray-600 uppercase mb-0.5">Duration with</div>
222
+ <div className="text-xs text-gray-300 tabular-nums">
223
+ {result.duration_with_ms != null ? `${result.duration_with_ms.toFixed(0)}ms` : '—'}
224
+ </div>
225
+ </div>
226
+ </div>
227
+ )}
228
+ </div>
229
+ );
230
+ }
231
+
232
+ function BadgePill({ tier }: { tier: string | null }) {
233
+ if (!tier) return null;
234
+ const colors: Record<string, string> = {
235
+ gold: 'bg-yellow-500/20 text-yellow-300 border-yellow-500/30',
236
+ silver: 'bg-gray-400/20 text-gray-300 border-gray-400/30',
237
+ bronze: 'bg-orange-500/20 text-orange-300 border-orange-500/30',
238
+ };
239
+ const cls = colors[tier.toLowerCase()] || 'bg-purple-500/20 text-purple-300 border-purple-500/30';
240
+ return (
241
+ <span className={`text-[9px] px-1.5 py-0.5 rounded border font-medium uppercase ${cls}`}>
242
+ {tier}
243
+ </span>
244
+ );
245
+ }
246
+
247
+ const BENCHMARK_CATEGORIES = [
248
+ 'codebase-qa',
249
+ 'bug-fixing',
250
+ 'code-generation',
251
+ 'refactoring',
252
+ 'style-convention',
253
+ 'decision-recall',
254
+ 'cross-session',
255
+ 'error-recovery',
256
+ 'domain-knowledge',
257
+ 'multi-layer',
258
+ 'performance-optimization',
259
+ 'api-integration',
260
+ 'security-access',
261
+ 'meta-self',
262
+ 'lobe-specific',
263
+ ];
264
+
265
+ const PRESET_META: Record<string, { label: string; desc: string; tasks: string; time: string }> = {
266
+ quick: {
267
+ label: 'Quick Test',
268
+ desc: 'Single task per category',
269
+ tasks: '~15 tasks',
270
+ time: '~3 min',
271
+ },
272
+ standard: {
273
+ label: 'Standard',
274
+ desc: '5 tasks per category',
275
+ tasks: '~75 tasks',
276
+ time: '~20 min',
277
+ },
278
+ full: {
279
+ label: 'Comprehensive',
280
+ desc: 'All tasks',
281
+ tasks: '~156 tasks',
282
+ time: '~1 hour',
283
+ },
284
+ };
285
+
286
+ function ProgressBar({ current, total }: { current: number; total: number }) {
287
+ const pct = total > 0 ? Math.round((current / total) * 100) : 0;
288
+ return (
289
+ <div className="w-full">
290
+ <div className="flex items-center justify-between mb-1">
291
+ <span className="text-[10px] text-gray-500 tabular-nums">
292
+ {current} / {total > 0 ? total : '?'} tasks
293
+ </span>
294
+ <span className="text-[10px] text-gray-500 tabular-nums">{pct}%</span>
295
+ </div>
296
+ <div className="h-1.5 bg-white/[0.06] rounded-full overflow-hidden">
297
+ <div
298
+ className="h-full bg-purple-500 rounded-full transition-all duration-500"
299
+ style={{ width: `${pct}%` }}
300
+ />
301
+ </div>
302
+ </div>
303
+ );
304
+ }
305
+
306
+ function RunLauncher({ onRunComplete }: { onRunComplete: () => void }) {
307
+ const { data: status } = useBenchmarkStatus();
308
+ const startBenchmark = useStartBenchmark();
309
+
310
+ const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
311
+ const [customModel, setCustomModel] = useState('claude-haiku-4-5');
312
+ const [noJudge, setNoJudge] = useState(false);
313
+ const [concurrency, setConcurrency] = useState(1);
314
+ const [showCustom, setShowCustom] = useState(false);
315
+
316
+ const isRunning = status?.running === true;
317
+
318
+ // When a run transitions from running -> finished, trigger refresh of runs list
319
+ const prevRunningRef = useRef<boolean | undefined>(undefined);
320
+ useEffect(() => {
321
+ if (prevRunningRef.current === true && !isRunning && status?.exitCode != null) {
322
+ onRunComplete();
323
+ }
324
+ prevRunningRef.current = isRunning;
325
+ }, [isRunning, status?.exitCode, onRunComplete]);
326
+
327
+ function handlePreset(preset: string) {
328
+ startBenchmark.mutate({ preset });
329
+ }
330
+
331
+ function handleCustomRun() {
332
+ startBenchmark.mutate({
333
+ preset: 'custom',
334
+ categories: selectedCategories.length > 0 ? selectedCategories.join(',') : undefined,
335
+ noJudge,
336
+ model: customModel,
337
+ concurrency,
338
+ });
339
+ }
340
+
341
+ function toggleCategory(cat: string) {
342
+ setSelectedCategories(prev =>
343
+ prev.includes(cat) ? prev.filter(c => c !== cat) : [...prev, cat],
344
+ );
345
+ }
346
+
347
+ const lastLines = status?.output
348
+ ? status.output
349
+ .split('\n')
350
+ .filter((l: string) => l.trim().length > 0)
351
+ .slice(-6)
352
+ : [];
353
+
354
+ if (isRunning) {
355
+ return (
356
+ <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-4 space-y-3">
357
+ <div className="flex items-center justify-between">
358
+ <div className="flex items-center gap-2">
359
+ <Loader2 className="w-3.5 h-3.5 text-purple-400 animate-spin" />
360
+ <span className="text-xs font-medium text-gray-300">
361
+ Benchmark running — {status?.preset}
362
+ {status?.categories && status.categories !== 'all' ? ` (${status.categories})` : ''}
363
+ </span>
364
+ </div>
365
+ <span className="text-[10px] text-gray-600 font-mono">
366
+ {status?.model}
367
+ </span>
368
+ </div>
369
+
370
+ <ProgressBar
371
+ current={status?.progress?.current ?? 0}
372
+ total={status?.progress?.total ?? 0}
373
+ />
374
+
375
+ {lastLines.length > 0 && (
376
+ <div className="bg-black/30 rounded-md p-3 font-mono text-[10px] text-gray-500 space-y-0.5 max-h-28 overflow-y-auto">
377
+ {lastLines.map((line: string, i: number) => (
378
+ <div key={i} className="leading-relaxed">{line}</div>
379
+ ))}
380
+ </div>
381
+ )}
382
+ </div>
383
+ );
384
+ }
385
+
386
+ // Not running — show launcher
387
+ const startError = (startBenchmark.data as any)?.error;
388
+
389
+ return (
390
+ <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg overflow-hidden">
391
+ <div className="px-4 py-3 border-b border-white/[0.05]">
392
+ <h3 className="text-xs font-medium text-gray-400">Run Benchmark</h3>
393
+ </div>
394
+
395
+ <div className="p-4 space-y-2">
396
+ {/* Preset buttons */}
397
+ {Object.entries(PRESET_META).map(([preset, meta]) => (
398
+ <div
399
+ key={preset}
400
+ className="flex items-center justify-between px-3 py-2.5 rounded-lg border border-white/[0.05] hover:border-white/[0.10] hover:bg-white/[0.02] transition-colors"
401
+ >
402
+ <div className="min-w-0">
403
+ <div className="flex items-center gap-2">
404
+ <span className="text-xs font-medium text-gray-300">{meta.label}</span>
405
+ <span className="text-[10px] text-gray-600">{meta.desc}</span>
406
+ </div>
407
+ <div className="text-[10px] text-gray-600 mt-0.5 tabular-nums">
408
+ {meta.tasks} &middot; {meta.time}
409
+ </div>
410
+ </div>
411
+ <button
412
+ onClick={() => handlePreset(preset)}
413
+ disabled={startBenchmark.isPending}
414
+ className="ml-4 flex items-center gap-1.5 px-3 py-1 text-[11px] font-medium rounded-md bg-purple-600/20 text-purple-300 border border-purple-500/20 hover:bg-purple-600/30 hover:border-purple-500/40 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shrink-0"
415
+ >
416
+ <Play className="w-2.5 h-2.5" />
417
+ Run
418
+ </button>
419
+ </div>
420
+ ))}
421
+
422
+ {/* Custom section toggle */}
423
+ <div className="pt-1">
424
+ <button
425
+ onClick={() => setShowCustom(v => !v)}
426
+ className="flex items-center gap-1.5 text-[11px] text-gray-500 hover:text-gray-400 transition-colors"
427
+ >
428
+ {showCustom ? <ChevronDown className="w-3 h-3" /> : <ChevronRight className="w-3 h-3" />}
429
+ Custom
430
+ </button>
431
+
432
+ {showCustom && (
433
+ <div className="mt-3 space-y-3 pl-1">
434
+ {/* Category checkboxes */}
435
+ <div>
436
+ <div className="text-[10px] text-gray-600 uppercase tracking-wider mb-2">Categories</div>
437
+ <div className="flex flex-wrap gap-1.5">
438
+ {BENCHMARK_CATEGORIES.map(cat => {
439
+ const active = selectedCategories.includes(cat);
440
+ return (
441
+ <button
442
+ key={cat}
443
+ onClick={() => toggleCategory(cat)}
444
+ className={`px-2 py-0.5 text-[10px] rounded border transition-colors ${
445
+ active
446
+ ? 'bg-purple-500/20 text-purple-300 border-purple-500/30'
447
+ : 'bg-white/[0.03] text-gray-500 border-white/[0.06] hover:text-gray-400 hover:border-white/[0.10]'
448
+ }`}
449
+ >
450
+ {cat}
451
+ </button>
452
+ );
453
+ })}
454
+ </div>
455
+ {selectedCategories.length === 0 && (
456
+ <div className="text-[10px] text-gray-600 mt-1">None selected = all categories</div>
457
+ )}
458
+ </div>
459
+
460
+ {/* Model + noJudge row */}
461
+ <div className="flex items-center gap-4">
462
+ <div>
463
+ <div className="text-[10px] text-gray-600 uppercase tracking-wider mb-1">Model</div>
464
+ <select
465
+ value={customModel}
466
+ onChange={e => setCustomModel(e.target.value)}
467
+ className="px-2.5 py-1 text-xs bg-white/5 border border-white/10 rounded-md text-gray-300 focus:outline-none focus:border-purple-500/50"
468
+ >
469
+ <option value="claude-haiku-4-5">claude-haiku-4-5</option>
470
+ <option value="claude-sonnet-4-5">claude-sonnet-4-5</option>
471
+ <option value="claude-opus-4-5">claude-opus-4-5</option>
472
+ </select>
473
+ </div>
474
+
475
+ <div>
476
+ <div className="text-[10px] text-gray-600 uppercase tracking-wider mb-1">Concurrency</div>
477
+ <input
478
+ type="number"
479
+ min={1}
480
+ max={5}
481
+ value={concurrency}
482
+ onChange={e => setConcurrency(Math.min(5, Math.max(1, parseInt(e.target.value) || 1)))}
483
+ className="w-16 px-2.5 py-1 text-xs bg-white/5 border border-white/10 rounded-md text-gray-300 focus:outline-none focus:border-purple-500/50"
484
+ />
485
+ </div>
486
+
487
+ <div className="flex items-center gap-2 mt-4">
488
+ <input
489
+ id="no-judge"
490
+ type="checkbox"
491
+ checked={noJudge}
492
+ onChange={e => setNoJudge(e.target.checked)}
493
+ className="w-3.5 h-3.5 rounded accent-purple-500"
494
+ />
495
+ <label htmlFor="no-judge" className="text-[11px] text-gray-400 cursor-pointer">
496
+ Skip judge
497
+ </label>
498
+ </div>
499
+ </div>
500
+
501
+ {/* Run custom */}
502
+ <button
503
+ onClick={handleCustomRun}
504
+ disabled={startBenchmark.isPending}
505
+ className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md bg-purple-600/20 text-purple-300 border border-purple-500/20 hover:bg-purple-600/30 hover:border-purple-500/40 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
506
+ >
507
+ <Play className="w-3 h-3" />
508
+ Run Custom
509
+ </button>
510
+ </div>
511
+ )}
512
+ </div>
513
+
514
+ {startError && (
515
+ <div className="text-[11px] text-red-400 bg-red-500/10 border border-red-500/20 rounded-md px-3 py-2">
516
+ {startError}
517
+ </div>
518
+ )}
519
+
520
+ {status && !isRunning && status.exitCode != null && (
521
+ <div className="text-[11px] text-gray-500 bg-white/[0.02] border border-white/[0.05] rounded-md px-3 py-2">
522
+ Last run finished exit code {status.exitCode}
523
+ {status.exitCode === 0 ? ' (success)' : ' (error)'}
524
+ </div>
525
+ )}
526
+ </div>
527
+ </div>
528
+ );
529
+ }
530
+
531
+ export function BenchmarkTab() {
532
+ const { data: runsData, isLoading: runsLoading, refetch: refetchRuns } = useBenchmarkRuns();
533
+ const runs: BenchmarkRun[] = runsData?.runs ?? [];
534
+ const [selectedRunId, setSelectedRunId] = useState<string | null>(null);
535
+
536
+ // Default to latest run once loaded
537
+ const effectiveRunId = selectedRunId ?? runs[0]?.id ?? null;
538
+
539
+ const { data: runDetail, isLoading: detailLoading } = useBenchmarkRun(effectiveRunId);
540
+ const { data: lobesData } = useBenchmarkLobes();
541
+
542
+ const summary: BenchmarkRunSummary | null = runDetail?.summary ?? null;
543
+ const categories: CategoryBreakdown[] = runDetail?.categories ?? [];
544
+ const results: BenchmarkTaskResult[] = runDetail?.results ?? [];
545
+ const lobes: BenchmarkLobeScore[] = lobesData?.lobes ?? [];
546
+
547
+ const noData = !runsLoading && runs.length === 0;
548
+
549
+ if (runsLoading) {
550
+ return (
551
+ <div className="p-6 max-w-5xl space-y-6">
552
+ <RunLauncher onRunComplete={() => refetchRuns()} />
553
+ <div className="text-sm text-gray-500">Loading benchmark data...</div>
554
+ </div>
555
+ );
556
+ }
557
+
558
+ if (noData) {
559
+ return (
560
+ <div className="p-6 max-w-5xl space-y-6">
561
+ <RunLauncher onRunComplete={() => refetchRuns()} />
562
+ <div className="flex flex-col items-center justify-center gap-4 py-16 text-gray-600">
563
+ <FlaskConical className="w-10 h-10" />
564
+ <p className="text-sm text-center max-w-xs">
565
+ No benchmark data yet. Use the launcher above or run{' '}
566
+ <span className="text-gray-500 font-mono text-xs">npm run benchmark</span>
567
+ {' '}to generate results.
568
+ </p>
569
+ </div>
570
+ </div>
571
+ );
572
+ }
573
+
574
+ const tokenDeltaChartData = categories.map(c => ({
575
+ name: c.category,
576
+ delta: parseFloat(c.avgTokenDeltaPercent.toFixed(1)),
577
+ }));
578
+
579
+ const qualityChartData = categories.map(c => ({
580
+ name: c.category,
581
+ without: parseFloat(c.avgQualityWithout.toFixed(3)),
582
+ with: parseFloat(c.avgQualityWith.toFixed(3)),
583
+ }));
584
+
585
+ const hitRateChartData = [...categories]
586
+ .sort((a, b) => b.hitRate - a.hitRate)
587
+ .map(c => ({
588
+ name: c.category,
589
+ hitRate: parseFloat((c.hitRate * 100).toFixed(1)),
590
+ }));
591
+
592
+ return (
593
+ <div className="p-6 max-w-5xl space-y-6">
594
+ {/* Run launcher */}
595
+ <RunLauncher onRunComplete={() => refetchRuns()} />
596
+
597
+ {/* Run selector */}
598
+ <div className="flex items-center gap-3">
599
+ <label className="text-[11px] text-gray-500 shrink-0">Run</label>
600
+ <select
601
+ value={effectiveRunId ?? ''}
602
+ onChange={e => setSelectedRunId(e.target.value || null)}
603
+ className="px-3 py-1.5 text-xs bg-white/5 border border-white/10 rounded-lg text-gray-300 focus:outline-none focus:border-purple-500/50"
604
+ >
605
+ {runs.map((r: BenchmarkRun) => (
606
+ <option key={r.id} value={r.id}>
607
+ {new Date(r.timestamp).toLocaleString()} {r.model} ({r.preset}, {r.task_count} tasks)
608
+ </option>
609
+ ))}
610
+ </select>
611
+ </div>
612
+
613
+ {/* Overview stat cards */}
614
+ {summary && (
615
+ <div className="grid grid-cols-2 md:grid-cols-5 gap-3">
616
+ <StatCard
617
+ label="Avg Token Delta"
618
+ value={
619
+ summary.avgTokenDeltaPercent != null
620
+ ? `${summary.avgTokenDeltaPercent > 0 ? '+' : ''}${summary.avgTokenDeltaPercent.toFixed(1)}%`
621
+ : '—'
622
+ }
623
+ sub="vs baseline"
624
+ color={
625
+ summary.avgTokenDeltaPercent < 0
626
+ ? 'text-green-400'
627
+ : summary.avgTokenDeltaPercent < 5
628
+ ? 'text-amber-400'
629
+ : 'text-red-400'
630
+ }
631
+ />
632
+ <StatCard
633
+ label="Quality (with)"
634
+ value={summary.avgQualityWith.toFixed(2)}
635
+ sub="avg LLM judge score"
636
+ color="text-purple-400"
637
+ />
638
+ <StatCard
639
+ label="Quality (without)"
640
+ value={summary.avgQualityWithout.toFixed(2)}
641
+ sub="baseline"
642
+ />
643
+ <StatCard
644
+ label="Tasks"
645
+ value={summary.taskCount.toString()}
646
+ sub={`${categories.length} categories`}
647
+ />
648
+ <StatCard
649
+ label="Avg Retrieval"
650
+ value={
651
+ summary.avgRetrievalLatencyMs
652
+ ? `${summary.avgRetrievalLatencyMs.toFixed(0)}ms`
653
+ : '—'
654
+ }
655
+ sub={
656
+ summary.avgRetrievalRelevance
657
+ ? `${summary.avgRetrievalRelevance.toFixed(3)} relevance`
658
+ : 'relevance'
659
+ }
660
+ />
661
+ </div>
662
+ )}
663
+
664
+ {detailLoading && (
665
+ <div className="text-sm text-gray-500">Loading run details...</div>
666
+ )}
667
+
668
+ {/* Category breakdown table */}
669
+ {categories.length > 0 && (
670
+ <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg overflow-hidden">
671
+ <div className="px-4 py-3 border-b border-white/[0.05]">
672
+ <h3 className="text-xs font-medium text-gray-400">Category Breakdown</h3>
673
+ </div>
674
+ <div className="overflow-x-auto">
675
+ <table className="w-full text-xs">
676
+ <thead>
677
+ <tr className="border-b border-white/[0.05]">
678
+ <th className="px-4 py-2 text-left text-[10px] text-gray-500 uppercase tracking-wider">Category</th>
679
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Tasks</th>
680
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Token Delta</th>
681
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Quality w/o</th>
682
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Quality with</th>
683
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Hit Rate</th>
684
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Relevance</th>
685
+ </tr>
686
+ </thead>
687
+ <tbody>
688
+ {categories.map((cat, i) => (
689
+ <tr
690
+ key={cat.category}
691
+ className={`border-b border-white/[0.03] ${i % 2 === 0 ? '' : 'bg-white/[0.01]'}`}
692
+ >
693
+ <td className="px-4 py-2 text-gray-300">{cat.category}</td>
694
+ <td className="px-4 py-2 text-right text-gray-400 tabular-nums">{cat.taskCount}</td>
695
+ <td
696
+ className="px-4 py-2 text-right tabular-nums font-medium"
697
+ style={{ color: deltaColor(cat.avgTokenDeltaPercent) }}
698
+ >
699
+ {cat.avgTokenDeltaPercent > 0 ? '+' : ''}
700
+ {cat.avgTokenDeltaPercent.toFixed(1)}%
701
+ </td>
702
+ <td className="px-4 py-2 text-right text-gray-400 tabular-nums">
703
+ {cat.avgQualityWithout.toFixed(2)}
704
+ </td>
705
+ <td className="px-4 py-2 text-right text-gray-300 tabular-nums font-medium">
706
+ {cat.avgQualityWith.toFixed(2)}
707
+ </td>
708
+ <td className="px-4 py-2 text-right text-gray-400 tabular-nums">
709
+ {(cat.hitRate * 100).toFixed(0)}%
710
+ </td>
711
+ <td className="px-4 py-2 text-right text-gray-400 tabular-nums">
712
+ {cat.avgRetrievalRelevance.toFixed(3)}
713
+ </td>
714
+ </tr>
715
+ ))}
716
+ </tbody>
717
+ </table>
718
+ </div>
719
+ </div>
720
+ )}
721
+
722
+ {/* Charts row */}
723
+ {categories.length > 0 && (
724
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
725
+ {/* Token delta by category */}
726
+ <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-4">
727
+ <h3 className="text-xs font-medium text-gray-400 mb-3">Token Delta % by Category</h3>
728
+ <ResponsiveContainer width="100%" height={160}>
729
+ <BarChart data={tokenDeltaChartData} margin={{ top: 4, right: 4, bottom: 4, left: 0 }}>
730
+ <XAxis dataKey="name" tick={{ fontSize: 10, fill: '#6b7280' }} />
731
+ <YAxis tick={{ fontSize: 10, fill: '#6b7280' }} />
732
+ <Tooltip
733
+ contentStyle={CHART_TOOLTIP_STYLE}
734
+ formatter={(v: any) => [`${v > 0 ? '+' : ''}${v}%`, 'Token delta']}
735
+ />
736
+ <Bar dataKey="delta" radius={[2, 2, 0, 0]}>
737
+ {tokenDeltaChartData.map((entry, i) => (
738
+ <Cell key={i} fill={deltaColor(entry.delta)} />
739
+ ))}
740
+ </Bar>
741
+ </BarChart>
742
+ </ResponsiveContainer>
743
+ </div>
744
+
745
+ {/* Quality comparison */}
746
+ <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-4">
747
+ <h3 className="text-xs font-medium text-gray-400 mb-3">Quality Score by Category</h3>
748
+ <div className="flex items-center gap-4 mb-2">
749
+ <span className="flex items-center gap-1 text-[10px] text-gray-500">
750
+ <span className="w-2 h-2 rounded-sm inline-block" style={{ background: '#6b7280' }} />
751
+ Without
752
+ </span>
753
+ <span className="flex items-center gap-1 text-[10px] text-gray-500">
754
+ <span className="w-2 h-2 rounded-sm inline-block" style={{ background: '#7c3aed' }} />
755
+ With Cortex
756
+ </span>
757
+ </div>
758
+ <ResponsiveContainer width="100%" height={160}>
759
+ <BarChart data={qualityChartData} margin={{ top: 4, right: 4, bottom: 4, left: 0 }}>
760
+ <XAxis dataKey="name" tick={{ fontSize: 10, fill: '#6b7280' }} />
761
+ <YAxis domain={[0, 1]} tick={{ fontSize: 10, fill: '#6b7280' }} />
762
+ <Tooltip contentStyle={CHART_TOOLTIP_STYLE} />
763
+ <Bar dataKey="without" fill="#4b5563" radius={[2, 2, 0, 0]} />
764
+ <Bar dataKey="with" fill="#7c3aed" radius={[2, 2, 0, 0]} />
765
+ </BarChart>
766
+ </ResponsiveContainer>
767
+ </div>
768
+
769
+ {/* Hit rate */}
770
+ <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg p-4 md:col-span-2">
771
+ <h3 className="text-xs font-medium text-gray-400 mb-3">Knowledge Retrieval Hit Rate %</h3>
772
+ <ResponsiveContainer width="100%" height={120}>
773
+ <BarChart
774
+ data={hitRateChartData}
775
+ layout="vertical"
776
+ margin={{ top: 4, right: 4, bottom: 4, left: 60 }}
777
+ >
778
+ <XAxis type="number" domain={[0, 100]} tick={{ fontSize: 10, fill: '#6b7280' }} />
779
+ <YAxis
780
+ type="category"
781
+ dataKey="name"
782
+ tick={{ fontSize: 10, fill: '#6b7280' }}
783
+ width={56}
784
+ />
785
+ <Tooltip
786
+ contentStyle={CHART_TOOLTIP_STYLE}
787
+ formatter={(v: any) => [`${v}%`, 'Hit rate']}
788
+ />
789
+ <Bar dataKey="hitRate" fill="#06b6d4" radius={[0, 2, 2, 0]} />
790
+ </BarChart>
791
+ </ResponsiveContainer>
792
+ </div>
793
+ </div>
794
+ )}
795
+
796
+ {/* Lobe scores */}
797
+ {lobes.length > 0 && (
798
+ <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg overflow-hidden">
799
+ <div className="px-4 py-3 border-b border-white/[0.05]">
800
+ <h3 className="text-xs font-medium text-gray-400">Lobe Scores</h3>
801
+ </div>
802
+ <div className="overflow-x-auto">
803
+ <table className="w-full text-xs">
804
+ <thead>
805
+ <tr className="border-b border-white/[0.05]">
806
+ <th className="px-4 py-2 text-left text-[10px] text-gray-500 uppercase tracking-wider">Lobe</th>
807
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Overall</th>
808
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Token Savings</th>
809
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Quality +</th>
810
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Coverage</th>
811
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Badge</th>
812
+ <th className="px-4 py-2 text-right text-[10px] text-gray-500 uppercase tracking-wider">Marketplace</th>
813
+ </tr>
814
+ </thead>
815
+ <tbody>
816
+ {lobes.map((lobe, i) => (
817
+ <tr
818
+ key={lobe.id}
819
+ className={`border-b border-white/[0.03] ${i % 2 === 0 ? '' : 'bg-white/[0.01]'}`}
820
+ >
821
+ <td className="px-4 py-2">
822
+ <div className="text-gray-300">{lobe.lobe_name}</div>
823
+ <div className="text-[9px] text-gray-600 font-mono">{lobe.lobe_id}</div>
824
+ </td>
825
+ <td className="px-4 py-2 text-right text-purple-400 tabular-nums font-medium">
826
+ {lobe.overall_score != null ? lobe.overall_score.toFixed(2) : '—'}
827
+ </td>
828
+ <td
829
+ className="px-4 py-2 text-right tabular-nums"
830
+ style={{ color: (lobe.token_savings ?? 0) > 0 ? '#22c55e' : '#6b7280' }}
831
+ >
832
+ {lobe.token_savings != null
833
+ ? `${lobe.token_savings > 0 ? '+' : ''}${lobe.token_savings.toFixed(1)}%`
834
+ : '—'}
835
+ </td>
836
+ <td
837
+ className="px-4 py-2 text-right tabular-nums"
838
+ style={{ color: (lobe.quality_improvement ?? 0) > 0 ? '#22c55e' : '#6b7280' }}
839
+ >
840
+ {lobe.quality_improvement != null
841
+ ? `${lobe.quality_improvement > 0 ? '+' : ''}${lobe.quality_improvement.toFixed(3)}`
842
+ : '—'}
843
+ </td>
844
+ <td className="px-4 py-2 text-right text-gray-400 tabular-nums">
845
+ {lobe.coverage_score != null ? lobe.coverage_score.toFixed(2) : '—'}
846
+ </td>
847
+ <td className="px-4 py-2 text-right">
848
+ <BadgePill tier={lobe.badge_tier} />
849
+ </td>
850
+ <td className="px-4 py-2 text-right">
851
+ {lobe.marketplace_ready ? (
852
+ <span className="text-[9px] px-1.5 py-0.5 rounded border bg-green-500/10 text-green-400 border-green-500/20">
853
+ Ready
854
+ </span>
855
+ ) : (
856
+ <span className="text-[9px] text-gray-600">—</span>
857
+ )}
858
+ </td>
859
+ </tr>
860
+ ))}
861
+ </tbody>
862
+ </table>
863
+ </div>
864
+ </div>
865
+ )}
866
+
867
+ {/* Task results */}
868
+ {results.length > 0 && (
869
+ <div className="bg-white/[0.02] border border-white/[0.06] rounded-lg overflow-hidden">
870
+ <div className="px-4 py-3 border-b border-white/[0.05] flex items-center justify-between">
871
+ <h3 className="text-xs font-medium text-gray-400">Task Results</h3>
872
+ <span className="text-[10px] text-gray-600">{results.length} tasks</span>
873
+ </div>
874
+ <div className="px-4 py-2">
875
+ {/* Column headers */}
876
+ <div className="flex items-center gap-3 px-3 py-1 mb-1">
877
+ <span className="w-3.5" />
878
+ <span className="text-[9px] text-gray-600 uppercase tracking-wider flex-1">Task ID</span>
879
+ <span className="text-[9px] text-gray-600 uppercase tracking-wider w-20">Category</span>
880
+ <span className="text-[9px] text-gray-600 uppercase tracking-wider w-12">Diff</span>
881
+ <span className="text-[9px] text-gray-600 uppercase tracking-wider w-16 text-right">Token %</span>
882
+ <span className="text-[9px] text-gray-600 uppercase tracking-wider w-20 text-right">Quality w/w</span>
883
+ </div>
884
+ <div className="space-y-1">
885
+ {results.map(r => (
886
+ <TaskRow key={r.id} result={r} />
887
+ ))}
888
+ </div>
889
+ </div>
890
+ </div>
891
+ )}
892
+ </div>
893
+ );
894
+ }