@mutagent/helix 0.1.0-alpha.14

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 (357) hide show
  1. package/.claude/skills/mutagent-helix/SKILL.md +113 -0
  2. package/.claude/skills/mutagent-helix/scripts/cli/codex-transcode.ts +143 -0
  3. package/.claude/skills/mutagent-helix/scripts/cli/doctor.ts +111 -0
  4. package/.claude/skills/mutagent-helix/scripts/cli/init.ts +382 -0
  5. package/.claude/skills/mutagent-helix/scripts/cli/run.sh +61 -0
  6. package/CLAUDE.md +193 -0
  7. package/LICENSE +201 -0
  8. package/NOTICE +22 -0
  9. package/README.md +209 -0
  10. package/assets/adl-loop.svg +162 -0
  11. package/assets/system-status.svg +422 -0
  12. package/bin/mutagent-cli.mjs +9950 -0
  13. package/bin/mutagent-helix.mjs +78 -0
  14. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/CLAUDE.md +28 -0
  15. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/SKILL.md +138 -0
  16. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl +247 -0
  17. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/frameworks/doc-pins.md +53 -0
  18. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/principles.md +91 -0
  19. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/requirements.yaml +295 -0
  20. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/workflows/orchestrator-protocol.md +302 -0
  21. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/doctor.ts +116 -0
  22. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/init.ts +230 -0
  23. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/cli/run.sh +60 -0
  24. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/config/resolve-spec-dir.ts +199 -0
  25. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/contract/agentspec.schema.ts +455 -0
  26. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/setup/detect.ts +67 -0
  27. package/mutagent-agentspec/.claude/skills/mutagent-agentspec/scripts/validate/validate-spec.ts +93 -0
  28. package/mutagent-agentspec/LICENSE +201 -0
  29. package/mutagent-agentspec/NOTICE +19 -0
  30. package/mutagent-agentspec/README.md +44 -0
  31. package/mutagent-builder/.claude/skills/mutagent-builder/SKILL.md +100 -0
  32. package/mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md +312 -0
  33. package/mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md +357 -0
  34. package/mutagent-builder/.claude/skills/mutagent-builder/assets/templates/build-report.md.tpl +39 -0
  35. package/mutagent-builder/.claude/skills/mutagent-builder/references/principles.md +31 -0
  36. package/mutagent-builder/.claude/skills/mutagent-builder/references/workflows/build-protocol.md +61 -0
  37. package/mutagent-builder/.claude/skills/mutagent-builder/references/workflows/improve-handoff.md +23 -0
  38. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/cli/run.sh +60 -0
  39. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/handoff/validate-build-input.ts +72 -0
  40. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/sync-spec/check-sync-spec.ts +499 -0
  41. package/mutagent-builder/.claude/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts +182 -0
  42. package/mutagent-builder/CLAUDE.md +25 -0
  43. package/mutagent-builder/README.md +26 -0
  44. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/README.md +192 -0
  45. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/SKILL.md +352 -0
  46. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/ai-architect.md +256 -0
  47. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/ai-engineer.md +344 -0
  48. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/diagnostics-analyzer.md +576 -0
  49. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/agents/discovery.md +425 -0
  50. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/audit.json.tpl +24 -0
  51. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/audit.md.tpl +49 -0
  52. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/config.yaml.tpl +100 -0
  53. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/pr-body.md.tpl +56 -0
  54. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/report.html.tpl +327 -0
  55. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/README.md +27 -0
  56. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/iter-N-handover.md.tpl +125 -0
  57. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/self-diagnosis-contract.v0.1.0.yaml.tpl +234 -0
  58. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/spec.yaml.tpl +152 -0
  59. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/team.yaml.tpl +127 -0
  60. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/templates/shared/wave-N-dashboard.html.tpl +1712 -0
  61. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.1-nl-query.md +59 -0
  62. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.2-tier0-progress.md +58 -0
  63. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.3-analysis-progress.md +44 -0
  64. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.4-html-report.md +61 -0
  65. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.5-rca-detail.md +69 -0
  66. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.6-stale-warning.md +53 -0
  67. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.1-welcome.md +60 -0
  68. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.2-source-platform-picker.md +41 -0
  69. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.3-source-auth.md +75 -0
  70. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.4-target-picker.md +48 -0
  71. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.5-ask-tool.md +43 -0
  72. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.6-config-review.md +57 -0
  73. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.7-filter-defaults.md +52 -0
  74. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.8-first-run.md +59 -0
  75. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/examples/sample-findings.json +92 -0
  76. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/examples/sample-meta.json +47 -0
  77. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/adapter-strategy.md +75 -0
  78. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/config-migration.md +84 -0
  79. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/config.md +159 -0
  80. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/filter-search-matrix.md +66 -0
  81. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/harness-knowledge.md +22 -0
  82. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/memory-format.md +78 -0
  83. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/onboarding-decisions.yaml +187 -0
  84. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/operation-inventory.md +59 -0
  85. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/overview.md +167 -0
  86. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/reference.md +119 -0
  87. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/script-index.md +101 -0
  88. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-adapter-contract.md +93 -0
  89. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/claude-code-transcripts.md +66 -0
  90. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/codex-transcripts.md +78 -0
  91. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/codex.md +145 -0
  92. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/install-paths.md +57 -0
  93. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/langfuse.md +178 -0
  94. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/local-jsonl.md +55 -0
  95. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/openobserve.md +102 -0
  96. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/source-platforms/otel.md +63 -0
  97. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/cloud-rest.md +84 -0
  98. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-claude.md +65 -0
  99. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cloud-agent-sdk.md +92 -0
  100. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-codex.md +72 -0
  101. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cursor.md +108 -0
  102. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-mastra.md +77 -0
  103. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/target-platforms/local-opencode.md +70 -0
  104. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/apply-pr-comment-format.md +82 -0
  105. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/diagnostics.md +35 -0
  106. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/handover-contract.md +247 -0
  107. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/onboarding.md +300 -0
  108. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/orchestrator-protocol.md +1861 -0
  109. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/rca.md +331 -0
  110. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/rendering-anatomy.md +314 -0
  111. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/schedule-prep.md +100 -0
  112. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/scope-model.md +128 -0
  113. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/references/workflows/verification-methodology.md +174 -0
  114. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/aggregate/sort-findings.ts +0 -0
  115. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/awareness/blind-spots.ts +167 -0
  116. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/awareness/llm-sample.ts +681 -0
  117. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/doctor.ts +215 -0
  118. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/init.ts +1013 -0
  119. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/install-agents.ts +350 -0
  120. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/run.sh +61 -0
  121. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/cli/shared-templates.ts +79 -0
  122. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/load.ts +392 -0
  123. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/resolve-credential.ts +120 -0
  124. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/schema.ts +641 -0
  125. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/config/validate.ts +134 -0
  126. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/context/build-diagnosis-context.ts +417 -0
  127. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/context/load-context.ts +105 -0
  128. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/contract/types.ts +166 -0
  129. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/build-render-input.ts +1964 -0
  130. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/corpus-severity.ts +172 -0
  131. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/dismissal-match.ts +270 -0
  132. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/enrich/rank-remedies.ts +75 -0
  133. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/hooks/install-hooks.sh +46 -0
  134. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/hooks/pre-push.sh +78 -0
  135. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/invocation/parse-brief.ts +188 -0
  136. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/match.ts +114 -0
  137. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/paths.ts +95 -0
  138. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/store.ts +535 -0
  139. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/library/types.ts +181 -0
  140. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/lint/template-inline-js.ts +267 -0
  141. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/memory/append.ts +188 -0
  142. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/memory/read.ts +218 -0
  143. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/platforms/entity-context.ts +686 -0
  144. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/read-unitf.ts +267 -0
  145. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/trace.ts +1078 -0
  146. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-adapter.ts +0 -0
  147. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-types.ts +213 -0
  148. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/report/persist-selections.ts +174 -0
  149. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/report/render.ts +3254 -0
  150. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/run/diagnose.ts +64 -0
  151. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/run/session.ts +167 -0
  152. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/caps.ts +345 -0
  153. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/deep-read-gate.ts +424 -0
  154. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/sample/representative.ts +584 -0
  155. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/scan/objection.ts +224 -0
  156. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/scan/trajectory.ts +489 -0
  157. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/dispatch.ts +135 -0
  158. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/probe.ts +170 -0
  159. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/detect.ts +307 -0
  160. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/ensure-cli.ts +315 -0
  161. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/reconfigure.ts +77 -0
  162. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/setup/verify-agents.ts +207 -0
  163. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/slicer.ts +166 -0
  164. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/claude-code.ts +17 -0
  165. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/codex.ts +11 -0
  166. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/langfuse.ts +17 -0
  167. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/local-jsonl.ts +12 -0
  168. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/adapters/otel.ts +12 -0
  169. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/index.ts +54 -0
  170. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/registry.ts +45 -0
  171. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/source/types.ts +86 -0
  172. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/stale-detector.ts +74 -0
  173. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/test/render-playwright.cli.ts +477 -0
  174. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0/claude-code.ts +133 -0
  175. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0/langfuse.ts +143 -0
  176. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/tier0-scan.ts +423 -0
  177. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/completeness-check.ts +436 -0
  178. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/doc-refs.ts +190 -0
  179. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/finalize-gate.ts +417 -0
  180. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/findings-contract.ts +628 -0
  181. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/render-js-syntax.ts +188 -0
  182. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/report-checklist.yaml +217 -0
  183. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/trace-shape.ts +262 -0
  184. package/mutagent-diagnostics/.claude/skills/mutagent-diagnostics/scripts/validate/wave6-checklist.ts +326 -0
  185. package/mutagent-diagnostics/CLAUDE.md +41 -0
  186. package/mutagent-diagnostics/LICENSE +201 -0
  187. package/mutagent-diagnostics/NOTICE +18 -0
  188. package/mutagent-diagnostics/README.md +343 -0
  189. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/SKILL.md +548 -0
  190. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/audit-executor.md +169 -0
  191. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/dataset-builder.md +160 -0
  192. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/discovery.md +425 -0
  193. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/agents/evaluator.md +1108 -0
  194. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/brand/theme.css +213 -0
  195. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/assets/brand/wordmark.html +9 -0
  196. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/context-flow-lens.md +85 -0
  197. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/data-lens.md +47 -0
  198. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/decision-lens.md +48 -0
  199. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/methodology-critic-lens.md +53 -0
  200. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/lenses/trajectory-lens.md +44 -0
  201. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/build-review-interface.md +83 -0
  202. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/edd-loop.md +134 -0
  203. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/error-analysis.md +113 -0
  204. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/eval-audit.md +154 -0
  205. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/eval-stage.md +168 -0
  206. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/generate-synthetic-data.md +81 -0
  207. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/grounded-adjudication.md +221 -0
  208. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/memory-format.md +65 -0
  209. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/methodology.md +201 -0
  210. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/operation-inventory.md +197 -0
  211. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/validate-evaluator.md +125 -0
  212. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/workflows/orchestrator-protocol.md +300 -0
  213. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/references/write-judge-prompt.md +123 -0
  214. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/behavior-tree.schema.yaml +73 -0
  215. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/dataset.schema.yaml +66 -0
  216. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/edd-change-request.schema.yaml +114 -0
  217. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/eval-matrix.schema.yaml +74 -0
  218. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/flow-graph.schema.yaml +69 -0
  219. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/flow-profile.schema.yaml +49 -0
  220. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/methodology-review.schema.yaml +40 -0
  221. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/schemas/scorecard.schema.yaml +85 -0
  222. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/agent-dispatch.ts +0 -0
  223. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/aggregate-discover.ts +543 -0
  224. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/artifact-paths.ts +115 -0
  225. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/assemble-scorecard.ts +172 -0
  226. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-dataset.ts +186 -0
  227. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-evals.ts +93 -0
  228. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/build-review-ui.ts +393 -0
  229. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/check-method-router.ts +170 -0
  230. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/aggregate.ts +112 -0
  231. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/audit-run.ts +182 -0
  232. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/doctor.ts +211 -0
  233. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/dogfood.ts +133 -0
  234. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/init.ts +601 -0
  235. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/methodology-review.ts +122 -0
  236. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/prep.ts +295 -0
  237. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/profile-subject.ts +165 -0
  238. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/run.sh +56 -0
  239. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cli/variance-check.ts +105 -0
  240. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/code-eval.ts +248 -0
  241. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/code-quality-verdict.ts +285 -0
  242. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/codegen-evals.ts +173 -0
  243. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cold-start-project.ts +151 -0
  244. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/cold-start-sampler.ts +267 -0
  245. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/config/load.ts +343 -0
  246. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/config/schema.ts +380 -0
  247. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/agentspec-evals.ts +85 -0
  248. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/dataset.ts +149 -0
  249. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-engine.ts +118 -0
  250. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-matrix.ts +577 -0
  251. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/eval-types.ts +1074 -0
  252. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/flow-graph.ts +194 -0
  253. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/types.ts +303 -0
  254. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/contracts/validation.ts +193 -0
  255. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/derive-dataset.ts +152 -0
  256. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/determine-outcome.ts +219 -0
  257. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/diff-discriminate.ts +160 -0
  258. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/discover-criteria.ts +348 -0
  259. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/change-request.ts +232 -0
  260. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/edd-types.ts +210 -0
  261. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/edd/variance-gate.ts +186 -0
  262. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/emit-completeness.ts +111 -0
  263. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/eval-engine.ts +160 -0
  264. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/evaluate.ts +333 -0
  265. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/flow-graph.ts +230 -0
  266. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/judge-prompt-template.ts +253 -0
  267. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/judge-provider.ts +135 -0
  268. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/lint-grounding.ts +229 -0
  269. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/lint-uniformity.ts +168 -0
  270. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/living-suite.ts +109 -0
  271. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-bundle.ts +203 -0
  272. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-profile-vocab.ts +64 -0
  273. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/load-profile.ts +106 -0
  274. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/mask.ts +138 -0
  275. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/materialize-dataset.ts +113 -0
  276. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/matrix-judge.ts +750 -0
  277. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/memory/append.ts +215 -0
  278. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/memory/read.ts +168 -0
  279. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/persist-eval-criteria.ts +232 -0
  280. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/prep-tasks.ts +125 -0
  281. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/profile-subject.ts +310 -0
  282. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/publish-report.ts +131 -0
  283. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/read-unitf-traces.ts +81 -0
  284. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-build-cards.ts +195 -0
  285. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-discover-report.ts +1640 -0
  286. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-eval-report.ts +3838 -0
  287. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/render-report.ts +212 -0
  288. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/resolve-credential.ts +110 -0
  289. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/resolve-ref.ts +98 -0
  290. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/result-verify.ts +129 -0
  291. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/route-failures.ts +330 -0
  292. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-deterministic.ts +367 -0
  293. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-evaluate.ts +719 -0
  294. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-judge.ts +155 -0
  295. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/run-pipeline.ts +175 -0
  296. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/sample-traces.ts +210 -0
  297. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/self-audit.ts +387 -0
  298. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/source-map.ts +106 -0
  299. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/subject-profile.ts +134 -0
  300. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/substrate.ts +162 -0
  301. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/sync-eval-criteria.ts +244 -0
  302. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/ui-slots.ts +119 -0
  303. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/unitf-to-evaltrace.ts +284 -0
  304. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/validate-judge.ts +358 -0
  305. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/variance-compare.ts +177 -0
  306. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/behavior-tree.yaml +140 -0
  307. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/eval-matrix.yaml +1270 -0
  308. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/methodology-review.yaml +105 -0
  309. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/audit.workflow.js +82 -0
  310. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/data-leak.workflow.js +236 -0
  311. package/mutagent-evaluator/.claude/skills/mutagent-evaluator/workflows/variance.workflow.js +163 -0
  312. package/mutagent-evaluator/CLAUDE.md +45 -0
  313. package/mutagent-evaluator/LICENSE +201 -0
  314. package/mutagent-evaluator/NOTICE +23 -0
  315. package/mutagent-evaluator/README.md +88 -0
  316. package/mutagent-optimize/.claude/skills/mutagent-optimize/SKILL.md +287 -0
  317. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/contracts/amend-request.ts +503 -0
  318. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/improve-loop-run.ts +304 -0
  319. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/loop-state-cli.ts +300 -0
  320. package/mutagent-optimize/.claude/skills/mutagent-optimize/scripts/loop-state.ts +440 -0
  321. package/mutagent-optimize/CLAUDE.md +49 -0
  322. package/mutagent-optimize/README.md +26 -0
  323. package/mutagent-orchestrator/CLAUDE.md +102 -0
  324. package/mutagent-orchestrator/README.md +20 -0
  325. package/mutagent-orchestrator/assets/agents/discovery.md +425 -0
  326. package/mutagent-orchestrator/assets/agents/dogfood-monitor.md +266 -0
  327. package/mutagent-orchestrator/assets/agents/monitor.md +258 -0
  328. package/mutagent-orchestrator/orchestrator.md +782 -0
  329. package/mutagent-orchestrator/references/MONITORING.md +209 -0
  330. package/mutagent-orchestrator/references/config-fields.md +132 -0
  331. package/mutagent-orchestrator/references/config-migration.md +132 -0
  332. package/mutagent-orchestrator/references/index-registry.md +92 -0
  333. package/mutagent-orchestrator/routing.yaml +391 -0
  334. package/mutagent-orchestrator/scripts/config-schema.ts +1010 -0
  335. package/mutagent-orchestrator/scripts/dispatch.ts +439 -0
  336. package/mutagent-orchestrator/scripts/dogfood/extract-feedback.ts +203 -0
  337. package/mutagent-orchestrator/scripts/dogfood/reconstruct-trajectory.ts +327 -0
  338. package/mutagent-orchestrator/scripts/dogfood/render-dogfood-report.ts +347 -0
  339. package/mutagent-orchestrator/scripts/dogfood/resolve-subagents.ts +160 -0
  340. package/mutagent-orchestrator/scripts/dogfood/run-report.ts +264 -0
  341. package/mutagent-orchestrator/scripts/dogfood/slack-thread.ts +106 -0
  342. package/mutagent-orchestrator/scripts/dogfood/types.ts +257 -0
  343. package/mutagent-orchestrator/scripts/eval-routing.ts +753 -0
  344. package/mutagent-orchestrator/scripts/gate.ts +219 -0
  345. package/mutagent-orchestrator/scripts/handover-contract.ts +362 -0
  346. package/mutagent-orchestrator/scripts/index/build-index.ts +351 -0
  347. package/mutagent-orchestrator/scripts/index/render-index.ts +110 -0
  348. package/mutagent-orchestrator/scripts/monitor/slack-notify.ts +111 -0
  349. package/mutagent-orchestrator/scripts/monitor/triggers.ts +162 -0
  350. package/mutagent-orchestrator/scripts/onboarding-check.ts +369 -0
  351. package/mutagent-orchestrator/scripts/render-roster.ts +308 -0
  352. package/mutagent-orchestrator/scripts/resolve-credential.ts +185 -0
  353. package/mutagent-orchestrator/scripts/resolve-paths.ts +114 -0
  354. package/mutagent-orchestrator/scripts/slack/format.ts +63 -0
  355. package/mutagent-orchestrator/scripts/slack/post.ts +115 -0
  356. package/mutagent-orchestrator/scripts/sync-index.ts +311 -0
  357. package/package.json +64 -0
@@ -0,0 +1,327 @@
1
+ // ---------------------------------------------------------------------------
2
+ // reconstruct-trajectory — a Helix session JSONL (+ its dispatched subagent
3
+ // JSONLs) → a structured Trajectory (lifecycle timeline · command usage ·
4
+ // per-subagent internal steps · a Call-Stack DAG). The `*dogfood` monitor calls
5
+ // this on every drift + on the 3m heartbeat.
6
+ //
7
+ // PURITY: the reconstruction CORE (`reconstructTrajectoryFromTraces`) is pure —
8
+ // no clock, no random, no I/O; the wall-clock `now` is INJECTED. The file wrapper
9
+ // (`reconstructTrajectory`) does the ONLY I/O: it reads the named JSONL paths
10
+ // THROUGH the shared `mutagent-tools` claude-code adapter → UniTF. We do NOT write
11
+ // a second transcript parser — the adapter is the single source of truth for the
12
+ // Claude Code session schema (api_error / compact_boundary / agentName / tool-use).
13
+ // ---------------------------------------------------------------------------
14
+
15
+ import { claudeCodeAdapter } from "../../../mutagent-tools/src/adapters/claude-code.ts";
16
+ import type { FetchContext } from "../../../mutagent-tools/src/adapters/types.ts";
17
+ import type { UnifiedTrace } from "../../../mutagent-tools/src/format/unitf.ts";
18
+
19
+ import {
20
+ type CommandInvocation,
21
+ type CommandUsage,
22
+ type DagEdge,
23
+ type DagNode,
24
+ type DagSpec,
25
+ type StageSegment,
26
+ type SubagentActivity,
27
+ type Trajectory,
28
+ STAGE_META,
29
+ stageForCommand,
30
+ } from "./types.ts";
31
+
32
+ // ── File → UniTF (via the shared adapter) ─────────────────────────────────────
33
+
34
+ /**
35
+ * Parse ONE Claude Code session JSONL into a UniTF trace via the shared adapter.
36
+ * The adapter's `collect` reads only `ctx.query.source.paths`; the rest of the
37
+ * FetchContext is inert for a local file transform, so we hand it a minimal ctx.
38
+ * Returns null when the file is unreadable / has no recognizable events.
39
+ */
40
+ export async function parseSessionFile(path: string): Promise<UnifiedTrace | null> {
41
+ const ctx = {
42
+ query: { source: { paths: [path] } },
43
+ now: 0,
44
+ window: {},
45
+ projectRoot: "",
46
+ } as unknown as FetchContext;
47
+ const res = await claudeCodeAdapter.transform!(ctx);
48
+ return res.traces[0] ?? null;
49
+ }
50
+
51
+ // ── Span text extraction ──────────────────────────────────────────────────────
52
+
53
+ /** Best-effort deterministic stringify of a span input/output payload. */
54
+ function spanText(v: unknown): string {
55
+ if (v === undefined || v === null) return "";
56
+ if (typeof v === "string") return v;
57
+ if (typeof v === "number" || typeof v === "boolean") return String(v);
58
+ if (typeof v === "object") {
59
+ const o = v as Record<string, unknown>;
60
+ for (const k of ["text", "content", "response", "prompt", "message"]) {
61
+ if (typeof o[k] === "string") return o[k] as string;
62
+ }
63
+ try {
64
+ return JSON.stringify(v);
65
+ } catch {
66
+ return "";
67
+ }
68
+ }
69
+ return "";
70
+ }
71
+
72
+ // ── Command detection ─────────────────────────────────────────────────────────
73
+
74
+ /**
75
+ * Detect the `*command` invocation in one user turn. A command is invoked by
76
+ * being the LEADING token of the (trimmed) user message — exactly how Helix
77
+ * commands are typed. This deliberately ignores `*command` MENTIONS mid-prose
78
+ * (e.g. a `[feedback]` block that references `*evaluate`) and markdown emphasis
79
+ * (`*like this*`), which are not invocations. Returns the leading command WITH its
80
+ * `*` (at most one per turn), or an empty array.
81
+ */
82
+ export function detectCommandTokens(text: string): string[] {
83
+ const m = /^(\*[a-z][a-z0-9-]*)/.exec(text.trimStart());
84
+ return m ? [m[1]] : [];
85
+ }
86
+
87
+ /** Extract the ordered `*command` invocations from a main-session trace. */
88
+ export function extractCommands(main: UnifiedTrace): CommandInvocation[] {
89
+ const invocations: CommandInvocation[] = [];
90
+ let turnIndex = 0;
91
+ for (const span of main.spans) {
92
+ if (span.role !== "user") continue;
93
+ const text = spanText(span.output ?? span.input);
94
+ const tokens = detectCommandTokens(text);
95
+ for (const token of tokens) {
96
+ const inv: CommandInvocation = {
97
+ command: token,
98
+ stage: stageForCommand(token),
99
+ spanId: span.spanId,
100
+ sessionId: main.sessionId ?? main.traceId,
101
+ turnIndex,
102
+ };
103
+ if (span.startTime) inv.timestamp = span.startTime;
104
+ invocations.push(inv);
105
+ }
106
+ turnIndex++;
107
+ }
108
+ return invocations;
109
+ }
110
+
111
+ // ── Timeline + usage ──────────────────────────────────────────────────────────
112
+
113
+ /** epoch-ms → ISO-8601 (for the injected `now`; not a self-read clock). */
114
+ function isoFromEpoch(now: number): string {
115
+ return new Date(now).toISOString();
116
+ }
117
+
118
+ /**
119
+ * Build the lifecycle stage timeline: each command opens a segment that closes
120
+ * when the NEXT command opens (or at the injected `now` for the last one).
121
+ */
122
+ export function buildTimeline(commands: CommandInvocation[], now: number): StageSegment[] {
123
+ const nowIso = isoFromEpoch(now);
124
+ return commands.map((c, i) => {
125
+ const next = i + 1 < commands.length ? commands[i + 1] : undefined;
126
+ const endTime = next?.timestamp ?? nowIso;
127
+ const seg: StageSegment = { stage: c.stage, command: c.command };
128
+ if (c.timestamp) seg.startTime = c.timestamp;
129
+ if (endTime) seg.endTime = endTime;
130
+ if (c.timestamp && endTime) {
131
+ const d = Date.parse(endTime) - Date.parse(c.timestamp);
132
+ if (Number.isFinite(d) && d >= 0) seg.durationMs = d;
133
+ }
134
+ return seg;
135
+ });
136
+ }
137
+
138
+ /** Ordered `*command` usage with counts (first-seen order preserved). */
139
+ export function buildCommandUsage(commands: CommandInvocation[]): CommandUsage[] {
140
+ const order: string[] = [];
141
+ const counts = new Map<string, number>();
142
+ for (const c of commands) {
143
+ if (!counts.has(c.command)) order.push(c.command);
144
+ counts.set(c.command, (counts.get(c.command) ?? 0) + 1);
145
+ }
146
+ return order.map((command) => ({
147
+ command,
148
+ stage: stageForCommand(command),
149
+ count: counts.get(command) ?? 0,
150
+ }));
151
+ }
152
+
153
+ // ── Subagent activity ─────────────────────────────────────────────────────────
154
+
155
+ /** Derive a subagent's internal activity (key tool-steps) from its session trace. */
156
+ export function buildSubagentActivity(sub: UnifiedTrace): SubagentActivity {
157
+ const steps: SubagentActivity["steps"] = [];
158
+ const toolCounts: Record<string, number> = {};
159
+ for (const span of sub.spans) {
160
+ // tool_use spans carry a toolName; tool_result spans (role toolResult) do not.
161
+ if (span.kind !== "tool" || !span.toolName) continue;
162
+ const step: SubagentActivity["steps"][number] = {
163
+ toolName: span.toolName,
164
+ spanId: span.spanId,
165
+ };
166
+ if (span.startTime) step.timestamp = span.startTime;
167
+ steps.push(step);
168
+ toolCounts[span.toolName] = (toolCounts[span.toolName] ?? 0) + 1;
169
+ }
170
+ return {
171
+ agentName: sub.agentName ?? sub.sessionId ?? sub.traceId,
172
+ sessionId: sub.sessionId ?? sub.traceId,
173
+ steps,
174
+ toolCounts,
175
+ };
176
+ }
177
+
178
+ // ── Call-Stack DAG ────────────────────────────────────────────────────────────
179
+
180
+ /** mermaid-safe node id (alphanumeric + underscore). */
181
+ function sanitizeId(s: string): string {
182
+ return s.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "n";
183
+ }
184
+
185
+ /** Sanitize a label for a mermaid `["..."]` (strip quotes + collapse whitespace). */
186
+ function sanitizeLabel(s: string): string {
187
+ return s.replace(/["[\]]/g, "").replace(/\s+/g, " ").trim();
188
+ }
189
+
190
+ /** Index of the command whose [start,end) window contains `iso`, else -1. */
191
+ function commandWindowFor(
192
+ iso: string | undefined,
193
+ commands: CommandInvocation[],
194
+ now: number,
195
+ ): number {
196
+ if (!iso) return -1;
197
+ const t = Date.parse(iso);
198
+ if (!Number.isFinite(t)) return -1;
199
+ for (let i = 0; i < commands.length; i++) {
200
+ const start = commands[i].timestamp ? Date.parse(commands[i].timestamp as string) : NaN;
201
+ if (!Number.isFinite(start)) continue;
202
+ const next = i + 1 < commands.length ? commands[i + 1] : undefined;
203
+ const end = next?.timestamp ? Date.parse(next.timestamp as string) : now;
204
+ if (t >= start && t <= end) return i;
205
+ }
206
+ return -1;
207
+ }
208
+
209
+ /** Max tool-steps rendered per subagent in the DAG (the rest are in section 3). */
210
+ const MAX_DAG_STEPS = 6;
211
+
212
+ /**
213
+ * Build the Call-Stack DAG: Helix → each `*command` → its stage skill → any
214
+ * subagent dispatched during that command's window → up to MAX_DAG_STEPS steps.
215
+ * Emits a {nodes,edges} spec + a deterministic mermaid flowchart string.
216
+ */
217
+ export function buildDag(
218
+ commands: CommandInvocation[],
219
+ subagents: SubagentActivity[],
220
+ now: number,
221
+ ): DagSpec {
222
+ const nodes: DagNode[] = [];
223
+ const edges: DagEdge[] = [];
224
+ const seen = new Set<string>();
225
+ const addNode = (n: DagNode): void => {
226
+ if (seen.has(n.id)) return;
227
+ seen.add(n.id);
228
+ nodes.push(n);
229
+ };
230
+
231
+ addNode({ id: "helix", label: "🧬 Helix", kind: "helix" });
232
+
233
+ // command + skill nodes
234
+ commands.forEach((c, i) => {
235
+ const cmdId = `cmd${i}`;
236
+ addNode({ id: cmdId, label: c.command, kind: "command" });
237
+ edges.push({ from: "helix", to: cmdId, kind: "dispatch" });
238
+ const skillId = `skill_${c.stage}`;
239
+ addNode({ id: skillId, label: STAGE_META[c.stage].skill, kind: "skill" });
240
+ edges.push({ from: cmdId, to: skillId, kind: "call" });
241
+ });
242
+
243
+ // subagents attached under the skill of their active command (else under Helix)
244
+ subagents.forEach((sub, si) => {
245
+ const firstTs = sub.steps.find((s) => s.timestamp)?.timestamp;
246
+ const cmdIdx = commandWindowFor(firstTs, commands, now);
247
+ const agentId = `agent_${sanitizeId(sub.agentName)}_${si}`;
248
+ addNode({ id: agentId, label: sub.agentName, kind: "agent" });
249
+ if (cmdIdx >= 0) {
250
+ const parentSkill = `skill_${commands[cmdIdx].stage}`;
251
+ edges.push({ from: parentSkill, to: agentId, kind: "dispatch" });
252
+ } else {
253
+ edges.push({ from: "helix", to: agentId, kind: "dispatch" });
254
+ }
255
+ sub.steps.slice(0, MAX_DAG_STEPS).forEach((step, sti) => {
256
+ const stepId = `step_${si}_${sti}`;
257
+ addNode({ id: stepId, label: step.toolName, kind: "step" });
258
+ edges.push({ from: agentId, to: stepId, kind: "call" });
259
+ });
260
+ });
261
+
262
+ return { nodes, edges, mermaid: mermaidFromDag(nodes, edges) };
263
+ }
264
+
265
+ /** Render a {nodes,edges} DAG to a deterministic mermaid `flowchart TD` string. */
266
+ export function mermaidFromDag(nodes: DagNode[], edges: DagEdge[]): string {
267
+ const lines: string[] = ["flowchart TD"];
268
+ for (const n of nodes) {
269
+ lines.push(` ${n.id}["${sanitizeLabel(n.label)}"]`);
270
+ }
271
+ for (const e of edges) {
272
+ lines.push(` ${e.from} -->|${e.kind}| ${e.to}`);
273
+ }
274
+ return lines.join("\n");
275
+ }
276
+
277
+ // ── Public API ────────────────────────────────────────────────────────────────
278
+
279
+ /** Pure reconstruction core — traces in, Trajectory out. No I/O, no clock. */
280
+ export function reconstructTrajectoryFromTraces(
281
+ main: UnifiedTrace,
282
+ subs: UnifiedTrace[],
283
+ now: number,
284
+ ): Trajectory {
285
+ const commands = extractCommands(main);
286
+ const subagents = subs.map(buildSubagentActivity);
287
+ const traj: Trajectory = {
288
+ sessionId: main.sessionId ?? main.traceId,
289
+ now,
290
+ timeline: buildTimeline(commands, now),
291
+ commands,
292
+ commandUsage: buildCommandUsage(commands),
293
+ subagents,
294
+ dag: buildDag(commands, subagents, now),
295
+ };
296
+ if (main.startTime) traj.startTime = main.startTime;
297
+ return traj;
298
+ }
299
+
300
+
301
+
302
+ export interface ReconstructInput {
303
+ /** The main Helix session JSONL path. */
304
+ mainPath: string;
305
+ /** The dispatched subagent session JSONL paths. */
306
+ subagentPaths?: string[];
307
+ /** Injected wall-clock (epoch ms) — the trajectory's "as of" time. */
308
+ now: number;
309
+ }
310
+
311
+ /**
312
+ * File wrapper: read the named session JSONL paths through the shared adapter,
313
+ * then reconstruct. The ONLY I/O in this module. Throws if the main session is
314
+ * unreadable / empty; skips unreadable subagent files (best-effort).
315
+ */
316
+ export async function reconstructTrajectory(input: ReconstructInput): Promise<Trajectory> {
317
+ const main = await parseSessionFile(input.mainPath);
318
+ if (main === null) {
319
+ throw new Error(`reconstruct-trajectory: no recognizable events in main session ${input.mainPath}`);
320
+ }
321
+ const subs: UnifiedTrace[] = [];
322
+ for (const p of input.subagentPaths ?? []) {
323
+ const t = await parseSessionFile(p);
324
+ if (t !== null) subs.push(t);
325
+ }
326
+ return reconstructTrajectoryFromTraces(main, subs, input.now);
327
+ }
@@ -0,0 +1,347 @@
1
+ // ---------------------------------------------------------------------------
2
+ // render-dogfood-report — Trajectory + FeedbackItem[] + meta → a self-contained
3
+ // live status HTML string. Five sections:
4
+ // 1) Lifecycle stage TIMELINE (Gantt-style colored bars, per-stage color vars)
5
+ // 2) *command / skill usage (ordered, with counts)
6
+ // 3) Agent internal steps (per subagent, collapsible)
7
+ // 4) User feedback + notes TABLE (verbatim + actionable + rationale + evidence)
8
+ // 5) Trajectory Call-Stack DAG (embedded mermaid ESM CDN, dark theme)
9
+ //
10
+ // STYLE: the operator-approved `docs/architecture.html` visual language — Space
11
+ // Grotesk + IBM Plex Mono, restrained dark, per-stage color vars, sharp corners,
12
+ // toned status. Tokens are INLINED (the report ships standalone under
13
+ // .mutagent/dogfood/{runId}/, with no external CSS to link).
14
+ //
15
+ // PURITY: pure — input → string. No clock (meta.generatedAt is injected), no I/O.
16
+ // The ONLY <script> emitted is a STATIC mermaid module import — so it is always
17
+ // syntactically valid (no dynamic data is interpolated into any <script>).
18
+ // ---------------------------------------------------------------------------
19
+
20
+ import { STAGE_META } from "./types.ts";
21
+ import type { DogfoodReportInput, FeedbackItem, SubagentActivity } from "./types.ts";
22
+
23
+ // ── HTML escaping ─────────────────────────────────────────────────────────────
24
+
25
+ /** Escape a value for safe embedding in HTML text/attributes. */
26
+ function esc(s: unknown): string {
27
+ return String(s)
28
+ .replace(/&/g, "&amp;")
29
+ .replace(/</g, "&lt;")
30
+ .replace(/>/g, "&gt;")
31
+ .replace(/"/g, "&quot;")
32
+ .replace(/'/g, "&#39;");
33
+ }
34
+
35
+ /** Round a percentage to 2dp for byte-stable output. */
36
+ function pct(n: number): number {
37
+ return Math.round(n * 100) / 100;
38
+ }
39
+
40
+ // ── Section 1 · lifecycle timeline (Gantt) ────────────────────────────────────
41
+
42
+ function timelineBounds(input: DogfoodReportInput): { startMs: number; span: number } | null {
43
+ const { trajectory } = input;
44
+ const starts = trajectory.timeline
45
+ .map((s) => (s.startTime ? Date.parse(s.startTime) : NaN))
46
+ .filter((n) => Number.isFinite(n));
47
+ if (starts.length === 0) return null;
48
+ const startMs = trajectory.startTime && Number.isFinite(Date.parse(trajectory.startTime))
49
+ ? Date.parse(trajectory.startTime)
50
+ : Math.min(...starts);
51
+ const span = trajectory.now - startMs;
52
+ if (!(span > 0)) return null;
53
+ return { startMs, span };
54
+ }
55
+
56
+ function renderTimeline(input: DogfoodReportInput): string {
57
+ const { timeline } = input.trajectory;
58
+ if (timeline.length === 0) {
59
+ return `<p class="empty">No <code>*command</code> invocations detected yet — the timeline populates as the session runs.</p>`;
60
+ }
61
+ const bounds = timelineBounds(input);
62
+ const rows = timeline
63
+ .map((seg, i) => {
64
+ const meta = STAGE_META[seg.stage];
65
+ let leftPct = 0;
66
+ let widthPct = 100 / timeline.length;
67
+ if (bounds && seg.startTime) {
68
+ const start = Date.parse(seg.startTime);
69
+ const end = seg.endTime ? Date.parse(seg.endTime) : input.trajectory.now;
70
+ leftPct = pct(((start - bounds.startMs) / bounds.span) * 100);
71
+ widthPct = pct(Math.max(1.5, ((end - start) / bounds.span) * 100));
72
+ if (leftPct + widthPct > 100) widthPct = pct(100 - leftPct);
73
+ } else {
74
+ leftPct = pct(i * widthPct);
75
+ widthPct = pct(widthPct);
76
+ }
77
+ const dur = seg.durationMs !== undefined ? `${Math.round(seg.durationMs / 1000)}s` : "live";
78
+ return `<div class="gantt-row">
79
+ <div class="gantt-lab" style="color:var(${meta.colorVar})">${esc(meta.label)}</div>
80
+ <div class="gantt-track">
81
+ <div class="gantt-bar" style="left:${leftPct}%;width:${widthPct}%;background:var(${meta.colorVar})" title="${esc(seg.command)} · ${esc(dur)}">
82
+ <span class="gantt-cmd">${esc(seg.command)}</span>
83
+ </div>
84
+ </div>
85
+ <div class="gantt-dur ds-mono">${esc(dur)}</div>
86
+ </div>`;
87
+ })
88
+ .join("\n");
89
+ return `<div class="gantt">${rows}</div>`;
90
+ }
91
+
92
+ // ── Section 2 · command / skill usage ─────────────────────────────────────────
93
+
94
+ function renderUsage(input: DogfoodReportInput): string {
95
+ const { commandUsage } = input.trajectory;
96
+ if (commandUsage.length === 0) {
97
+ return `<p class="empty">No commands recorded yet.</p>`;
98
+ }
99
+ const chips = commandUsage
100
+ .map((u) => {
101
+ const meta = STAGE_META[u.stage];
102
+ return `<div class="usechip" style="border-left-color:var(${meta.colorVar})">
103
+ <span class="uc-cmd">${esc(u.command)}</span>
104
+ <span class="uc-skill ds-mono">${esc(meta.skill)}</span>
105
+ <span class="uc-count">×${u.count}</span>
106
+ </div>`;
107
+ })
108
+ .join("\n");
109
+ return `<div class="usewrap">${chips}</div>`;
110
+ }
111
+
112
+ // ── Section 3 · agent internal steps (collapsible) ────────────────────────────
113
+
114
+ function renderSubagent(sub: SubagentActivity): string {
115
+ const tools = Object.entries(sub.toolCounts)
116
+ .map(([name, n]) => `<span class="ds-chip">${esc(name)} ×${n}</span>`)
117
+ .join(" ");
118
+ const steps = sub.steps.length
119
+ ? sub.steps
120
+ .map((s, i) => {
121
+ const ts = s.timestamp ? `<span class="step-ts ds-mono">${esc(s.timestamp)}</span>` : "";
122
+ return `<li><span class="step-idx ds-mono">${i + 1}</span><span class="step-tool">${esc(s.toolName)}</span>${ts}</li>`;
123
+ })
124
+ .join("\n")
125
+ : `<li class="empty">No tool-steps recorded.</li>`;
126
+ return `<details class="subagent">
127
+ <summary>
128
+ <span class="sa-name">${esc(sub.agentName)}</span>
129
+ <span class="sa-meta ds-mono">${sub.steps.length} steps</span>
130
+ <span class="sa-tools">${tools}</span>
131
+ </summary>
132
+ <ol class="steps">${steps}</ol>
133
+ </details>`;
134
+ }
135
+
136
+ function renderSubagents(input: DogfoodReportInput): string {
137
+ const { subagents } = input.trajectory;
138
+ if (subagents.length === 0) {
139
+ return `<p class="empty">No subagents dispatched by this session.</p>`;
140
+ }
141
+ return subagents.map(renderSubagent).join("\n");
142
+ }
143
+
144
+ // ── Section 4 · feedback table ────────────────────────────────────────────────
145
+
146
+ function renderFeedbackRow(f: FeedbackItem): string {
147
+ const ev = f.evidencePointer;
148
+ return `<tr class="sev-${esc(f.severity)}">
149
+ <td><span class="sev-pill sev-${esc(f.severity)}">${esc(f.severity)}</span></td>
150
+ <td class="ds-mono">${esc(f.source)}<br/><span class="fk">${esc(f.kind)}</span></td>
151
+ <td class="verbatim">${esc(f.observation)}</td>
152
+ <td>${esc(f.actionable)}</td>
153
+ <td class="rationale">${esc(f.rationale)}</td>
154
+ <td class="ds-mono evidence">turn ${esc(ev.turnIndex)}<br/><span class="ev-span">${esc(ev.spanId)}</span></td>
155
+ </tr>`;
156
+ }
157
+
158
+ function renderFeedback(input: DogfoodReportInput): string {
159
+ const { feedback } = input;
160
+ if (feedback.length === 0) {
161
+ return `<p class="empty">No explicit <code>[feedback]</code> blocks or implicit reactions captured yet.</p>`;
162
+ }
163
+ const rows = feedback.map(renderFeedbackRow).join("\n");
164
+ return `<table class="fbtable">
165
+ <thead><tr>
166
+ <th>severity</th><th>source</th><th>observation (verbatim)</th>
167
+ <th>actionable</th><th>rationale</th><th>evidence</th>
168
+ </tr></thead>
169
+ <tbody>${rows}</tbody>
170
+ </table>`;
171
+ }
172
+
173
+ // ── Section 5 · Call-Stack DAG (mermaid) ──────────────────────────────────────
174
+
175
+ function renderDag(input: DogfoodReportInput): string {
176
+ const { dag } = input.trajectory;
177
+ // Escape the mermaid source: the browser decodes textContent, so mermaid still
178
+ // receives the raw graph — but the HTML never mis-parses a stray angle bracket.
179
+ return `<pre class="mermaid">${esc(dag.mermaid)}</pre>`;
180
+ }
181
+
182
+ // ── The stylesheet (inlined @mutagent/templates tokens) ───────────────────────
183
+
184
+ const STYLE = `
185
+ :root{
186
+ --bg:#06060a;--surf:#14141f;--surf-2:#1b1b29;--surf-3:#262636;
187
+ --border:rgba(255,255,255,.10);--border-strong:rgba(255,255,255,.18);
188
+ --fg:#dde2ee;--fg-strong:#f3f5fb;--muted:#9b97ab;--dim:#65617a;
189
+ --primary:#7E47D7;--primary-soft:#b794f4;--cyan:#45b8cc;
190
+ --pass:#43c39a;--fail:#e06666;--warn:#e8a64d;
191
+ --spec:#b794f4;--build:#5aa6d6;--eval:#7E47D7;--diag:#43c39a;--improve:#e8a64d;
192
+ --radius:0px;--font:'Space Grotesk',system-ui,-apple-system,sans-serif;
193
+ --mono:'IBM Plex Mono',ui-monospace,monospace;
194
+ }
195
+ *{box-sizing:border-box;border-radius:var(--radius)}
196
+ body{margin:0;background:
197
+ radial-gradient(1100px 620px at 78% -8%,rgba(126,71,215,.10),transparent 62%),
198
+ radial-gradient(900px 540px at 8% 4%,rgba(69,184,204,.07),transparent 60%),var(--bg);
199
+ color:var(--fg);font-family:var(--font);font-size:15px;line-height:1.55}
200
+ .ds-mono{font-family:var(--mono)}
201
+ code{font-family:var(--mono);color:var(--primary-soft);font-size:.9em}
202
+ .wrap{max-width:1160px;margin:0 auto;padding:0 22px 80px}
203
+ .header{position:sticky;top:0;z-index:10;background:rgba(6,6,10,.92);backdrop-filter:blur(10px);
204
+ border-bottom:1px solid var(--border-strong);padding:14px 22px;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
205
+ .wm{font-weight:700;font-size:20px;letter-spacing:.5px}
206
+ .wm b{background:linear-gradient(90deg,var(--primary-soft),var(--cyan));-webkit-background-clip:text;background-clip:text;color:transparent}
207
+ .header .hmeta{margin-left:auto;font-family:var(--mono);font-size:12px;color:var(--muted)}
208
+ .metarow{display:flex;gap:8px;flex-wrap:wrap;margin:16px 0 4px}
209
+ .metarow i{font-family:var(--mono);font-size:10.5px;font-style:normal;padding:3px 9px;border:1px solid var(--border);color:var(--muted)}
210
+ .metarow i b{color:var(--fg-strong)}
211
+ section{margin:34px 0 0}
212
+ .lbl{font-family:var(--mono);font-size:11.5px;letter-spacing:.16em;color:var(--cyan);text-transform:uppercase}
213
+ h1{font-size:30px;margin:12px 0 6px;font-weight:700;color:var(--fg-strong)}
214
+ h1 b{background:linear-gradient(90deg,var(--primary-soft),var(--cyan));-webkit-background-clip:text;background-clip:text;color:transparent}
215
+ h2{font-size:20px;margin:6px 0 12px;font-weight:600;color:var(--fg-strong)}
216
+ .panel{border:1px solid var(--border);background:var(--surf);padding:14px 16px}
217
+ .empty{color:var(--dim);font-family:var(--mono);font-size:12.5px}
218
+ /* gantt */
219
+ .gantt{display:flex;flex-direction:column;gap:7px}
220
+ .gantt-row{display:grid;grid-template-columns:96px 1fr 56px;align-items:center;gap:10px}
221
+ .gantt-lab{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-align:right}
222
+ .gantt-track{position:relative;height:22px;background:var(--surf-2);border:1px solid var(--border)}
223
+ .gantt-bar{position:absolute;top:0;bottom:0;opacity:.82;display:flex;align-items:center;min-width:2px;overflow:hidden}
224
+ .gantt-cmd{font-family:var(--mono);font-size:10px;color:#06060a;font-weight:600;padding:0 6px;white-space:nowrap}
225
+ .gantt-dur{font-size:10px;color:var(--muted);text-align:right}
226
+ /* usage */
227
+ .usewrap{display:flex;flex-wrap:wrap;gap:8px}
228
+ .usechip{display:flex;align-items:center;gap:9px;border:1px solid var(--border);border-left:3px solid var(--cyan);
229
+ background:var(--surf-2);padding:6px 11px}
230
+ .uc-cmd{font-family:var(--mono);font-size:12px;color:var(--fg-strong);font-weight:600}
231
+ .uc-skill{font-size:10px;color:var(--muted)}
232
+ .uc-count{font-family:var(--mono);font-size:11px;color:var(--cyan)}
233
+ /* subagents */
234
+ .subagent{border:1px solid var(--border);background:var(--surf-2);margin-bottom:8px}
235
+ .subagent summary{cursor:pointer;padding:9px 13px;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
236
+ .sa-name{font-weight:600;color:var(--fg-strong)}
237
+ .sa-meta{font-size:10.5px;color:var(--cyan)}
238
+ .sa-tools{display:flex;gap:5px;flex-wrap:wrap;margin-left:auto}
239
+ .ds-chip{font-family:var(--mono);font-size:9.5px;color:var(--muted);border:1px solid var(--border);padding:1px 6px}
240
+ .steps{margin:0;padding:10px 13px 13px 34px;display:flex;flex-direction:column;gap:4px}
241
+ .steps li{list-style:none;display:flex;align-items:center;gap:10px;font-size:12.5px}
242
+ .step-idx{color:var(--dim);font-size:10px;min-width:18px}
243
+ .step-tool{font-family:var(--mono);color:var(--primary-soft);font-size:12px}
244
+ .step-ts{color:var(--dim);font-size:10px;margin-left:auto}
245
+ /* feedback table */
246
+ .fbtable{width:100%;border-collapse:collapse;font-size:12.5px}
247
+ .fbtable th{font-family:var(--mono);font-size:9.5px;text-transform:uppercase;letter-spacing:.06em;
248
+ color:var(--primary-soft);text-align:left;padding:7px 9px;border-bottom:1px solid var(--border-strong);background:var(--surf-2)}
249
+ .fbtable td{padding:8px 9px;border-bottom:1px solid var(--border);vertical-align:top}
250
+ .fbtable .verbatim{color:var(--fg-strong);white-space:pre-wrap;max-width:260px}
251
+ .fbtable .rationale{color:var(--muted);max-width:220px}
252
+ .fbtable .evidence{color:var(--dim);font-size:10.5px;white-space:nowrap}
253
+ .fbtable .ev-span{color:var(--cyan)}
254
+ .fbtable .fk{color:var(--dim);font-size:10px}
255
+ .sev-pill{font-family:var(--mono);font-size:9.5px;font-weight:700;padding:2px 8px;text-transform:uppercase;border:1px solid}
256
+ .sev-pill.sev-high{color:var(--fail);border-color:var(--fail)}
257
+ .sev-pill.sev-med{color:var(--warn);border-color:var(--warn)}
258
+ .sev-pill.sev-low{color:var(--muted);border-color:var(--border-strong)}
259
+ tr.sev-high td{background:rgba(224,102,102,.05)}
260
+ /* dag */
261
+ .mermaid{background:var(--surf-2);border:1px solid var(--border);padding:16px;overflow:auto;font-family:var(--mono);font-size:12px}
262
+ .foot{margin-top:34px;color:var(--dim);font-size:11px;border-top:1px solid var(--border);padding-top:12px;font-family:var(--mono)}
263
+ `;
264
+
265
+ // ── The mermaid loader (STATIC — never interpolates dynamic data) ─────────────
266
+
267
+ const MERMAID_SCRIPT = `import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
268
+ mermaid.initialize({ startOnLoad: true, theme: 'dark', securityLevel: 'loose', themeVariables: { fontFamily: 'IBM Plex Mono, monospace', fontSize: '13px' } });`;
269
+
270
+ // ── The document ──────────────────────────────────────────────────────────────
271
+
272
+ /**
273
+ * Render the full live-status report as a single self-contained HTML string.
274
+ * Deterministic: identical inputs → byte-identical output (meta.generatedAt is the
275
+ * only time value, and it is injected).
276
+ */
277
+ export function renderDogfoodReport(input: DogfoodReportInput): string {
278
+ const { meta, trajectory, feedback } = input;
279
+ const title = meta.title ?? "Helix Dogfood — Live Status";
280
+ const cmdCount = trajectory.commands.length;
281
+ const subCount = meta.subagentCount ?? trajectory.subagents.length;
282
+
283
+ return `<!doctype html>
284
+ <html lang="en" data-theme="dark"><head><meta charset="utf-8"/>${
285
+ meta.refreshSeconds ? `\n<meta http-equiv="refresh" content="${meta.refreshSeconds}"/>` : ""
286
+ }
287
+ <meta name="viewport" content="width=device-width,initial-scale=1"/>
288
+ <title>${esc(title)}</title>
289
+ <link rel="preconnect" href="https://fonts.googleapis.com">
290
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
291
+ <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
292
+ <style>${STYLE}</style>
293
+ </head><body>
294
+
295
+ <div class="header">
296
+ <div class="wm">MUTAGENT<b>/dogfood</b></div>
297
+ <span class="ds-mono" style="font-size:11px;color:var(--muted)">live session status</span>
298
+ <span class="hmeta">run ${esc(meta.runId)} · generated ${esc(meta.generatedAt)}</span>
299
+ </div>
300
+
301
+ <div class="wrap">
302
+ <div class="lbl">🧬 the agentic development lifecycle · dogfood vacuum</div>
303
+ <h1>${esc(title)}</h1>
304
+ <div class="metarow">
305
+ <i>session <b>${esc(meta.sessionId)}</b></i>
306
+ <i>commands <b>${cmdCount}</b></i>
307
+ <i>subagents <b>${subCount}</b></i>
308
+ <i>feedback <b>${feedback.length}</b></i>
309
+ ${meta.sourceDir ? `<i>source <b>${esc(meta.sourceDir)}</b></i>` : ""}
310
+ </div>
311
+
312
+ <section>
313
+ <div class="lbl">section 1 · lifecycle</div>
314
+ <h2>Stage timeline</h2>
315
+ <div class="panel">${renderTimeline(input)}</div>
316
+ </section>
317
+
318
+ <section>
319
+ <div class="lbl">section 2 · usage</div>
320
+ <h2>*command / skill usage</h2>
321
+ <div class="panel">${renderUsage(input)}</div>
322
+ </section>
323
+
324
+ <section>
325
+ <div class="lbl">section 3 · agents</div>
326
+ <h2>Agent internal steps</h2>
327
+ <div class="panel">${renderSubagents(input)}</div>
328
+ </section>
329
+
330
+ <section>
331
+ <div class="lbl">section 4 · feedback</div>
332
+ <h2>User feedback + notes</h2>
333
+ <div class="panel">${renderFeedback(input)}</div>
334
+ </section>
335
+
336
+ <section>
337
+ <div class="lbl">section 5 · trajectory</div>
338
+ <h2>Call-Stack DAG</h2>
339
+ <div class="panel">${renderDag(input)}</div>
340
+ </section>
341
+
342
+ <div class="foot">MutagenT · Helix dogfood live-status · ${esc(meta.generatedAt)} · restrained-dark · @mutagent/templates palette</div>
343
+ </div>
344
+
345
+ <script type="module">${MERMAID_SCRIPT}</script>
346
+ </body></html>`;
347
+ }