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,213 @@
1
+ """
2
+ ②③ DIAGNOSTICA + FORMULA — GEPA Strategic Layer
3
+
4
+ GEPA (Goal → Execution → Plan → Action) analyzes anomalies detected by trace ingestion
5
+ and formulates SkillGenesis packets for DSPy compilation.
6
+
7
+ This is the "brain" of the Promethean Cycle — it decides WHAT to learn.
8
+ """
9
+
10
+ from __future__ import annotations
11
+ import json
12
+ import re
13
+ from datetime import datetime
14
+ from pathlib import Path
15
+ from typing import Optional
16
+
17
+ from .models import SkillGenesisPacket, CyclePhase, CycleState
18
+ from .trace_ingestion import get_ingestor
19
+
20
+ SKILLS_DIR = Path.home() / ".hermes" / "skills"
21
+ MEMORY_DIR = Path.home() / ".hermes" / "memory"
22
+
23
+
24
+ class GEPAStrategist:
25
+ """Strategic layer: diagnoses skill gaps and formulates learning objectives."""
26
+
27
+ def __init__(self):
28
+ self.ingestor = get_ingestor()
29
+
30
+ # ── Diagnosis ──────────────────────────────────────────────────
31
+ def diagnose(self, anomalies: list[dict]) -> list[dict]:
32
+ """Analyze anomalies and determine if they represent skill gaps.
33
+
34
+ Returns list of gap diagnoses with:
35
+ - gap_id: unique identifier
36
+ - root_cause: identified root cause
37
+ - existing_skills: skills that partially cover this (if any)
38
+ - confidence: 0-1 probability that a new skill would help
39
+ - recommended_action: "compile_skill" | "monitor" | "ignore"
40
+ """
41
+ gaps = []
42
+
43
+ for anomaly in anomalies:
44
+ sig = anomaly["error_signature"]
45
+ occurrences = anomaly["occurrences"]
46
+ agents = anomaly.get("agents_affected", [])
47
+
48
+ # Check if any existing skill covers this
49
+ existing = self._find_covering_skills(sig)
50
+
51
+ # Determine root cause from error pattern
52
+ root_cause = self._infer_root_cause(sig, anomaly.get("sample_traces", []))
53
+
54
+ # Calculate confidence based on:
55
+ # - Number of occurrences (more = more confident)
56
+ # - Number of agents affected (cross-agent = more confident)
57
+ # - Whether existing skills partially cover it
58
+ occ_factor = min(occurrences / 10, 1.0) # Capped at 10 occurrences
59
+ agent_factor = min(len(agents) / 4, 1.0) if agents else 0.3
60
+ coverage_factor = 0.0 if existing else 0.5 # No coverage = higher need
61
+
62
+ confidence = round((occ_factor * 0.4 + agent_factor * 0.3 + coverage_factor * 0.3), 2)
63
+
64
+ # Decide action
65
+ if confidence > 0.5 and not existing:
66
+ action = "compile_skill"
67
+ elif confidence > 0.3:
68
+ action = "monitor"
69
+ else:
70
+ action = "ignore"
71
+
72
+ gaps.append({
73
+ "gap_id": f"gap_{sig[:20].replace(' ', '_')}",
74
+ "error_signature": sig,
75
+ "root_cause": root_cause,
76
+ "occurrences": occurrences,
77
+ "agents_affected": agents,
78
+ "existing_skills": existing,
79
+ "confidence": confidence,
80
+ "recommended_action": action,
81
+ "diagnosed_at": datetime.now().isoformat(),
82
+ })
83
+
84
+ return gaps
85
+
86
+ # ── Formulation ─────────────────────────────────────────────────
87
+ def formulate(self, gap: dict, cycle_state: CycleState) -> Optional[SkillGenesisPacket]:
88
+ """Formulate a SkillGenesis packet from a confirmed gap.
89
+
90
+ Only creates packets for gaps with recommended_action == 'compile_skill'.
91
+ """
92
+ if gap["recommended_action"] != "compile_skill":
93
+ return None
94
+
95
+ sig = gap["error_signature"]
96
+ root_cause = gap["root_cause"]
97
+
98
+ # Extract dataset from trace storage
99
+ dataset_path = self.ingestor.extract_dataset(sig, limit=50)
100
+
101
+ # Infer the DSPy signature from the error pattern
102
+ signature = self._infer_signature(sig, root_cause)
103
+
104
+ # Generate intent description
105
+ intent = f"Autonomous resolution for: {root_cause}. Detected from {gap['occurrences']} failures across {len(gap['agents_affected'])} agents."
106
+
107
+ # Select metric based on error type
108
+ metric = self._select_metric(sig)
109
+
110
+ # Calculate dynamic threshold based on confidence
111
+ threshold = max(0.10, gap["confidence"] * 0.30)
112
+
113
+ packet = SkillGenesisPacket(
114
+ intent=intent,
115
+ signature=signature,
116
+ dataset_path=dataset_path,
117
+ metric=metric,
118
+ threshold=threshold,
119
+ target_agent=",".join(gap["agents_affected"]) if gap["agents_affected"] else "all",
120
+ )
121
+
122
+ cycle_state.genesis_packets.append(packet)
123
+ return packet
124
+
125
+ def formulate_all(self, gaps: list[dict], cycle_state: CycleState) -> list[SkillGenesisPacket]:
126
+ """Formulate packets for all actionable gaps."""
127
+ packets = []
128
+ for gap in gaps:
129
+ packet = self.formulate(gap, cycle_state)
130
+ if packet:
131
+ packets.append(packet)
132
+ return packets
133
+
134
+ # ── Internal: Skill Discovery ───────────────────────────────────
135
+ def _find_covering_skills(self, error_signature: str) -> list[str]:
136
+ """Find existing skills that might cover this error pattern."""
137
+ if not SKILLS_DIR.exists():
138
+ return []
139
+
140
+ keywords = set(re.findall(r'[a-z]+', error_signature.lower()))
141
+ covering = []
142
+
143
+ for skill_dir in SKILLS_DIR.rglob("SKILL.md"):
144
+ try:
145
+ content = skill_dir.read_text()[:500].lower()
146
+ matches = sum(1 for kw in keywords if kw in content)
147
+ if matches >= 2:
148
+ covering.append(skill_dir.parent.name)
149
+ except Exception:
150
+ continue
151
+
152
+ return covering
153
+
154
+ # ── Internal: Root Cause Inference ──────────────────────────────
155
+ def _infer_root_cause(self, error_signature: str, sample_traces: list[str]) -> str:
156
+ """Infer root cause from error signature and sample traces."""
157
+ patterns = {
158
+ r"timeout|timed?.*out": "Operation timeout — likely resource or network constraint",
159
+ r"auth|unauthorized|forbidden|401|403": "Authentication or authorization failure",
160
+ r"migrat|schema|drizzle.*error": "Database migration or schema mismatch",
161
+ r"build.*fail|compil|syntax|type.*error": "Build or compilation failure",
162
+ r"import.*error|module.*not.*found|no.*module": "Missing dependency or import path error",
163
+ r"deploy|eas|expo.*build": "Deployment pipeline failure",
164
+ r"docker|container|sandbox|e2b": "Sandbox or container orchestration failure",
165
+ r"network|dns|refused|unreachable|econnrefused": "Network connectivity failure",
166
+ r"memory|oom|killed|heap": "Memory exhaustion",
167
+ r"permission|denied|eacces": "File system permission error",
168
+ }
169
+
170
+ for pattern, cause in patterns.items():
171
+ if re.search(pattern, error_signature, re.IGNORECASE):
172
+ return cause
173
+
174
+ return f"Uncategorized operational failure: {error_signature[:80]}"
175
+
176
+ # ── Internal: Signature Inference ───────────────────────────────
177
+ def _infer_signature(self, error_signature: str, root_cause: str) -> str:
178
+ """Infer a DSPy Signature string from error context."""
179
+ if re.search(r"build|deploy|eas|dockerfile", error_signature, re.IGNORECASE):
180
+ return "error_log, build_context → fixed_config, explanation"
181
+ elif re.search(r"migrat|schema|drizzle", error_signature, re.IGNORECASE):
182
+ return "migration_error, schema_snapshot → fix_commands, root_cause"
183
+ elif re.search(r"auth|unauthorized|forbidden", error_signature, re.IGNORECASE):
184
+ return "auth_error, config_snapshot → fix_steps, updated_config"
185
+ elif re.search(r"import|module.*not.*found", error_signature, re.IGNORECASE):
186
+ return "import_error, package_json → fix_commands, dependency_name"
187
+ elif re.search(r"network|dns|refused|timeout", error_signature, re.IGNORECASE):
188
+ return "network_error, service_context → recovery_steps, root_cause"
189
+ else:
190
+ return "error_log, context → fix_steps, explanation"
191
+
192
+ # ── Internal: Metric Selection ──────────────────────────────────
193
+ def _select_metric(self, error_signature: str) -> str:
194
+ """Select the most appropriate metric for this type of error."""
195
+ if re.search(r"timeout|slow|performance", error_signature, re.IGNORECASE):
196
+ return "delta_resolution_time"
197
+ elif re.search(r"build|deploy|eas", error_signature, re.IGNORECASE):
198
+ return "delta_build_success_rate"
199
+ elif re.search(r"migrat|schema", error_signature, re.IGNORECASE):
200
+ return "delta_migration_success_rate"
201
+ else:
202
+ return "delta_resolution_rate"
203
+
204
+
205
+ # ── Singleton ───────────────────────────────────────────────────────
206
+ _strategist: Optional[GEPAStrategist] = None
207
+
208
+
209
+ def get_strategist() -> GEPAStrategist:
210
+ global _strategist
211
+ if _strategist is None:
212
+ _strategist = GEPAStrategist()
213
+ return _strategist
@@ -0,0 +1,260 @@
1
+ """
2
+ Promethean Models — Data structures for the Ciclo Prometeico.
3
+
4
+ SkillGenesis Packet: The interface between GEPA (strategy) and DSPy (compilation).
5
+ TraceRecord: Standardized trace from any AI agent.
6
+ CycleState: Full state machine for the 7-phase cycle.
7
+ """
8
+
9
+ from __future__ import annotations
10
+ from dataclasses import dataclass, field, asdict
11
+ from datetime import datetime
12
+ from enum import Enum
13
+ from typing import Optional, Any
14
+ import json
15
+ import uuid
16
+
17
+
18
+ # ── Phase Enum ──────────────────────────────────────────────────────
19
+ class CyclePhase(str, Enum):
20
+ PERCIBE = "perceive"
21
+ DIAGNOSTICA = "diagnose"
22
+ FORMULA = "formulate"
23
+ COMPILA = "compile"
24
+ VALIDA = "validate"
25
+ DESPLIEGA = "deploy"
26
+ OBSERVA = "observe"
27
+
28
+
29
+ # ── Trace Record (any agent → dashboard) ───────────────────────────
30
+ @dataclass
31
+ class TraceRecord:
32
+ """Standardized trace emitted by any AI agent."""
33
+ agent: str # "claude-code", "opencode", "codex", "hermes"
34
+ agent_version: str
35
+ timestamp: str # ISO 8601
36
+ task: str # Description of what was attempted
37
+ outcome: str # "success" | "failure" | "partial"
38
+ error_signature: Optional[str] = None # Unique error fingerprint
39
+ context: dict = field(default_factory=dict) # files_touched, commands, stack_trace
40
+ resolution: Optional[str] = None # How it was resolved (null if unresolved → gap)
41
+ trace_id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])
42
+
43
+ def to_json(self) -> str:
44
+ return json.dumps(asdict(self), indent=2, default=str)
45
+
46
+ @classmethod
47
+ def from_json(cls, data: str | dict) -> "TraceRecord":
48
+ if isinstance(data, str):
49
+ data = json.loads(data)
50
+ return cls(**{k: v for k, v in data.items() if k in cls.__dataclass_fields__})
51
+
52
+ def to_canonical(self) -> CanonicalRun:
53
+ """Convert TraceRecord to vendor-neutral CanonicalRun schema."""
54
+ errors = []
55
+ if self.error_signature:
56
+ errors = [{"signature": self.error_signature, "message": None, "stack_excerpt": None, "count": 1}]
57
+
58
+ return CanonicalRun(
59
+ run_id=self.trace_id,
60
+ agent_name=self.agent,
61
+ agent_version=self.agent_version,
62
+ collector="hermes-trace-ingestor",
63
+ collector_version="0.1.0",
64
+ started_at=self.timestamp,
65
+ ended_at=self.timestamp,
66
+ task_name=self.task,
67
+ outcome=self.outcome,
68
+ provider="hermes",
69
+ errors=errors,
70
+ context=self.context or {},
71
+ resolution=self.resolution,
72
+ )
73
+
74
+
75
+ # ── SkillGenesis Packet (GEPA → DSPy) ──────────────────────────────
76
+ @dataclass
77
+ class SkillGenesisPacket:
78
+ """GEPA formulates this. DSPy consumes it. A skill is born."""
79
+ intent: str # What the skill should do (human-readable)
80
+ signature: str # "input_fields → output_fields" (DSPy Signature format)
81
+ dataset_path: str # Path to training dataset (JSONL)
82
+ metric: str # Metric name for optimization
83
+ threshold: float = 0.15 # Minimum delta to accept (e.g., 0.15 = 15% improvement)
84
+ holdout: float = 0.2 # Fraction of data reserved for validation
85
+ optimizers: list[str] = field(default_factory=lambda: ["GEPA", "BootstrapFinetune"])
86
+ strategy: str = "p -> w -> p" # BetterTogether strategy string
87
+ target_agent: str = "all" # Which agent(s) this skill targets
88
+ max_attempts: int = 3 # Max re-compilation attempts if validation fails
89
+ packet_id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])
90
+
91
+ def to_dict(self) -> dict:
92
+ return asdict(self)
93
+
94
+ def to_json(self) -> str:
95
+ return json.dumps(self.to_dict(), indent=2)
96
+
97
+ @classmethod
98
+ def from_dict(cls, data: dict) -> "SkillGenesisPacket":
99
+ return cls(**{k: v for k, v in data.items() if k in cls.__dataclass_fields__})
100
+
101
+
102
+ # ── Compilation Result (DSPy → GEPA) ───────────────────────────────
103
+ @dataclass
104
+ class CompilationResult:
105
+ """DSPy returns this after compiling a skill."""
106
+ packet_id: str
107
+ success: bool
108
+ skill_name: str # Generated skill name
109
+ skill_path: str # Where the skill was saved
110
+ iterations: int # Number of optimization iterations
111
+ best_score: float # Best metric score achieved
112
+ delta: float # Improvement over baseline
113
+ threshold_met: bool # delta >= threshold?
114
+ attempt: int = 1 # Which attempt (1 to max_attempts)
115
+ error: Optional[str] = None # Error message if failed
116
+ compiled_at: str = field(default_factory=lambda: datetime.now().isoformat())
117
+
118
+
119
+ # ── Cycle State ─────────────────────────────────────────────────────
120
+ @dataclass
121
+ class CycleState:
122
+ """Full state of a Promethean Cycle execution."""
123
+ cycle_id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])
124
+ phase: CyclePhase = CyclePhase.PERCIBE
125
+ traces_ingested: int = 0
126
+ anomalies_detected: int = 0
127
+ genesis_packets: list[SkillGenesisPacket] = field(default_factory=list)
128
+ compilation_results: list[CompilationResult] = field(default_factory=list)
129
+ skills_deployed: int = 0
130
+ started_at: str = field(default_factory=lambda: datetime.now().isoformat())
131
+ completed_at: Optional[str] = None
132
+ errors: list[str] = field(default_factory=list)
133
+
134
+ def advance(self, new_phase: CyclePhase):
135
+ self.phase = new_phase
136
+ if new_phase == CyclePhase.OBSERVA:
137
+ self.completed_at = datetime.now().isoformat()
138
+
139
+ def summary(self) -> dict:
140
+ return {
141
+ "cycle_id": self.cycle_id,
142
+ "phase": self.phase.value,
143
+ "traces_ingested": self.traces_ingested,
144
+ "anomalies_detected": self.anomalies_detected,
145
+ "genesis_packets": len(self.genesis_packets),
146
+ "skills_compiled": len([r for r in self.compilation_results if r.success]),
147
+ "skills_deployed": self.skills_deployed,
148
+ "started_at": self.started_at,
149
+ "completed_at": self.completed_at,
150
+ "errors": self.errors,
151
+ }
152
+
153
+
154
+ # ── Metric Snapshot (for delta calculation) ─────────────────────────
155
+ @dataclass
156
+ class MetricSnapshot:
157
+ """Before/after metric snapshot for a skill evaluation."""
158
+ skill_name: str
159
+ baseline: dict # {"success_rate": 0.67, "avg_time": 98, ...}
160
+ evolved: dict # {"success_rate": 0.94, "avg_time": 61, ...}
161
+ deltas: dict # {"success_rate": +0.27, "avg_time": -0.38}
162
+ threshold: float
163
+ passed: bool
164
+ dataset_size: int
165
+ holdout_size: int
166
+ evaluated_at: str = field(default_factory=lambda: datetime.now().isoformat())
167
+
168
+
169
+ # ── Canonical Run Schema (Agent-Agnostic Telemetry) ───────────────────
170
+ @dataclass
171
+ class ToolCallRecord:
172
+ """Record of a single tool invocation."""
173
+ id: str
174
+ name: str
175
+ input_summary: Optional[str] = None
176
+ duration_ms: Optional[int] = None
177
+ result_summary: Optional[str] = None
178
+ error: Optional[str] = None
179
+
180
+
181
+ @dataclass
182
+ class FileTouchRecord:
183
+ """Record of file read/write/delete operation."""
184
+ path: str
185
+ action: str = "write" # "read" | "write" | "delete"
186
+ size_bytes: Optional[int] = None
187
+
188
+
189
+ @dataclass
190
+ class RunMetrics:
191
+ """Aggregated execution metrics for a run."""
192
+ input_tokens: Optional[int] = None
193
+ output_tokens: Optional[int] = None
194
+ cache_tokens: Optional[int] = None
195
+ latency_ms: Optional[int] = None
196
+ cost_usd: Optional[float] = None
197
+ tool_call_count: int = 0
198
+
199
+
200
+ @dataclass
201
+ class CanonicalRun:
202
+ """Vendor-neutral canonical run event. Maps from any agent's native format."""
203
+ # Required fields
204
+ run_id: str
205
+ agent_name: str
206
+ collector: str
207
+ started_at: str
208
+ task_name: str
209
+ outcome: str # "success" | "failure" | "partial" | "unknown"
210
+
211
+ # Optional fields
212
+ agent_version: Optional[str] = None
213
+ provider: Optional[str] = None
214
+ model: Optional[str] = None
215
+ repo: Optional[str] = None
216
+ session_id: Optional[str] = None
217
+ ended_at: Optional[str] = None
218
+ tool_calls: list[ToolCallRecord] = field(default_factory=list)
219
+ files_touched: list[FileTouchRecord] = field(default_factory=list)
220
+ artifacts: list[dict] = field(default_factory=list)
221
+ errors: list[dict] = field(default_factory=list)
222
+ metrics: Optional[RunMetrics] = None
223
+ eval_scores: list[dict] = field(default_factory=list)
224
+ improvement_candidates: list[dict] = field(default_factory=list)
225
+ context: dict = field(default_factory=dict)
226
+ resolution: Optional[str] = None
227
+ collector_version: str = "0.1.0"
228
+
229
+ def to_dict(self) -> dict:
230
+ """Convert to dict, handling nested dataclasses."""
231
+ data = asdict(self)
232
+ # Convert nested dataclasses to dicts
233
+ if self.metrics:
234
+ data["metrics"] = asdict(self.metrics)
235
+ if self.tool_calls:
236
+ data["tool_calls"] = [asdict(tc) for tc in self.tool_calls]
237
+ if self.files_touched:
238
+ data["files_touched"] = [asdict(ft) for ft in self.files_touched]
239
+ return data
240
+
241
+ def to_json(self) -> str:
242
+ return json.dumps(self.to_dict(), indent=2, default=str)
243
+
244
+ @classmethod
245
+ def from_dict(cls, data: dict) -> "CanonicalRun":
246
+ """Reconstruct from dict, handling nested dataclasses."""
247
+ # Reconstruct nested objects
248
+ if data.get("metrics") and not isinstance(data["metrics"], RunMetrics):
249
+ data["metrics"] = RunMetrics(**data["metrics"])
250
+ if data.get("tool_calls"):
251
+ data["tool_calls"] = [
252
+ ToolCallRecord(**tc) if isinstance(tc, dict) else tc
253
+ for tc in data["tool_calls"]
254
+ ]
255
+ if data.get("files_touched"):
256
+ data["files_touched"] = [
257
+ FileTouchRecord(**ft) if isinstance(ft, dict) else ft
258
+ for ft in data["files_touched"]
259
+ ]
260
+ return cls(**{k: v for k, v in data.items() if k in cls.__dataclass_fields__})
@@ -0,0 +1,195 @@
1
+ """
2
+ ⑥ DESPLIEGA — Skill Deployer Module
3
+
4
+ Auto-registers compiled and validated skills into the skill registry.
5
+ Creates SKILL.md files and makes them available to all agents.
6
+
7
+ This is the "birth" — the skill becomes real and accessible.
8
+ """
9
+
10
+ from __future__ import annotations
11
+ import shutil
12
+ from datetime import datetime
13
+ from pathlib import Path
14
+ from typing import Optional
15
+
16
+ from .models import SkillGenesisPacket, CompilationResult, MetricSnapshot
17
+
18
+ SKILLS_DIR = Path.home() / ".hermes" / "skills"
19
+
20
+
21
+ class SkillDeployer:
22
+ """Deploys validated skills to the multi-agent skill registry."""
23
+
24
+ def __init__(self):
25
+ SKILLS_DIR.mkdir(parents=True, exist_ok=True)
26
+ self.deployment_log = Path.home() / ".hermes" / "traces" / "deployments.jsonl"
27
+
28
+ # ── Deploy ──────────────────────────────────────────────────────
29
+ def deploy(
30
+ self,
31
+ packet: SkillGenesisPacket,
32
+ compilation: CompilationResult,
33
+ validation: MetricSnapshot,
34
+ ) -> dict:
35
+ """Deploy a validated skill to the registry.
36
+
37
+ Returns deployment info with paths and status.
38
+ """
39
+ if not validation.passed:
40
+ return {
41
+ "deployed": False,
42
+ "skill_name": compilation.skill_name,
43
+ "reason": f"Validation failed. Delta {validation.deltas} < threshold {packet.threshold}",
44
+ }
45
+
46
+ # Determine skill category
47
+ category = self._categorize(packet)
48
+
49
+ # Create skill directory
50
+ skill_dir = SKILLS_DIR / category / compilation.skill_name
51
+ skill_dir.mkdir(parents=True, exist_ok=True)
52
+
53
+ # Generate SKILL.md
54
+ skill_md = self._generate_skill_md(packet, compilation, validation)
55
+ (skill_dir / "SKILL.md").write_text(skill_md)
56
+
57
+ # Copy compiled artifacts if they exist
58
+ compiled_path = Path(compilation.skill_path)
59
+ if compiled_path.exists():
60
+ for f in compiled_path.glob("*"):
61
+ if f.name != "SKILL.md":
62
+ dest = skill_dir / f.name
63
+ if f.is_dir():
64
+ shutil.copytree(f, dest, dirs_exist_ok=True)
65
+ else:
66
+ shutil.copy2(f, dest)
67
+
68
+ # Log deployment
69
+ deploy_info = {
70
+ "deployed": True,
71
+ "skill_name": compilation.skill_name,
72
+ "category": category,
73
+ "skill_dir": str(skill_dir),
74
+ "packet_id": packet.packet_id,
75
+ "intent": packet.intent,
76
+ "delta": validation.deltas,
77
+ "threshold": packet.threshold,
78
+ "passed": validation.passed,
79
+ "deployed_at": datetime.now().isoformat(),
80
+ "target_agent": packet.target_agent,
81
+ "compilation_iteration": compilation.attempt,
82
+ "dspy_score": compilation.best_score,
83
+ }
84
+
85
+ with open(self.deployment_log, "a") as f:
86
+ f.write(__import__('json').dumps(deploy_info) + "\n")
87
+
88
+ return deploy_info
89
+
90
+ # ── SKILL.md Generation ─────────────────────────────────────────
91
+ def _generate_skill_md(
92
+ self,
93
+ packet: SkillGenesisPacket,
94
+ compilation: CompilationResult,
95
+ validation: MetricSnapshot,
96
+ ) -> str:
97
+ """Generate a professional SKILL.md for the new skill."""
98
+ return f"""---
99
+ name: {compilation.skill_name}
100
+ category: software-development
101
+ description: Auto-generated by Promethean Cycle. {packet.intent}
102
+ auto_generated: true
103
+ promethean_packet_id: {packet.packet_id}
104
+ generated_at: {datetime.now().isoformat()}
105
+ ---
106
+
107
+ # {compilation.skill_name.replace('-', ' ').title()}
108
+
109
+ > 🤖 Auto-compiled by the Promethean Cycle (GEPA ⊕ DSPy)
110
+ > **Intent:** {packet.intent}
111
+ > **Delta:** {validation.deltas}
112
+ > **Threshold:** {packet.threshold} → {"✅ PASSED" if validation.passed else "❌ FAILED"}
113
+
114
+ ## When to Use
115
+
116
+ This skill was automatically generated in response to detected operational failures.
117
+ Use when encountering errors matching the pattern:
118
+
119
+ ```
120
+ {packet.error_signature if hasattr(packet, 'error_signature') else packet.intent[:100]}
121
+ ```
122
+
123
+ ## Validation Results
124
+
125
+ | Metric | Baseline | Evolved | Delta |
126
+ |--------|----------|---------|-------|
127
+ {chr(10).join(f"| {k} | {validation.baseline.get(k, 'N/A')} | {validation.evolved.get(k, 'N/A')} | {v} |" for k, v in validation.deltas.items())}
128
+
129
+ - **Dataset size:** {validation.dataset_size}
130
+ - **Holdout size:** {validation.holdout_size}
131
+ - **DSPy Best Score:** {compilation.best_score}
132
+ - **Compilation iterations:** {compilation.iterations}
133
+
134
+ ## Target Agents
135
+
136
+ {packet.target_agent}
137
+
138
+ ## Compilation Strategy
139
+
140
+ BetterTogether: `{packet.strategy}`
141
+
142
+ ## Signature
143
+
144
+ ```
145
+ {packet.signature}
146
+ ```
147
+
148
+ ## Notes
149
+
150
+ This skill was born from the Promethean Cycle — the dashboard detected a capability gap,
151
+ GEPA formulated a learning objective, DSPy compiled the solution, and the delta validator
152
+ confirmed its effectiveness. No human wrote this skill. The system learned it.
153
+ """
154
+
155
+ # ── Categorization ──────────────────────────────────────────────
156
+ def _categorize(self, packet: SkillGenesisPacket) -> str:
157
+ """Determine the best category for this skill."""
158
+ intent_lower = packet.intent.lower()
159
+ if any(kw in intent_lower for kw in ["deploy", "build", "docker", "ci", "pipeline"]):
160
+ return "devops"
161
+ elif any(kw in intent_lower for kw in ["database", "migration", "drizzle", "sql"]):
162
+ return "backend-patterns"
163
+ elif any(kw in intent_lower for kw in ["test", "validation", "qa", "verify"]):
164
+ return "testing"
165
+ elif any(kw in intent_lower for kw in ["auth", "login", "session", "oauth"]):
166
+ return "security"
167
+ elif any(kw in intent_lower for kw in ["expo", "react-native", "mobile", "app"]):
168
+ return "software-development"
169
+ else:
170
+ return "software-development"
171
+
172
+ # ── Registry Update ─────────────────────────────────────────────
173
+ def get_deployment_history(self, limit: int = 20) -> list[dict]:
174
+ """Get recent deployment history."""
175
+ if not self.deployment_log.exists():
176
+ return []
177
+
178
+ deployments = []
179
+ with open(self.deployment_log) as f:
180
+ for line in f:
181
+ if line.strip():
182
+ deployments.append(__import__('json').loads(line))
183
+
184
+ return deployments[-limit:]
185
+
186
+
187
+ # ── Singleton ───────────────────────────────────────────────────────
188
+ _deployer: Optional[SkillDeployer] = None
189
+
190
+
191
+ def get_deployer() -> SkillDeployer:
192
+ global _deployer
193
+ if _deployer is None:
194
+ _deployer = SkillDeployer()
195
+ return _deployer