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,405 @@
1
+ # Agent-Agnostic Agent Intelligence Platform Plan
2
+
3
+ > **For Hermes:** Use `subagent-driven-development` only after the spec is approved. This plan is deliberately agent-agnostic so Claude Code, OpenCode, Codex, Hermes, and future agents can all emit comparable telemetry.
4
+
5
+ **Goal:** Build a vendor-neutral platform that works with *any* agent, ingests their runs through explicit collectors, normalizes execution traces, evaluates outcomes, and surfaces measurable improvements through a dashboard.
6
+
7
+ **Architecture:** The system is split into four layers: (1) collectors / adapters that ingest each agent’s native CLI or log output into a shared event schema, (2) a normalization and storage layer, (3) an evaluation engine that runs tests/scoring/benchmarks, and (4) a dashboard/API layer that reads the stored data and visualizes runs, comparisons, regressions, and suggested improvements. The dashboard does not capture runs; it is a consumer of the platform’s data.
8
+
9
+ **Tech Stack:** Shared event schema in JSONL or SQLite/Postgres, CLI collectors and adapter modules per agent, evaluation workers, web dashboard, optional MCP server for agent access, and export/import hooks for CI and PR workflows.
10
+
11
+ ---
12
+
13
+ ## Problem Statement
14
+
15
+ Today, agent improvements are usually trapped inside a single ecosystem. That creates three problems:
16
+
17
+ 1. The data model is proprietary to one agent.
18
+ 2. Evaluation results are not comparable across tools.
19
+ 3. Improvement loops cannot be reused by different agents.
20
+
21
+ The product should solve the opposite problem: *one canonical telemetry and improvement layer* that any agent can plug into.
22
+
23
+ ---
24
+
25
+ ## Non-Goals
26
+
27
+ - Rebuilding Claude Code, OpenCode, Codex, or Hermes internally.
28
+ - Forcing all agents to use the same runtime or CLI.
29
+ - Optimizing for pretty charts before having trustworthy data.
30
+ - Automating code changes without review or rollback.
31
+
32
+ ---
33
+
34
+ ## Product Shape
35
+
36
+ The system should answer these questions:
37
+
38
+ - What did the agent try to do?
39
+ - Which tools did it call?
40
+ - What files or artifacts changed?
41
+ - Where did it fail?
42
+ - Did the change improve the target metric?
43
+ - How does one agent compare with another on the same task?
44
+
45
+ If it cannot answer those questions, it is not yet the product.
46
+
47
+ ---
48
+
49
+ ## Core Concepts
50
+
51
+ ### 1) Collector / Ingestor
52
+ A small module or wrapper that captures a native agent run from CLI output, logs, JSON, or session files and converts it into the canonical schema.
53
+
54
+ Examples:
55
+ - Hermes CLI collector
56
+ - Claude Code collector
57
+ - Codex collector
58
+ - OpenCode collector
59
+
60
+ The collector is the only layer that knows how a specific agent speaks. Everything after this point should be agent-neutral.
61
+
62
+ ### 2) Canonical Run Event Schema
63
+ Minimum fields:
64
+
65
+ - `run_id`
66
+ - `agent_name`
67
+ - `provider`
68
+ - `model`
69
+ - `repo`
70
+ - `session_id`
71
+ - `task_name`
72
+ - `started_at`
73
+ - `ended_at`
74
+ - `tool_calls[]`
75
+ - `files_touched[]`
76
+ - `artifacts[]`
77
+ - `errors[]`
78
+ - `metrics{}`
79
+ - `eval_scores[]`
80
+ - `improvement_candidates[]`
81
+
82
+ ### 3) Normalization + Storage Layer
83
+ Takes collector output, deduplicates it, stores it, and makes it queryable.
84
+
85
+ This layer owns:
86
+ - schema validation
87
+ - event normalization
88
+ - persistence
89
+ - indexing
90
+
91
+ ### 4) Evaluation Engine
92
+ Runs deterministic checks over a run:
93
+
94
+ - unit tests
95
+ - lint/type checks
96
+ - benchmark tasks
97
+ - regression detection
98
+ - semantic scoring
99
+ - cost and latency scoring
100
+
101
+ ### 5) Dashboard
102
+ Shows:
103
+
104
+ - per-run timelines
105
+ - agent comparisons
106
+ - regressions
107
+ - best-performing variants
108
+ - suggested prompt/skill/tool-description changes
109
+
110
+ The dashboard is read-only with respect to ingestion. It visualizes the state created by collectors, storage, and evaluation.
111
+
112
+ ### 6) Optional Improvement Loop
113
+ Generates candidate improvements for:
114
+
115
+ - prompts
116
+ - skills
117
+ - tool descriptions
118
+ - code paths
119
+
120
+ But those changes should be gated by tests and human review.
121
+
122
+
123
+ ---
124
+
125
+ ## Architecture Decision
126
+
127
+ ### Chosen path: Event-first, UI-second
128
+
129
+ Do **not** start with the dashboard UI.
130
+ Start with the event contract and adapters.
131
+
132
+ Why:
133
+ - if the schema is wrong, the UI becomes a lie
134
+ - if the adapters are weak, the data is noisy
135
+ - if the evaluator is unclear, the charts are decorative only
136
+
137
+ ---
138
+
139
+ ## MVP Scope
140
+
141
+ The MVP should include:
142
+
143
+ 1. One shared event schema
144
+ 2. Two collectors at minimum
145
+ - Hermes
146
+ - Claude Code or Codex
147
+ 3. A storage backend
148
+ 4. A basic evaluator
149
+ 5. A dashboard with:
150
+ - list of runs
151
+ - run detail view
152
+ - agent comparison view
153
+ - score trend view
154
+ 6. Export to JSON/CSV
155
+
156
+ ---
157
+
158
+ ## Phase 1: Define the Canonical Schema
159
+
160
+ **Objective:** Establish the minimum event format that every agent can emit.
161
+
162
+ **Files:**
163
+ - Create: `specs/event-schema.md`
164
+ - Create: `specs/examples/run.jsonl`
165
+ - Create: `src/schema/README.md` if code exists later
166
+
167
+ **Deliverable:**
168
+ A written contract for runs, tools, artifacts, errors, and evaluation metrics.
169
+
170
+ **Verification:**
171
+ - Schema covers Hermes, Claude Code, Codex, and OpenCode without special casing.
172
+ - Example payloads are valid JSON.
173
+
174
+ ---
175
+
176
+ ## Phase 2: Build the Hermes Collector
177
+
178
+ **Objective:** Convert Hermes CLI output, session logs, or JSON traces into the canonical schema.
179
+
180
+ **Files:**
181
+ - Create: `src/collectors/hermes_collector.py`
182
+ - Create: `tests/collectors/test_hermes_collector.py`
183
+
184
+ **What it must extract:**
185
+ - session metadata
186
+ - tool calls
187
+ - final output
188
+ - errors
189
+ - touched files when available
190
+
191
+ **Verification:**
192
+ - A sample Hermes run converts into a valid canonical event.
193
+ - Missing optional fields do not break the collector.
194
+
195
+ ---
196
+
197
+ ## Phase 3: Build One Non-Hermes Collector
198
+
199
+ **Objective:** Prove the system is not Hermes-specific.
200
+
201
+ **Files:**
202
+ - Create: `src/collectors/claude_code_collector.py` or `src/collectors/codex_collector.py`
203
+ - Create: `tests/collectors/test_non_hermes_collector.py`
204
+
205
+ **Verification:**
206
+ - The output structure matches the Hermes collector output shape.
207
+ - A comparison test confirms parity of required fields.
208
+
209
+ ---
210
+
211
+ ## Phase 4: Add Storage and Query Layer
212
+
213
+ **Objective:** Persist runs and make them queryable.
214
+
215
+ **Files:**
216
+ - Create: `src/storage/*.py`
217
+ - Create: `tests/storage/*.py`
218
+
219
+ **Storage choice:**
220
+ - SQLite for MVP
221
+ - Postgres if multi-user and remote access are needed early
222
+
223
+ **Verification:**
224
+ - Insert run
225
+ - Query by agent
226
+ - Query by repo
227
+ - Query by date
228
+ - Query by score
229
+
230
+ ---
231
+
232
+ ## Phase 5: Implement the Evaluation Engine
233
+
234
+ **Objective:** Score runs consistently across agents.
235
+
236
+ **Files:**
237
+ - Create: `src/eval/engine.py`
238
+ - Create: `tests/eval/test_engine.py`
239
+
240
+ **Metrics to start with:**
241
+ - tests pass/fail
242
+ - diff size
243
+ - number of tool calls
244
+ - latency
245
+ - token/cost estimate
246
+ - task success
247
+
248
+ **Verification:**
249
+ - The same run always scores the same way.
250
+ - A failing benchmark produces an explicit regression entry.
251
+
252
+ ---
253
+
254
+ ## Phase 6: Build the Dashboard API
255
+
256
+ **Objective:** Expose runs, metrics, and comparisons to the UI.
257
+
258
+ **Files:**
259
+ - Create: `src/api/*.py`
260
+ - Create: `tests/api/*.py`
261
+
262
+ **Endpoints to include:**
263
+ - `GET /runs`
264
+ - `GET /runs/:id`
265
+ - `GET /agents`
266
+ - `GET /comparisons`
267
+ - `GET /metrics/trends`
268
+
269
+ **Verification:**
270
+ - API returns canonical event data without agent-specific branching.
271
+
272
+ ---
273
+
274
+ ## Phase 7: Build the Dashboard UI
275
+
276
+ **Objective:** Make the data readable and actionable.
277
+
278
+ **Files:**
279
+ - Create: `web/*`
280
+
281
+ **Views:**
282
+ - Run list
283
+ - Run detail
284
+ - Agent comparison
285
+ - Regression timeline
286
+ - Improvement suggestions
287
+
288
+ **Verification:**
289
+ - A user can inspect a run in under 30 seconds.
290
+ - A user can compare two agents on the same task.
291
+
292
+ ---
293
+
294
+ ## Phase 8: Add the Improvement Loop
295
+
296
+ **Objective:** Turn observations into candidate improvements.
297
+
298
+ **Files:**
299
+ - Create: `src/improve/*.py`
300
+ - Create: `tests/improve/*.py`
301
+
302
+ **Allowed improvements:**
303
+ - prompt edits
304
+ - skill edits
305
+ - tool description edits
306
+ - code patches behind review gates
307
+
308
+ **Guardrails:**
309
+ - never auto-merge to main
310
+ - never change semantics without a regression gate
311
+ - never bypass tests
312
+
313
+ **Verification:**
314
+ - Candidate improvements are stored as proposals, not applied directly.
315
+
316
+ ---
317
+
318
+ ## Phase 9: Add Agent-Readable Access
319
+
320
+ **Objective:** Let agents query the system themselves.
321
+
322
+ **Files:**
323
+ - Create: `src/mcp/server.py` if using MCP
324
+ - Create: `tests/mcp/test_server.py`
325
+
326
+ **Useful tools for agents:**
327
+ - get recent runs
328
+ - fetch latest regression
329
+ - fetch best-known variant
330
+ - compare two runs
331
+ - read score trend
332
+
333
+ **Verification:**
334
+ - At least one agent can consume the system programmatically.
335
+
336
+ ---
337
+
338
+ ## Risk Register
339
+
340
+ ### Risk 1: Inconsistent source formats
341
+ Different agents expose wildly different logs.
342
+
343
+ **Mitigation:** adapters must normalize into the same schema and drop unsupported noise.
344
+
345
+ ### Risk 2: False confidence from weak evaluation
346
+ Pretty UI can hide bad metrics.
347
+
348
+ **Mitigation:** tests and benchmark gates must be first-class, not optional.
349
+
350
+ ### Risk 3: Overfitting to one agent
351
+ The system accidentally becomes “Hermes with some plugins”.
352
+
353
+ **Mitigation:** require at least one non-Hermes adapter before declaring MVP complete.
354
+
355
+ ### Risk 4: Improvement automation becomes unsafe
356
+ Auto-generated changes can regress silently.
357
+
358
+ **Mitigation:** every proposed change requires human approval plus an eval gate.
359
+
360
+ ---
361
+
362
+ ## MVP Success Criteria
363
+
364
+ The MVP is good enough if it can:
365
+
366
+ - ingest at least two agent types
367
+ - normalize them into one schema
368
+ - score runs consistently
369
+ - compare runs side by side
370
+ - surface regressions clearly
371
+ - export data for downstream analysis
372
+
373
+ If it cannot do that, it is still a demo.
374
+
375
+ ---
376
+
377
+ ## Recommended Build Order
378
+
379
+ 1. Canonical schema
380
+ 2. Hermes adapter
381
+ 3. One other agent adapter
382
+ 4. Storage layer
383
+ 5. Evaluation engine
384
+ 6. Dashboard API
385
+ 7. UI
386
+ 8. Improvement loop
387
+ 9. MCP access
388
+
389
+ This order is intentional. Skip it and you get a prettier version of the same ambiguity.
390
+
391
+ ---
392
+
393
+ ## Open Questions
394
+
395
+ - Should storage be SQLite first or Postgres from day one?
396
+ - Should the adapters read raw CLI output, session files, or both?
397
+ - Should the dashboard be local-first or multi-user from the start?
398
+ - Which metric matters most for the first release: correctness, speed, or cost?
399
+
400
+ ---
401
+
402
+ ## Final Note
403
+
404
+ This should be treated as infrastructure, not as a single-agent feature.
405
+ If Hermes is the only system that fits, the design is wrong.
@@ -0,0 +1,277 @@
1
+ """Claude Code collector — converts session JSONL to CanonicalRun schema."""
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Optional
6
+ from backend.promethean.models import CanonicalRun, ToolCallRecord, FileTouchRecord, RunMetrics
7
+
8
+
9
+ CLAUDE_SESSIONS_DIR = Path.home() / ".claude" / "projects"
10
+
11
+
12
+ class ClaudeCodeCollector:
13
+ """Collects and normalizes Claude Code session logs into CanonicalRun events."""
14
+
15
+ VERSION = "0.1.0"
16
+ AGENT_NAME = "claude-code"
17
+
18
+ def collect_session(self, session_file: Path) -> Optional[CanonicalRun]:
19
+ """Parse a single session JSONL file into a CanonicalRun."""
20
+ events = self._load_events(session_file)
21
+ if not events:
22
+ return None
23
+
24
+ run_id = self._extract_session_id(events)
25
+ task_name = self._extract_task(events)
26
+ started_at, ended_at = self._extract_timestamps(events)
27
+ model = self._extract_model(events)
28
+ repo = self._extract_repo(events)
29
+ tool_calls = self._extract_tool_calls(events)
30
+ files_touched = self._extract_files_touched(events)
31
+ metrics = self._extract_metrics(events)
32
+ errors = self._extract_errors(events)
33
+ outcome = self._infer_outcome(events, errors)
34
+
35
+ return CanonicalRun(
36
+ run_id=run_id,
37
+ agent_name=self.AGENT_NAME,
38
+ collector="claude-code-session-collector",
39
+ collector_version=self.VERSION,
40
+ started_at=started_at,
41
+ ended_at=ended_at,
42
+ task_name=task_name,
43
+ outcome=outcome,
44
+ model=model,
45
+ provider="anthropic",
46
+ repo=repo,
47
+ session_id=run_id,
48
+ tool_calls=tool_calls,
49
+ files_touched=files_touched,
50
+ metrics=metrics,
51
+ errors=errors,
52
+ context={"cwd": self._extract_cwd(events)},
53
+ )
54
+
55
+ def collect_all(self, project_path: Optional[str] = None, limit: int = 50) -> list[CanonicalRun]:
56
+ """Collect runs from all sessions under a project path or all projects."""
57
+ runs = []
58
+
59
+ if project_path:
60
+ # Single project: search under that path
61
+ search_dir = Path(project_path)
62
+ else:
63
+ # All projects
64
+ search_dir = CLAUDE_SESSIONS_DIR
65
+
66
+ if not search_dir.exists():
67
+ return runs
68
+
69
+ count = 0
70
+ for session_file in sorted(search_dir.rglob("*.jsonl"), reverse=True):
71
+ if count >= limit:
72
+ break
73
+ try:
74
+ run = self.collect_session(session_file)
75
+ if run:
76
+ runs.append(run)
77
+ count += 1
78
+ except Exception:
79
+ continue
80
+
81
+ return runs
82
+
83
+ # ── Internal extraction methods ──────────────────────────────────
84
+
85
+ def _load_events(self, path: Path) -> list[dict]:
86
+ """Load JSONL events from file. Returns empty list on error."""
87
+ lines = []
88
+ try:
89
+ for line in path.read_text().splitlines():
90
+ if not line.strip():
91
+ continue
92
+ try:
93
+ lines.append(json.loads(line))
94
+ except json.JSONDecodeError:
95
+ continue
96
+ except Exception:
97
+ pass
98
+ return lines
99
+
100
+ def _extract_session_id(self, events: list[dict]) -> str:
101
+ """Extract or generate session ID from events."""
102
+ for event in events:
103
+ if isinstance(event, dict):
104
+ # Try attachment event first (has sessionId)
105
+ if event.get("type") == "attachment":
106
+ session_id = event.get("sessionId")
107
+ if session_id:
108
+ return session_id
109
+ # Try message with sessionId
110
+ msg = event.get("message", {})
111
+ if isinstance(msg, dict):
112
+ session_id = msg.get("sessionId")
113
+ if session_id:
114
+ return session_id
115
+ # Fallback: generate from first timestamp
116
+ import uuid
117
+ return str(uuid.uuid4())[:8]
118
+
119
+ def _extract_task(self, events: list[dict]) -> str:
120
+ """Extract task name from first user text content."""
121
+ for event in events:
122
+ if not isinstance(event, dict):
123
+ continue
124
+ if event.get("type") == "user":
125
+ msg = event.get("message", {})
126
+ if isinstance(msg, dict):
127
+ content = msg.get("content", "")
128
+ if isinstance(content, str) and content.strip():
129
+ # Clean up command wrappers
130
+ text = content.strip()
131
+ if text.startswith("<command-message>"):
132
+ continue
133
+ return text[:500]
134
+ if isinstance(content, list):
135
+ for item in content:
136
+ if isinstance(item, dict) and item.get("type") == "text":
137
+ text = item.get("text", "").strip()
138
+ if text and not text.startswith("<command-message>"):
139
+ return text[:500]
140
+ return "unknown"
141
+
142
+ def _extract_timestamps(self, events: list[dict]) -> tuple[str, str]:
143
+ """Extract start and end timestamps from events."""
144
+ timestamps = []
145
+ for event in events:
146
+ if isinstance(event, dict) and "timestamp" in event:
147
+ try:
148
+ timestamps.append(event["timestamp"])
149
+ except Exception:
150
+ pass
151
+
152
+ if not timestamps:
153
+ from datetime import datetime, timezone
154
+ now = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
155
+ return now, now
156
+
157
+ return timestamps[0], timestamps[-1]
158
+
159
+ def _extract_model(self, events: list[dict]) -> Optional[str]:
160
+ """Extract model name from assistant messages."""
161
+ for event in events:
162
+ if isinstance(event, dict) and event.get("type") == "assistant":
163
+ msg = event.get("message", {})
164
+ if isinstance(msg, dict):
165
+ model = msg.get("model")
166
+ if model:
167
+ return model
168
+ return None
169
+
170
+ def _extract_repo(self, events: list[dict]) -> Optional[str]:
171
+ """Extract repo/branch info from attachment events."""
172
+ for event in events:
173
+ if isinstance(event, dict) and event.get("type") == "attachment":
174
+ git_branch = event.get("gitBranch")
175
+ if git_branch:
176
+ return git_branch
177
+ return None
178
+
179
+ def _extract_cwd(self, events: list[dict]) -> Optional[str]:
180
+ """Extract current working directory."""
181
+ for event in events:
182
+ if isinstance(event, dict) and event.get("type") == "attachment":
183
+ cwd = event.get("cwd")
184
+ if cwd:
185
+ return cwd
186
+ return None
187
+
188
+ def _extract_tool_calls(self, events: list[dict]) -> list[ToolCallRecord]:
189
+ """Extract all tool_use items from assistant messages."""
190
+ tool_calls = []
191
+ for event in events:
192
+ if not isinstance(event, dict) or event.get("type") != "assistant":
193
+ continue
194
+ msg = event.get("message", {})
195
+ if not isinstance(msg, dict):
196
+ continue
197
+ for content_item in msg.get("content", []):
198
+ if isinstance(content_item, dict) and content_item.get("type") == "tool_use":
199
+ tool_calls.append(ToolCallRecord(
200
+ id=content_item.get("id", ""),
201
+ name=content_item.get("name", ""),
202
+ input_summary=str(content_item.get("input", ""))[:200],
203
+ ))
204
+ return tool_calls
205
+
206
+ def _extract_files_touched(self, events: list[dict]) -> list[FileTouchRecord]:
207
+ """Extract file operations from tool_use results (simplified)."""
208
+ files = []
209
+ for event in events:
210
+ if not isinstance(event, dict) or event.get("type") != "user":
211
+ continue
212
+ msg = event.get("message", {})
213
+ if not isinstance(msg, dict):
214
+ continue
215
+ for content_item in msg.get("content", []):
216
+ if isinstance(content_item, dict) and content_item.get("type") == "tool_result":
217
+ # Could parse file paths from result, but simplified for MVP
218
+ pass
219
+ return files
220
+
221
+ def _extract_metrics(self, events: list[dict]) -> RunMetrics:
222
+ """Aggregate token usage across all assistant messages."""
223
+ total_input = total_output = total_cache = 0
224
+ for event in events:
225
+ if not isinstance(event, dict) or event.get("type") != "assistant":
226
+ continue
227
+ msg = event.get("message", {})
228
+ if not isinstance(msg, dict):
229
+ continue
230
+ usage = msg.get("usage", {})
231
+ if isinstance(usage, dict):
232
+ total_input += usage.get("input_tokens", 0)
233
+ total_output += usage.get("output_tokens", 0)
234
+ total_cache += usage.get("cache_read_input_tokens", 0)
235
+
236
+ return RunMetrics(
237
+ input_tokens=total_input if total_input > 0 else None,
238
+ output_tokens=total_output if total_output > 0 else None,
239
+ cache_tokens=total_cache if total_cache > 0 else None,
240
+ tool_call_count=len(self._extract_tool_calls(events)),
241
+ )
242
+
243
+ def _extract_errors(self, events: list[dict]) -> list[dict]:
244
+ """Extract errors from system or tool_result events."""
245
+ errors = []
246
+ for event in events:
247
+ if not isinstance(event, dict):
248
+ continue
249
+ if event.get("type") == "system":
250
+ error = event.get("error")
251
+ if error:
252
+ errors.append({
253
+ "signature": error[:100],
254
+ "message": error,
255
+ "stack_excerpt": None,
256
+ "count": 1,
257
+ })
258
+ return errors
259
+
260
+ def _infer_outcome(self, events: list[dict], errors: list[dict]) -> str:
261
+ """Infer success/failure/partial from events."""
262
+ # Has system error → failure
263
+ if errors:
264
+ return "failure" if len(errors) > 1 else "partial"
265
+
266
+ # Check for successful completion
267
+ for event in events:
268
+ if not isinstance(event, dict):
269
+ continue
270
+ if event.get("type") == "assistant":
271
+ msg = event.get("message", {})
272
+ if isinstance(msg, dict):
273
+ stop_reason = msg.get("stop_reason")
274
+ if stop_reason == "end_turn":
275
+ return "success"
276
+
277
+ return "unknown"