genoma-evolution 1.0.0

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 (445) hide show
  1. package/.brv/.obsidian/app.json +1 -0
  2. package/.brv/.obsidian/appearance.json +1 -0
  3. package/.brv/.obsidian/core-plugins.json +33 -0
  4. package/.brv/.obsidian/graph.json +22 -0
  5. package/.brv/.obsidian/workspace.json +195 -0
  6. package/.brv/Sin ti/314/201tulo 1.canvas" +1 -0
  7. package/.brv/Sin ti/314/201tulo 2.canvas" +1 -0
  8. package/.brv/Sin ti/314/201tulo.canvas" +1 -0
  9. package/.brv/_queue_status.json +1 -0
  10. package/.brv/config.json +5 -0
  11. package/.brv/context-tree/_index.md +60 -0
  12. package/.brv/context-tree/_manifest.json +165 -0
  13. package/.brv/context-tree/backend/_index.md +24 -0
  14. package/.brv/context-tree/backend/backend/_index.md +40 -0
  15. package/.brv/context-tree/backend/backend/init.abstract.md +0 -0
  16. package/.brv/context-tree/backend/backend/init.md +27 -0
  17. package/.brv/context-tree/backend/backend/init.overview.md +29 -0
  18. package/.brv/context-tree/backend/backend/job_tracker.abstract.md +1 -0
  19. package/.brv/context-tree/backend/backend/job_tracker.md +273 -0
  20. package/.brv/context-tree/backend/backend/job_tracker.overview.md +31 -0
  21. package/.brv/context-tree/backend/backend/main.abstract.md +0 -0
  22. package/.brv/context-tree/backend/backend/main.md +1292 -0
  23. package/.brv/context-tree/backend/backend/main.overview.md +30 -0
  24. package/.brv/context-tree/backend/backend/requirements.abstract.md +1 -0
  25. package/.brv/context-tree/backend/backend/requirements.md +37 -0
  26. package/.brv/context-tree/backend/backend/requirements.overview.md +28 -0
  27. package/.brv/context-tree/docs/_index.md +37 -0
  28. package/.brv/context-tree/docs/api/_index.md +54 -0
  29. package/.brv/context-tree/docs/api/context.md +11 -0
  30. package/.brv/context-tree/docs/api/hermes_api_openapi_specification.abstract.md +0 -0
  31. package/.brv/context-tree/docs/api/hermes_api_openapi_specification.md +468 -0
  32. package/.brv/context-tree/docs/api/hermes_api_openapi_specification.overview.md +44 -0
  33. package/.brv/context-tree/frontend/_index.md +48 -0
  34. package/.brv/context-tree/frontend/hermes_dashboard/_index.md +31 -0
  35. package/.brv/context-tree/frontend/hermes_dashboard/architecture_overview.abstract.md +0 -0
  36. package/.brv/context-tree/frontend/hermes_dashboard/architecture_overview.md +41 -0
  37. package/.brv/context-tree/frontend/hermes_dashboard/architecture_overview.overview.md +34 -0
  38. package/.brv/context-tree/frontend/src/_index.md +53 -0
  39. package/.brv/context-tree/frontend/src/components/_index.md +52 -0
  40. package/.brv/context-tree/frontend/src/components/sidebar_navigation_component.abstract.md +0 -0
  41. package/.brv/context-tree/frontend/src/components/sidebar_navigation_component.md +161 -0
  42. package/.brv/context-tree/frontend/src/components/sidebar_navigation_component.overview.md +32 -0
  43. package/.brv/context-tree/frontend/src/context.md +10 -0
  44. package/.brv/context-tree/frontend/src/functioncallingpage.abstract.md +0 -0
  45. package/.brv/context-tree/frontend/src/functioncallingpage.md +34 -0
  46. package/.brv/context-tree/frontend/src/functioncallingpage.overview.md +26 -0
  47. package/.brv/context-tree/frontend/src/lib/_index.md +48 -0
  48. package/.brv/context-tree/frontend/src/lib/api_client_library.abstract.md +1 -0
  49. package/.brv/context-tree/frontend/src/lib/api_client_library.md +403 -0
  50. package/.brv/context-tree/frontend/src/lib/api_client_library.overview.md +69 -0
  51. package/.brv/context-tree/frontend/src/page.abstract.md +0 -0
  52. package/.brv/context-tree/frontend/src/page.md +103 -0
  53. package/.brv/context-tree/frontend/src/page.overview.md +7 -0
  54. package/.brv/context-tree/frontend/src/settingspage.abstract.md +0 -0
  55. package/.brv/context-tree/frontend/src/settingspage.md +124 -0
  56. package/.brv/context-tree/frontend/src/settingspage.overview.md +34 -0
  57. package/.brv/context-tree/frontend/src/sidebar.abstract.md +0 -0
  58. package/.brv/context-tree/frontend/src/sidebar.md +170 -0
  59. package/.brv/context-tree/frontend/src/sidebar.overview.md +25 -0
  60. package/.brv/context-tree/meta/_index.md +24 -0
  61. package/.brv/context-tree/meta/curation_context/_index.md +24 -0
  62. package/.brv/context-tree/meta/curation_context/empty_context.abstract.md +4 -0
  63. package/.brv/context-tree/meta/curation_context/empty_context.md +35 -0
  64. package/.brv/context-tree/meta/curation_context/empty_context.overview.md +20 -0
  65. package/.brv/dream-log/drm-1777341062653.json +33 -0
  66. package/.brv/dream-state.json +8 -0
  67. package/.brv/dream.lock +0 -0
  68. package/.brv/review-backups/docs/api/hermes_api_openapi_specification.md +468 -0
  69. package/.claude/settings.local.json +7 -0
  70. package/.claude/worktrees/phase-2-mcp/.brv/.obsidian/app.json +1 -0
  71. package/.claude/worktrees/phase-2-mcp/.brv/.obsidian/appearance.json +1 -0
  72. package/.claude/worktrees/phase-2-mcp/.brv/.obsidian/core-plugins.json +33 -0
  73. package/.claude/worktrees/phase-2-mcp/.brv/.obsidian/graph.json +22 -0
  74. package/.claude/worktrees/phase-2-mcp/.brv/.obsidian/workspace.json +195 -0
  75. package/.claude/worktrees/phase-2-mcp/.brv/Sin t/303/255tulo 1.canvas" +1 -0
  76. package/.claude/worktrees/phase-2-mcp/.brv/Sin t/303/255tulo 2.canvas" +1 -0
  77. package/.claude/worktrees/phase-2-mcp/.brv/Sin t/303/255tulo.canvas" +1 -0
  78. package/.claude/worktrees/phase-2-mcp/.brv/_queue_status.json +1 -0
  79. package/.claude/worktrees/phase-2-mcp/.brv/config.json +5 -0
  80. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/_index.md +60 -0
  81. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/_manifest.json +165 -0
  82. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/_index.md +24 -0
  83. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/_index.md +40 -0
  84. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/init.abstract.md +0 -0
  85. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/init.md +27 -0
  86. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/init.overview.md +29 -0
  87. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/job_tracker.abstract.md +1 -0
  88. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/job_tracker.md +273 -0
  89. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/job_tracker.overview.md +31 -0
  90. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/main.abstract.md +0 -0
  91. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/main.md +1292 -0
  92. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/main.overview.md +30 -0
  93. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/requirements.abstract.md +1 -0
  94. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/requirements.md +37 -0
  95. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/backend/backend/requirements.overview.md +28 -0
  96. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/docs/_index.md +37 -0
  97. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/docs/api/_index.md +54 -0
  98. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/docs/api/context.md +11 -0
  99. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/docs/api/hermes_api_openapi_specification.abstract.md +0 -0
  100. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/docs/api/hermes_api_openapi_specification.md +468 -0
  101. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/docs/api/hermes_api_openapi_specification.overview.md +44 -0
  102. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/_index.md +48 -0
  103. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/hermes_dashboard/_index.md +31 -0
  104. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/hermes_dashboard/architecture_overview.abstract.md +0 -0
  105. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/hermes_dashboard/architecture_overview.md +41 -0
  106. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/hermes_dashboard/architecture_overview.overview.md +34 -0
  107. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/_index.md +53 -0
  108. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/components/_index.md +52 -0
  109. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/components/sidebar_navigation_component.abstract.md +0 -0
  110. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/components/sidebar_navigation_component.md +161 -0
  111. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/components/sidebar_navigation_component.overview.md +32 -0
  112. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/context.md +10 -0
  113. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/functioncallingpage.abstract.md +0 -0
  114. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/functioncallingpage.md +34 -0
  115. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/functioncallingpage.overview.md +26 -0
  116. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/lib/_index.md +48 -0
  117. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/lib/api_client_library.abstract.md +1 -0
  118. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/lib/api_client_library.md +403 -0
  119. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/lib/api_client_library.overview.md +69 -0
  120. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/page.abstract.md +0 -0
  121. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/page.md +103 -0
  122. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/page.overview.md +7 -0
  123. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/settingspage.abstract.md +0 -0
  124. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/settingspage.md +124 -0
  125. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/settingspage.overview.md +34 -0
  126. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/sidebar.abstract.md +0 -0
  127. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/sidebar.md +170 -0
  128. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/frontend/src/sidebar.overview.md +25 -0
  129. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/meta/_index.md +24 -0
  130. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/meta/curation_context/_index.md +24 -0
  131. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/meta/curation_context/empty_context.abstract.md +4 -0
  132. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/meta/curation_context/empty_context.md +35 -0
  133. package/.claude/worktrees/phase-2-mcp/.brv/context-tree/meta/curation_context/empty_context.overview.md +20 -0
  134. package/.claude/worktrees/phase-2-mcp/.brv/dream-log/drm-1777341062653.json +33 -0
  135. package/.claude/worktrees/phase-2-mcp/.brv/dream-state.json +8 -0
  136. package/.claude/worktrees/phase-2-mcp/.brv/dream.lock +0 -0
  137. package/.claude/worktrees/phase-2-mcp/.brv/review-backups/docs/api/hermes_api_openapi_specification.md +468 -0
  138. package/.claude/worktrees/phase-2-mcp/.claude/settings.local.json +13 -0
  139. package/.claude/worktrees/phase-2-mcp/.kilocode/package-lock.json +378 -0
  140. package/.claude/worktrees/phase-2-mcp/.kilocode/package.json +5 -0
  141. package/.claude/worktrees/phase-2-mcp/AGENTS.md +5 -0
  142. package/.claude/worktrees/phase-2-mcp/CLAUDE.md +29 -0
  143. package/.claude/worktrees/phase-2-mcp/QA_AUDIT_PLAN.md +156 -0
  144. package/.claude/worktrees/phase-2-mcp/README.md +316 -0
  145. package/.claude/worktrees/phase-2-mcp/agent-agnostic-evolution-dashboard.md +405 -0
  146. package/.claude/worktrees/phase-2-mcp/backend/__init__.py +0 -0
  147. package/.claude/worktrees/phase-2-mcp/backend/collectors/__init__.py +0 -0
  148. package/.claude/worktrees/phase-2-mcp/backend/collectors/claude_code_collector.py +277 -0
  149. package/.claude/worktrees/phase-2-mcp/backend/collectors/hermes_collector.py +68 -0
  150. package/.claude/worktrees/phase-2-mcp/backend/curator.py +512 -0
  151. package/.claude/worktrees/phase-2-mcp/backend/eval/__init__.py +19 -0
  152. package/.claude/worktrees/phase-2-mcp/backend/eval/engine.py +116 -0
  153. package/.claude/worktrees/phase-2-mcp/backend/eval/scorers.py +201 -0
  154. package/.claude/worktrees/phase-2-mcp/backend/generate_dataset.py +86 -0
  155. package/.claude/worktrees/phase-2-mcp/backend/job_tracker.py +232 -0
  156. package/.claude/worktrees/phase-2-mcp/backend/main.py +1746 -0
  157. package/.claude/worktrees/phase-2-mcp/backend/mcp_server.py +250 -0
  158. package/.claude/worktrees/phase-2-mcp/backend/promethean/__init__.py +24 -0
  159. package/.claude/worktrees/phase-2-mcp/backend/promethean/cycle_orchestrator.py +270 -0
  160. package/.claude/worktrees/phase-2-mcp/backend/promethean/delta_validator.py +191 -0
  161. package/.claude/worktrees/phase-2-mcp/backend/promethean/dspy_compiler.py +315 -0
  162. package/.claude/worktrees/phase-2-mcp/backend/promethean/gepa_strategist.py +213 -0
  163. package/.claude/worktrees/phase-2-mcp/backend/promethean/models.py +260 -0
  164. package/.claude/worktrees/phase-2-mcp/backend/promethean/skill_deployer.py +195 -0
  165. package/.claude/worktrees/phase-2-mcp/backend/promethean/trace_ingestion.py +142 -0
  166. package/.claude/worktrees/phase-2-mcp/backend/requirements.txt +6 -0
  167. package/.claude/worktrees/phase-2-mcp/backend/sdd_evolve.py +459 -0
  168. package/.claude/worktrees/phase-2-mcp/backend/skill_detector.py +227 -0
  169. package/.claude/worktrees/phase-2-mcp/backend/skill_registry.py +289 -0
  170. package/.claude/worktrees/phase-2-mcp/backend/storage/__init__.py +5 -0
  171. package/.claude/worktrees/phase-2-mcp/backend/storage/run_store.py +393 -0
  172. package/.claude/worktrees/phase-2-mcp/backend/storage/schema.sql +99 -0
  173. package/.claude/worktrees/phase-2-mcp/backend/validate_evolution.py +267 -0
  174. package/.claude/worktrees/phase-2-mcp/components.json +28 -0
  175. package/.claude/worktrees/phase-2-mcp/docs/api/hermes-api.openapi.yaml +438 -0
  176. package/.claude/worktrees/phase-2-mcp/docs/hero.svg +148 -0
  177. package/.claude/worktrees/phase-2-mcp/eslint.config.mjs +18 -0
  178. package/.claude/worktrees/phase-2-mcp/install.sh +245 -0
  179. package/.claude/worktrees/phase-2-mcp/next-env.d.ts +6 -0
  180. package/.claude/worktrees/phase-2-mcp/next.config.ts +32 -0
  181. package/.claude/worktrees/phase-2-mcp/package-lock.json +11936 -0
  182. package/.claude/worktrees/phase-2-mcp/package.json +41 -0
  183. package/.claude/worktrees/phase-2-mcp/pnpm-workspace.yaml +4 -0
  184. package/.claude/worktrees/phase-2-mcp/postcss.config.mjs +7 -0
  185. package/.claude/worktrees/phase-2-mcp/public/file.svg +1 -0
  186. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Display-Bold.otf +0 -0
  187. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Display-Heavy.otf +0 -0
  188. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Display-Medium.otf +0 -0
  189. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Display-Regular.otf +0 -0
  190. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Display-Semibold.otf +0 -0
  191. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Text-Bold.otf +0 -0
  192. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Text-Heavy.otf +0 -0
  193. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Text-Medium.otf +0 -0
  194. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Text-Regular.otf +0 -0
  195. package/.claude/worktrees/phase-2-mcp/public/fonts/SF-Pro-Text-Semibold.otf +0 -0
  196. package/.claude/worktrees/phase-2-mcp/public/globe.svg +1 -0
  197. package/.claude/worktrees/phase-2-mcp/public/next.svg +1 -0
  198. package/.claude/worktrees/phase-2-mcp/public/theme-preview.html +257 -0
  199. package/.claude/worktrees/phase-2-mcp/public/vercel.svg +1 -0
  200. package/.claude/worktrees/phase-2-mcp/public/window.svg +1 -0
  201. package/.claude/worktrees/phase-2-mcp/run.sh +26 -0
  202. package/.claude/worktrees/phase-2-mcp/skills-lock.json +10 -0
  203. package/.claude/worktrees/phase-2-mcp/specs/event-schema.md +223 -0
  204. package/.claude/worktrees/phase-2-mcp/specs/examples/run.jsonl +3 -0
  205. package/.claude/worktrees/phase-2-mcp/src/app/api/[...path]/route.ts +55 -0
  206. package/.claude/worktrees/phase-2-mcp/src/app/api/auth/token/route.ts +22 -0
  207. package/.claude/worktrees/phase-2-mcp/src/app/evolution/page.tsx +589 -0
  208. package/.claude/worktrees/phase-2-mcp/src/app/favicon.ico +0 -0
  209. package/.claude/worktrees/phase-2-mcp/src/app/globals.css +321 -0
  210. package/.claude/worktrees/phase-2-mcp/src/app/layout.tsx +63 -0
  211. package/.claude/worktrees/phase-2-mcp/src/app/page.tsx +70 -0
  212. package/.claude/worktrees/phase-2-mcp/src/app/skills/page.tsx +369 -0
  213. package/.claude/worktrees/phase-2-mcp/src/components/ApiConfigCard.tsx +199 -0
  214. package/.claude/worktrees/phase-2-mcp/src/components/ColorBends.css +1 -0
  215. package/.claude/worktrees/phase-2-mcp/src/components/ColorBends.d.ts +1 -0
  216. package/.claude/worktrees/phase-2-mcp/src/components/ColorBends.jsx +1 -0
  217. package/.claude/worktrees/phase-2-mcp/src/components/CoreLoopToggle.tsx +111 -0
  218. package/.claude/worktrees/phase-2-mcp/src/components/EnvironmentStatus.tsx +176 -0
  219. package/.claude/worktrees/phase-2-mcp/src/components/EvolutionBackground.tsx +1 -0
  220. package/.claude/worktrees/phase-2-mcp/src/components/ReactQueryProvider.tsx +24 -0
  221. package/.claude/worktrees/phase-2-mcp/src/components/Sidebar.tsx +247 -0
  222. package/.claude/worktrees/phase-2-mcp/src/components/SkillDiffViewer.tsx +154 -0
  223. package/.claude/worktrees/phase-2-mcp/src/components/ThemeAwareBackground.tsx +67 -0
  224. package/.claude/worktrees/phase-2-mcp/src/components/ThemeToggle.tsx +54 -0
  225. package/.claude/worktrees/phase-2-mcp/src/components/WelcomeHero.tsx +77 -0
  226. package/.claude/worktrees/phase-2-mcp/src/components/bits/ClickSpark.tsx +116 -0
  227. package/.claude/worktrees/phase-2-mcp/src/components/bits/CountUp.tsx +98 -0
  228. package/.claude/worktrees/phase-2-mcp/src/components/bits/DarkSelect.tsx +95 -0
  229. package/.claude/worktrees/phase-2-mcp/src/components/bits/DecryptedText.tsx +161 -0
  230. package/.claude/worktrees/phase-2-mcp/src/components/bits/ElectricBorder.tsx +184 -0
  231. package/.claude/worktrees/phase-2-mcp/src/components/bits/GlitchText.tsx +34 -0
  232. package/.claude/worktrees/phase-2-mcp/src/components/bits/ShinyText.tsx +55 -0
  233. package/.claude/worktrees/phase-2-mcp/src/components/bits/SpotlightCard.tsx +42 -0
  234. package/.claude/worktrees/phase-2-mcp/src/components/bits/TextType.tsx +95 -0
  235. package/.claude/worktrees/phase-2-mcp/src/components/bits/index.ts +9 -0
  236. package/.claude/worktrees/phase-2-mcp/src/components/pages/CuratorPage.tsx +632 -0
  237. package/.claude/worktrees/phase-2-mcp/src/components/pages/DatasetPage.tsx +271 -0
  238. package/.claude/worktrees/phase-2-mcp/src/components/pages/EvolutionPage.tsx +676 -0
  239. package/.claude/worktrees/phase-2-mcp/src/components/pages/FunctionCallingPage.tsx +1 -0
  240. package/.claude/worktrees/phase-2-mcp/src/components/pages/LogsPage.tsx +272 -0
  241. package/.claude/worktrees/phase-2-mcp/src/components/pages/MetricsPage.tsx +246 -0
  242. package/.claude/worktrees/phase-2-mcp/src/components/pages/OverviewPage.tsx +420 -0
  243. package/.claude/worktrees/phase-2-mcp/src/components/pages/SettingsPage.tsx +88 -0
  244. package/.claude/worktrees/phase-2-mcp/src/components/pages/SkillStudioPage.tsx +376 -0
  245. package/.claude/worktrees/phase-2-mcp/src/components/ui/animated-theme-toggler.tsx +97 -0
  246. package/.claude/worktrees/phase-2-mcp/src/components/ui/button.tsx +67 -0
  247. package/.claude/worktrees/phase-2-mcp/src/components/ui/card.tsx +103 -0
  248. package/.claude/worktrees/phase-2-mcp/src/components/ui/input.tsx +19 -0
  249. package/.claude/worktrees/phase-2-mcp/src/components/ui/separator.tsx +28 -0
  250. package/.claude/worktrees/phase-2-mcp/src/components/ui/sheet.tsx +147 -0
  251. package/.claude/worktrees/phase-2-mcp/src/components/ui/sidebar.tsx +702 -0
  252. package/.claude/worktrees/phase-2-mcp/src/components/ui/skeleton.tsx +13 -0
  253. package/.claude/worktrees/phase-2-mcp/src/components/ui/theme-toggle.tsx +272 -0
  254. package/.claude/worktrees/phase-2-mcp/src/components/ui/tooltip.tsx +57 -0
  255. package/.claude/worktrees/phase-2-mcp/src/hooks/use-mobile.ts +19 -0
  256. package/.claude/worktrees/phase-2-mcp/src/lib/api.ts +455 -0
  257. package/.claude/worktrees/phase-2-mcp/src/lib/queryClient.ts +12 -0
  258. package/.claude/worktrees/phase-2-mcp/src/lib/utils.ts +6 -0
  259. package/.claude/worktrees/phase-2-mcp/stitch/agent_dashboard/DESIGN_SPEC.md +521 -0
  260. package/.claude/worktrees/phase-2-mcp/stitch/agent_dashboard/prototype.html +676 -0
  261. package/.claude/worktrees/phase-2-mcp/stitch/curator_workspace/code.html +448 -0
  262. package/.claude/worktrees/phase-2-mcp/stitch/curator_workspace/screen.png +0 -0
  263. package/.claude/worktrees/phase-2-mcp/stitch/datasets/code.html +479 -0
  264. package/.claude/worktrees/phase-2-mcp/stitch/datasets/screen.png +0 -0
  265. package/.claude/worktrees/phase-2-mcp/stitch/evolution_history/code.html +461 -0
  266. package/.claude/worktrees/phase-2-mcp/stitch/evolution_history/screen.png +0 -0
  267. package/.claude/worktrees/phase-2-mcp/stitch/hermes_dashboard/DESIGN.md +192 -0
  268. package/.claude/worktrees/phase-2-mcp/stitch/hermes_dashboard/DESIGN_SPEC.md +455 -0
  269. package/.claude/worktrees/phase-2-mcp/stitch/hermes_overview/code.html +399 -0
  270. package/.claude/worktrees/phase-2-mcp/stitch/hermes_overview/screen.png +0 -0
  271. package/.claude/worktrees/phase-2-mcp/stitch/live_logs/code.html +324 -0
  272. package/.claude/worktrees/phase-2-mcp/stitch/live_logs/screen.png +0 -0
  273. package/.claude/worktrees/phase-2-mcp/stitch/skill_hub/code.html +596 -0
  274. package/.claude/worktrees/phase-2-mcp/stitch/skill_hub/screen.png +0 -0
  275. package/.claude/worktrees/phase-2-mcp/stitch/system_metrics/code.html +527 -0
  276. package/.claude/worktrees/phase-2-mcp/stitch/system_metrics/screen.png +0 -0
  277. package/.claude/worktrees/phase-2-mcp/stitch/system_settings/code.html +257 -0
  278. package/.claude/worktrees/phase-2-mcp/stitch/system_settings/screen.png +0 -0
  279. package/.claude/worktrees/phase-2-mcp/test_dashboard.py +201 -0
  280. package/.claude/worktrees/phase-2-mcp/tests/collectors/__init__.py +0 -0
  281. package/.claude/worktrees/phase-2-mcp/tests/collectors/fixtures/sample_session.jsonl +7 -0
  282. package/.claude/worktrees/phase-2-mcp/tests/collectors/test_claude_code_collector.py +171 -0
  283. package/.claude/worktrees/phase-2-mcp/tests/collectors/test_hermes_collector.py +167 -0
  284. package/.claude/worktrees/phase-2-mcp/tests/eval/test_engine.py +234 -0
  285. package/.claude/worktrees/phase-2-mcp/tests/eval/test_scorers.py +249 -0
  286. package/.claude/worktrees/phase-2-mcp/tests/storage/__init__.py +0 -0
  287. package/.claude/worktrees/phase-2-mcp/tests/storage/test_run_store.py +359 -0
  288. package/.claude/worktrees/phase-2-mcp/tests/test_curator.py +559 -0
  289. package/.claude/worktrees/phase-2-mcp/tests/test_mcp_server.py +114 -0
  290. package/.claude/worktrees/phase-2-mcp/tsconfig.json +34 -0
  291. package/.env.example +72 -0
  292. package/.kilocode/package-lock.json +378 -0
  293. package/.kilocode/package.json +5 -0
  294. package/AGENTS.md +5 -0
  295. package/CLAUDE.md +29 -0
  296. package/QA_AUDIT_PLAN.md +156 -0
  297. package/README.md +355 -0
  298. package/agent-agnostic-evolution-dashboard.md +405 -0
  299. package/backend/__init__.py +0 -0
  300. package/backend/collectors/__init__.py +0 -0
  301. package/backend/collectors/claude_code_collector.py +277 -0
  302. package/backend/collectors/hermes_collector.py +68 -0
  303. package/backend/curator.py +512 -0
  304. package/backend/eval/__init__.py +19 -0
  305. package/backend/eval/engine.py +116 -0
  306. package/backend/eval/scorers.py +201 -0
  307. package/backend/generate_dataset.py +86 -0
  308. package/backend/job_tracker.py +232 -0
  309. package/backend/main.py +1746 -0
  310. package/backend/mcp_server.py +250 -0
  311. package/backend/promethean/__init__.py +24 -0
  312. package/backend/promethean/cycle_orchestrator.py +270 -0
  313. package/backend/promethean/delta_validator.py +191 -0
  314. package/backend/promethean/dspy_compiler.py +315 -0
  315. package/backend/promethean/gepa_strategist.py +213 -0
  316. package/backend/promethean/models.py +260 -0
  317. package/backend/promethean/skill_deployer.py +195 -0
  318. package/backend/promethean/trace_ingestion.py +142 -0
  319. package/backend/requirements.txt +6 -0
  320. package/backend/sdd_evolve.py +459 -0
  321. package/backend/skill_detector.py +227 -0
  322. package/backend/skill_registry.py +289 -0
  323. package/backend/storage/__init__.py +5 -0
  324. package/backend/storage/run_store.py +393 -0
  325. package/backend/storage/schema.sql +99 -0
  326. package/backend/validate_evolution.py +267 -0
  327. package/bin/genoma.js +250 -0
  328. package/components.json +28 -0
  329. package/docs/api/hermes-api.openapi.yaml +438 -0
  330. package/docs/hero.svg +148 -0
  331. package/eslint.config.mjs +18 -0
  332. package/install.sh +245 -0
  333. package/next-env.d.ts +6 -0
  334. package/next.config.ts +32 -0
  335. package/package.json +46 -0
  336. package/pnpm-workspace.yaml +4 -0
  337. package/postcss.config.mjs +7 -0
  338. package/public/file.svg +1 -0
  339. package/public/fonts/SF-Pro-Display-Bold.otf +0 -0
  340. package/public/fonts/SF-Pro-Display-Heavy.otf +0 -0
  341. package/public/fonts/SF-Pro-Display-Medium.otf +0 -0
  342. package/public/fonts/SF-Pro-Display-Regular.otf +0 -0
  343. package/public/fonts/SF-Pro-Display-Semibold.otf +0 -0
  344. package/public/fonts/SF-Pro-Text-Bold.otf +0 -0
  345. package/public/fonts/SF-Pro-Text-Heavy.otf +0 -0
  346. package/public/fonts/SF-Pro-Text-Medium.otf +0 -0
  347. package/public/fonts/SF-Pro-Text-Regular.otf +0 -0
  348. package/public/fonts/SF-Pro-Text-Semibold.otf +0 -0
  349. package/public/globe.svg +1 -0
  350. package/public/next.svg +1 -0
  351. package/public/theme-preview.html +257 -0
  352. package/public/vercel.svg +1 -0
  353. package/public/window.svg +1 -0
  354. package/run.sh +26 -0
  355. package/scripts/postinstall.js +50 -0
  356. package/skills-lock.json +10 -0
  357. package/specs/event-schema.md +223 -0
  358. package/specs/examples/run.jsonl +3 -0
  359. package/src/app/api/[...path]/route.ts +55 -0
  360. package/src/app/api/auth/token/route.ts +22 -0
  361. package/src/app/evolution/page.tsx +589 -0
  362. package/src/app/favicon.ico +0 -0
  363. package/src/app/globals.css +321 -0
  364. package/src/app/layout.tsx +63 -0
  365. package/src/app/page.tsx +70 -0
  366. package/src/app/skills/page.tsx +369 -0
  367. package/src/components/ApiConfigCard.tsx +199 -0
  368. package/src/components/ColorBends.css +1 -0
  369. package/src/components/ColorBends.d.ts +1 -0
  370. package/src/components/ColorBends.jsx +1 -0
  371. package/src/components/CoreLoopToggle.tsx +111 -0
  372. package/src/components/EnvironmentStatus.tsx +176 -0
  373. package/src/components/EvolutionBackground.tsx +1 -0
  374. package/src/components/ReactQueryProvider.tsx +24 -0
  375. package/src/components/Sidebar.tsx +247 -0
  376. package/src/components/SkillDiffViewer.tsx +154 -0
  377. package/src/components/ThemeAwareBackground.tsx +67 -0
  378. package/src/components/ThemeToggle.tsx +54 -0
  379. package/src/components/WelcomeHero.tsx +77 -0
  380. package/src/components/bits/ClickSpark.tsx +116 -0
  381. package/src/components/bits/CountUp.tsx +98 -0
  382. package/src/components/bits/DarkSelect.tsx +95 -0
  383. package/src/components/bits/DecryptedText.tsx +161 -0
  384. package/src/components/bits/ElectricBorder.tsx +184 -0
  385. package/src/components/bits/GlitchText.tsx +34 -0
  386. package/src/components/bits/ShinyText.tsx +55 -0
  387. package/src/components/bits/SpotlightCard.tsx +42 -0
  388. package/src/components/bits/TextType.tsx +95 -0
  389. package/src/components/bits/index.ts +9 -0
  390. package/src/components/pages/CuratorPage.tsx +632 -0
  391. package/src/components/pages/DatasetPage.tsx +271 -0
  392. package/src/components/pages/EvolutionPage.tsx +676 -0
  393. package/src/components/pages/FunctionCallingPage.tsx +1 -0
  394. package/src/components/pages/LogsPage.tsx +272 -0
  395. package/src/components/pages/MetricsPage.tsx +246 -0
  396. package/src/components/pages/OverviewPage.tsx +420 -0
  397. package/src/components/pages/SettingsPage.tsx +88 -0
  398. package/src/components/pages/SkillStudioPage.tsx +376 -0
  399. package/src/components/ui/animated-theme-toggler.tsx +97 -0
  400. package/src/components/ui/button.tsx +67 -0
  401. package/src/components/ui/card.tsx +103 -0
  402. package/src/components/ui/input.tsx +19 -0
  403. package/src/components/ui/separator.tsx +28 -0
  404. package/src/components/ui/sheet.tsx +147 -0
  405. package/src/components/ui/sidebar.tsx +702 -0
  406. package/src/components/ui/skeleton.tsx +13 -0
  407. package/src/components/ui/theme-toggle.tsx +272 -0
  408. package/src/components/ui/tooltip.tsx +57 -0
  409. package/src/hooks/use-mobile.ts +19 -0
  410. package/src/lib/api.ts +455 -0
  411. package/src/lib/queryClient.ts +12 -0
  412. package/src/lib/utils.ts +6 -0
  413. package/stitch/agent_dashboard/DESIGN_SPEC.md +521 -0
  414. package/stitch/agent_dashboard/prototype.html +676 -0
  415. package/stitch/curator_workspace/code.html +448 -0
  416. package/stitch/curator_workspace/screen.png +0 -0
  417. package/stitch/datasets/code.html +479 -0
  418. package/stitch/datasets/screen.png +0 -0
  419. package/stitch/evolution_history/code.html +461 -0
  420. package/stitch/evolution_history/screen.png +0 -0
  421. package/stitch/hermes_dashboard/DESIGN.md +192 -0
  422. package/stitch/hermes_dashboard/DESIGN_SPEC.md +455 -0
  423. package/stitch/hermes_overview/code.html +399 -0
  424. package/stitch/hermes_overview/screen.png +0 -0
  425. package/stitch/live_logs/code.html +324 -0
  426. package/stitch/live_logs/screen.png +0 -0
  427. package/stitch/skill_hub/code.html +596 -0
  428. package/stitch/skill_hub/screen.png +0 -0
  429. package/stitch/system_metrics/code.html +527 -0
  430. package/stitch/system_metrics/screen.png +0 -0
  431. package/stitch/system_settings/code.html +257 -0
  432. package/stitch/system_settings/screen.png +0 -0
  433. package/test_dashboard.py +201 -0
  434. package/tests/collectors/__init__.py +0 -0
  435. package/tests/collectors/fixtures/sample_session.jsonl +7 -0
  436. package/tests/collectors/test_claude_code_collector.py +171 -0
  437. package/tests/collectors/test_hermes_collector.py +167 -0
  438. package/tests/eval/test_engine.py +234 -0
  439. package/tests/eval/test_scorers.py +249 -0
  440. package/tests/storage/__init__.py +0 -0
  441. package/tests/storage/test_run_store.py +359 -0
  442. package/tests/test_curator.py +559 -0
  443. package/tests/test_e2e_npm.py +621 -0
  444. package/tests/test_mcp_server.py +114 -0
  445. package/tsconfig.json +34 -0
@@ -0,0 +1,676 @@
1
+ "use client";
2
+
3
+ import { useState, useEffect, useRef, useCallback } from "react";
4
+ import { motion, AnimatePresence } from "framer-motion";
5
+ import {
6
+ GitBranch,
7
+ Play,
8
+ Square,
9
+ Loader2,
10
+ CheckCircle2,
11
+ XCircle,
12
+ Clock,
13
+ TrendingUp,
14
+ TrendingDown,
15
+ Minus,
16
+ Dna,
17
+ ChevronDown,
18
+ ChevronRight,
19
+ Activity,
20
+ AlertCircle,
21
+ Code2,
22
+ FileText,
23
+ X,
24
+ RefreshCw,
25
+ WifiOff,
26
+ Zap,
27
+ Sparkles,
28
+ } from "lucide-react";
29
+ import {
30
+ fetchEvolutionRuns,
31
+ fetchSkills,
32
+ fetchJobs,
33
+ fetchJobLogs,
34
+ startEvolution,
35
+ cancelJob,
36
+ fetchSkillDiff,
37
+ checkHealth,
38
+ isApiError,
39
+ api,
40
+ type SkillDiff,
41
+ type EvolutionRun,
42
+ type SkillInfo,
43
+ type EvolutionJob,
44
+ } from "@/lib/api";
45
+ import { ElectricBorder, ShinyText, SpotlightCard, ClickSpark } from "@/components/bits";
46
+ import DarkSelect from "@/components/bits/DarkSelect";
47
+ import SkillDiffViewer from "@/components/SkillDiffViewer";
48
+
49
+ // ── Provider config ────────────────────────────────────────────────
50
+ const PROVIDER_META: Record<string, { icon: string; color: string }> = {
51
+ hermes: { icon: "🪽", color: "emerald" },
52
+ "claude-code": { icon: "🤖", color: "violet" },
53
+ opencode: { icon: "💻", color: "blue" },
54
+ kilocode: { icon: "⚡", color: "amber" },
55
+ antigravity: { icon: "🚀", color: "rose" },
56
+ };
57
+
58
+ interface EvolvableProvider {
59
+ provider: string;
60
+ total: number;
61
+ enabled: number;
62
+ skills: { name: string; description: string; enabled: boolean; category: string }[];
63
+ }
64
+
65
+ const STATUS_LABELS: Record<string, string> = {
66
+ queued: "Queued",
67
+ loading_skill: "Loading Skill",
68
+ building_dataset: "Building Dataset",
69
+ validating: "Validating",
70
+ configuring: "Configuring",
71
+ optimizing: "Optimizing",
72
+ evaluating: "Evaluating",
73
+ saving: "Saving",
74
+ completed: "Completed",
75
+ failed: "Failed",
76
+ };
77
+
78
+ type ConnectionState = "checking" | "connected" | "disconnected";
79
+
80
+ function ProgressBar({ progress, status }: { progress: number; status: string }) {
81
+ const color =
82
+ status === "failed"
83
+ ? "bg-error"
84
+ : status === "completed"
85
+ ? "bg-success"
86
+ : "bg-gradient-to-r from-accent-violet to-accent-cyan";
87
+
88
+ return (
89
+ <div className="h-1.5 bg-white/[0.05] rounded-full overflow-hidden">
90
+ <motion.div
91
+ className={`h-full rounded-full ${color}`}
92
+ initial={{ width: 0 }}
93
+ animate={{ width: `${Math.max(progress * 100, 2)}%` }}
94
+ transition={{ duration: 0.5, ease: "easeOut" }}
95
+ style={
96
+ status !== "failed" && status !== "completed"
97
+ ? { boxShadow: "0 0 8px rgba(139,92,246,0.5)" }
98
+ : {}
99
+ }
100
+ />
101
+ </div>
102
+ );
103
+ }
104
+
105
+ function ActiveJobCard({
106
+ job,
107
+ onCancel,
108
+ }: {
109
+ job: EvolutionJob;
110
+ onCancel: (id: string) => void;
111
+ }) {
112
+ const [expanded, setExpanded] = useState(true);
113
+ const [logs, setLogs] = useState<string[]>(job.logs || []);
114
+ const logsRef = useRef<HTMLDivElement>(null);
115
+ const logIndex = useRef(logs.length);
116
+
117
+ useEffect(() => {
118
+ if (job.status === "completed" || job.status === "failed") return;
119
+
120
+ const interval = setInterval(async () => {
121
+ try {
122
+ const data = await fetchJobLogs(job.id, logIndex.current);
123
+ if (data.logs?.length) {
124
+ setLogs((prev) => [...prev, ...data.logs]);
125
+ logIndex.current = data.total_lines;
126
+ }
127
+ } catch {}
128
+ }, 1500);
129
+
130
+ return () => clearInterval(interval);
131
+ }, [job.id, job.status]);
132
+
133
+ useEffect(() => {
134
+ if (logsRef.current) logsRef.current.scrollTop = logsRef.current.scrollHeight;
135
+ }, [logs]);
136
+
137
+ const isActive = job.status !== "completed" && job.status !== "failed";
138
+
139
+ return (
140
+ <motion.div layout initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -10 }}>
141
+ <ElectricBorder color={job.status === "failed" ? "#ef4444" : "#8b5cf6"} active={isActive} speed={1.5} borderRadius={16}>
142
+ <div className="glass-card rounded-2xl overflow-hidden">
143
+ <div className="p-4 flex items-center justify-between">
144
+ <div className="flex items-center gap-3">
145
+ {isActive ? (
146
+ <Loader2 className="w-3.5 h-3.5 text-accent-violet animate-spin" />
147
+ ) : job.status === "completed" ? (
148
+ <CheckCircle2 className="w-3.5 h-3.5 text-success" />
149
+ ) : (
150
+ <XCircle className="w-3.5 h-3.5 text-error" />
151
+ )}
152
+ <div>
153
+ <p className="text-sm font-semibold">{job.skill_name}</p>
154
+ <div className="flex items-center gap-2 mt-0.5">
155
+ <span className="text-[10px] font-mono text-muted-foreground">
156
+ {STATUS_LABELS[job.status] || job.status}
157
+ </span>
158
+ {isActive && job.status === "optimizing" && (
159
+ <span className="text-[10px] font-mono text-accent-violet">
160
+ iter {job.current_iteration}/{job.iterations}
161
+ </span>
162
+ )}
163
+ {job.pid && <span className="text-[10px] font-mono text-muted-foreground/50">pid:{job.pid}</span>}
164
+ </div>
165
+ </div>
166
+ </div>
167
+
168
+ <div className="flex items-center gap-2">
169
+ {isActive && (
170
+ <ShinyText text={STATUS_LABELS[job.status] || "Running"} speed={2} color="#8b5cf6" shineColor="#c4b5fd" className="text-xs font-bold" />
171
+ )}
172
+ {isActive && (
173
+ <button onClick={() => onCancel(job.id)} className="p-1.5 rounded-lg bg-error/10 text-error hover:bg-error/20 transition-colors" title="Cancel">
174
+ <Square className="w-3 h-3" />
175
+ </button>
176
+ )}
177
+ <button onClick={() => setExpanded(!expanded)} className="p-1.5 rounded-lg bg-white/[0.03] text-muted-foreground hover:text-foreground transition-colors">
178
+ {expanded ? <ChevronDown className="w-3 h-3" /> : <ChevronRight className="w-3 h-3" />}
179
+ </button>
180
+ </div>
181
+ </div>
182
+
183
+ <div className="px-4 pb-2">
184
+ <ProgressBar progress={job.progress} status={job.status} />
185
+ </div>
186
+
187
+ {/* Scores */}
188
+ {(job.baseline_score !== null || job.evolved_score !== null || job.current_best_score !== null) && (
189
+ <div className="px-4 pb-2 flex items-center gap-4 text-xs flex-wrap">
190
+ {job.baseline_score !== null && (
191
+ <span className="text-muted-foreground">Baseline: <span className="font-mono">{(job.baseline_score * 100).toFixed(0)}%</span></span>
192
+ )}
193
+ {job.evolved_score !== null && (
194
+ <span className="text-accent-violet">Evolved: <span className="font-mono font-semibold">{(job.evolved_score * 100).toFixed(0)}%</span></span>
195
+ )}
196
+ {job.improvement !== null && job.improvement !== 0 && (
197
+ <span className={job.improvement > 0 ? "text-success" : "text-error"}>
198
+ {job.improvement > 0 ? "+" : ""}{(job.improvement * 100).toFixed(1)}%
199
+ </span>
200
+ )}
201
+ {job.current_best_score !== null && (
202
+ <span className="text-accent-cyan">Best: <span className="font-mono">{(job.current_best_score * 100).toFixed(0)}%</span></span>
203
+ )}
204
+ </div>
205
+ )}
206
+
207
+ {/* Error */}
208
+ {job.error && (
209
+ <div className="px-4 pb-2">
210
+ <div className="flex items-start gap-2 text-xs text-error bg-error/5 rounded-lg px-3 py-2">
211
+ <AlertCircle className="w-3.5 h-3.5 flex-shrink-0 mt-0.5" />
212
+ <span>{job.error}</span>
213
+ </div>
214
+ </div>
215
+ )}
216
+
217
+ {/* Logs */}
218
+ <AnimatePresence>
219
+ {expanded && (
220
+ <motion.div initial={{ height: 0 }} animate={{ height: "auto" }} exit={{ height: 0 }} className="overflow-hidden">
221
+ <div ref={logsRef} className="mx-4 mb-4 rounded-xl bg-black/50 border border-white/[0.04] max-h-48 overflow-y-auto">
222
+ <div className="p-3 font-mono text-[10px] leading-relaxed">
223
+ {logs.length === 0 ? (
224
+ <p className="text-muted-foreground/40">Waiting for output...</p>
225
+ ) : (
226
+ logs.map((line, i) => {
227
+ const isPhase = /Loaded:|Building|Validating|Configuring|Running|Evaluating|Optimization/.test(line);
228
+ const isError = /✗|Error|error|FAILED|failed/.test(line);
229
+ const isSuccess = /✓|completed|Saved/.test(line);
230
+ return (
231
+ <div key={i} className={isError ? "text-error" : isSuccess ? "text-success" : isPhase ? "text-accent-cyan font-semibold" : "text-muted-foreground/70"}>
232
+ {line}
233
+ </div>
234
+ );
235
+ })
236
+ )}
237
+ {isActive && <span className="cursor-blink text-muted-foreground/30" />}
238
+ </div>
239
+ </div>
240
+ </motion.div>
241
+ )}
242
+ </AnimatePresence>
243
+ </div>
244
+ </ElectricBorder>
245
+ </motion.div>
246
+ );
247
+ }
248
+
249
+ // ── Circuit Breaker Banner ────────────────────────────────────────────
250
+ function DisconnectedBanner({ onRetry }: { onRetry: () => void }) {
251
+ return (
252
+ <motion.div
253
+ initial={{ opacity: 0, y: -10 }}
254
+ animate={{ opacity: 1, y: 0 }}
255
+ className="glass-card rounded-2xl p-6 border border-error/20 bg-error/[0.03]"
256
+ >
257
+ <div className="flex items-start gap-4">
258
+ <div className="w-10 h-10 rounded-xl bg-error/10 flex items-center justify-center flex-shrink-0">
259
+ <WifiOff className="w-5 h-5 text-error" />
260
+ </div>
261
+ <div className="flex-1 min-w-0">
262
+ <h3 className="text-sm font-semibold text-foreground">Backend Unavailable</h3>
263
+ <p className="text-xs text-muted-foreground mt-1">
264
+ Hermes gateway is not responding. The service may be starting up or was restarted.
265
+ </p>
266
+ </div>
267
+ <ClickSpark sparkColor="#ef4444" sparkCount={8}>
268
+ <button
269
+ onClick={onRetry}
270
+ className="flex items-center gap-2 px-4 py-2 rounded-xl bg-error/10 text-error hover:bg-error/20 transition-colors text-sm font-medium"
271
+ >
272
+ <RefreshCw className="w-4 h-4" />
273
+ Retry
274
+ </button>
275
+ </ClickSpark>
276
+ </div>
277
+ </motion.div>
278
+ );
279
+ }
280
+
281
+ // ── Main Page ─────────────────────────────────────────────────────────
282
+ export default function EvolutionPage() {
283
+ const [runs, setRuns] = useState<EvolutionRun[]>([]);
284
+ const [skills, setSkills] = useState<SkillInfo[]>([]);
285
+ const [activeJobs, setActiveJobs] = useState<EvolutionJob[]>([]);
286
+ const [selectedSkill, setSelectedSkill] = useState("");
287
+ const [iterations, setIterations] = useState(3);
288
+ const [launching, setLaunching] = useState(false);
289
+ const [launchError, setLaunchError] = useState("");
290
+ const [loading, setLoading] = useState(true);
291
+ const [openDiff, setOpenDiff] = useState<{ skill: string; runDir: string } | null>(null);
292
+ const [validating, setValidating] = useState<string | null>(null);
293
+ const [validationResults, setValidationResults] = useState<Record<string, any>>({});
294
+
295
+ // Multi-provider state
296
+ const [evolvableProviders, setEvolvableProviders] = useState<EvolvableProvider[]>([]);
297
+ const [providerFilter, setProviderFilter] = useState<string>("all");
298
+
299
+ // Circuit Breaker state
300
+ const [connection, setConnection] = useState<ConnectionState>("checking");
301
+ const [connectionError, setConnectionError] = useState("");
302
+
303
+ const verifyConnection = useCallback(async (): Promise<boolean> => {
304
+ setConnection("checking");
305
+ const result = await checkHealth();
306
+ if (result.ok) {
307
+ setConnection("connected");
308
+ setConnectionError("");
309
+ return true;
310
+ }
311
+ setConnection("disconnected");
312
+ setConnectionError(result.message ?? "Cannot reach Hermes backend");
313
+ return false;
314
+ }, []);
315
+
316
+ const loadData = useCallback(async () => {
317
+ setLoading(true);
318
+
319
+ const ok = await verifyConnection();
320
+ if (!ok) {
321
+ setLoading(false);
322
+ return;
323
+ }
324
+
325
+ try {
326
+ const [r, s, j, ep] = await Promise.all([
327
+ fetchEvolutionRuns().catch((e) => {
328
+ if (isApiError(e)) setConnectionError(`${e.kind}: ${e.message}`);
329
+ return [] as EvolutionRun[];
330
+ }),
331
+ fetchSkills().catch((e) => {
332
+ if (isApiError(e)) setConnectionError(`${e.kind}: ${e.message}`);
333
+ return [] as SkillInfo[];
334
+ }),
335
+ fetchJobs(true).catch((e) => {
336
+ if (isApiError(e)) setConnectionError(`${e.kind}: ${e.message}`);
337
+ return [] as EvolutionJob[];
338
+ }),
339
+ api<{ status: string; providers: EvolvableProvider[] }>("/api/evolution/evolvable").catch(() => ({ status: "ok", providers: [] as EvolvableProvider[] })),
340
+ ]);
341
+ setRuns(r);
342
+ setSkills(s);
343
+ setActiveJobs(j);
344
+ setEvolvableProviders(ep.providers || []);
345
+ } catch (e) {
346
+ if (e instanceof Error) setConnectionError(e.message);
347
+ }
348
+ setLoading(false);
349
+ }, [verifyConnection]);
350
+
351
+ // Initial load + connection verification
352
+ useEffect(() => {
353
+ loadData();
354
+ }, [loadData]);
355
+
356
+ // Poll active jobs
357
+ useEffect(() => {
358
+ if (connection !== "connected") return;
359
+ const interval = setInterval(() => {
360
+ fetchJobs(true).then(setActiveJobs).catch(() => {});
361
+ }, 2000);
362
+ return () => clearInterval(interval);
363
+ }, [connection]);
364
+
365
+ const handleStart = async () => {
366
+ if (!selectedSkill) {
367
+ setLaunchError("Please select a skill first");
368
+ return;
369
+ }
370
+ if (iterations < 1 || iterations > 20) {
371
+ setLaunchError("Iterations must be between 1 and 20");
372
+ return;
373
+ }
374
+
375
+ setLaunching(true);
376
+ setLaunchError("");
377
+
378
+ try {
379
+ const result = await startEvolution(selectedSkill, iterations);
380
+
381
+ if (result.error) {
382
+ setLaunchError(result.error);
383
+ } else {
384
+ const jobs = await fetchJobs(true);
385
+ setActiveJobs(jobs);
386
+ setSelectedSkill("");
387
+ }
388
+ } catch (e: unknown) {
389
+ if (isApiError(e)) {
390
+ setLaunchError(`${e.kind}: ${e.message}`);
391
+ // Circuit breaker: mark disconnected on network errors
392
+ if (e.kind === "network" || e.kind === "timeout") {
393
+ setConnection("disconnected");
394
+ }
395
+ } else {
396
+ setLaunchError(e instanceof Error ? e.message : "Failed to start evolution");
397
+ }
398
+ }
399
+
400
+ setLaunching(false);
401
+ };
402
+
403
+ const handleCancel = async (jobId: string) => {
404
+ try {
405
+ await cancelJob(jobId);
406
+ setActiveJobs((prev) => prev.filter((j) => j.id !== jobId));
407
+ } catch {}
408
+ };
409
+
410
+ const handleValidate = async (skillName: string) => {
411
+ setValidating(skillName);
412
+ try {
413
+ const API_BASE = process.env.NEXT_PUBLIC_API_BASE || "http://localhost:8000";
414
+ const res = await fetch(`${API_BASE}/api/evolution/validate?skill_name=${skillName}`, { method: "POST" });
415
+ const data = await res.json();
416
+ setValidationResults(prev => ({ ...prev, [skillName]: data }));
417
+ } catch (e) {
418
+ setValidationResults(prev => ({ ...prev, [skillName]: { final_verdict: "ERROR", error: String(e) } }));
419
+ }
420
+ setValidating(null);
421
+ };
422
+
423
+ const handleRetry = async () => {
424
+ await loadData();
425
+ };
426
+
427
+ const runsBySkill = runs.reduce((acc, run) => {
428
+ (acc[run.skill_name] = acc[run.skill_name] || []).push(run);
429
+ return acc;
430
+ }, {} as Record<string, EvolutionRun[]>);
431
+
432
+ return (
433
+ <div className="space-y-6">
434
+ {/* Circuit Breaker — Disconnected banner */}
435
+ {connection === "disconnected" && <DisconnectedBanner onRetry={handleRetry} />}
436
+
437
+ {/* Active Evolutions */}
438
+ {connection === "connected" && activeJobs.length > 0 && (
439
+ <motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }} className="space-y-3">
440
+ <h2 className="text-sm font-semibold uppercase tracking-wider flex items-center gap-2">
441
+ <Activity className="w-4 h-4 text-accent-violet" />
442
+ Active Evolutions
443
+ <span className="text-[10px] font-mono text-accent-violet bg-accent-violet/10 px-2 py-0.5 rounded-full">{activeJobs.length}</span>
444
+ </h2>
445
+ <AnimatePresence>
446
+ {activeJobs.map((job) => (
447
+ <ActiveJobCard key={job.id} job={job} onCancel={handleCancel} />
448
+ ))}
449
+ </AnimatePresence>
450
+ </motion.div>
451
+ )}
452
+
453
+ {/* Launch Panel */}
454
+ {connection !== "disconnected" && (
455
+ <ElectricBorder color="#8b5cf6" active={launching} speed={1.5} borderRadius={16}>
456
+ <motion.div initial={{ opacity: 0, y: 15 }} animate={{ opacity: 1, y: 0 }} className="glass-card rounded-2xl p-6">
457
+ <h2 className="text-sm font-semibold uppercase tracking-wider flex items-center gap-2 mb-4">
458
+ <Zap className="w-4 h-4 text-accent-violet" />
459
+ Evolution Hub
460
+ {evolvableProviders.length > 0 && (
461
+ <span className="text-[10px] font-mono text-accent-violet bg-accent-violet/10 px-2 py-0.5 rounded-full ml-auto">
462
+ {evolvableProviders.reduce((acc, p) => acc + p.skills.length, 0)} skills · {evolvableProviders.length} providers
463
+ </span>
464
+ )}
465
+ </h2>
466
+
467
+ {/* Provider filter tabs */}
468
+ {evolvableProviders.length > 0 && (
469
+ <div className="flex gap-2 flex-wrap mb-4">
470
+ <button
471
+ onClick={() => setProviderFilter("all")}
472
+ className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all ${
473
+ providerFilter === "all"
474
+ ? "bg-white/10 text-white border border-white/20"
475
+ : "bg-white/[0.03] text-muted-foreground border border-transparent hover:border-white/10"
476
+ }`}
477
+ >
478
+ All
479
+ </button>
480
+ {evolvableProviders.map((p) => {
481
+ const meta = PROVIDER_META[p.provider] ?? { icon: "🔧", color: "" };
482
+ return (
483
+ <button
484
+ key={p.provider}
485
+ onClick={() => setProviderFilter(p.provider)}
486
+ className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-all flex items-center gap-1.5 ${
487
+ providerFilter === p.provider
488
+ ? "bg-accent-violet/10 text-accent-violet border border-accent-violet/20"
489
+ : "bg-white/[0.03] text-muted-foreground border border-transparent hover:border-white/10"
490
+ }`}
491
+ >
492
+ <span>{meta.icon}</span>
493
+ <span className="capitalize">{p.provider}</span>
494
+ <span className="text-[10px] opacity-50">({p.skills.length})</span>
495
+ </button>
496
+ );
497
+ })}
498
+ </div>
499
+ )}
500
+
501
+ <div className="flex flex-wrap items-end gap-4">
502
+ <div className="flex-1 min-w-[200px]">
503
+ <label className="text-xs text-muted-foreground mb-1 block">Skill</label>
504
+ {loading || connection === "checking" ? (
505
+ <div className="px-4 py-2.5 rounded-xl bg-[#1a1a1a] border border-white/[0.08] text-sm text-muted-foreground animate-pulse">
506
+ {connection === "checking" ? "Checking connection..." : "Loading skills..."}
507
+ </div>
508
+ ) : skills.length === 0 ? (
509
+ <div className="px-4 py-2.5 rounded-xl bg-[#1a1a1a] border border-white/[0.08] text-sm text-error flex items-center gap-2">
510
+ <AlertCircle className="w-3.5 h-3.5" />
511
+ No skills found — check backend connection
512
+ </div>
513
+ ) : (
514
+ <DarkSelect
515
+ value={selectedSkill}
516
+ onChange={setSelectedSkill}
517
+ placeholder="Select a skill..."
518
+ options={skills.map((s) => ({
519
+ value: s.name,
520
+ label: `${s.name} (${s.provider_count} provider${s.provider_count > 1 ? "s" : ""})`,
521
+ }))}
522
+ />
523
+ )}
524
+ </div>
525
+
526
+ <div className="w-32">
527
+ <label className="text-xs text-muted-foreground mb-1 block">Iterations</label>
528
+ <input
529
+ type="number"
530
+ min={1}
531
+ max={20}
532
+ value={iterations}
533
+ onChange={(e) => {
534
+ const v = parseInt(e.target.value);
535
+ if (!isNaN(v) && v >= 1 && v <= 20) setIterations(v);
536
+ }}
537
+ className="w-full px-4 py-2.5 rounded-xl bg-[#1a1a1a] border border-white/[0.08] text-sm text-foreground focus:outline-none focus:border-accent-violet/50"
538
+ />
539
+ <p className="text-[10px] text-muted-foreground mt-1">Current: {iterations}</p>
540
+ </div>
541
+
542
+ <ClickSpark sparkColor="#8b5cf6" sparkCount={10}>
543
+ <button
544
+ onClick={handleStart}
545
+ disabled={!selectedSkill || launching}
546
+ className="flex items-center gap-2 px-5 py-2.5 rounded-xl bg-accent-violet text-white text-sm font-medium hover:bg-accent-violet/90 transition-colors disabled:opacity-40"
547
+ >
548
+ {launching ? <Loader2 className="w-4 h-4 animate-spin" /> : <Play className="w-4 h-4" />}
549
+ {launching ? "Starting..." : `Evolve (${iterations} iter${iterations > 1 ? "s" : ""})`}
550
+ </button>
551
+ </ClickSpark>
552
+ </div>
553
+
554
+ {launchError && (
555
+ <motion.div initial={{ opacity: 0, y: -5 }} animate={{ opacity: 1, y: 0 }} className="mt-3 flex items-start gap-2 text-xs text-error bg-error/5 rounded-lg px-3 py-2">
556
+ <AlertCircle className="w-3.5 h-3.5 flex-shrink-0 mt-0.5" />
557
+ <span>{launchError}</span>
558
+ </motion.div>
559
+ )}
560
+ </motion.div>
561
+ </ElectricBorder>
562
+ )}
563
+
564
+ {/* Evolution History */}
565
+ {connection !== "disconnected" && (
566
+ <motion.div initial={{ opacity: 0, y: 15 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.2 }} className="glass-card rounded-2xl p-6">
567
+ <h2 className="text-sm font-semibold uppercase tracking-wider flex items-center gap-2 mb-4">
568
+ <GitBranch className="w-4 h-4 text-accent-cyan" />
569
+ Evolution History
570
+ </h2>
571
+
572
+ {connection === "checking" && (
573
+ <p className="text-sm text-muted-foreground py-8 text-center">Checking connection...</p>
574
+ )}
575
+ {!loading && connection === "connected" && Object.keys(runsBySkill).length === 0 && (
576
+ <p className="text-sm text-muted-foreground py-8 text-center">No evolution runs yet.</p>
577
+ )}
578
+ {Object.keys(runsBySkill).length > 0 && (
579
+ <div className="space-y-6">
580
+ {Object.entries(runsBySkill).map(([skillName, skillRuns]) => (
581
+ <div key={skillName}>
582
+ <div className="flex items-center gap-3 mb-3">
583
+ <div className="w-3 h-3 rounded-full bg-accent-violet" />
584
+ <span className="text-sm font-semibold">{skillName}</span>
585
+ <span className="text-[10px] text-muted-foreground font-mono">{skillRuns.length} run{skillRuns.length > 1 ? "s" : ""}</span>
586
+ {/* Validation badge */}
587
+ {validationResults[skillName] && (
588
+ <span className={`text-[10px] px-1.5 py-0.5 rounded font-mono ${
589
+ validationResults[skillName].final_verdict?.includes("PASS") ? "bg-success/10 text-success" :
590
+ validationResults[skillName].final_verdict?.includes("MIXED") ? "bg-accent-cyan/10 text-accent-cyan" :
591
+ "bg-error/10 text-error"
592
+ }`}>
593
+ {validationResults[skillName].final_verdict}
594
+ </span>
595
+ )}
596
+ <button
597
+ onClick={() => handleValidate(skillName)}
598
+ disabled={validating === skillName}
599
+ className="text-[10px] px-2 py-0.5 rounded-lg bg-accent-violet/10 text-accent-violet hover:bg-accent-violet/20 transition-colors disabled:opacity-50"
600
+ >
601
+ {validating === skillName ? "..." : "Validate"}
602
+ </button>
603
+ </div>
604
+ <div className="ml-6 border-l border-white/[0.08] pl-6 space-y-3">
605
+ {skillRuns.map((run, i) => {
606
+ const improved = (run.improvement ?? 0) > 0;
607
+ const regressed = (run.improvement ?? 0) < 0;
608
+ return (
609
+ <motion.div key={i} initial={{ opacity: 0, x: -10 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: i * 0.1 }}>
610
+ <SpotlightCard
611
+ spotlightColor={improved ? "rgba(34,197,94,0.08)" : regressed ? "rgba(239,68,68,0.08)" : "rgba(255,255,255,0.03)"}
612
+ className="relative flex items-start gap-4 p-4 rounded-xl border border-white/[0.04]"
613
+ >
614
+ <div className="absolute -left-[31px] top-5 w-2 h-2 rounded-full bg-white/20" />
615
+ {run.constraints_passed ? <CheckCircle2 className="w-4 h-4 text-success flex-shrink-0 mt-0.5" /> : <XCircle className="w-4 h-4 text-error flex-shrink-0 mt-0.5" />}
616
+ <div className="flex-1 min-w-0">
617
+ <div className="flex items-center gap-2">
618
+ <span className="text-xs font-mono text-muted-foreground">{run.timestamp}</span>
619
+ <span className="text-[10px] px-1.5 py-0.5 rounded bg-white/[0.05] text-muted-foreground">{run.iterations} iters</span>
620
+ </div>
621
+ <div className="flex items-center gap-3 mt-2">
622
+ <div className="text-sm">
623
+ <span className="text-muted-foreground font-mono">{(run.baseline_score * 100).toFixed(0)}%</span>
624
+ <span className="text-muted-foreground mx-2">→</span>
625
+ <span className={`font-mono font-semibold ${improved ? "text-success" : regressed ? "text-error" : "text-muted-foreground"}`}>
626
+ {(run.evolved_score * 100).toFixed(0)}%
627
+ </span>
628
+ </div>
629
+ {improved ? <TrendingUp className="w-3.5 h-3.5 text-success" /> : regressed ? <TrendingDown className="w-3.5 h-3.5 text-error" /> : <Minus className="w-3.5 h-3.5 text-muted-foreground" />}
630
+ </div>
631
+ </div>
632
+ <div className="flex items-center gap-2">
633
+ <div className="flex items-center gap-1 text-[10px] text-muted-foreground">
634
+ <Clock className="w-3 h-3" />
635
+ {run.elapsed_seconds?.toFixed(0)}s
636
+ </div>
637
+ <button
638
+ onClick={(e) => {
639
+ e.stopPropagation();
640
+ if (openDiff?.skill === skillName && openDiff?.runDir === run.timestamp) {
641
+ setOpenDiff(null);
642
+ } else {
643
+ setOpenDiff({ skill: skillName, runDir: run.timestamp });
644
+ }
645
+ }}
646
+ className={`text-[10px] px-2 py-0.5 rounded-lg transition-colors border ${
647
+ openDiff?.skill === skillName && openDiff?.runDir === run.timestamp
648
+ ? "bg-accent-violet/10 text-accent-violet border-accent-violet/20"
649
+ : "bg-white/[0.03] text-muted-foreground hover:text-foreground hover:bg-white/[0.08] border-white/[0.06]"
650
+ }`}
651
+ >
652
+ <GitBranch className="w-3 h-3 inline mr-0.5" />
653
+ {openDiff?.skill === skillName && openDiff?.runDir === run.timestamp ? "Close" : "Diff"}
654
+ </button>
655
+ </div>
656
+ </SpotlightCard>
657
+ {openDiff?.skill === skillName && openDiff?.runDir === run.timestamp && (
658
+ <SkillDiffViewer
659
+ skillName={skillName}
660
+ runDir={run.timestamp}
661
+ onClose={() => setOpenDiff(null)}
662
+ />
663
+ )}
664
+ </motion.div>
665
+ );
666
+ })}
667
+ </div>
668
+ </div>
669
+ ))}
670
+ </div>
671
+ )}
672
+ </motion.div>
673
+ )}
674
+ </div>
675
+ );
676
+ }
@@ -0,0 +1 @@
1
+ // File removed. This page was part of the old Function Calling feature.