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,54 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+ import { Sun, Moon } from "lucide-react";
5
+
6
+ export default function ThemeToggle() {
7
+ const [isDark, setIsDark] = useState(true);
8
+ const [mounted, setMounted] = useState(false);
9
+
10
+ useEffect(() => {
11
+ setMounted(true);
12
+ const saved = localStorage.getItem("genoma-theme");
13
+ const prefersDark = saved ? saved === "dark" : true;
14
+ setIsDark(prefersDark);
15
+ if (prefersDark) {
16
+ document.documentElement.classList.add("dark");
17
+ } else {
18
+ document.documentElement.classList.remove("dark");
19
+ }
20
+ }, []);
21
+
22
+ const toggle = () => {
23
+ const next = !isDark;
24
+ setIsDark(next);
25
+ localStorage.setItem("genoma-theme", next ? "dark" : "light");
26
+ if (next) {
27
+ document.documentElement.classList.add("dark");
28
+ } else {
29
+ document.documentElement.classList.remove("dark");
30
+ }
31
+ };
32
+
33
+ if (!mounted) {
34
+ return (
35
+ <button className="w-9 h-9 rounded-lg flex items-center justify-center text-gray-400">
36
+ <Sun className="w-5 h-5" />
37
+ </button>
38
+ );
39
+ }
40
+
41
+ return (
42
+ <button
43
+ onClick={toggle}
44
+ className={`w-9 h-9 rounded-lg flex items-center justify-center transition-all duration-200 ${
45
+ isDark
46
+ ? "bg-gray-800 text-yellow-400 hover:bg-gray-700"
47
+ : "bg-white text-primary-600 shadow-[var(--evo-shadow-md)] border border-gray-200 hover:bg-[var(--evo-bg-surface-hover)]"
48
+ }`}
49
+ title={isDark ? "Cambiar a Light Mode" : "Cambiar a Dark Mode"}
50
+ >
51
+ {isDark ? <Moon className="w-5 h-5" /> : <Sun className="w-5 h-5" />}
52
+ </button>
53
+ );
54
+ }
@@ -0,0 +1,77 @@
1
+ "use client";
2
+
3
+ import { motion } from "framer-motion";
4
+ import { Sparkles, Dna } from "lucide-react";
5
+
6
+ export default function WelcomeHero() {
7
+ return (
8
+ <motion.section
9
+ initial={{ opacity: 0, y: 20 }}
10
+ animate={{ opacity: 1, y: 0 }}
11
+ transition={{ duration: 0.8, ease: [0.25, 0.46, 0.45, 0.94] }}
12
+ className="relative flex flex-col items-center justify-center py-20 px-4 overflow-hidden"
13
+ >
14
+ {/* Background orbs */}
15
+ <div className="absolute inset-0 overflow-hidden pointer-events-none">
16
+ <motion.div
17
+ animate={{ scale: [1, 1.2, 1], opacity: [0.08, 0.15, 0.08] }}
18
+ transition={{ duration: 6, repeat: Infinity, ease: "easeInOut" }}
19
+ className="absolute top-1/4 left-1/4 w-96 h-96 rounded-full"
20
+ style={{
21
+ background: "radial-gradient(circle, rgba(139,92,246,0.3) 0%, transparent 70%)",
22
+ }}
23
+ />
24
+ <motion.div
25
+ animate={{ scale: [1.2, 1, 1.2], opacity: [0.08, 0.12, 0.08] }}
26
+ transition={{ duration: 8, repeat: Infinity, ease: "easeInOut", delay: 2 }}
27
+ className="absolute bottom-1/4 right-1/4 w-96 h-96 rounded-full"
28
+ style={{
29
+ background: "radial-gradient(circle, rgba(6,182,212,0.3) 0%, transparent 70%)",
30
+ }}
31
+ />
32
+ </div>
33
+
34
+ {/* Badge */}
35
+ <motion.div
36
+ initial={{ opacity: 0, scale: 0.9 }}
37
+ animate={{ opacity: 1, scale: 1 }}
38
+ transition={{ delay: 0.3, duration: 0.5 }}
39
+ className="flex items-center gap-2 px-4 py-1.5 rounded-full glass-card mb-6"
40
+ >
41
+ <Dna className="w-3.5 h-3.5 text-accent-violet" />
42
+ <span className="text-xs font-medium text-muted-foreground tracking-wide uppercase">
43
+ Autonomous Evolution Interface
44
+ </span>
45
+ <Sparkles className="w-3.5 h-3.5 text-accent-cyan" />
46
+ </motion.div>
47
+
48
+ {/* Title */}
49
+ <motion.h1
50
+ initial={{ opacity: 0, y: 10 }}
51
+ animate={{ opacity: 1, y: 0 }}
52
+ transition={{ delay: 0.5, duration: 0.8 }}
53
+ className="text-5xl md:text-7xl font-bold text-center leading-tight tracking-tight"
54
+ >
55
+ <span className="gradient-text">Genoma</span>
56
+ </motion.h1>
57
+
58
+ {/* Subtitle */}
59
+ <motion.p
60
+ initial={{ opacity: 0 }}
61
+ animate={{ opacity: 1 }}
62
+ transition={{ delay: 0.8, duration: 0.6 }}
63
+ className="mt-4 text-lg md:text-xl text-muted-foreground text-center max-w-xl"
64
+ >
65
+ Self-evolving intelligence. Zero-friction setup.
66
+ </motion.p>
67
+
68
+ {/* Divider line */}
69
+ <motion.div
70
+ initial={{ scaleX: 0 }}
71
+ animate={{ scaleX: 1 }}
72
+ transition={{ delay: 1.0, duration: 0.8, ease: "easeOut" }}
73
+ className="mt-10 w-full max-w-2xl h-px bg-gradient-to-r from-transparent via-white/10 to-transparent"
74
+ />
75
+ </motion.section>
76
+ );
77
+ }
@@ -0,0 +1,116 @@
1
+ "use client";
2
+
3
+ import { useRef, useEffect, useCallback } from "react";
4
+
5
+ interface ClickSparkProps {
6
+ children: React.ReactNode;
7
+ sparkColor?: string;
8
+ sparkSize?: number;
9
+ sparkRadius?: number;
10
+ sparkCount?: number;
11
+ duration?: number;
12
+ className?: string;
13
+ }
14
+
15
+ export default function ClickSpark({
16
+ children,
17
+ sparkColor = "#8b5cf6",
18
+ sparkSize = 8,
19
+ sparkRadius = 20,
20
+ sparkCount = 8,
21
+ duration = 400,
22
+ className = "",
23
+ }: ClickSparkProps) {
24
+ const canvasRef = useRef<HTMLCanvasElement>(null);
25
+ const sparksRef = useRef<
26
+ Array<{ x: number; y: number; angle: number; startTime: number }>
27
+ >([]);
28
+
29
+ useEffect(() => {
30
+ const canvas = canvasRef.current;
31
+ if (!canvas) return;
32
+ const parent = canvas.parentElement;
33
+ if (!parent) return;
34
+
35
+ const resize = () => {
36
+ const { width, height } = parent.getBoundingClientRect();
37
+ canvas.width = width;
38
+ canvas.height = height;
39
+ };
40
+
41
+ resize();
42
+ const ro = new ResizeObserver(resize);
43
+ ro.observe(parent);
44
+
45
+ const ctx = canvas.getContext("2d");
46
+ if (!ctx) return;
47
+
48
+ let raf: number;
49
+
50
+ const draw = (ts: number) => {
51
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
52
+
53
+ sparksRef.current = sparksRef.current.filter((spark) => {
54
+ const elapsed = ts - spark.startTime;
55
+ if (elapsed > duration) return false;
56
+
57
+ const progress = elapsed / duration;
58
+ const dist = sparkRadius * progress;
59
+ const opacity = 1 - progress;
60
+
61
+ const x = spark.x + Math.cos(spark.angle) * dist;
62
+ const y = spark.y + Math.sin(spark.angle) * dist;
63
+
64
+ ctx.beginPath();
65
+ ctx.arc(x, y, sparkSize * (1 - progress) * 0.5, 0, Math.PI * 2);
66
+ ctx.fillStyle = sparkColor;
67
+ ctx.globalAlpha = opacity;
68
+ ctx.fill();
69
+ ctx.globalAlpha = 1;
70
+
71
+ return true;
72
+ });
73
+
74
+ raf = requestAnimationFrame(draw);
75
+ };
76
+
77
+ raf = requestAnimationFrame(draw);
78
+
79
+ return () => {
80
+ cancelAnimationFrame(raf);
81
+ ro.disconnect();
82
+ };
83
+ }, [sparkColor, sparkSize, sparkRadius, sparkCount, duration]);
84
+
85
+ const handleClick = useCallback(
86
+ (e: React.MouseEvent) => {
87
+ const canvas = canvasRef.current;
88
+ if (!canvas) return;
89
+ const rect = canvas.getBoundingClientRect();
90
+ const x = e.clientX - rect.left;
91
+ const y = e.clientY - rect.top;
92
+ const now = performance.now();
93
+
94
+ for (let i = 0; i < sparkCount; i++) {
95
+ sparksRef.current.push({
96
+ x,
97
+ y,
98
+ angle: (Math.PI * 2 * i) / sparkCount,
99
+ startTime: now,
100
+ });
101
+ }
102
+ },
103
+ [sparkCount]
104
+ );
105
+
106
+ return (
107
+ <div className={`relative ${className}`} onClick={handleClick}>
108
+ <canvas
109
+ ref={canvasRef}
110
+ className="absolute inset-0 pointer-events-none"
111
+ style={{ zIndex: 50 }}
112
+ />
113
+ {children}
114
+ </div>
115
+ );
116
+ }
@@ -0,0 +1,98 @@
1
+ "use client";
2
+
3
+ import { useRef, useEffect, useCallback, useState } from "react";
4
+ import { useInView, useMotionValue, useSpring } from "framer-motion";
5
+
6
+ interface CountUpProps {
7
+ to: number;
8
+ from?: number;
9
+ direction?: "up" | "down";
10
+ delay?: number;
11
+ duration?: number;
12
+ className?: string;
13
+ separator?: string;
14
+ onStart?: () => void;
15
+ onEnd?: () => void;
16
+ }
17
+
18
+ export default function CountUp({
19
+ to,
20
+ from = 0,
21
+ direction = "up",
22
+ delay = 0,
23
+ duration = 2,
24
+ className = "",
25
+ separator = "",
26
+ onStart,
27
+ onEnd,
28
+ }: CountUpProps) {
29
+ const ref = useRef<HTMLSpanElement>(null);
30
+ const motionValue = useMotionValue(direction === "down" ? to : from);
31
+ const damping = 20 + 40 * (1 / duration);
32
+ const stiffness = 100 * (1 / duration);
33
+ const springValue = useSpring(motionValue, { damping, stiffness });
34
+ const isInView = useInView(ref, { once: true, margin: "0px" });
35
+ const [displayValue, setDisplayValue] = useState<string>(
36
+ () => formatValue(direction === "down" ? to : from, from, to, separator)
37
+ );
38
+
39
+ const maxDecimals = Math.max(
40
+ getDecimalPlaces(from),
41
+ getDecimalPlaces(to)
42
+ );
43
+
44
+ // Spring animation → state update (never mutates DOM)
45
+ useEffect(() => {
46
+ const unsubscribe = springValue.on("change", (latest) => {
47
+ setDisplayValue(formatValue(latest, from, to, separator));
48
+ });
49
+ return unsubscribe;
50
+ }, [springValue, from, to, separator]);
51
+
52
+ // Trigger animation on enter viewport
53
+ useEffect(() => {
54
+ if (isInView) {
55
+ onStart?.();
56
+ const timeout = setTimeout(() => {
57
+ motionValue.set(direction === "down" ? from : to);
58
+ }, delay * 1000);
59
+ const endTimeout = setTimeout(() => {
60
+ onEnd?.();
61
+ }, delay * 1000 + duration * 1000);
62
+ return () => {
63
+ clearTimeout(timeout);
64
+ clearTimeout(endTimeout);
65
+ };
66
+ }
67
+ }, [isInView, from, to, direction, delay, duration, motionValue, onStart, onEnd]);
68
+
69
+ return <span ref={ref} className={className}>{displayValue}</span>;
70
+ }
71
+
72
+ // ── Helpers ──
73
+
74
+ function getDecimalPlaces(num: number): number {
75
+ const str = num.toString();
76
+ if (str.includes(".")) {
77
+ const decimals = str.split(".")[1];
78
+ if (parseInt(decimals) !== 0) return decimals.length;
79
+ }
80
+ return 0;
81
+ }
82
+
83
+ function formatValue(
84
+ value: number,
85
+ from: number,
86
+ to: number,
87
+ separator: string
88
+ ): string {
89
+ const maxDecimals = Math.max(getDecimalPlaces(from), getDecimalPlaces(to));
90
+ const hasDecimals = maxDecimals > 0;
91
+ const options: Intl.NumberFormatOptions = {
92
+ useGrouping: !!separator,
93
+ minimumFractionDigits: hasDecimals ? maxDecimals : 0,
94
+ maximumFractionDigits: hasDecimals ? maxDecimals : 0,
95
+ };
96
+ const formatted = new Intl.NumberFormat("en-US", options).format(value);
97
+ return separator ? formatted.replace(/,/g, separator) : formatted;
98
+ }
@@ -0,0 +1,95 @@
1
+ "use client";
2
+
3
+ import { useState, useRef, useEffect } from "react";
4
+ import { motion, AnimatePresence } from "framer-motion";
5
+ import { ChevronDown, Check } from "lucide-react";
6
+
7
+ interface Option {
8
+ value: string;
9
+ label: string;
10
+ }
11
+
12
+ interface DarkSelectProps {
13
+ value: string;
14
+ onChange: (value: string) => void;
15
+ options: Option[];
16
+ placeholder?: string;
17
+ }
18
+
19
+ export default function DarkSelect({
20
+ value,
21
+ onChange,
22
+ options,
23
+ placeholder = "Select...",
24
+ }: DarkSelectProps) {
25
+ const [open, setOpen] = useState(false);
26
+ const ref = useRef<HTMLDivElement>(null);
27
+
28
+ const selected = options.find((o) => o.value === value);
29
+
30
+ useEffect(() => {
31
+ const handleClick = (e: MouseEvent) => {
32
+ if (ref.current && !ref.current.contains(e.target as Node)) {
33
+ setOpen(false);
34
+ }
35
+ };
36
+ document.addEventListener("mousedown", handleClick);
37
+ return () => document.removeEventListener("mousedown", handleClick);
38
+ }, []);
39
+
40
+ return (
41
+ <div ref={ref} className="relative">
42
+ <button
43
+ type="button"
44
+ onClick={() => setOpen(!open)}
45
+ className="w-full flex items-center justify-between px-4 py-2.5 rounded-xl bg-[#1a1a1a] border border-white/[0.08] text-sm text-[#e5e5e5] hover:border-white/[0.15] transition-colors focus:outline-none focus:border-accent-violet/50"
46
+ >
47
+ <span className={!selected ? "text-[#666]" : ""}>
48
+ {selected ? selected.label : placeholder}
49
+ </span>
50
+ <ChevronDown
51
+ className={`w-4 h-4 text-[#888] transition-transform ${
52
+ open ? "rotate-180" : ""
53
+ }`}
54
+ />
55
+ </button>
56
+
57
+ <AnimatePresence>
58
+ {open && (
59
+ <motion.div
60
+ initial={{ opacity: 0, y: -4 }}
61
+ animate={{ opacity: 1, y: 0 }}
62
+ exit={{ opacity: 0, y: -4 }}
63
+ transition={{ duration: 0.15 }}
64
+ className="absolute z-50 top-full left-0 right-0 mt-1 rounded-xl bg-[#121212] border border-white/[0.08] shadow-2xl overflow-hidden max-h-60 overflow-y-auto"
65
+ >
66
+ {options.length === 0 ? (
67
+ <div className="px-4 py-3 text-sm text-[#666]">No options</div>
68
+ ) : (
69
+ options.map((opt) => (
70
+ <button
71
+ key={opt.value}
72
+ type="button"
73
+ onClick={() => {
74
+ onChange(opt.value);
75
+ setOpen(false);
76
+ }}
77
+ className={`w-full flex items-center justify-between px-4 py-2.5 text-sm transition-colors ${
78
+ opt.value === value
79
+ ? "bg-accent-violet/15 text-[#ffffff]"
80
+ : "text-[#cccccc] hover:bg-white/[0.06] hover:text-[#ffffff]"
81
+ }`}
82
+ >
83
+ <span className="truncate">{opt.label}</span>
84
+ {opt.value === value && (
85
+ <Check className="w-3.5 h-3.5 text-accent-violet flex-shrink-0" />
86
+ )}
87
+ </button>
88
+ ))
89
+ )}
90
+ </motion.div>
91
+ )}
92
+ </AnimatePresence>
93
+ </div>
94
+ );
95
+ }
@@ -0,0 +1,161 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState, useRef, useMemo, useCallback } from "react";
4
+ import { motion } from "framer-motion";
5
+
6
+ interface DecryptedTextProps {
7
+ text: string;
8
+ speed?: number;
9
+ maxIterations?: number;
10
+ sequential?: boolean;
11
+ revealDirection?: "start" | "end" | "center";
12
+ useOriginalCharsOnly?: boolean;
13
+ characters?: string;
14
+ className?: string;
15
+ parentClassName?: string;
16
+ encryptedClassName?: string;
17
+ animateOn?: "hover" | "view" | "click";
18
+ }
19
+
20
+ export default function DecryptedText({
21
+ text,
22
+ speed = 50,
23
+ maxIterations = 10,
24
+ sequential = false,
25
+ revealDirection = "start",
26
+ useOriginalCharsOnly = false,
27
+ characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+",
28
+ className = "",
29
+ parentClassName = "",
30
+ encryptedClassName = "",
31
+ animateOn = "hover",
32
+ }: DecryptedTextProps) {
33
+ const [displayText, setDisplayText] = useState(text);
34
+ const [isAnimating, setIsAnimating] = useState(false);
35
+ const [revealedIndices, setRevealedIndices] = useState<Set<number>>(new Set());
36
+ const containerRef = useRef<HTMLSpanElement>(null);
37
+ const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
38
+
39
+ const availableChars = useMemo(() => {
40
+ return useOriginalCharsOnly
41
+ ? Array.from(new Set(text.split(""))).filter((c) => c !== " ")
42
+ : characters.split("");
43
+ }, [useOriginalCharsOnly, text, characters]);
44
+
45
+ const shuffleText = useCallback(
46
+ (original: string, revealed: Set<number>) => {
47
+ return original
48
+ .split("")
49
+ .map((char, i) => {
50
+ if (char === " ") return " ";
51
+ if (revealed.has(i)) return original[i];
52
+ return availableChars[Math.floor(Math.random() * availableChars.length)];
53
+ })
54
+ .join("");
55
+ },
56
+ [availableChars]
57
+ );
58
+
59
+ const getOrder = useCallback(
60
+ (len: number) => {
61
+ const order: number[] = [];
62
+ if (revealDirection === "start") {
63
+ for (let i = 0; i < len; i++) order.push(i);
64
+ } else if (revealDirection === "end") {
65
+ for (let i = len - 1; i >= 0; i--) order.push(i);
66
+ } else {
67
+ const mid = Math.floor(len / 2);
68
+ order.push(mid);
69
+ for (let i = 1; i <= mid; i++) {
70
+ if (mid - i >= 0) order.push(mid - i);
71
+ if (mid + i < len) order.push(mid + i);
72
+ }
73
+ }
74
+ return order;
75
+ },
76
+ [revealDirection]
77
+ );
78
+
79
+ const startAnimation = useCallback(() => {
80
+ if (isAnimating) return;
81
+ setIsAnimating(true);
82
+ setRevealedIndices(new Set());
83
+
84
+ let iteration = 0;
85
+ const order = getOrder(text.length);
86
+
87
+ intervalRef.current = setInterval(() => {
88
+ if (sequential) {
89
+ setRevealedIndices((prev) => {
90
+ const next = new Set(prev);
91
+ const nextIdx = order[next.size];
92
+ if (nextIdx !== undefined) next.add(nextIdx);
93
+ if (next.size >= text.length) {
94
+ clearInterval(intervalRef.current!);
95
+ setIsAnimating(false);
96
+ }
97
+ return next;
98
+ });
99
+ } else {
100
+ iteration++;
101
+ const revealed = new Set<number>();
102
+ const numToReveal = Math.floor((iteration / maxIterations) * text.length);
103
+ for (let i = 0; i < numToReveal && i < order.length; i++) {
104
+ revealed.add(order[i]);
105
+ }
106
+ setRevealedIndices(revealed);
107
+ if (iteration >= maxIterations) {
108
+ clearInterval(intervalRef.current!);
109
+ setIsAnimating(false);
110
+ }
111
+ }
112
+ }, speed);
113
+ }, [isAnimating, text, sequential, maxIterations, speed, getOrder]);
114
+
115
+ useEffect(() => {
116
+ if (animateOn === "view") {
117
+ const observer = new IntersectionObserver(
118
+ ([entry]) => {
119
+ if (entry.isIntersecting) startAnimation();
120
+ },
121
+ { threshold: 0.1 }
122
+ );
123
+ if (containerRef.current) observer.observe(containerRef.current);
124
+ return () => observer.disconnect();
125
+ }
126
+ }, [animateOn, startAnimation]);
127
+
128
+ useEffect(() => {
129
+ if (isAnimating) {
130
+ setDisplayText(shuffleText(text, revealedIndices));
131
+ } else if (revealedIndices.size === 0 && animateOn !== "view") {
132
+ setDisplayText(text);
133
+ } else {
134
+ setDisplayText(
135
+ text
136
+ .split("")
137
+ .map((c, i) => (revealedIndices.has(i) ? c : c === " " ? " " : availableChars[Math.floor(Math.random() * availableChars.length)]))
138
+ .join("")
139
+ );
140
+ }
141
+ }, [isAnimating, revealedIndices, text, shuffleText, availableChars, animateOn]);
142
+
143
+ useEffect(() => {
144
+ return () => {
145
+ if (intervalRef.current) clearInterval(intervalRef.current);
146
+ };
147
+ }, []);
148
+
149
+ return (
150
+ <motion.span
151
+ ref={containerRef}
152
+ className={`inline-block whitespace-pre-wrap ${parentClassName}`}
153
+ onMouseEnter={animateOn === "hover" ? startAnimation : undefined}
154
+ onClick={animateOn === "click" ? startAnimation : undefined}
155
+ >
156
+ <span className={isAnimating ? encryptedClassName : className}>
157
+ {displayText}
158
+ </span>
159
+ </motion.span>
160
+ );
161
+ }